Coverage Report - org.apache.shindig.social.core.util.xstream.StackWriterWrapper
 
Classes in this File Line Coverage Branch Coverage Complexity
StackWriterWrapper
100%
32/32
100%
14/14
0
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements. See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership. The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License. You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied. See the License for the
 16  
  * specific language governing permissions and limitations under the License.
 17  
  */
 18  
 package org.apache.shindig.social.core.util.xstream;
 19  
 
 20  
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
 21  
 import com.thoughtworks.xstream.io.WriterWrapper;
 22  
 
 23  
 import java.util.Map;
 24  
 import java.util.Map.Entry;
 25  
 
 26  
 /**
 27  
  * A Writer that provides a Stack based tracking of the location of the
 28  
  * underlying writer.
 29  
  */
 30  
 public class StackWriterWrapper extends WriterWrapper {
 31  
 
 32  
   /**
 33  
    * The stack that keeps track of current node.
 34  
    */
 35  
   private WriterStack writerStack;
 36  
   private Map<String, NamespaceSet> namespaces;
 37  
 
 38  
   /**
 39  
    * Create a {@link StackWriterWrapper} that wraps a
 40  
    * {@link HierarchicalStreamWriter} and tracks where that writer is in the
 41  
    * hierarchy.
 42  
    *
 43  
    * @param wrapped
 44  
    *          the underlying writer
 45  
    * @param writerStack
 46  
    *          the stack that will record where the writer is.
 47  
    * @param namespaces
 48  
    */
 49  
   public StackWriterWrapper(HierarchicalStreamWriter wrapped,
 50  
       WriterStack writerStack, Map<String, NamespaceSet> namespaces) {
 51  37
     super(wrapped);
 52  37
     this.writerStack = writerStack;
 53  37
     this.namespaces = namespaces;
 54  37
   }
 55  
 
 56  
   /**
 57  
    * Set attribute values on the current node, but filter out class attributes
 58  
    * from the writer, this is not strictly a feature of this class, but is
 59  
    * required (for shindig to meet the XSD requirements.
 60  
    *
 61  
    * @param name
 62  
    *          the name of attribute
 63  
    * @param value
 64  
    *          the value of the attribute.
 65  
    * @see com.thoughtworks.xstream.io.WriterWrapper#addAttribute(java.lang.String,
 66  
    *      java.lang.String)
 67  
    */
 68  
   public void addAttribute(String name, String value) {
 69  50
     if (!"class".equals(name)) {
 70  8
       super.addAttribute(name, value);
 71  
     }
 72  50
   }
 73  
 
 74  
   /**
 75  
    * Begin a new element or node of the supplied name.
 76  
    *
 77  
    * @param name
 78  
    *          the name of the node.
 79  
    *
 80  
    * @see com.thoughtworks.xstream.io.WriterWrapper#startNode(java.lang.String )
 81  
    */
 82  
   @Override
 83  
   public void startNode(String name) {
 84  115
     super.startNode(translateName(name));
 85  115
     addNamespace(name);
 86  115
   }
 87  
 
 88  
   /**
 89  
    * Start a node with a specific class. This may invoke
 90  
    * {@link StackWriterWrapper#startNode(String)} so we might have double
 91  
    * recording of the position in the stack. This would be a bug.
 92  
    *
 93  
    * @see com.thoughtworks.xstream.io.WriterWrapper#startNode(java.lang.String ,
 94  
    *      java.lang.Class)
 95  
    */
 96  
   @SuppressWarnings("unchecked")
 97  
   // API is not generic
 98  
   @Override
 99  
   public void startNode(String name, Class clazz) {
 100  432
     super.startNode(translateName(name), clazz);
 101  432
     addNamespace(name);
 102  432
   }
 103  
 
 104  
   /**
 105  
    * @param name
 106  
    * @return
 107  
    */
 108  
   private String translateName(String name) {
 109  547
     NamespaceSet namespaceSet = namespaces.get(name);
 110  547
     NamespaceSet currentNamespace = writerStack.peekNamespace();
 111  
     // specified by not current
 112  547
     if (namespaceSet != null &&  namespaceSet != currentNamespace) {
 113  41
         return namespaceSet.getElementName(name);
 114  
     }
 115  
     // current has been specified
 116  506
     if ( currentNamespace != null ) {
 117  428
       return currentNamespace.getElementName(name);
 118  
     }
 119  78
     return name;
 120  
 
 121  
   }
 122  
 
 123  
   /**
 124  
    * @param name
 125  
    */
 126  
   private void addNamespace(String name) {
 127  547
     NamespaceSet namespaceSet = namespaces.get(name);
 128  547
     NamespaceSet currentNamespace = writerStack.peekNamespace();
 129  
     // specified and not current
 130  547
     if ( namespaceSet != null && namespaceSet != currentNamespace ) {
 131  41
       for (Entry<String, String> e : namespaceSet.nameSpaceEntrySet()) {
 132  16
         super.addAttribute(e.getKey(), e.getValue());
 133  16
       }
 134  41
       currentNamespace = namespaceSet;
 135  
     }
 136  547
     writerStack.push(name, currentNamespace);
 137  547
   }
 138  
 
 139  
   /**
 140  
    * End the current node, making the parent node the active node.
 141  
    *
 142  
    * @see com.thoughtworks.xstream.io.WriterWrapper#endNode()
 143  
    */
 144  
   @Override
 145  
   public void endNode() {
 146  547
     writerStack.pop();
 147  547
     super.endNode();
 148  547
   }
 149  
 }