You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2009/02/10 02:53:59 UTC

svn commit: r742816 [2/5] - in /incubator/shindig/trunk/java: common/ common/src/main/java/org/apache/shindig/protocol/ common/src/main/java/org/apache/shindig/protocol/conversion/ common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/ co...

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java Tue Feb 10 01:53:52 2009
@@ -15,18 +15,16 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion;
 
-import org.apache.shindig.social.core.model.EnumImpl;
-import org.apache.shindig.social.opensocial.model.Enum;
-import org.apache.shindig.social.opensocial.service.BeanConverter;
+import org.apache.shindig.protocol.model.Enum;
+import org.apache.shindig.protocol.model.EnumImpl;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
-
 import org.joda.time.DateTime;
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -302,7 +300,7 @@
       List<Object> list = Lists.newArrayList();
       JSONArray jsonArray = jsonObject.getJSONArray(fieldName);
       for (int i = 0; i < jsonArray.length(); i++) {
-        if (org.apache.shindig.social.opensocial.model.Enum.class
+        if (org.apache.shindig.protocol.model.Enum.class
             .isAssignableFrom(rawType)) {
           list.add(convertEnum(listElementClass, jsonArray.getJSONObject(i)));
         } else {
@@ -332,7 +330,7 @@
 
       value = map;
 
-    } else if (org.apache.shindig.social.opensocial.model.Enum.class
+    } else if (org.apache.shindig.protocol.model.Enum.class
         .isAssignableFrom(expectedType)) {
       // TODO Need to stop using Enum as a class name :(
       value = convertEnum(
@@ -385,8 +383,11 @@
     if (jsonEnum.has(Enum.Field.VALUE.toString())) {
       Enum.EnumKey enumKey = (Enum.EnumKey) enumKeyType
           .getField(jsonEnum.getString(Enum.Field.VALUE.toString())).get(null);
-      value = new EnumImpl<Enum.EnumKey>(enumKey,
-          jsonEnum.getString(Enum.Field.DISPLAY_VALUE.toString()));
+      String displayValue = null;
+      if (jsonEnum.has(Enum.Field.DISPLAY_VALUE.toString())) {
+        displayValue = jsonEnum.getString(Enum.Field.DISPLAY_VALUE.toString());
+      }
+      value = new EnumImpl<Enum.EnumKey>(enumKey,displayValue);
     } else {
       value = new EnumImpl<Enum.EnumKey>(null,
           jsonEnum.getString(Enum.Field.DISPLAY_VALUE.toString()));

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonLibConverter.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConverter.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonLibConverter.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonLibConverter.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConverter.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConverter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonLibConverter.java Tue Feb 10 01:53:52 2009
@@ -15,23 +15,21 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion;
 
-import org.apache.shindig.social.opensocial.service.BeanConverter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shindig.protocol.conversion.jsonlib.JsonLibConverterUtils;
 
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.name.Named;
 import net.sf.json.JSONArray;
 import net.sf.json.JSONException;
 import net.sf.json.JSONObject;
 import net.sf.json.JsonConfig;
 import net.sf.json.util.JSONUtils;
 
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.name.Named;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import java.lang.reflect.Array;
 import java.util.List;
 
@@ -39,9 +37,6 @@
  * BeanConverter implementation us the net.sf.json-lib json library.
  */
 public class BeanJsonLibConverter implements BeanConverter {
-
-
-
   /**
    * The Logger.
    */
@@ -120,7 +115,15 @@
       T rootObject = injector.getInstance(rootBeanClass);
       Object o = JSONObject.toBean(jsonObject, rootObject, jsonConfig);
       return (T) o;
+    }
+  }
 
+  public JSONObject convertToJson(Object pojo) {
+    try {
+      JSONObject jsonObject = JSONObject.fromObject(pojo, jsonConfig);
+      return jsonObject;
+    } catch (JSONException jse) {
+      throw new RuntimeException(jse);
     }
   }
 

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonLibConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXStreamConverter.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXStreamConverter.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXStreamConverter.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXStreamConverter.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXStreamConverter.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXStreamConverter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXStreamConverter.java Tue Feb 10 01:53:52 2009
@@ -15,12 +15,19 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion;
 
-import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shindig.protocol.DataCollection;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.protocol.conversion.xstream.StackDriver;
+import org.apache.shindig.protocol.conversion.xstream.ThreadSafeWriterStack;
+import org.apache.shindig.protocol.conversion.xstream.WriterStack;
+import org.apache.shindig.protocol.conversion.xstream.XStreamConfiguration;
 
+import com.google.common.collect.Maps;
 import com.google.inject.Inject;
-
 import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
 import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
@@ -28,18 +35,6 @@
 import com.thoughtworks.xstream.mapper.DefaultMapper;
 import com.thoughtworks.xstream.mapper.Mapper;
 
-import org.apache.shindig.social.core.util.xstream.StackDriver;
-import org.apache.shindig.social.core.util.xstream.ThreadSafeWriterStack;
-import org.apache.shindig.social.core.util.xstream.WriterStack;
-import org.apache.shindig.social.core.util.xstream.XStreamConfiguration;
-import org.apache.shindig.social.core.util.xstream.XStreamConfiguration.ConverterConfig;
-import org.apache.shindig.social.opensocial.service.BeanConverter;
-import org.apache.shindig.social.opensocial.spi.DataCollection;
-import org.apache.shindig.social.opensocial.spi.RestfulCollection;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import java.util.Map;
 
 public class BeanXStreamConverter implements BeanConverter {
@@ -54,7 +49,7 @@
   protected WriterStack writerStack;
 
 
-  protected Map<XStreamConfiguration.ConverterSet, ConverterConfig> converterMap = Maps.newHashMap();
+  protected Map<XStreamConfiguration.ConverterSet, XStreamConfiguration.ConverterConfig> converterMap = Maps.newHashMap();
 
   @Inject
   public BeanXStreamConverter(XStreamConfiguration configuration) {
@@ -102,7 +97,7 @@
     writerStack.reset();
     if (obj instanceof Map) {
       Map<?, ?> m = (Map<?, ?>) obj;
-      ConverterConfig cc = converterMap
+      XStreamConfiguration.ConverterConfig cc = converterMap
           .get(XStreamConfiguration.ConverterSet.MAP);
       if (m.size() == 1) {
         Object s = m.values().iterator().next();
@@ -112,21 +107,21 @@
         return "<response>" + result + "</response>";
       }
     } else if (obj instanceof RestfulCollection) {
-      ConverterConfig cc = converterMap
+      XStreamConfiguration.ConverterConfig cc = converterMap
           .get(XStreamConfiguration.ConverterSet.COLLECTION);
       cc.mapper.setBaseObject(obj); // thread safe method
       String result = cc.xstream.toXML(obj);
       log.debug("Result is " + result);
       return result;
     } else if (obj instanceof DataCollection) {
-      ConverterConfig cc = converterMap
+      XStreamConfiguration.ConverterConfig cc = converterMap
           .get(XStreamConfiguration.ConverterSet.MAP);
       cc.mapper.setBaseObject(obj); // thread safe method
       String result = cc.xstream.toXML(obj);
       log.debug("Result is " + result);
       return result;
     }
-    ConverterConfig cc = converterMap
+    XStreamConfiguration.ConverterConfig cc = converterMap
         .get(XStreamConfiguration.ConverterSet.DEFAULT);
 
     cc.mapper.setBaseObject(obj); // thread safe method
@@ -137,7 +132,7 @@
 
   @SuppressWarnings("unchecked")
   public <T> T convertToObject(String xml, Class<T> className) {
-    ConverterConfig cc = converterMap.get(XStreamConfiguration.ConverterSet.DEFAULT);
+    XStreamConfiguration.ConverterConfig cc = converterMap.get(XStreamConfiguration.ConverterSet.DEFAULT);
     return (T) cc.xstream.fromXML(xml);
   }
 

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXStreamConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXmlConverter.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXmlConverter.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXmlConverter.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXmlConverter.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXmlConverter.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanXmlConverter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXmlConverter.java Tue Feb 10 01:53:52 2009
@@ -15,13 +15,12 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
-
-import org.apache.shindig.social.opensocial.service.BeanConverter;
+package org.apache.shindig.protocol.conversion;
 
 import org.apache.commons.betwixt.IntrospectionConfiguration;
 import org.apache.commons.betwixt.io.BeanReader;
 import org.apache.commons.betwixt.io.BeanWriter;
+
 import org.xml.sax.SAXException;
 
 import java.beans.IntrospectionException;

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanXmlConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BaseJsonLibConfig.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BaseJsonLibConfig.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BaseJsonLibConfig.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BaseJsonLibConfig.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.jsonlib;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import net.sf.ezmorph.MorpherRegistry;
+import net.sf.json.JsonConfig;
+import net.sf.json.util.EnumMorpher;
+import net.sf.json.util.JSONUtils;
+
+import java.util.Map;
+
+/**
+ * Base config for protocols
+ */
+public class BaseJsonLibConfig extends JsonConfig {
+
+  /**
+   * Construct the config with a Guice injector.
+   * @param injector the Guice injector
+   */
+  @Inject
+  public BaseJsonLibConfig(Injector injector) {
+
+    registerMorphers();
+
+    /*
+     * This hook deals with the creation of new beans in the JSON -> Java Bean
+     * conversion
+     */
+    setNewBeanInstanceStrategy(new InjectorBeanInstanceStrategy(injector));
+
+    /*
+     * We are expecting null for nulls
+     */
+    registerDefaultValueProcessor(String.class, new NullDefaultValueProcessor());
+
+    setJsonPropertyFilter(new NullPropertyFilter());
+    setJavaPropertyFilter(new NullPropertyFilter());
+    // the classMap deals with the basic json string to bean conversion
+
+    setClassMap(createClassMap());
+  }
+
+  /**
+   * Register morphers. Override to add more.
+   */
+  protected void registerMorphers() {
+    MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
+    morpherRegistry.registerMorpher(new EnumMorpher(org.apache.shindig.protocol.model.Enum.Field.class));
+    morpherRegistry.registerMorpher(new JsonObjectToMapMorpher());
+  }
+
+  /**
+   * Create a class map. Override to add
+   * @return
+   */
+  protected Map<String, Class<?>> createClassMap() {
+    return Maps.newHashMap();
+  }
+
+}
\ No newline at end of file

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BeanJsonLibConversionException.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConversionException.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BeanJsonLibConversionException.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BeanJsonLibConversionException.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConversionException.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonLibConversionException.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BeanJsonLibConversionException.java Tue Feb 10 01:53:52 2009
@@ -15,7 +15,7 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 /**
  * Where a conversion exception happens in the Json Lib conversion, this

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/BeanJsonLibConversionException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/InjectorBeanInstanceStrategy.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/InjectorBeanInstanceStrategy.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/InjectorBeanInstanceStrategy.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/InjectorBeanInstanceStrategy.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/InjectorBeanInstanceStrategy.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/InjectorBeanInstanceStrategy.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/InjectorBeanInstanceStrategy.java Tue Feb 10 01:53:52 2009
@@ -15,15 +15,14 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 import com.google.inject.Injector;
-
-import java.lang.reflect.InvocationTargetException;
-
 import net.sf.json.JSONObject;
 import net.sf.json.util.NewBeanInstanceStrategy;
 
+import java.lang.reflect.InvocationTargetException;
+
 /**
  * An Injector based NewBeanInstance strategy that will use Guice to create new
  * beans.
@@ -64,7 +63,7 @@
     if (beanClass != null) {
       return injector.getInstance(beanClass);
     }
-    return DEFAULT.newInstance(null, jsonObject);
+    return NewBeanInstanceStrategy.DEFAULT.newInstance(null, jsonObject);
   }
 
 }

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/InjectorBeanInstanceStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonLibConverterUtils.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonLibConverterUtils.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonLibConverterUtils.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonLibConverterUtils.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonLibConverterUtils.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonLibConverterUtils.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonLibConverterUtils.java Tue Feb 10 01:53:52 2009
@@ -15,16 +15,16 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.util.Map.Entry;
-
 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
 
+import java.util.Map.Entry;
+
 /**
  * Some utility functions to simpilfy handling SF json-lib objects.
  */

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonLibConverterUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonObjectToMapMorpher.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonObjectToMapMorpher.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonObjectToMapMorpher.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonObjectToMapMorpher.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonObjectToMapMorpher.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/JsonObjectToMapMorpher.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonObjectToMapMorpher.java Tue Feb 10 01:53:52 2009
@@ -15,17 +15,16 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 import com.google.common.collect.Maps;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
 import net.sf.ezmorph.Morpher;
 import net.sf.ezmorph.ObjectMorpher;
 import net.sf.json.JSONObject;
 
+import java.util.Map;
+import java.util.Map.Entry;
+
 /**
  * A morpher that converts objects into maps
  */

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/JsonObjectToMapMorpher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullDefaultValueProcessor.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullDefaultValueProcessor.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullDefaultValueProcessor.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullDefaultValueProcessor.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullDefaultValueProcessor.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullDefaultValueProcessor.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullDefaultValueProcessor.java Tue Feb 10 01:53:52 2009
@@ -15,7 +15,7 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 import net.sf.json.processors.DefaultValueProcessor;
 

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullDefaultValueProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullPropertyFilter.java (from r740988, incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullPropertyFilter.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullPropertyFilter.java?p2=incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullPropertyFilter.java&p1=incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullPropertyFilter.java&r1=740988&r2=742816&rev=742816&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/NullPropertyFilter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullPropertyFilter.java Tue Feb 10 01:53:52 2009
@@ -15,14 +15,14 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.shindig.social.core.util;
-
-import java.util.Collection;
+package org.apache.shindig.protocol.conversion.jsonlib;
 
 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
 import net.sf.json.util.PropertyFilter;
 
+import java.util.Collection;
+
 /**
  * A property filter that rejects null values.
  */

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/jsonlib/NullPropertyFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ClassFieldMapping.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ClassFieldMapping.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ClassFieldMapping.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ClassFieldMapping.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+/**
+ * This represents the mapping between a class and a field, potentially with a
+ * parent element. It is used to define the element names that are used to
+ * serialize the contents of a class.
+ *
+ * eg
+ * <pre>
+ * &lt;outerobject&gt;
+ * &lt;listcontainer&gt;
+ *    &lt;listelement&gt;
+ *       &lt;objectcontent&gt;
+ *    &lt;/listelement&gt;
+ * &lt;/listcontainer&gt;
+ * ...
+ * &lt;/outerobject&gt;
+ * </pre>
+ * or (not currently used in OS)
+ * <pre>
+ * &lt;person&gt;
+ *    &lt;emails&gt;
+ *       &lt;email&gt;
+ *          &lt;type&gt;&lt;/type&gt;
+ *          &lt;value&gt;&lt;/value&gt;
+ *       &lt;/email&gt;
+ *       ...
+ *    &lt;/emails&gt;
+ *    ...
+ * &lt;/person&gt;
+ * </pre>
+ * For a more compact mapping {@link ItemFieldMapping}.
+ *
+ *
+ */
+/**
+ *
+ */
+public class ClassFieldMapping {
+
+  /**
+   * The name of the element to map the class to.
+   */
+  private String elementName;
+
+  /**
+   * The class being mapped.
+   */
+  private Class<?> mappedClazz;
+  /**
+   * An optional parent element name.
+   */
+  private String fieldParentName;
+
+  /**
+   * Create a simple element class mapping, applicable to all parent elements.
+   *
+   * @param elementName
+   *          the name of the element
+   * @param mappedClazz
+   *          the class to map to the name of the element
+   */
+  public ClassFieldMapping(String elementName, Class<?> mappedClazz) {
+    this.elementName = elementName;
+    this.mappedClazz = mappedClazz;
+    this.fieldParentName = null;
+  }
+
+  /**
+   * Create a element class mapping, that only applies to one parent element
+   * name.
+   *
+   * @param parentName
+   *          the name of the parent element that this mapping applies to
+   * @param elementName
+   *          the name of the element
+   * @param mappedClazz
+   *          the class to map to the name of the element
+   */
+  public ClassFieldMapping(String parentName, String elementName, Class<?> mappedClazz) {
+    this.elementName = elementName;
+    this.mappedClazz = mappedClazz;
+    this.fieldParentName = parentName;
+  }
+
+  /**
+   * @return get the element name.
+   */
+  public String getElementName() {
+    return elementName;
+  }
+
+  /**
+   * @return get the mapped class.
+   */
+  public Class<?> getMappedClass() {
+    return mappedClazz;
+  }
+
+  /**
+   * Does this ClassFieldMapping match the supplied parent and type.
+   *
+   * @param parent
+   *          the parent element, which may be null
+   * @param type
+   *          the type of the field being stored
+   * @return true if this mapping is a match for the combination
+   */
+  public boolean matches(String parent, Class<?> type) {
+    if (fieldParentName == null) {
+      return mappedClazz.isAssignableFrom(type);
+    }
+    return fieldParentName.equals(parent)
+        && mappedClazz.isAssignableFrom(type);
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/DataCollectionConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/DataCollectionConverter.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/DataCollectionConverter.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/DataCollectionConverter.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import org.apache.shindig.protocol.DataCollection;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * This converter changes the way in which a collection is serialized
+ *
+ */
+public class DataCollectionConverter extends AbstractCollectionConverter {
+
+  /**
+   * @param mapper
+   */
+  public DataCollectionConverter(Mapper mapper) {
+    super(mapper);
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter#canConvert(java.lang.Class)
+   */
+  @Override
+  public boolean canConvert(Class clazz) {
+    return (DataCollection.class.isAssignableFrom(clazz));
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter#marshal(java.lang.Object,
+   *      com.thoughtworks.xstream.io.HierarchicalStreamWriter,
+   *      com.thoughtworks.xstream.converters.MarshallingContext)
+   */
+  @Override
+  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+
+    DataCollection collection = (DataCollection) source;
+    Map<String, Map<String, String>> internalMap = collection.getEntry();
+
+    for (Entry<String, Map<String, String>> eo : internalMap.entrySet()) {
+      writer.startNode("entry");
+      writer.startNode("key");
+      writer.setValue(eo.getKey());
+      writer.endNode();
+      writer.startNode("value");
+      for (Entry<String, String> ei : eo.getValue().entrySet()) {
+        writer.startNode("entry");
+        writer.startNode("key");
+        writer.setValue(ei.getKey());
+        writer.endNode();
+        writer.startNode("value");
+        writer.setValue(ei.getValue());
+        writer.endNode();
+        writer.endNode();
+      }
+
+      writer.endNode();
+      writer.endNode();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader,
+   *      com.thoughtworks.xstream.converters.UnmarshallingContext)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public Object unmarshal(HierarchicalStreamReader reader,
+      UnmarshallingContext context) {
+    Preconditions.checkNotNull(reader);
+    reader.moveDown();
+    Map<String, Object> m = Maps.newHashMap();
+    while (reader.hasMoreChildren()) {
+      reader.moveDown(); // entry
+      String ok = null;
+      Object ov = null;
+      while (reader.hasMoreChildren()) {
+        reader.moveDown(); // key or value
+        String elname = reader.getNodeName();
+        if ("key".equals(elname)) {
+          ok = reader.getValue();
+        } else if ("value".equals(elname)) {
+          ov = reader.getValue();
+          if (reader.hasMoreChildren()) {
+            Map<String, String> innerMap = Maps.newHashMap();
+            while (reader.hasMoreChildren()) {
+              reader.moveDown();// entry
+              String k = null;
+              String v = null;
+              while (reader.hasMoreChildren()) {
+                reader.moveDown(); // key or value
+                if ("key".equals(elname)) {
+                  k = reader.getValue();
+                } else if ("value".equals(elname)) {
+                  v = reader.getValue();
+                }
+                reader.moveUp();
+              }
+              innerMap.put(k, v);
+              reader.moveUp();
+            }
+            ov = innerMap;
+          } else {
+          }
+        }
+        reader.moveUp();
+      }
+      reader.moveUp();
+      m.put(ok, ov);
+    }
+    reader.moveUp();
+    // scan the map, if there are any maps, then everything should be in maps.
+    boolean nonmap = false;
+    for (Entry<String, Object> e : m.entrySet()) {
+      if (e.getValue() instanceof String) {
+        nonmap = true;
+      }
+    }
+    Map<String, Map<String, String>> fm = Maps.newHashMap();
+    if (nonmap) {
+      for (Entry<String, Object> e : m.entrySet()) {
+        if (e.getValue() instanceof Map) {
+          fm.put(e.getKey(), (Map<String, String>) e.getValue());
+        } else {
+          // not certain that this makes sense, but can't see how else.
+          Map<String, String> mv = Maps.newHashMap();
+          mv.put(e.getKey(), (String) e.getValue());
+          fm.put(e.getKey(), mv);
+        }
+      }
+
+    } else {
+      for (Entry<String, Object> e : m.entrySet()) {
+        fm.put(e.getKey(), (Map<String, String>) e.getValue());
+      }
+    }
+    return new DataCollection(fm);
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanConverter.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanConverter.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanConverter.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import org.apache.shindig.protocol.model.Exportablebean;
+
+import com.google.inject.Injector;
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
+
+import java.util.Collection;
+
+/**
+ *
+ */
+public class GuiceBeanConverter implements Converter {
+  private Mapper mapper;
+  private GuiceBeanProvider beanProvider;
+
+  public GuiceBeanConverter(Mapper mapper, Injector injector) {
+    this(mapper, new GuiceBeanProvider(injector));
+  }
+
+  public GuiceBeanConverter(Mapper mapper, GuiceBeanProvider beanProvider) {
+    this.mapper = mapper;
+    this.beanProvider = beanProvider;
+  }
+
+  /**
+   * Only checks for the availability of a public default constructor. If you
+   * need stricter checks, subclass JavaBeanConverter
+   */
+  public boolean canConvert(Class type) {
+    if ( type == null ) {
+      return false;
+    }
+    if (Object.class.equals(type)) {
+      return false;
+    }
+    if ( type.isInterface() ) {
+      return true;
+    }
+    for (Class<?> iff : type.getInterfaces()) {
+      if (iff.isAnnotationPresent(Exportablebean.class)) {
+        return true;
+      }
+    }
+    return canConvert(type.getSuperclass());
+  }
+
+  public void marshal(final Object source,
+      final HierarchicalStreamWriter writer, final MarshallingContext context) {
+    beanProvider.visitSerializableProperties(source,
+        new GuiceBeanProvider.Visitor() {
+          public boolean shouldVisit(String name, Class<?> definedIn) {
+            return mapper.shouldSerializeMember(definedIn, name);
+          }
+
+          public void visit(String propertyName, Class<?> fieldType,
+              Class<?> definedIn, Object newObj) {
+            if (newObj != null) {
+              Mapper.ImplicitCollectionMapping mapping = mapper
+                  .getImplicitCollectionDefForFieldName(source.getClass(),
+                      propertyName);
+              if (mapping != null) {
+                if (mapping.getItemFieldName() != null) {
+                  Collection<?> list = (Collection<?>) newObj;
+                  for (Object obj : list) {
+                    writeField(propertyName, mapping.getItemFieldName(),
+                        mapping.getItemType(), definedIn, obj);
+                  }
+                } else {
+                  context.convertAnother(newObj);
+                }
+              } else {
+                writeField(propertyName, propertyName, fieldType, definedIn,
+                    newObj);
+              }
+            }
+          }
+
+          private void writeField(String propertyName, String aliasName,
+              Class<?> fieldType, Class<?> definedIn, Object newObj) {
+            ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper
+                .serializedMember(source.getClass(), aliasName), fieldType);
+            context.convertAnother(newObj);
+            writer.endNode();
+
+          }
+        });
+  }
+
+  public Object unmarshal(final HierarchicalStreamReader reader,
+      final UnmarshallingContext context) {
+    final Object result = instantiateNewInstance(context);
+
+    while (reader.hasMoreChildren()) {
+      reader.moveDown();
+
+      String propertyName = mapper.realMember(result.getClass(), reader
+          .getNodeName());
+
+      boolean propertyExistsInClass = beanProvider.propertyDefinedInClass(
+          propertyName, result.getClass());
+
+      if (propertyExistsInClass) {
+        Class<?> type = determineType(reader, result, propertyName);
+        Object value = context.convertAnother(result, type);
+        beanProvider.writeProperty(result, propertyName, value);
+      } else if (mapper.shouldSerializeMember(result.getClass(), propertyName)) {
+        throw new ConversionException("Property '" + propertyName
+            + "' not defined in class " + result.getClass().getName());
+      }
+
+      reader.moveUp();
+    }
+
+    return result;
+  }
+
+  private Object instantiateNewInstance(UnmarshallingContext context) {
+    Object result = context.currentObject();
+    if (result == null) {
+      result = beanProvider.newInstance(context.getRequiredType());
+    }
+    return result;
+  }
+
+  private Class<?> determineType(HierarchicalStreamReader reader,
+      Object result, String fieldName) {
+    final String classAttributeName = mapper.attributeForAlias("class");
+    String classAttribute = reader.getAttribute(classAttributeName);
+    if (classAttribute != null) {
+      return mapper.realClass(classAttribute);
+    } else {
+      return mapper.defaultImplementationOf(beanProvider.getPropertyType(
+          result, fieldName));
+    }
+  }
+
+  /**
+   * @deprecated since 1.3
+   */
+  @Deprecated
+  public static class DuplicateFieldException extends ConversionException {
+    public DuplicateFieldException(String msg) {
+      super(msg);
+    }
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+import com.google.inject.Injector;
+import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ *
+ */
+public class GuiceBeanProvider {
+
+  protected static final Object[] NO_PARAMS = new Object[0];
+  private final Comparator<String> propertyNameComparator;
+  private final transient Map<Class<?>, Map<String, PropertyDescriptor>> propertyNameCache = new WeakHashMap<Class<?>, Map<String, PropertyDescriptor>>();
+  private Injector injector;
+
+  public GuiceBeanProvider(Injector injector) {
+    this(injector, null);
+  }
+
+  public GuiceBeanProvider(Injector injector,
+      final Comparator<String> propertyNameComparator) {
+    this.propertyNameComparator = propertyNameComparator;
+    this.injector = injector;
+  }
+
+  public Object newInstance(Class<?> type) {
+    return injector.getInstance(type);
+  }
+
+  public void visitSerializableProperties(Object object, Visitor visitor) {
+    for (PropertyDescriptor property : getSerializableProperties(object)) {
+      try {
+        Method readMethod = property.getReadMethod();
+        String name = property.getName();
+        Class<?> definedIn = readMethod.getDeclaringClass();
+        if (visitor.shouldVisit(name, definedIn)) {
+          Object value = readMethod.invoke(object);
+          visitor.visit(name, property.getPropertyType(), definedIn, value);
+        }
+      } catch (IllegalArgumentException e) {
+        throw new ObjectAccessException("Could not get property "
+            + object.getClass() + '.' + property.getName(), e);
+      } catch (IllegalAccessException e) {
+        throw new ObjectAccessException("Could not get property "
+            + object.getClass() + '.' + property.getName(), e);
+      } catch (InvocationTargetException e) {
+        throw new ObjectAccessException("Could not get property "
+            + object.getClass() + '.' + property.getName(), e);
+      }
+    }
+  }
+
+  public void writeProperty(Object object, String propertyName, Object value) {
+    PropertyDescriptor property = getProperty(propertyName, object.getClass());
+    try {
+      property.getWriteMethod().invoke(object, value);
+    } catch (IllegalArgumentException e) {
+      throw new ObjectAccessException("Could not set property "
+          + object.getClass() + '.' + property.getName(), e);
+    } catch (IllegalAccessException e) {
+      throw new ObjectAccessException("Could not set property "
+          + object.getClass() + '.' + property.getName(), e);
+    } catch (InvocationTargetException e) {
+      throw new ObjectAccessException("Could not set property "
+          + object.getClass() + '.' + property.getName(), e);
+    }
+  }
+
+  public Class<?> getPropertyType(Object object, String name) {
+    return getProperty(name, object.getClass()).getPropertyType();
+  }
+
+  public boolean propertyDefinedInClass(String name, Class<?> type) {
+    return getProperty(name, type) != null;
+  }
+
+  private List<PropertyDescriptor> getSerializableProperties(Object object) {
+    Map<String, PropertyDescriptor> nameMap = getNameMap(object.getClass());
+
+    Set<String> names = (propertyNameComparator == null) ? nameMap.keySet() :
+      ImmutableSortedSet.orderedBy(propertyNameComparator).copyOf(nameMap.keySet());
+
+    List<PropertyDescriptor> result = Lists.newArrayListWithExpectedSize(nameMap.size());
+
+    for (final String name : names) {
+      final PropertyDescriptor descriptor = nameMap.get(name);
+      if (canStreamProperty(descriptor)) {
+        result.add(descriptor);
+      }
+    }
+    return result;
+  }
+
+  protected boolean canStreamProperty(PropertyDescriptor descriptor) {
+    return descriptor.getReadMethod() != null
+        && descriptor.getWriteMethod() != null;
+  }
+
+  public boolean propertyWriteable(String name, Class<?> type) {
+    PropertyDescriptor property = getProperty(name, type);
+    return property.getWriteMethod() != null;
+  }
+
+  private PropertyDescriptor getProperty(String name, Class<?> type) {
+    return getNameMap(type).get(name);
+  }
+
+  private Map<String, PropertyDescriptor> getNameMap(Class<?> type) {
+    Map<String, PropertyDescriptor> nameMap = propertyNameCache.get(type);
+
+    if (nameMap != null) {
+      return nameMap;
+    }
+
+    ImmutableMap.Builder<String,PropertyDescriptor> nameMapBuilder = ImmutableMap.builder();
+
+    BeanInfo beanInfo;
+    try {
+      beanInfo = Introspector.getBeanInfo(type, Object.class);
+    } catch (IntrospectionException e) {
+      throw new ObjectAccessException("Cannot get BeanInfo of type "
+          + type.getName(), e);
+    }
+
+    for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
+        nameMapBuilder.put(descriptor.getName(), descriptor);
+    }
+    nameMap = nameMapBuilder.build();
+    propertyNameCache.put(type, nameMap);
+    return nameMap;
+  }
+
+  interface Visitor {
+    boolean shouldVisit(String name, Class<?> definedIn);
+
+    void visit(String name, Class<?> type, Class<?> definedIn, Object value);
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ImplicitCollectionFieldMapping.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ImplicitCollectionFieldMapping.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ImplicitCollectionFieldMapping.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/ImplicitCollectionFieldMapping.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import com.thoughtworks.xstream.mapper.Mapper.ImplicitCollectionMapping;
+
+/**
+ * <p>
+ * ItemFieldMapping defines a mapping of a class within a class to an element
+ * name. Where classes are tested, the must implement or extend the specified
+ * classes, unlike the standard behaviour of XStream they dont need to be the
+ * classes in question.
+ * </p>
+ * <p>
+ * The structure is used for implicit collections of the form *
+ * </p>
+ *
+ * <pre>
+ * &lt;outerobject&gt;
+ *    &lt;listelement&gt;
+ *       &lt;objectcontent&gt;
+ *    &lt;/listelement&gt;
+ *    &lt;listelement&gt;
+ *       &lt;objectcontent&gt;
+ *    &lt;/listelement&gt;
+ * ...
+ * &lt;/outerobject&gt;
+ * </pre>
+ * <p>
+ * or
+ * </p>
+ *
+ * <pre>
+ * &lt;person&gt;
+ *     &lt;emails&gt;
+ *        &lt;type&gt;&lt;/type&gt;
+ *        &lt;value&gt;&lt;/value&gt;
+ *     &lt;/emails&gt;
+ *     &lt;emails&gt;
+ *        &lt;type&gt;&lt;/type&gt;
+ *        &lt;value&gt;&lt;/value&gt;
+ *     &lt;/emails&gt;
+ *     &lt;emails&gt;
+ *        &lt;type&gt;&lt;/type&gt;
+ *        &lt;value&gt;&lt;/value&gt;
+ *     &lt;/emails&gt;
+ *     ...
+ * &lt;/person&gt;
+ * </pre>
+ * <p>
+ * would be specified with NewItemFieldMapping(Person.class, "emails",
+ * ListField.class, "emails");
+ * </p>
+ */
+public class ImplicitCollectionFieldMapping implements ImplicitCollectionMapping {
+
+  /**
+   * The Class that the field is defined in.
+   */
+  private Class<?> definedIn;
+  /**
+   * The class of the item that is being defined.
+   */
+  private Class<?> itemType;
+  /**
+   * The name of the fields in the class (get and set methods)
+   */
+  private String fieldName;
+  /**
+   * The name of the element that should be used for this field.
+   */
+  private String itemFieldName;
+
+  /**
+   * Create a Item Field Mapping object specifying that where the class itemType
+   * appears in the Class definedIn, the elementName should be used for the
+   * Element Name.
+   *
+   * @param definedIn
+   *          the class which contains the method
+   * @param fieldName
+   *          the name of the method/field in the class.
+   * @param itemType
+   *          the type of the method/field in the class.
+   * @param itemFieldName
+   *          the name of element in the xml
+   *
+   */
+  public ImplicitCollectionFieldMapping(Class<?> definedIn, String fieldName,
+      Class<?> itemType, String itemFieldName) {
+    this.definedIn = definedIn;
+    this.itemType = itemType;
+    this.itemFieldName = itemFieldName;
+    this.fieldName = fieldName;
+  }
+
+  /**
+   * Does this ItemFieldMapping match the supplied classes.
+   *
+   * @param definedIn
+   *          the class that the target test class is defiend in, this is a real
+   *          class
+   * @param itemType
+   *          the target class, the real class
+   * @return true if the defiendIn class implements the defiendIn class of this
+   *         ItemFieldMapping and the itemType class implements the itemType
+   *         class of this ItemFieldMapping.
+   */
+  public boolean matches(Class<?> definedIn, Class<?> itemType) {
+    return (this.definedIn.isAssignableFrom(definedIn) && this.itemType
+        .isAssignableFrom(itemType));
+  }
+
+  public boolean matches(Class<?> definedIn, String fieldName) {
+    return (this.definedIn.isAssignableFrom(definedIn) && this.fieldName
+        .equals(fieldName));
+  }
+
+  /**
+   * @return
+   */
+  public String getFieldName() {
+    return fieldName;
+  }
+
+  /**
+   * @return
+   */
+  public String getItemFieldName() {
+    return itemFieldName;
+  }
+
+  /**
+   * @return
+   */
+  public Class<?> getItemType() {
+    return itemType;
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceClassMapper.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceClassMapper.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceClassMapper.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceClassMapper.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.thoughtworks.xstream.mapper.Mapper;
+import com.thoughtworks.xstream.mapper.MapperWrapper;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The InterfaceClassMapper provides the central mapping of the XStream bean
+ * converter. It is used by XStream to determine the element names and classes
+ * being mapped. This is driven by a number of read only data structures that
+ * are injected on creation. The resolution of classes follow the inheritance
+ * model. To map all collections to an element we would use the Collection.class
+ * as the reference class and then ArrayList and Set would both be mapped to the
+ * same element.
+ */
+
+public class InterfaceClassMapper extends MapperWrapper {
+
+  /**
+   * A logger.
+   */
+  private static final Log log = LogFactory.getLog(InterfaceClassMapper.class);
+  /**
+   * A map of element names to classes.
+   */
+  private Map<String, Class<?>> elementClassMap = Maps.newHashMap();
+  /**
+   * The first child of the root object. If the root object is not a collection,
+   * this is null. If the root object is a collection and all the elements are
+   * the same this is set to the class of those elements. Once the first call
+   * has been made to the mapper, this is set back to null. Note its a thread
+   * local enabling this class to remain multi threaded.
+   */
+  private ThreadLocal<Class<?>> firstChild = new ThreadLocal<Class<?>>();
+  /**
+   * A map of classed to ommit, the key is the field name, and the value is an
+   * array of classes where that field is ommitted from the output.
+   */
+  private Multimap<String, Class<?>> omitMMap;
+  /**
+   * A map of elements, where the ClassMapping object defines how the classes
+   * are mapped to elements.
+   */
+  private List<ClassFieldMapping> elementMappingList;
+  /**
+   * A map of parent elements used where there is a collection as the root
+   * object being serialized. This ensures that the root obejct gets the right
+   * element name rather than list a generic &gt;list&lt;
+   */
+  private List<ClassFieldMapping> listElementMappingList;
+  /**
+   * An implementation of a tracking stack for the writer. If this class is to
+   * be thread safe, the implementation of this field must also be thread safe
+   * as it is shared over multiple threads.
+   */
+  private WriterStack writerStack;
+
+  /**
+   * A list of explicit mapping specifications.
+   */
+  private List<ImplicitCollectionFieldMapping> itemFieldMappings;
+
+  /**
+   * Create an Interface Class Mapper with a configuration.
+   *
+   * @param writerStack
+   *          A thread safe WriterStack implementation connected to the XStream
+   *          driver and hence all the writers.
+   * @param wrapped
+   *          the base mapper to be wrapped by this wrapper. All mappers must
+   *          wrap the default mapper.
+   * @param elementMappingList
+   *          A list of element to class mappings specified by ClassFieldMapping
+   *          Object. This list is priority ordered with the highest priority
+   *          mappings coming first.
+   * @param listElementMappingList
+   *          A list of element names to use as the base element where there is
+   *          a collection of the same type objects being serialized.
+   * @param omitMMap
+   *          A Multimap of fields in classes to omit from serialization.
+   * @param elementClassMap
+   *          a map of element names to class types.
+   */
+  public InterfaceClassMapper(WriterStack writerStack,
+      Mapper wrapped,
+      List<ClassFieldMapping> elementMappingList,
+      List<ClassFieldMapping> listElementMappingList,
+      List<ImplicitCollectionFieldMapping> itemFieldMappings,
+      Multimap<String, Class<?>> omitMMap,
+      Map<String, Class<?>> elementClassMap) {
+    super(wrapped);
+    this.elementClassMap = elementClassMap;
+    this.elementMappingList = elementMappingList;
+    this.listElementMappingList = listElementMappingList;
+    this.omitMMap = omitMMap;
+    this.writerStack = writerStack;
+    this.itemFieldMappings = itemFieldMappings;
+  }
+
+  /**
+   * Set the base object at the start of a serialization, this ensures that the
+   * base element type is appropriate for the elements that are contained within
+   * the object. This method only has any effect if the base object is a
+   * Collection of some form. other wise this method has no effect on the state.
+   * The method is thread safe attaching state to the thread for later
+   * retrieval.
+   *
+   * @param base
+   *          the base object being serialized.
+   */
+  public void setBaseObject(Object base) {
+    firstChild.set(null);
+    if (Collection.class.isAssignableFrom(base.getClass())) {
+      Collection<?> c = (Collection<?>) base;
+      Class<?> clazz = null;
+
+      for (Object o : c) {
+        if (clazz == null) {
+          clazz = o.getClass();
+        } else {
+          if (!clazz.equals(o.getClass())) {
+            clazz = null;
+            break;
+          }
+        }
+      }
+      firstChild.set(clazz);
+      if (log.isDebugEnabled()) {
+        log.debug("First Child set to " + clazz);
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Get the serialized element name for a specific class. If this is the first
+   * object to be serialized, and it is a collection, then the elements of the
+   * collection will have been inspected to determine if the container should
+   * have a special name. These names are specified in the
+   * listElementMappingList which is specified on construction. If the first
+   * element is not found a standard list.container element name is used to
+   * contain all the others, this list type is only ever used in the unit tests.
+   * </p>
+   * <p>
+   * For subsequent elements, the class is mapped directly to a element name at
+   * the same level, specified via the elementMappingList which is injected in
+   * the constructor. This mapping looks to see if the class in question
+   * inherits of extends the classes in the list and uses the element name
+   * associated wit the first match.
+   * </p>
+   *
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#serializedClass(java.lang.Class)
+   * @param type
+   *          the type of the class to the serialized
+   * @return the name of the element that that should be used to contain the
+   *         class when serialized.
+   */
+  @SuppressWarnings("unchecked")
+  // the API is not generic
+  @Override
+  public String serializedClass(Class type) {
+    String parentElementName = writerStack.peek();
+    if (Collection.class.isAssignableFrom(type) && firstChild.get() != null) {
+      // empty list, if this is the first one, then we need to look at the
+      // first child setup on startup.
+      if (log.isDebugEnabled()) {
+        log.debug("Converting Child to " + firstChild.get());
+      }
+      type = firstChild.get();
+      firstChild.set(null);
+      if (log.isDebugEnabled()) {
+        log.debug("serializedClass(" + type + ") is a collection member "
+            + Collection.class.isAssignableFrom(type));
+      }
+      for (ClassFieldMapping cfm : listElementMappingList) {
+        if (cfm.matches(parentElementName, type)) {
+          return cfm.getElementName();
+        }
+      }
+      return "list.container";
+    } else {
+      // but after we have been asked once, then clear
+      firstChild.set(null);
+      if (log.isDebugEnabled()) {
+        log.debug("serializedClass(" + type + ')');
+      }
+      for (ClassFieldMapping cfm : elementMappingList) {
+        if (cfm.matches(parentElementName, type)) {
+          if (log.isDebugEnabled()) {
+            log.debug("From MAP serializedClass(" + type + ")  =="
+                + cfm.getElementName());
+          }
+          return cfm.getElementName();
+        }
+      }
+
+    }
+
+    String fieldName = super.serializedClass(type);
+    if (log.isDebugEnabled()) {
+      log.debug("--- From Super serializedClass(" + type + ")  ==" + fieldName);
+    }
+    return fieldName;
+
+  }
+
+  /**
+   * Checks to see if the field in a class should be serialized. This is
+   * controlled buy the omitMMap Multimap which is keyed by the field name. Each entry
+   * in the map contains a list of classes where the field name should be
+   * excluded from the output.
+   *
+   * @param definedIn
+   *          the class the field is defined in
+   * @param fieldName
+   *          the field being considered
+   * @return true of the field should be serialized false if it should be
+   *         ignored.
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#shouldSerializeMember(java.lang.Class,
+   *      java.lang.String)
+   *
+   */
+  @SuppressWarnings("unchecked")
+  // API is not generic
+  @Override
+  public boolean shouldSerializeMember(Class definedIn, String fieldName) {
+    for (Class<?> omit : omitMMap.get(fieldName)) {
+      if (omit.isAssignableFrom(definedIn)) {
+        return false;
+      }
+    }
+    return super.shouldSerializeMember(definedIn, fieldName);
+  }
+
+  /**
+   * Get the real class associated with an element name from the
+   * elementMappingList.
+   *
+   * @param elementName
+   *          the name of the element being read.
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#realClass(java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public Class realClass(String elementName) {
+    Class<?> clazz = elementClassMap.get(elementName);
+    if (clazz == null) {
+      clazz = super.realClass(elementName);
+    }
+    return clazz;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#getImplicitCollectionDefForFieldName(java.lang.Class, java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) {
+    for ( ImplicitCollectionFieldMapping ifm : itemFieldMappings) {
+      if ( ifm.matches(itemType, fieldName) ) {
+        return ifm;
+      }
+    }
+    return super.getImplicitCollectionDefForFieldName(itemType, fieldName);
+  }
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasMapping.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasMapping.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasMapping.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasMapping.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+/**
+ *
+ */
+public class InterfaceFieldAliasMapping {
+
+  private String alias;
+  private Class<?> type;
+  private String fieldName;
+  private String parent;
+
+  /**
+   * @param alias
+   *          the name of the element to be used in the xml
+   * @param type
+   *          the type containing the field
+   * @param fieldName
+   *          the field name.
+   */
+  public InterfaceFieldAliasMapping(String alias, Class<?> type,
+      String fieldName) {
+    this.alias = alias;
+    this.type = type;
+    this.fieldName = fieldName;
+  }
+
+  /**
+   * @param alias
+   *          the name of the element to be used in the xml
+   * @param type
+   *          the type containing the field
+   * @param fieldName
+   *          the field name.
+   * @param parent
+   *          the parent element
+   */
+  public InterfaceFieldAliasMapping(String alias, Class<?> type,
+      String fieldName, String parent) {
+    this.alias = alias;
+    this.type = type;
+    this.fieldName = fieldName;
+    this.parent = parent;
+  }
+
+  /**
+   * @return
+   */
+  public Class<?> getType() {
+    return type;
+  }
+
+  /**
+   * @return
+   */
+  public String getAlias() {
+    return alias;
+  }
+
+  /**
+   * @return
+   */
+  public String getFieldName() {
+    return fieldName;
+  }
+
+  /**
+   * @return the parent
+   */
+  public String getParent() {
+    return parent;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see java.lang.Object#toString()
+   */
+  @Override
+  public String toString() {
+    if (parent == null) {
+      return type + ".get" + fieldName + "() <-> <" + alias + '>';
+    } else {
+      return type + ".get" + fieldName + "() <-> <" + alias
+          + "> inside parent <" + parent + '>';
+    }
+  }
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasingMapper.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasingMapper.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasingMapper.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/InterfaceFieldAliasingMapper.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.thoughtworks.xstream.mapper.Mapper;
+import com.thoughtworks.xstream.mapper.MapperWrapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class InterfaceFieldAliasingMapper extends MapperWrapper {
+
+  private Map<String, List<InterfaceFieldAliasMapping>> serializedMap = Maps.newHashMap();
+  private Map<String, List<InterfaceFieldAliasMapping>> membersMap = Maps.newHashMap();
+  private WriterStack writerStack;
+
+  /**
+   * @param wrapped
+   */
+  public InterfaceFieldAliasingMapper(Mapper wrapped, WriterStack writerStack,
+      List<InterfaceFieldAliasMapping> ifaList) {
+    super(wrapped);
+    this.writerStack = writerStack;
+    for (InterfaceFieldAliasMapping ifa : ifaList) {
+
+      List<InterfaceFieldAliasMapping> serializedMatches = serializedMap.get(ifa.getFieldName());
+      if (serializedMatches == null) {
+        serializedMatches = Lists.newArrayList();
+        serializedMap.put(ifa.getFieldName(), serializedMatches);
+      }
+      serializedMatches.add(ifa);
+      List<InterfaceFieldAliasMapping> memberMatches = membersMap.get(ifa.getAlias());
+      if (memberMatches == null) {
+        memberMatches = Lists.newArrayList();
+        membersMap.put(ifa.getAlias(), memberMatches);
+      }
+      memberMatches.add(ifa);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#realMember(java.lang.Class,
+   *      java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public String realMember(Class type, String serialized) {
+    // get the possible member spec, using the serialized elment as the key.
+    // comes from the map of members.
+    List<InterfaceFieldAliasMapping> serializedMatches = membersMap
+        .get(serialized);
+    if (serializedMatches != null) {
+      for (InterfaceFieldAliasMapping ifa : serializedMatches) {
+        if (ifa.getType().isAssignableFrom(type)) {
+          return ifa.getFieldName();
+        }
+      }
+    }
+    return super.realMember(type, serialized);
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.thoughtworks.xstream.mapper.MapperWrapper#serializedMember(java.lang.Class,
+   *      java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public String serializedMember(Class type, String memberName) {
+    // get the possible serialized spec, using the memberName elment as the key.
+    // comes from the map of serialized elements.
+    List<InterfaceFieldAliasMapping> memberMatches = serializedMap
+        .get(memberName);
+    if (memberMatches != null) {
+      for (InterfaceFieldAliasMapping ifa : memberMatches) {
+        if (ifa.getParent() == null) {
+          if (ifa.getType().isAssignableFrom(type)) {
+            return ifa.getAlias();
+          }
+        } else {
+          if (ifa.getType().isAssignableFrom(type)
+              && ifa.getParent().equals(writerStack.peek())) {
+            return ifa.getAlias();
+          }
+        }
+      }
+    }
+    return super.serializedMember(type, memberName);
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/MapConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/MapConverter.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/MapConverter.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/MapConverter.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.collect.Maps;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * converts a map to and from the form &lt;container&gt;
+ * &lt;key&gt;value&lt;/key&gt; &lt;key&gt;value&lt;/key&gt; <container>.
+ */
+public class MapConverter extends AbstractCollectionConverter {
+
+  /**
+   * The logger.
+   */
+  private static final Log log = LogFactory.getLog(MapConverter.class);
+  /**
+   * If true will use a short form of xml serialization.
+   */
+  private boolean shortform = false;
+
+  /**
+   * Create a MapConverter that use use the supplied mapper.
+   *
+   * @param mapper
+   *          the mapped to base the conversion on.
+   */
+  public MapConverter(Mapper mapper) {
+    super(mapper);
+  }
+
+  /**
+   * output the Map in the simplified form.
+   *
+   * @param source
+   *          the object to be output
+   * @param writer
+   *          the writer to use to perform the output.
+   * @param context
+   *          the context in which to perform the output.
+   *
+   * @see com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object,
+   *      com.thoughtworks.xstream.io.HierarchicalStreamWriter,
+   *      com.thoughtworks.xstream.converters.MarshallingContext)
+   */
+  @Override
+  public void marshal(Object source, HierarchicalStreamWriter writer,
+      MarshallingContext context) {
+    Map<?, ?> map = (Map<?, ?>) source;
+    if (shortform) {
+      for (Entry<?, ?> e : map.entrySet()) {
+        writer.startNode(String.valueOf(e.getKey()));
+        context.convertAnother(e.getValue());
+        writer.endNode();
+      }
+    } else {
+      for (Entry<?, ?> e : map.entrySet()) {
+        writer.startNode("entry");
+        writer.startNode("key");
+        writer.setValue(String.valueOf(e.getKey()));
+        writer.endNode();
+        writer.startNode("value");
+        context.convertAnother(e.getValue());
+        writer.endNode();
+        writer.endNode();
+      }
+
+    }
+  }
+
+  /**
+   * Convert a suitably positioned reader stream into a Map object.
+   *
+   * @param reader
+   *          the stream reader positioned at the start of the object.
+   * @param context
+   *          the unmarshalling context.
+   * @return the object representing the stream.
+   * @see com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader,
+   *      com.thoughtworks.xstream.converters.UnmarshallingContext)
+   */
+  @Override
+  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+    Map<String, Object> m = Maps.newConcurrentHashMap();
+    reader.moveDown();
+    while (reader.hasMoreChildren()) {
+      String key = reader.getNodeName();
+      if ("entry".equals(key)) {
+        Object value = null;
+        reader.moveDown();
+        String type = reader.getNodeName();
+        if ("key".equals(type)) {
+          key = reader.getValue();
+        } else {
+          if (reader.hasMoreChildren()) {
+            value = readItem(reader, context, m);
+          } else {
+            value = reader.getValue();
+          }
+        }
+        reader.moveUp();
+        reader.moveDown();
+        type = reader.getNodeName();
+        if ("key".equals(type)) {
+          key = reader.getValue();
+        } else {
+          if (reader.hasMoreChildren()) {
+            value = readItem(reader, context, m);
+          } else {
+            value = reader.getValue();
+          }
+        }
+        m.put(key, value);
+        reader.moveUp();
+      } else {
+        reader.moveDown();
+        if (reader.hasMoreChildren()) {
+          m.put(key, readItem(reader, context, m));
+        } else {
+          m.put(key, reader.getValue());
+        }
+        reader.moveUp();
+      }
+    }
+    reader.moveUp();
+    return m;
+  }
+
+  /**
+   * Can this Converter convert the type supplied.
+   *
+   * @param clazz
+   *          the type being converted.
+   * @return true if the type supplied is a form of Map.
+   * @see com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java.lang.Class)
+   */
+  @Override
+  @SuppressWarnings("unchecked")
+  // API is not generic
+  public boolean canConvert(Class clazz) {
+    return (Map.class.isAssignableFrom(clazz));
+  }
+
+}

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/NamespaceSet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/NamespaceSet.java?rev=742816&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/NamespaceSet.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/NamespaceSet.java Tue Feb 10 01:53:52 2009
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.protocol.conversion.xstream;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * A container class that defines namespaces and subsequent element named for an
+ * element in the output stack. A set of active namespaces are defined by
+ * addNamespace and a name to prefixed name translation is specified by
+ * addPrefixedElement.
+ */
+public class NamespaceSet {
+
+  /**
+   * A map namespace attributes to the namespace uri.
+   */
+  private Map<String, String> namespaces = Maps.newHashMap();
+  /**
+   * A map of localElement names to prefixed element names.
+   */
+  private Map<String, String> elementNames = Maps.newHashMap();
+
+  /**
+   * Add a namespace to the list.
+   *
+   * @param nsAttribute
+   *          the attribute to be used to specify the namespace
+   * @param namespace
+   *          the namespace URI
+   */
+  public void addNamespace(String nsAttribute, String namespace) {
+    namespaces.put(nsAttribute, namespace);
+  }
+
+  /**
+   * Add a localname translation.
+   *
+   * @param elementName
+   *          the local name of the element
+   * @param namespacedElementName
+   *          the final name of the element with prefix.
+   */
+  public void addPrefixedElement(String elementName, String namespacedElementName) {
+    elementNames.put(elementName, namespacedElementName);
+  }
+
+  /**
+   * Convert an element name, if necessary.
+   *
+   * @param name
+   *          the name to be converted.
+   * @return the converted name, left as is if no conversion was required.
+   */
+  public String getElementName(String name) {
+    return Objects.firstNonNull(elementNames.get(name), name);
+  }
+
+  /**
+   * @return an Set of entries containing the namespace attributes and uris,
+   *         attributes in the key, uri's in the value or each entry.
+   */
+  public Set<Entry<String, String>> nameSpaceEntrySet() {
+    return namespaces.entrySet();
+  }
+
+}