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