Coverage Report - org.kuali.rice.core.xml.XMLImportExportServiceBase
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLImportExportServiceBase
0%
0/50
0%
0/30
5
XMLImportExportServiceBase$State
0%
0/1
N/A
5
 
 1  
 /*
 2  
  * Copyright 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;
 17  
 
 18  
 import org.apache.commons.beanutils.PropertyUtils;
 19  
 import org.apache.log4j.Logger;
 20  
 import org.xml.sax.InputSource;
 21  
 
 22  
 import javax.xml.bind.Unmarshaller;
 23  
 import javax.xml.bind.UnmarshallerHandler;
 24  
 import javax.xml.parsers.SAXParserFactory;
 25  
 import java.io.InputStream;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 
 29  
 /**
 30  
  * Base implementation of an XMLImportExportService.  Will be extracted into
 31  
  * an interface when completed.
 32  
  */
 33  0
 public class XMLImportExportServiceBase {
 34  0
     private static final Logger LOG = Logger.getLogger(XMLImportExportServiceBase.class);
 35  
             
 36  0
     private enum State { INIT, LINKING }
 37  
     
 38  
     private List<XMLInputFilterDefinition> definitions;
 39  
     
 40  
     // TODO: This method is going to have to be changed to support creating
 41  
     //       multiple instances of the given Class.  It should also not
 42  
     //       return an instance, because the import will yield multiple
 43  
     //       instances that need to be saved to the data store.
 44  
     public <T extends Class> T unmarshal(T clazz, Unmarshaller unmarshaller, InputStream in) throws Exception {
 45  0
         SAXParserFactory spf = SAXParserFactory.newInstance();
 46  0
         spf.setNamespaceAware(true);
 47  
 
 48  0
         InitialXMLFilter filter = new InitialXMLFilter();
 49  0
         filter.setXMLImportExportService(this);
 50  
 
 51  
         // Set the InitialXMLFilter's reported Schema URI
 52  0
         List<XMLInputFilterDefinition> definitions = getDefinitions();
 53  0
         if ( filter != null && definitions.size() > 0 ) {
 54  0
             XMLInputFilterDefinition definition = definitions.get(definitions.size()-1);
 55  0
             filter.setReportedSchemaURI(definition.getSchemaURI());
 56  
         }
 57  
 
 58  0
         filter.setParent(spf.newSAXParser().getXMLReader());
 59  
 
 60  0
         UnmarshallerHandler handler = unmarshaller.getUnmarshallerHandler();
 61  
 
 62  0
         filter.setContentHandler(handler);
 63  
 
 64  0
         filter.parse(new InputSource(in));
 65  
 
 66  0
         return (T)handler.getResult();
 67  
     }
 68  
     
 69  
     /**
 70  
      * Returns the linked set of ChainedXMLFilter instances required to
 71  
      * transform a document of the specified schema to current.
 72  
      *
 73  
      * @param schemaURI The Schema URI of the current Document
 74  
      * @return The starting ChainedXMLFilter for transforming the Document
 75  
      */
 76  
     protected ChainedXMLFilter getFilterForSchemaURI(String schemaURI) {
 77  0
         List<XMLInputFilterDefinition> definitions = getDefinitions();
 78  0
         if ( definitions == null )
 79  0
             return new PassthruXMLFilter();
 80  
         
 81  0
         ChainedXMLFilter result = null, prevFilter = null;
 82  0
         State state = State.INIT;
 83  0
         for ( XMLInputFilterDefinition definition : definitions ) {
 84  0
             if ( state == State.INIT && definition.getSchemaURI().equals(schemaURI) ) {
 85  
                 // We actually want to skip this entry and start linking
 86  
                 // at the next one, as we don't need to convert to self.
 87  0
                 state = State.LINKING;
 88  
             }
 89  0
             else if ( state == State.LINKING && definition.getEntries() != null ) {
 90  0
                 for ( XMLInputFilterEntry entry : definition.getEntries() ) {
 91  0
                     if ( entry.getFilterClass() == null )
 92  0
                         continue;
 93  
                     try {
 94  0
                         ChainedXMLFilter filter = entry.getFilterClass().newInstance();
 95  0
                         configureFilter(entry, filter);
 96  0
                         if ( prevFilter != null )
 97  0
                             prevFilter.setParent(filter);
 98  0
                         if ( result == null )
 99  0
                             result = filter;
 100  0
                         prevFilter = filter;
 101  
                     }
 102  0
                     catch ( Exception e ) {
 103  0
                         throw new RuntimeException("Could not instantiate ChainedXMLFilter", e);
 104  0
                     }
 105  
                 }
 106  
             }
 107  
         }
 108  0
         return result != null ? result : new PassthruXMLFilter();
 109  
     }
 110  
 
 111  
     protected void configureFilter(XMLInputFilterEntry entry,
 112  
                                    ChainedXMLFilter filter) {
 113  0
         Map<String, Object> properties = entry.getProperties();
 114  0
         if ( properties != null ) {
 115  
             try {
 116  0
                 for ( Map.Entry<String, Object> property : properties.entrySet() ) {
 117  0
                     PropertyUtils.setProperty(filter, property.getKey(),
 118  
                                               property.getValue());
 119  
                 }
 120  
             }
 121  0
             catch ( Exception e ) {
 122  0
                 throw new RuntimeException("Cannot configure Filter", e);
 123  0
             }
 124  
         }
 125  0
     }
 126  
 
 127  
     /**
 128  
      * Returns the XML Filter Definitions for this Import/Export Service
 129  
      *
 130  
      * @return The Service's XMLInputFilterDefinition List
 131  
      */
 132  
     public List<XMLInputFilterDefinition> getDefinitions() {
 133  0
         return definitions;
 134  
     }
 135  
 
 136  
     /**
 137  
      * Set the XML Filter Definitions for this Import/Export Service
 138  
      *
 139  
      * @param definitions The Service's XMLInputFilterDefinition List
 140  
      */
 141  
     public void setDefinitions(List<XMLInputFilterDefinition> definitions) {
 142  0
         this.definitions = definitions;
 143  0
     }
 144  
 }