Coverage Report - org.kuali.rice.core.ojb.BaseOjbConfigurer
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseOjbConfigurer
0%
0/98
0%
0/22
2.062
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 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  
  * Base Ojb Configurer implementation which configures OJB for a particular rice module.
 56  
  *
 57  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 58  
  */
 59  
 public class BaseOjbConfigurer extends BaseLifecycle implements InitializingBean {
 60  
 
 61  0
     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  
      * The OJB JCD aliases 
 69  
      */
 70  
     protected String[] jcdAliases;
 71  
     /**
 72  
      * The location of the OJB repository/metadata descriptor
 73  
      */
 74  
     protected String metadataLocation;
 75  
 
 76  
     /**
 77  
      * No-arg constructor
 78  
      */
 79  0
     public BaseOjbConfigurer() {
 80  
         // nothing
 81  0
     }
 82  
 
 83  
     /**
 84  
      * Constructor that derives jcd aliases and repository metadata location from the module name
 85  
      * jcdAliases = [ moduleName.toLowerCase() + "DataSource" ]
 86  
      * metadataLocation = "classpath:OJB-repository-" + moduleName.toLowerCase() + ".xml";
 87  
      * 
 88  
      * @param moduleName the module name
 89  
      */
 90  0
     public BaseOjbConfigurer(String moduleName) {
 91  0
         this.metadataLocation = "classpath:org/kuali/rice/" + moduleName.toLowerCase() + "/config/OJB-repository-" + moduleName.toLowerCase() + ".xml";
 92  0
         this.jcdAliases = new String[] { moduleName.toLowerCase() + "DataSource" };
 93  0
     }
 94  
 
 95  
     /**
 96  
      * Constructor which takes the jcdAliases and metadata location
 97  
      * 
 98  
      * @param jcdAliases the jcd aliases
 99  
      * @param metadataLocation the metadata location
 100  
      */
 101  0
     public BaseOjbConfigurer(String[] jcdAliases, String metadataLocation) {
 102  0
         this.jcdAliases = jcdAliases;
 103  0
         this.metadataLocation = metadataLocation;
 104  0
     }
 105  
 
 106  
     @Override
 107  
     public void start() throws Exception {
 108  
         // if OJB has not already been loaded, let's trigger a load using our built-in OJB properties file
 109  0
         String currentValue = System.getProperty(OJB_PROPERTIES_PROP);
 110  
         try {
 111  0
             System.setProperty(OJB_PROPERTIES_PROP, getOjbPropertiesLocation());
 112  0
             MetadataManager mm = MetadataManager.getInstance();
 113  0
             establishConnectionMetaData(mm);
 114  0
             establishRepositoryMetaData(mm);
 115  0
         } finally {
 116  0
             if (currentValue == null) {
 117  0
                 System.getProperties().remove(OJB_PROPERTIES_PROP);
 118  
             } else {
 119  0
                 System.setProperty(OJB_PROPERTIES_PROP, currentValue);
 120  
             }
 121  0
         }
 122  0
         super.start();
 123  0
     }
 124  
 
 125  
     @Override
 126  
     public void stop() throws Exception {
 127  0
         super.stop();
 128  0
     }
 129  
 
 130  
 
 131  
 
 132  
     protected String getOjbPropertiesLocation() {
 133  0
         String ojbPropertiesLocation = ConfigContext.getCurrentContextConfig().getProperty(RICE_OJB_PROPERTIES_PARAM);
 134  0
         if (!StringUtils.isBlank(ojbPropertiesLocation)) {
 135  0
             LOG.info("Using custom OJB.properites from: " + ojbPropertiesLocation);
 136  
         } else {                
 137  0
             ojbPropertiesLocation = DEFAULT_OJB_PROPERTIES;
 138  0
             ConfigContext.getCurrentContextConfig().putProperty(RICE_OJB_PROPERTIES_PARAM, ojbPropertiesLocation);
 139  0
             LOG.info("Using default OJB.properties from: " + ojbPropertiesLocation);
 140  
         }
 141  0
         return ojbPropertiesLocation;
 142  
     }
 143  
 
 144  
     protected void establishConnectionMetaData(MetadataManager mm) throws Exception {
 145  0
         String connMetadata = getMetadataLocation();
 146  0
         if (StringUtils.isBlank(connMetadata)) {
 147  0
             LOG.info("No OJB connection metadata loaded.");
 148  0
             return;
 149  
         }
 150  0
         if (!isConnectionAlreadyConfigured(mm)) {
 151  0
             LOG.info("Loading OJB Connection Metadata from " + connMetadata);
 152  0
             DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
 153  0
             InputStream is = resourceLoader.getResource(connMetadata).getInputStream();
 154  0
             is = preprocessConnectionMetadata(is);
 155  0
             ConnectionRepository cr = mm.readConnectionRepository(is);
 156  0
             mm.mergeConnectionRepository(cr);
 157  
             try {
 158  0
                 is.close();
 159  0
             } catch (Exception e) {
 160  0
                 LOG.warn("Failed to close stream to file " + connMetadata, e);
 161  0
             }
 162  0
         } else {
 163  0
             LOG.info("OJB Connections already configured for jcd aliases '" + StringUtils.join(getJcdAliases(), ", ") + "', skipping Metadata merge.");
 164  
         }
 165  0
     }
 166  
 
 167  
     protected InputStream preprocessConnectionMetadata(InputStream inputStream) throws Exception {
 168  0
         Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(inputStream));
 169  0
         XPath xpath = XPathFactory.newInstance().newXPath();
 170  0
         NodeList connectionDescriptors = (NodeList)xpath.evaluate("/descriptor-repository/jdbc-connection-descriptor", document, XPathConstants.NODESET);
 171  0
         for (int index = 0; index < connectionDescriptors.getLength(); index++) {
 172  0
             Element descriptor = (Element)connectionDescriptors.item(index);
 173  0
             String currentPlatform = descriptor.getAttribute("platform");
 174  0
             if (StringUtils.isBlank(currentPlatform)) {
 175  0
                 String ojbPlatform = ConfigContext.getCurrentContextConfig().getProperty(Config.OJB_PLATFORM);
 176  0
                 if (StringUtils.isEmpty(ojbPlatform)) {
 177  0
                     throw new ConfigurationException("Could not configure OJB, the '" + Config.OJB_PLATFORM + "' configuration property was not set.");
 178  
                 }
 179  0
                 LOG.info("Setting OJB connection descriptor database platform to '" + ojbPlatform + "'");
 180  0
                 descriptor.setAttribute("platform", ojbPlatform);
 181  
             }
 182  
         }
 183  0
         Transformer transformer = TransformerFactory.newInstance().newTransformer();
 184  0
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 185  0
         transformer.transform(new DOMSource(document), new StreamResult(new BufferedOutputStream(baos)));
 186  0
         return new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray()));
 187  
     }
 188  
 
 189  
     @SuppressWarnings("unchecked")
 190  
         protected boolean isConnectionAlreadyConfigured(MetadataManager mm) {
 191  0
         List descriptors = mm.connectionRepository().getAllDescriptor();
 192  0
         for (Iterator iterator = descriptors.iterator(); iterator.hasNext();) {
 193  0
             JdbcConnectionDescriptor descriptor = (JdbcConnectionDescriptor) iterator.next();
 194  0
             for (String jcdAlias : getJcdAliases()) {
 195  0
                 if (descriptor.getJcdAlias().equals(jcdAlias)) {
 196  0
                     return true;
 197  
                 }
 198  
             }
 199  0
         }
 200  0
         return false;
 201  
     }
 202  
 
 203  
     protected InputStream preprocessRepositoryMetadata(InputStream inputStream) throws Exception {
 204  0
         return inputStream;
 205  
     }
 206  
 
 207  
     protected void establishRepositoryMetaData(MetadataManager mm) throws Exception {
 208  0
         String repoMetadata = getMetadataLocation();
 209  0
         if (StringUtils.isBlank(repoMetadata)) {
 210  0
             LOG.info("No OJB repository metadata loaded.");
 211  0
             return;
 212  
         }
 213  0
         LOG.info("Loading OJB Metadata from " + repoMetadata);
 214  0
         DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
 215  0
         InputStream is = resourceLoader.getResource(repoMetadata).getInputStream();
 216  0
         is = preprocessRepositoryMetadata(is);
 217  0
         DescriptorRepository dr = mm.readDescriptorRepository(is);
 218  0
         mm.mergeDescriptorRepository(dr);
 219  
         try {
 220  0
             is.close();
 221  0
         } catch (Exception e) {
 222  0
             LOG.warn("Failed to close stream to file " + repoMetadata, e);
 223  0
         }
 224  0
     }
 225  
 
 226  
     /**
 227  
      * Return the jcd alias of the connection loaded by the connection metadata.
 228  
      * The default implementation returns the jcd alias with which the instance was created (if any) 
 229  
      * @return the jcd alias of the connection loaded by the connection metadata.
 230  
      */
 231  
     protected String[] getJcdAliases() {
 232  0
         return jcdAliases;
 233  
     }
 234  
 
 235  
     /**
 236  
      * Should return a String representing the location of a file to load OJB connection and
 237  
      * repository metadata from.  If null or empty than no metadata will be loaded.
 238  
      * The default implementation returns the metadata location with which the instance was created (if any)
 239  
      */
 240  
     protected String getMetadataLocation() {
 241  0
         return metadataLocation;
 242  
     }
 243  
 
 244  
         /***
 245  
          * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 246  
          */
 247  
         public void afterPropertiesSet() throws Exception {
 248  0
                 this.start();
 249  0
         }
 250  
 
 251  
         /**
 252  
          * @param jcdAliases the jcdAliases to set
 253  
          */
 254  
         public void setJcdAliases(String[] jcdAliases) {
 255  0
                 this.jcdAliases = jcdAliases;
 256  0
         }
 257  
 
 258  
         /**
 259  
          * @param metadataLocation the metadataLocation to set
 260  
          */
 261  
         public void setMetadataLocation(String metadataLocation) {
 262  0
                 this.metadataLocation = metadataLocation;
 263  0
         }
 264  
 
 265  
 }