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>
+ * <outerobject>
+ * <listcontainer>
+ * <listelement>
+ * <objectcontent>
+ * </listelement>
+ * </listcontainer>
+ * ...
+ * </outerobject>
+ * </pre>
+ * or (not currently used in OS)
+ * <pre>
+ * <person>
+ * <emails>
+ * <email>
+ * <type></type>
+ * <value></value>
+ * </email>
+ * ...
+ * </emails>
+ * ...
+ * </person>
+ * </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>
+ * <outerobject>
+ * <listelement>
+ * <objectcontent>
+ * </listelement>
+ * <listelement>
+ * <objectcontent>
+ * </listelement>
+ * ...
+ * </outerobject>
+ * </pre>
+ * <p>
+ * or
+ * </p>
+ *
+ * <pre>
+ * <person>
+ * <emails>
+ * <type></type>
+ * <value></value>
+ * </emails>
+ * <emails>
+ * <type></type>
+ * <value></value>
+ * </emails>
+ * <emails>
+ * <type></type>
+ * <value></value>
+ * </emails>
+ * ...
+ * </person>
+ * </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 >list<
+ */
+ 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 <container>
+ * <key>value</key> <key>value</key> <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();
+ }
+
+}