Coverage Report - org.apache.shindig.social.core.util.BeanXStreamConverter
 
Classes in this File Line Coverage Branch Coverage Complexity
BeanXStreamConverter
100%
42/42
100%
10/10
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;
 19  
 
 20  
 import com.google.common.collect.Maps;
 21  
 
 22  
 import com.google.inject.Inject;
 23  
 
 24  
 import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
 25  
 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
 26  
 import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
 27  
 import com.thoughtworks.xstream.io.xml.StaxDriver;
 28  
 import com.thoughtworks.xstream.io.xml.XppDriver;
 29  
 import com.thoughtworks.xstream.mapper.DefaultMapper;
 30  
 import com.thoughtworks.xstream.mapper.Mapper;
 31  
 
 32  
 import org.apache.shindig.social.core.util.xstream.StackDriver;
 33  
 import org.apache.shindig.social.core.util.xstream.ThreadSafeWriterStack;
 34  
 import org.apache.shindig.social.core.util.xstream.WriterStack;
 35  
 import org.apache.shindig.social.core.util.xstream.XStreamConfiguration;
 36  
 import org.apache.shindig.social.core.util.xstream.XStreamConfiguration.ConverterConfig;
 37  
 import org.apache.shindig.social.opensocial.service.BeanConverter;
 38  
 import org.apache.shindig.social.opensocial.spi.DataCollection;
 39  
 import org.apache.shindig.social.opensocial.spi.RestfulCollection;
 40  
 
 41  
 import org.apache.commons.logging.Log;
 42  
 import org.apache.commons.logging.LogFactory;
 43  
 
 44  
 import java.util.HashMap;
 45  
 import java.util.Map;
 46  
 
 47  
 public class BeanXStreamConverter implements BeanConverter {
 48  
   public static final String XML_DECL = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
 49  1
   private static final XStreamConfiguration.ConverterSet[] MAPPER_SCOPES = new XStreamConfiguration.ConverterSet[] {
 50  
       XStreamConfiguration.ConverterSet.MAP,
 51  
       XStreamConfiguration.ConverterSet.COLLECTION,
 52  
       XStreamConfiguration.ConverterSet.DEFAULT };
 53  1
   private static Log log = LogFactory.getLog(BeanXStreamConverter.class);
 54  
   private ReflectionProvider rp;
 55  
   private HierarchicalStreamDriver driver;
 56  
   protected WriterStack writerStack;
 57  
 
 58  
 
 59  74
   protected Map<XStreamConfiguration.ConverterSet, ConverterConfig> converterMap = Maps.newHashMap();
 60  
 
 61  
   @Inject
 62  74
   public BeanXStreamConverter(XStreamConfiguration configuration) {
 63  74
     rp = new PureJavaReflectionProvider();
 64  74
     Mapper dmapper = new DefaultMapper(this.getClass().getClassLoader());
 65  
     /*
 66  
      * Putting this here means only one conversion per thread may be active at
 67  
      * any one time, but since the conversion process is atomic this will not
 68  
      * matter unless the class is extended.
 69  
      */
 70  74
     writerStack = new ThreadSafeWriterStack();
 71  
         
 72  
 
 73  
     /*
 74  
      * create a driver that wires into a standard driver, and updates the stack
 75  
      * position.
 76  
      */
 77  74
     driver = new StackDriver(new XppDriver(), writerStack, configuration.getNameSpaces());
 78  
     /*
 79  
      * Create an interface class mapper that understands class hierarchy for
 80  
      * single items
 81  
      */
 82  296
     for (XStreamConfiguration.ConverterSet c : MAPPER_SCOPES) {
 83  222
       converterMap.put(c, configuration.getConverterConfig(c,rp,dmapper,driver,writerStack));
 84  
     }
 85  74
   }
 86  
 
 87  
   public String getContentType() {
 88  21
     return "application/xml";
 89  
   }
 90  
 
 91  
   public String convertToString(Object pojo) {
 92  29
     return convertToXml(pojo);
 93  
   }
 94  
 
 95  
   /**
 96  
    * convert an Object to XML, but make certain that only one of these is run on
 97  
    * a thread at any one time. This only matters if this class is extended.
 98  
    *
 99  
    * @param obj
 100  
    * @return
 101  
    */
 102  
   private String convertToXml(Object obj) {
 103  
 
 104  29
     writerStack.reset();
 105  29
     if (obj instanceof Map) {
 106  8
       Map<?, ?> m = (Map<?, ?>) obj;
 107  8
       ConverterConfig cc = converterMap
 108  
           .get(XStreamConfiguration.ConverterSet.MAP);
 109  8
       if (m.size() == 1) {
 110  6
         Object s = m.values().iterator().next();
 111  6
         cc.mapper.setBaseObject(s); // thread safe method
 112  6
         String result = cc.xstream.toXML(s);
 113  6
         log.debug("Result is " + result);
 114  6
         return "<response>" + result + "</response>";
 115  
       }
 116  2
     } else if (obj instanceof RestfulCollection) {
 117  6
       ConverterConfig cc = converterMap
 118  
           .get(XStreamConfiguration.ConverterSet.COLLECTION);
 119  6
       cc.mapper.setBaseObject(obj); // thread safe method
 120  6
       String result = cc.xstream.toXML(obj);
 121  6
       log.debug("Result is " + result);
 122  6
       return result;
 123  15
     } else if (obj instanceof DataCollection) {
 124  9
       ConverterConfig cc = converterMap
 125  
           .get(XStreamConfiguration.ConverterSet.MAP);
 126  9
       cc.mapper.setBaseObject(obj); // thread safe method
 127  9
       String result = cc.xstream.toXML(obj);
 128  9
       log.debug("Result is " + result);
 129  9
       return result;
 130  
     }
 131  8
     ConverterConfig cc = converterMap
 132  
         .get(XStreamConfiguration.ConverterSet.DEFAULT);
 133  
 
 134  8
     cc.mapper.setBaseObject(obj); // thread safe method
 135  8
     String result = cc.xstream.toXML(obj);
 136  8
     log.debug("Result is " + result);
 137  8
     return "<response>" + result + "</response>";
 138  
   }
 139  
 
 140  
   @SuppressWarnings("unchecked")
 141  
   public <T> T convertToObject(String xml, Class<T> className) {
 142  5
     ConverterConfig cc = converterMap.get(XStreamConfiguration.ConverterSet.DEFAULT);
 143  5
     return (T) cc.xstream.fromXML(xml);
 144  
   }
 145  
 
 146  
 }