Coverage Report - org.kuali.rice.core.xml.schema.RiceXmlSchemaFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
RiceXmlSchemaFactory
0%
0/57
0%
0/26
3.286
 
 1  
 /*
 2  
  * Copyright 2007-2010 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  
 package org.kuali.rice.core.xml.schema;
 17  
 
 18  
 import java.io.InputStream;
 19  
 import java.util.concurrent.ConcurrentHashMap;
 20  
 
 21  
 import javax.xml.XMLConstants;
 22  
 import javax.xml.transform.stream.StreamSource;
 23  
 import javax.xml.validation.Schema;
 24  
 import javax.xml.validation.SchemaFactory;
 25  
 
 26  
 import org.apache.cxf.common.util.StringUtils;
 27  
 import org.kuali.rice.core.util.RiceUtilities;
 28  
 import org.xml.sax.ErrorHandler;
 29  
 import org.xml.sax.SAXException;
 30  
 
 31  
 /**
 32  
  * This factory class manages compiled XML .xsd schema files.
 33  
  * Schemas are immutable, in-memory representation of grammar specified in an .xsd file.
 34  
  * They represent a set of constraints that can be checked/ enforced against an XML document.  
 35  
  * They are object is thread safe, so they are shared here. 
 36  
  * 
 37  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 38  
  *
 39  
  */
 40  0
 public class RiceXmlSchemaFactory {
 41  
 
 42  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RiceXmlSchemaFactory.class);
 43  
         private static final String SCHEMA_DIR = "classpath:schema/";
 44  
 
 45  
         // A map of already created schemas
 46  0
         private static ConcurrentHashMap schemaMap = new ConcurrentHashMap();
 47  
         
 48  
         /**
 49  
          * 
 50  
          * This method retrieves a schema.  
 51  
          * If the schema already exists, returns it.
 52  
          * If the schema does not exist, attempts to compile a new one using
 53  
          * the schemaName as the resource.   Looks in the default project resource 
 54  
          * schema directory for the .xsd file. 
 55  
          * 
 56  
          * @param schemaName
 57  
          * @return
 58  
          */
 59  
         public static Schema getSchema(String schemaName){
 60  0
                 Schema schema = null;
 61  0
                 if (schemaName != null) {
 62  
                         // if it has already been found, return it, 
 63  
                         // otherwise attempt to create it;
 64  0
                         schema = (Schema) schemaMap.get("schemaName");
 65  0
                         if (schema == null){
 66  0
                                 schema  = addSchema(schemaName);
 67  
                         }
 68  
                 }
 69  0
                 return schema;
 70  
         }
 71  
 
 72  
         /**
 73  
          * 
 74  
          * This method adds a schema to the collection of compiled schema objects.
 75  
          * Either adds a new schema or overrides the schema if it already exists.
 76  
          * Uses the default location to find the schema, the schema name is also 
 77  
          * the filename of the .xsd file
 78  
          * 
 79  
          * @param schemaName - the filename of the .xsd file, also used as the key
 80  
          *          to locate the schema
 81  
          * @return
 82  
          */
 83  
         public static Schema addSchema(String schemaName){
 84  0
                 Schema schema = null;
 85  0
                 if (schemaName != null){
 86  0
                         schema = compileSchema(schemaName);
 87  
                 }
 88  0
                 if (schema != null){
 89  0
                         schemaMap.put(schemaName, schema);
 90  
                 }
 91  0
                 return schema;
 92  
         }
 93  
 
 94  
         /**
 95  
          * 
 96  
          * This method adds a schema to the collection of compiled schema objects.
 97  
          * Either adds a new schema or overrides the schema if it already exists.
 98  
          * Allows for an alternate input stream (other than the default name and location).
 99  
          * 
 100  
          * @param schemaName - key to be used to identify the schema
 101  
          * @param stream - InputStream to be used as a source of the .xsd file
 102  
          *                                  if null, attempts to create an input stream using the 
 103  
          *                                  default schema location, and the schemaName as the resource filename.
 104  
          * @return
 105  
          */
 106  
         public static Schema addSchema(String schemaName, InputStream stream){
 107  0
                 Schema schema = null;
 108  0
                 if (schemaName != null){
 109  0
                         schema = compileSchema(schemaName, stream, null);
 110  
                 }
 111  0
                 if (schema != null){
 112  0
                         schemaMap.put(schemaName, schema);
 113  
                 }
 114  0
                 return schema;
 115  
         }
 116  
         
 117  
 
 118  
         /**
 119  
          * 
 120  
          * Adds a new schema, or overrides an existing schema.
 121  
          * 
 122  
          * @param schemaName
 123  
          * @param inStream
 124  
          * @param eHandler
 125  
          * @return
 126  
          */
 127  
         public static Schema addSchema(String schemaName, InputStream inStream, ErrorHandler eHandler){
 128  0
                 Schema schema = null;
 129  0
                 if (schemaName != null){
 130  
                         // if no input stream specified, get from default location using schemaName as filename
 131  0
                         if (inStream == null){
 132  0
                                 inStream = getInputStream(schemaName);
 133  
                         }
 134  
                         // if no error handler specified, use default
 135  0
                         if (eHandler == null){
 136  0
                                 eHandler = new SchemaValidationErrorHandler();
 137  
                         }
 138  0
                         schema = compileSchema(schemaName, inStream, eHandler);
 139  
                 }
 140  0
                 if (schema != null){
 141  0
                         schemaMap.put(schemaName, schema);
 142  
                 }
 143  0
                 return schema;
 144  
         }
 145  
 
 146  
         /**
 147  
          * 
 148  
          * This method creates a Schema object using the default error handler,
 149  
          * and creating an inputSource from a resource in the default project schema location.
 150  
          *
 151  
          * 
 152  
          * @param schemaName - the filename of the .xsd file, also the key used to identify the Schema object
 153  
          * @return
 154  
          */
 155  
         private static Schema compileSchema(String schemaName){
 156  0
                 InputStream inStream = getInputStream(schemaName);
 157  0
                 ErrorHandler eHandler = new SchemaValidationErrorHandler();
 158  0
                 return compileSchema(schemaName, inStream, eHandler);
 159  
         }
 160  
         
 161  
         /**
 162  
          * 
 163  
          * This method is the worker method that actually creates the Schema object.
 164  
          * 
 165  
          * @param schemaName - name of the schema
 166  
          * @param inStream - input stream created from the .xsd resource
 167  
          * @param errorHandler - the schema validation error handler
 168  
          * @return
 169  
          */
 170  
         private static Schema compileSchema(String schemaName, InputStream inStream, ErrorHandler errorHandler){
 171  0
                 Schema schema = null;
 172  
                 // get input stream
 173  0
                 if (!StringUtils.isEmpty(schemaName)){
 174  0
                         if (inStream != null){
 175  
                                 try{
 176  0
                                         String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
 177  0
                                         SchemaFactory factory = SchemaFactory.newInstance(language);
 178  0
                                         factory.setErrorHandler(errorHandler);
 179  0
                                         factory.setResourceResolver( new SchemaLSResourceResolver());
 180  0
                                         StreamSource ss = new StreamSource(inStream);
 181  0
                                         schema = factory.newSchema(ss);
 182  0
                                 } catch (SAXException e) {
 183  0
                                         LOG.error("The input schema ("+schemaName+") encountered a parsing error");
 184  0
                                         LOG.error(e.getMessage(), e);
 185  0
                                         e.printStackTrace();
 186  0
                                 } 
 187  
                         }
 188  
                 }
 189  0
                 return schema;
 190  
         }
 191  
 
 192  
         /**
 193  
          * 
 194  
          * This method creates an input stream, looking for the resourse in the default
 195  
          * project resource schema directory.
 196  
          * 
 197  
          * TODO: Once we start publishing the schemas, we may want to 
 198  
          * update this to get the published schema
 199  
          * 
 200  
          * @param schemaName
 201  
          * @return
 202  
          */
 203  
         private static InputStream getInputStream(String schemaName){
 204  0
                 InputStream xmlFile = null;
 205  0
                 if (!StringUtils.isEmpty(schemaName)){
 206  
                         try {
 207  
                                 // this will look in classpath:/schema directory
 208  0
                                 xmlFile = RiceUtilities.getResourceAsStream(SCHEMA_DIR + schemaName);
 209  0
                         } catch (Exception e) {
 210  0
                                 LOG.error(e.getMessage(), e);
 211  0
                                 throw new RuntimeException("Error getting XML Schema Input Stream using filename: "+schemaName, e);
 212  0
                         }
 213  
                 }
 214  0
                 return xmlFile;
 215  
         }
 216  
 }