Coverage Report - org.kuali.rice.kew.xml.AbstractTransformationFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractTransformationFilter
0%
0/25
0%
0/8
1.2
AbstractTransformationFilter$CurrentElement
0%
0/31
N/A
1.2
 
 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.kew.xml;
 17  
 
 18  
 import org.apache.commons.lang.StringEscapeUtils;
 19  
 import org.kuali.rice.core.api.util.ConcreteKeyValue;
 20  
 import org.kuali.rice.core.api.util.KeyValue;
 21  
 import org.xml.sax.Attributes;
 22  
 import org.xml.sax.SAXException;
 23  
 import org.xml.sax.helpers.XMLFilterImpl;
 24  
 
 25  
 import java.util.ArrayList;
 26  
 import java.util.List;
 27  
 
 28  
 /**
 29  
  * This abstract class handles the xml stack of elements and makes
 30  
  * it easier to run a transformation on certain elements.
 31  
  * 
 32  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 33  
  *
 34  
  */
 35  0
 public abstract class AbstractTransformationFilter extends XMLFilterImpl {
 36  
 
 37  
         
 38  
         // The list which helps keep track of where we are in the XML 
 39  
         // hierarchy as the stream is being processed
 40  0
         private List<String> groupXmlStack = new ArrayList<String>();
 41  
         
 42  
         /**
 43  
          * 
 44  
          * This method allows you to modify the element passed in.  The returned element
 45  
          * will be pushed into a "super.startElement(uri, localName, qName, atts)" call.
 46  
          * 
 47  
          * @param currentElement
 48  
          * @return
 49  
          */
 50  
         public abstract CurrentElement transformStartElement(CurrentElement currentElement) throws SAXException;
 51  
         
 52  
         /**
 53  
          * 
 54  
          * This method allows you to modify the element passed in.  The returned element
 55  
          * will be pushed into a "super.endElement(uri, localName, qName" call.
 56  
          * 
 57  
          * @param currentElement
 58  
          * @return
 59  
          */
 60  
         public abstract CurrentElement transformEndElement(CurrentElement currentElement) throws SAXException;
 61  
                 
 62  
         /*
 63  
          * Build a Map that maps elements we intend to transform to their corresponding transformed value.
 64  
          * The keys in this Map are "hierarchically-qualified" representations of the elements of concern.
 65  
          * 
 66  
          * For example, if "group" is a child of "groups", which is in turn a child of the root
 67  
          * element "data", then it is represented as "data.groups.group" in the Map.
 68  
          */
 69  
         public abstract List<KeyValue> getElementTransformationList();        
 70  
 
 71  
         /**
 72  
          * 
 73  
          * This method returns the element that we should start transforming at.
 74  
          * So, if we had:
 75  
          * <data>
 76  
          *   <groups>
 77  
          *     <group>
 78  
          *     
 79  
          * We might want to start transforming at the group level. 
 80  
          * In that case the startingElement = "group"
 81  
          * 
 82  
          * @return
 83  
          */
 84  
         public abstract String getStartingElementPath();
 85  
         
 86  
         @Override
 87  
         public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
 88  
                 // Push the element onto the stack
 89  0
                 if (groupXmlStack.isEmpty()){                        
 90  0
                                 groupXmlStack.add(localName);                                        
 91  
                 }
 92  
                 else {
 93  
                         // Push a child element by appending localName to the value of the top element in the stack
 94  0
                         groupXmlStack.add(groupXmlStack.get(groupXmlStack.size()-1) + "." + localName);
 95  
                 }
 96  
                 
 97  
                 // Fetch the current element from the top of the stack
 98  0
                 String currentElementKey = groupXmlStack.get(groupXmlStack.size()-1);
 99  0
                 CurrentElement currentElement = new CurrentElement(currentElementKey,uri, localName, qName, atts);
 100  
                                 
 101  
                 // Transform elements of concern:
 102  0
                 if (getElementTransformationList().contains(new ConcreteKeyValue(getTrimmedCurrentElementKey(currentElementKey), uri))){
 103  0
                         CurrentElement transformedElement = this.transformStartElement(currentElement);                        
 104  0
                         super.startElement(transformedElement.getUri(), transformedElement.getLocalName(), transformedElement.getqName(), transformedElement.getAttributes());
 105  0
                 }
 106  
                 else {
 107  
                         // Pass other elements through as they are
 108  0
                         super.startElement(uri, localName, qName, atts);
 109  
                 }
 110  0
     }
 111  
                 
 112  
         protected String getTrimmedCurrentElementKey(String currentElementKey){
 113  0
                 return currentElementKey.replaceFirst(StringEscapeUtils.escapeJava(this.getStartingElementPath()+"."), "");
 114  
         }
 115  
     @Override
 116  
         public void endElement(String uri, String localName, String qName) throws SAXException {
 117  
                 // Fetch the current element from the top of the stack
 118  0
                 String currentElementKey = groupXmlStack.get(groupXmlStack.size()-1);
 119  0
                 CurrentElement currentElement = new CurrentElement(currentElementKey,uri, localName, qName);
 120  
                 
 121  0
                 if (getElementTransformationList().contains(new ConcreteKeyValue(getTrimmedCurrentElementKey(currentElementKey), uri))){
 122  0
                         CurrentElement transformedElement = this.transformEndElement(currentElement);                        
 123  0
                         super.endElement(transformedElement.getUri(), transformedElement.getLocalName(), transformedElement.getqName());
 124  0
                 }                
 125  
                 else {
 126  
                         // Pass other elements through as they are
 127  0
                         super.endElement(uri, localName, qName);
 128  
                 }
 129  
                 
 130  
                 // Pop the element from the stack if it's not empty
 131  0
                 if (!groupXmlStack.isEmpty()){
 132  0
                         groupXmlStack.remove(currentElementKey);                        
 133  
                 }
 134  0
     }
 135  
 
 136  0
         public class CurrentElement {
 137  
                 String nameKey;
 138  
                 String uri;
 139  
                 String localName; 
 140  
                 String qName; 
 141  
                 Attributes attributes;
 142  
                 
 143  0
                 public CurrentElement(){}
 144  
                                 
 145  
                 public CurrentElement(String nameKey, String uri, String localName,
 146  0
                                 String qName) {
 147  0
                         super();
 148  0
                         this.nameKey = nameKey;
 149  0
                         this.uri = uri;
 150  0
                         this.localName = localName;
 151  0
                         this.qName = qName;
 152  0
                 }
 153  
 
 154  
                 public CurrentElement(String nameKey,String uri, String localName, String qName,
 155  0
                                 Attributes attributes) {
 156  0
                         super();
 157  0
                         this.nameKey = nameKey;
 158  0
                         this.uri = uri;
 159  0
                         this.localName = localName;
 160  0
                         this.qName = qName;
 161  0
                         this.attributes = attributes;
 162  0
                 }
 163  
 
 164  
 
 165  
                 public String getUri() {
 166  0
                         return this.uri;
 167  
                 }
 168  
                 public void setUri(String uri) {
 169  0
                         this.uri = uri;
 170  0
                 }
 171  
                 public String getLocalName() {
 172  0
                         return this.localName;
 173  
                 }
 174  
                 public void setLocalName(String localName) {
 175  0
                         this.localName = localName;
 176  0
                 }
 177  
                 public String getqName() {
 178  0
                         return this.qName;
 179  
                 }
 180  
                 public void setqName(String qName) {
 181  0
                         this.qName = qName;
 182  0
                 }
 183  
                 public Attributes getAttributes() {
 184  0
                         return this.attributes;
 185  
                 }
 186  
                 public void setAttributes(Attributes attributes) {
 187  0
                         this.attributes = attributes;
 188  0
                 }
 189  
 
 190  
                 public String getNameKey() {
 191  0
                         return this.nameKey;
 192  
                 }
 193  
 
 194  
                 public void setNameKey(String nameKey) {
 195  0
                         this.nameKey = nameKey;
 196  0
                 }                
 197  
         }
 198  
         
 199  
 }