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 java.util.ArrayList;
 19  
 import java.util.List;
 20  
 import java.util.Map;
 21  
 
 22  
 import org.apache.commons.lang.StringEscapeUtils;
 23  
 import org.kuali.rice.core.util.KeyValue;
 24  
 import org.xml.sax.Attributes;
 25  
 import org.xml.sax.SAXException;
 26  
 import org.xml.sax.helpers.XMLFilterImpl;
 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  
         public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
 87  
                 // Push the element onto the stack
 88  0
                 if (groupXmlStack.isEmpty()){                        
 89  0
                                 groupXmlStack.add(localName);                                        
 90  
                 }
 91  
                 else {
 92  
                         // Push a child element by appending localName to the value of the top element in the stack
 93  0
                         groupXmlStack.add(groupXmlStack.get(groupXmlStack.size()-1) + "." + localName);
 94  
                 }
 95  
                 
 96  
                 // Fetch the current element from the top of the stack
 97  0
                 String currentElementKey = groupXmlStack.get(groupXmlStack.size()-1);
 98  0
                 CurrentElement currentElement = new CurrentElement(currentElementKey,uri, localName, qName, atts);
 99  
                                 
 100  
                 // Transform elements of concern:
 101  0
                 if (getElementTransformationList().contains(new KeyValue(getTrimmedCurrentElementKey(currentElementKey), uri))){
 102  0
                         CurrentElement transformedElement = this.transformStartElement(currentElement);                        
 103  0
                         super.startElement(transformedElement.getUri(), transformedElement.getLocalName(), transformedElement.getqName(), transformedElement.getAttributes());
 104  0
                 }
 105  
                 else {
 106  
                         // Pass other elements through as they are
 107  0
                         super.startElement(uri, localName, qName, atts);
 108  
                 }
 109  0
     }
 110  
                 
 111  
         protected String getTrimmedCurrentElementKey(String currentElementKey){
 112  0
                 return currentElementKey.replaceFirst(StringEscapeUtils.escapeJava(this.getStartingElementPath()+"."), "");
 113  
         }
 114  
     public void endElement(String uri, String localName, String qName) throws SAXException {
 115  
                 // Fetch the current element from the top of the stack
 116  0
                 String currentElementKey = groupXmlStack.get(groupXmlStack.size()-1);
 117  0
                 CurrentElement currentElement = new CurrentElement(currentElementKey,uri, localName, qName);
 118  
                 
 119  0
                 if (getElementTransformationList().contains(new KeyValue(getTrimmedCurrentElementKey(currentElementKey), uri))){
 120  0
                         CurrentElement transformedElement = this.transformEndElement(currentElement);                        
 121  0
                         super.endElement(transformedElement.getUri(), transformedElement.getLocalName(), transformedElement.getqName());
 122  0
                 }                
 123  
                 else {
 124  
                         // Pass other elements through as they are
 125  0
                         super.endElement(uri, localName, qName);
 126  
                 }
 127  
                 
 128  
                 // Pop the element from the stack if it's not empty
 129  0
                 if (!groupXmlStack.isEmpty()){
 130  0
                         groupXmlStack.remove(currentElementKey);                        
 131  
                 }
 132  0
     }
 133  
 
 134  0
         public class CurrentElement {
 135  
                 String nameKey;
 136  
                 String uri;
 137  
                 String localName; 
 138  
                 String qName; 
 139  
                 Attributes attributes;
 140  
                 
 141  0
                 public CurrentElement(){}
 142  
                                 
 143  
                 public CurrentElement(String nameKey, String uri, String localName,
 144  0
                                 String qName) {
 145  0
                         super();
 146  0
                         this.nameKey = nameKey;
 147  0
                         this.uri = uri;
 148  0
                         this.localName = localName;
 149  0
                         this.qName = qName;
 150  0
                 }
 151  
 
 152  
                 public CurrentElement(String nameKey,String uri, String localName, String qName,
 153  0
                                 Attributes attributes) {
 154  0
                         super();
 155  0
                         this.nameKey = nameKey;
 156  0
                         this.uri = uri;
 157  0
                         this.localName = localName;
 158  0
                         this.qName = qName;
 159  0
                         this.attributes = attributes;
 160  0
                 }
 161  
 
 162  
 
 163  
                 public String getUri() {
 164  0
                         return this.uri;
 165  
                 }
 166  
                 public void setUri(String uri) {
 167  0
                         this.uri = uri;
 168  0
                 }
 169  
                 public String getLocalName() {
 170  0
                         return this.localName;
 171  
                 }
 172  
                 public void setLocalName(String localName) {
 173  0
                         this.localName = localName;
 174  0
                 }
 175  
                 public String getqName() {
 176  0
                         return this.qName;
 177  
                 }
 178  
                 public void setqName(String qName) {
 179  0
                         this.qName = qName;
 180  0
                 }
 181  
                 public Attributes getAttributes() {
 182  0
                         return this.attributes;
 183  
                 }
 184  
                 public void setAttributes(Attributes attributes) {
 185  0
                         this.attributes = attributes;
 186  0
                 }
 187  
 
 188  
                 public String getNameKey() {
 189  0
                         return this.nameKey;
 190  
                 }
 191  
 
 192  
                 public void setNameKey(String nameKey) {
 193  0
                         this.nameKey = nameKey;
 194  0
                 }                
 195  
         }
 196  
         
 197  
 }