1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.core.ojb;
18
19 import java.io.BufferedInputStream;
20 import java.io.BufferedOutputStream;
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.InputStream;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.transform.Transformer;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.dom.DOMSource;
31 import javax.xml.transform.stream.StreamResult;
32 import javax.xml.xpath.XPath;
33 import javax.xml.xpath.XPathConstants;
34 import javax.xml.xpath.XPathFactory;
35
36 import org.apache.commons.lang.StringUtils;
37 import org.apache.log4j.Logger;
38 import org.apache.ojb.broker.metadata.ConnectionRepository;
39 import org.apache.ojb.broker.metadata.DescriptorRepository;
40 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
41 import org.apache.ojb.broker.metadata.MetadataManager;
42 import org.kuali.rice.core.config.Config;
43 import org.kuali.rice.core.config.ConfigContext;
44 import org.kuali.rice.core.config.ConfigurationException;
45 import org.kuali.rice.core.lifecycle.BaseLifecycle;
46 import org.kuali.rice.core.util.ClassLoaderUtils;
47 import org.springframework.beans.factory.InitializingBean;
48 import org.springframework.core.io.DefaultResourceLoader;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.NodeList;
52 import org.xml.sax.InputSource;
53
54
55
56
57
58
59 public class BaseOjbConfigurer extends BaseLifecycle implements InitializingBean {
60
61 private static final Logger LOG = Logger.getLogger(BaseOjbConfigurer.class);
62
63 public static final String RICE_OJB_PROPERTIES_PARAM = "rice.custom.ojb.properties";
64 public static final String OJB_PROPERTIES_PROP = "OJB.properties";
65 public static final String DEFAULT_OJB_PROPERTIES = "org/kuali/rice/core/ojb/RiceOJB.properties";
66
67
68
69
70 protected String[] jcdAliases;
71
72
73
74 protected String metadataLocation;
75
76
77
78
79 public BaseOjbConfigurer() {
80
81 }
82
83
84
85
86
87
88
89
90 public BaseOjbConfigurer(String moduleName) {
91 this.metadataLocation = "classpath:org/kuali/rice/" + moduleName.toLowerCase() + "/config/OJB-repository-" + moduleName.toLowerCase() + ".xml";
92 this.jcdAliases = new String[] { moduleName.toLowerCase() + "DataSource" };
93 }
94
95
96
97
98
99
100
101 public BaseOjbConfigurer(String[] jcdAliases, String metadataLocation) {
102 this.jcdAliases = jcdAliases;
103 this.metadataLocation = metadataLocation;
104 }
105
106 @Override
107 public void start() throws Exception {
108
109 String currentValue = System.getProperty(OJB_PROPERTIES_PROP);
110 try {
111 System.setProperty(OJB_PROPERTIES_PROP, getOjbPropertiesLocation());
112 MetadataManager mm = MetadataManager.getInstance();
113 establishConnectionMetaData(mm);
114 establishRepositoryMetaData(mm);
115 } finally {
116 if (currentValue == null) {
117 System.getProperties().remove(OJB_PROPERTIES_PROP);
118 } else {
119 System.setProperty(OJB_PROPERTIES_PROP, currentValue);
120 }
121 }
122 super.start();
123 }
124
125 @Override
126 public void stop() throws Exception {
127 super.stop();
128 }
129
130
131
132 protected String getOjbPropertiesLocation() {
133 String ojbPropertiesLocation = ConfigContext.getCurrentContextConfig().getProperty(RICE_OJB_PROPERTIES_PARAM);
134 if (!StringUtils.isBlank(ojbPropertiesLocation)) {
135 LOG.info("Using custom OJB.properites from: " + ojbPropertiesLocation);
136 } else {
137 ojbPropertiesLocation = DEFAULT_OJB_PROPERTIES;
138 ConfigContext.getCurrentContextConfig().putProperty(RICE_OJB_PROPERTIES_PARAM, ojbPropertiesLocation);
139 LOG.info("Using default OJB.properties from: " + ojbPropertiesLocation);
140 }
141 return ojbPropertiesLocation;
142 }
143
144 protected void establishConnectionMetaData(MetadataManager mm) throws Exception {
145 String connMetadata = getMetadataLocation();
146 if (StringUtils.isBlank(connMetadata)) {
147 LOG.info("No OJB connection metadata loaded.");
148 return;
149 }
150 if (!isConnectionAlreadyConfigured(mm)) {
151 LOG.info("Loading OJB Connection Metadata from " + connMetadata);
152 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
153 InputStream is = resourceLoader.getResource(connMetadata).getInputStream();
154 is = preprocessConnectionMetadata(is);
155 ConnectionRepository cr = mm.readConnectionRepository(is);
156 mm.mergeConnectionRepository(cr);
157 try {
158 is.close();
159 } catch (Exception e) {
160 LOG.warn("Failed to close stream to file " + connMetadata, e);
161 }
162 } else {
163 LOG.info("OJB Connections already configured for jcd aliases '" + StringUtils.join(getJcdAliases(), ", ") + "', skipping Metadata merge.");
164 }
165 }
166
167 protected InputStream preprocessConnectionMetadata(InputStream inputStream) throws Exception {
168 Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(inputStream));
169 XPath xpath = XPathFactory.newInstance().newXPath();
170 NodeList connectionDescriptors = (NodeList)xpath.evaluate("/descriptor-repository/jdbc-connection-descriptor", document, XPathConstants.NODESET);
171 for (int index = 0; index < connectionDescriptors.getLength(); index++) {
172 Element descriptor = (Element)connectionDescriptors.item(index);
173 String currentPlatform = descriptor.getAttribute("platform");
174 if (StringUtils.isBlank(currentPlatform)) {
175 String ojbPlatform = ConfigContext.getCurrentContextConfig().getProperty(Config.OJB_PLATFORM);
176 if (StringUtils.isEmpty(ojbPlatform)) {
177 throw new ConfigurationException("Could not configure OJB, the '" + Config.OJB_PLATFORM + "' configuration property was not set.");
178 }
179 LOG.info("Setting OJB connection descriptor database platform to '" + ojbPlatform + "'");
180 descriptor.setAttribute("platform", ojbPlatform);
181 }
182 }
183 Transformer transformer = TransformerFactory.newInstance().newTransformer();
184 ByteArrayOutputStream baos = new ByteArrayOutputStream();
185 transformer.transform(new DOMSource(document), new StreamResult(new BufferedOutputStream(baos)));
186 return new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray()));
187 }
188
189 @SuppressWarnings("unchecked")
190 protected boolean isConnectionAlreadyConfigured(MetadataManager mm) {
191 List descriptors = mm.connectionRepository().getAllDescriptor();
192 for (Iterator iterator = descriptors.iterator(); iterator.hasNext();) {
193 JdbcConnectionDescriptor descriptor = (JdbcConnectionDescriptor) iterator.next();
194 for (String jcdAlias : getJcdAliases()) {
195 if (descriptor.getJcdAlias().equals(jcdAlias)) {
196 return true;
197 }
198 }
199 }
200 return false;
201 }
202
203 protected InputStream preprocessRepositoryMetadata(InputStream inputStream) throws Exception {
204 return inputStream;
205 }
206
207 protected void establishRepositoryMetaData(MetadataManager mm) throws Exception {
208 String repoMetadata = getMetadataLocation();
209 if (StringUtils.isBlank(repoMetadata)) {
210 LOG.info("No OJB repository metadata loaded.");
211 return;
212 }
213 LOG.info("Loading OJB Metadata from " + repoMetadata);
214 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
215 InputStream is = resourceLoader.getResource(repoMetadata).getInputStream();
216 is = preprocessRepositoryMetadata(is);
217 DescriptorRepository dr = mm.readDescriptorRepository(is);
218 mm.mergeDescriptorRepository(dr);
219 try {
220 is.close();
221 } catch (Exception e) {
222 LOG.warn("Failed to close stream to file " + repoMetadata, e);
223 }
224 }
225
226
227
228
229
230
231 protected String[] getJcdAliases() {
232 return jcdAliases;
233 }
234
235
236
237
238
239
240 protected String getMetadataLocation() {
241 return metadataLocation;
242 }
243
244
245
246
247 public void afterPropertiesSet() throws Exception {
248 this.start();
249 }
250
251
252
253
254 public void setJcdAliases(String[] jcdAliases) {
255 this.jcdAliases = jcdAliases;
256 }
257
258
259
260
261 public void setMetadataLocation(String metadataLocation) {
262 this.metadataLocation = metadataLocation;
263 }
264
265 }