You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Kevin Brown <et...@google.com> on 2008/07/19 21:50:25 UTC
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Hey Ian,
The casing is inconsistent here -- it should be Json and Api for all cases
rather than JSON or API.
Thanks!
On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
> Author: ieb
> Date: Sat Jul 19 06:51:03 2008
> New Revision: 678158
>
> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
> Log:
> SHINDIG-451
> Applying patch from the JIRA.
>
> Adds a json-lib (net.sf) converter, not wired into social-api at present.
>
> Added:
>
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
>
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
>
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
>
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
> Modified:
> incubator/shindig/trunk/java/social-api/pom.xml
> incubator/shindig/trunk/pom.xml
>
> Modified: incubator/shindig/trunk/java/social-api/pom.xml
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>
> ==============================================================================
> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19 06:51:03
> 2008
> @@ -60,12 +60,31 @@
> <groupId>org.apache.shindig</groupId>
> <artifactId>shindig-common</artifactId>
> </dependency>
> + <!-- is this Ok, only used in test to load the features -->
> + <dependency>
> + <groupId>org.apache.shindig</groupId>
> + <artifactId>shindig-features</artifactId>
> + <scope>test</scope>
> + </dependency>
>
> <!-- external depenencies -->
> <dependency>
> <groupId>org.json</groupId>
> <artifactId>json</artifactId>
> </dependency>
> + <!-- the classifier prevents this working in dep management -->
> + <dependency>
> + <groupId>net.sf.json-lib</groupId>
> + <artifactId>json-lib</artifactId>
> + <version>2.2</version>
> + <classifier>jdk15</classifier>
> + <type>jar</type>
> + </dependency>
> + <dependency>
> + <groupId>rhino</groupId>
> + <artifactId>js</artifactId>
> + <scope>test</scope>
> + </dependency>
> <dependency>
> <groupId>com.google.code.guice</groupId>
> <artifactId>guice</artifactId>
> @@ -112,5 +131,10 @@
> <artifactId>core</artifactId>
> <scope>compile</scope>
> </dependency>
> + <dependency>
> + <groupId>log4j</groupId>
> + <artifactId>log4j</artifactId>
> + <scope>test</scope>
> + </dependency>
> </dependencies>
> </project>
>
> Added:
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,43 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +/**
> + * Where a conversion exception happens in the Json Lib conversion, this
> + * exception is thrown.
> + */
> +public class BeanJsonLibConversionException extends RuntimeException {
> +
> + private static final long serialVersionUID = -8609384443448202372L;
> +
> + public BeanJsonLibConversionException() {
> + }
> +
> + public BeanJsonLibConversionException(String arg0) {
> + super(arg0);
> + }
> +
> + public BeanJsonLibConversionException(Throwable arg0) {
> + super(arg0);
> + }
> +
> + public BeanJsonLibConversionException(String arg0, Throwable arg1) {
> + super(arg0, arg1);
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,286 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import java.lang.reflect.Array;
> +import java.lang.reflect.InvocationTargetException;
> +import java.util.Collection;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import net.sf.ezmorph.MorpherRegistry;
> +import net.sf.json.JSONArray;
> +import net.sf.json.JSONException;
> +import net.sf.json.JSONObject;
> +import net.sf.json.JsonConfig;
> +import net.sf.json.processors.DefaultValueProcessor;
> +import net.sf.json.util.EnumMorpher;
> +import net.sf.json.util.JSONUtils;
> +import net.sf.json.util.NewBeanInstanceStrategy;
> +import net.sf.json.util.PropertyFilter;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.apache.shindig.social.opensocial.model.Address;
> +import org.apache.shindig.social.opensocial.model.Email;
> +import org.apache.shindig.social.opensocial.model.Enum;
> +import org.apache.shindig.social.opensocial.model.MediaItem;
> +import org.apache.shindig.social.opensocial.model.Organization;
> +import org.apache.shindig.social.opensocial.model.Phone;
> +import org.apache.shindig.social.opensocial.model.Url;
> +
> +
> +import com.google.inject.Inject;
> +import com.google.inject.Injector;
> +
> +/**
> + *
> + */
> +public class BeanJsonLibConverter implements BeanConverter {
> +
> + protected static final Log log = LogFactory
> + .getLog(BeanJsonLibConverter.class);
> + private Injector injector;
> + private JsonConfig jsonConfig;
> + private boolean debugMode = false;
> +
> + /*
> + * Register the Enum Morphers so that JSON -> Bean works correctly for
> enums.
> + */
> + static {
> + MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
> + morpherRegistry.registerMorpher(new EnumMorpher(Address.Field.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Phone.Field.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Email.Field.class));
> + morpherRegistry.registerMorpher(new
> EnumMorpher(MediaItem.Field.class));
> + morpherRegistry.registerMorpher(new
> EnumMorpher(MediaItem.Type.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Drinker.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Field.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Gender.class));
> + morpherRegistry
> + .registerMorpher(new EnumMorpher(Enum.NetworkPresence.class));
> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Smoker.class));
> +
> + morpherRegistry.registerMorpher(new JSONObjectToMapMorpher());
> + }
> +
> + @Inject
> + public BeanJsonLibConverter(Injector injector) {
> + this.injector = injector;
> + createJsonConfig();
> + }
> +
> + @SuppressWarnings("unchecked")
> + public <T> T convertToObject(String string, final Class<T>
> rootBeanClass) {
> +
> + if (string.startsWith("[")) {
> + JSONArray jsonArray = JSONArray.fromObject(string, jsonConfig);
> + if (debugMode) {
> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
> + }
> +
> + if (rootBeanClass.isArray()) {
> + Class<?> componentType = rootBeanClass.getComponentType();
> + Object rootObject = injector.getInstance(componentType);
> + List<?> o = JSONArray.toList(jsonArray, rootObject, jsonConfig);
> + Object[] result = (Object[]) Array.newInstance(componentType,
> o.size());
> + for (int i = 0; i < o.size(); i++) {
> + result[i] = o.get(i);
> + }
> + return (T) result;
> +
> + } else {
> + T rootObject = injector.getInstance(rootBeanClass);
> + Object o = JSONArray.toArray(jsonArray, rootObject, jsonConfig);
> + return (T) o;
> + }
> + } else {
> + JSONObject jsonObject = JSONObject.fromObject(string, jsonConfig);
> +
> + if (debugMode) {
> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
> + }
> +
> + T rootObject = injector.getInstance(rootBeanClass);
> + Object o = JSONObject.toBean(jsonObject, rootObject, jsonConfig);
> + return (T) o;
> +
> + }
> + }
> +
> + /**
> + * @return
> + */
> + private void createJsonConfig() {
> +
> + jsonConfig = new JsonConfig();
> +
> + /*
> + * This hook deals with the creation of new beans in the JSON -> Java
> Bean
> + * conversion
> + */
> + jsonConfig.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy() {
> +
> + @SuppressWarnings("unchecked")
> + @Override
> + public Object newInstance(Class beanClass, JSONObject jsonObject)
> + throws InstantiationException, IllegalAccessException,
> + SecurityException, NoSuchMethodException,
> InvocationTargetException {
> + if (beanClass != null) {
> + Object o =
> BeanJsonLibConverter.this.injector.getInstance(beanClass);
> + if (debugMode) {
> + log.info("Created Object " + o + " for " + beanClass + " with
> ["
> + + jsonObject + "]");
> + }
> + return o;
> + }
> + return DEFAULT.newInstance(beanClass, jsonObject);
> + }
> +
> + });
> +
> + /*
> + * We are expecting null for nulls
> + */
> + jsonConfig.registerDefaultValueProcessor(String.class,
> + new DefaultValueProcessor() {
> + @SuppressWarnings("unchecked")
> + public Object getDefaultValue(Class target) {
> + return null;
> + }
> + });
> +
> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
> +
> + public boolean apply(Object source, String name, Object value) {
> + return filterProperty(source, name, value);
> + }
> +
> + });
> +
> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
> +
> + public boolean apply(Object source, String name, Object value) {
> + return filterProperty(source,name,value);
> + }
> +
> + });
> +
> + // the classMap deals with the basic json string to bean conversion
> +
> + Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
> +
> + /*
> + * mappings are required where there is a List of objects in the
> interface
> + * with no indication of what type the list should contain. At the
> moment,
> + * we are using 1 map for all json trees, as there is no conflict, but
> if
> + * there is a map could be selected on the basis of the root object.
> It
> + * would be better to do this with generics, but this is good enough
> and
> + * compact enough for the moment.
> + *
> + */
> + //
> + // activity
> + classMap.put("mediaItems", MediaItem.class);
> + // this may not be necessary
> + classMap.put("templateParams", Map.class);
> + // BodyType needs no mappings
> + // Message needs no mappings
> + // Name needs no mappings
> + // Organization needs no mappings
> + // Url needs no mappings
> + // Email needs no mappings
> + // Phone Needs no mappings
> + // Address Needs no mappings
> + // MediaItem needs no mappings
> +
> + // Person map
> + classMap.put("addresses", Address.class);
> + classMap.put("phoneNumbers", Phone.class);
> + classMap.put("emails", Email.class);
> + classMap.put("mediaItems", MediaItem.class);
> + classMap.put("jobs", Organization.class);
> + classMap.put("schools", Organization.class);
> + classMap.put("urls", Url.class);
> + jsonConfig.setClassMap(classMap);
> +
> + }
> +
> + /**
> + * @param source
> + * @param name
> + * @param value
> + * @return
> + */
> + protected boolean filterProperty(Object source, String name, Object
> value) {
> + if ( value == null ) {
> + return true;
> + }
> + if ( value instanceof JSONArray ) {
> + JSONArray array = (JSONArray) value;
> + if ( array.size() == 0 ) {
> + return true;
> + }
> + }
> + if ( value instanceof JSONObject ) {
> + JSONObject object = (JSONObject) value;
> + if ( object.isNullObject() || object.isEmpty() ) {
> + return true;
> + }
> + }
> + if ( value instanceof Collection) {
> + Collection<?> collection = (Collection<?>) value;
> + if ( collection.size() == 0 ) {
> + return true;
> + }
> + }
> + if ( value instanceof Object[] ) {
> + Object[] oarray = (Object[]) value;
> + if ( oarray.length == 0 ) {
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + public String convertToString(Object pojo) {
> +
> + try {
> + JSONObject jsonObject = JSONObject.fromObject(pojo, jsonConfig);
> + return jsonObject.toString();
> + } catch (JSONException jse) {
> + Class<?> pojoClass = pojo.getClass();
> + if (JSONUtils.isArray(pojoClass)) {
> + JSONArray jsonArray = JSONArray.fromObject(pojo);
> + String result = jsonArray.toString();
> + return result;
> + }
> + throw jse;
> + }
> + }
> +
> + /**
> + * @param string
> + * @param class1
> + */
> + public void addMapping(String key, Class<?> class1) {
> + jsonConfig.getClassMap().put(key, class1);
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,72 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +import net.sf.json.JSONArray;
> +import net.sf.json.JSONObject;
> +
> +/**
> + *
> + */
> +public class JSONLibConverterUtils {
> + protected static final Log log = LogFactory
> + .getLog(JSONLibConverterUtils.class);
> +
> +
> + /**
> + * @param jsonObject
> + */
> + public static final void dumpJsonObject(JSONObject jsonObject, String
> indent) {
> + for (Object key : jsonObject.keySet()) {
> + Object value = jsonObject.get(key);
> + if (value instanceof JSONObject) {
> + log.info(indent + key + ":JSONObject");
> + dumpJsonObject((JSONObject) value, indent + " ");
> + } else if (value instanceof JSONArray) {
> + log.info(indent + key + ":JSONArray " + ((JSONArray)
> value).size());
> + dumpJsonArray((JSONArray) value, indent + " ");
> + } else {
> + log.info(indent + key + ":" + value + ":"
> + + (value == null ? "na" : value.getClass()));
> + }
> + }
> + }
> +
> +
> + /**
> + * @param value
> + * @param string
> + */
> + static void dumpJsonArray(JSONArray array, String indent) {
> + for (Object value : array) {
> + if (value instanceof JSONObject) {
> + log.info(indent + ":JSONObject");
> + dumpJsonObject((JSONObject) value, indent + " ");
> + } else if (value instanceof JSONArray) {
> + log.info(indent + ":JSONArray " + ((JSONArray) value).size());
> + dumpJsonArray((JSONArray) value, indent + " ");
> + } else {
> + log.info(indent + ":" + value + ":"
> + + (value == null ? "na" : value.getClass()));
> + }
> + }
> + }
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,50 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import java.util.HashMap;
> +import java.util.Map;
> +
> +import net.sf.ezmorph.Morpher;
> +import net.sf.ezmorph.ObjectMorpher;
> +import net.sf.json.JSONObject;
> +
> +/**
> + *
> + */
> +public class JSONObjectToMapMorpher implements Morpher, ObjectMorpher {
> +
> + public Class<?> morphsTo() {
> + return Map.class;
> + }
> +
> + @SuppressWarnings("unchecked")
> + public boolean supports(Class clazz) {
> + return (JSONObject.class.equals(clazz));
> + }
> +
> + public Object morph(Object bean) {
> + Map<Object, Object> result = new HashMap<Object, Object>();
> + JSONObject jsonObject = (JSONObject) bean;
> + for ( Object key : jsonObject.keySet()) {
> + result.put(key,jsonObject.get(key));
> + }
> + return result;
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,40 @@
> +/*
> + * 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.social;
> +
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import com.google.inject.AbstractModule;
> +
> +/**
> + * Provides social api component injection for all large tests
> + */
> +public class JsonLibTestsGuiceModule extends AbstractModule {
> + @Override
> + protected void configure() {
> +
> + bind(Map.class).to(HashMap.class);
> + bind(List.class).to(ArrayList.class);
> + bind(Map[].class).to(HashMap[].class);
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,352 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.io.InputStreamReader;
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import javax.xml.parsers.DocumentBuilder;
> +import javax.xml.parsers.DocumentBuilderFactory;
> +import javax.xml.parsers.ParserConfigurationException;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.mozilla.javascript.Context;
> +import org.mozilla.javascript.EvaluatorException;
> +import org.mozilla.javascript.Script;
> +import org.mozilla.javascript.ScriptableObject;
> +import org.w3c.dom.Document;
> +import org.w3c.dom.NamedNodeMap;
> +import org.w3c.dom.Node;
> +import org.w3c.dom.NodeList;
> +import org.xml.sax.SAXException;
> +
> +/**
> + * A class that loads a feature set from features into a Javascript Parser
> to
> + * make the model available to validate JSON messages against.
> + */
> +public class APIValidator {
> +
> + private static final Log log = LogFactory.getLog(APIValidator.class);
> + private Context ctx;
> + private ScriptableObject scope;
> +
> + /**
> + * @param feature
> + * The name of the feature are eg "opensocial-reference",
> this
> + * is a classpath stub (not starting with /) where the
> location
> + * contains a feature.xml file.
> + * @throws SAXException
> + * if feature.xml is not parsable
> + * @throws ParserConfigurationException
> + * if the parsers are invalid
> + * @throws IOException
> + * if feature.xml or the javascript that represents the
> + * feature is missing
> + *
> + */
> + public APIValidator(String feature) throws IOException,
> + ParserConfigurationException, SAXException {
> + ctx = Context.enter();
> + scope = ctx.initStandardObjects();
> + load(feature);
> + }
> +
> + /**
> + * @param json
> + * The json to validate expected in a form { xyz: yyy }
> form
> + * @param object
> + * The json Fields object specifying the structure of the
> json
> + * object, each field in this object contains the name of
> the
> + * json field in the json structure.
> + * @param optionalFields
> + * If any of the fields that appear in the json structure
> are
> + * optional, then they should be defined in this
> parameter.
> + * @param nullfields
> + * @throws APIValidatorExpcetion
> + * if there is a problem validating the json
> + * @return a map so string object pairs containing the fields at the top
> level
> + * of the json tree. Where these are native java objects, they
> will
> + * appear as native object. Complex json objects will appear as
> Rhino
> + * specific objects
> + */
> + public Map<String, Object> validate(String json, String object,
> + String[] optionalFields, String[] nullfields)
> + throws APIValidatorExpcetion {
> +
> + /*
> + * Object[] ids = ScriptableObject.getPropertyIds(scope); for (Object
> id :
> + * ids) { Object o = ScriptableObject.getProperty(scope,
> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
> id.getClass() + "
> + * is " + o); if (o instanceof ScriptableObject) {
> + * listScriptable(String.valueOf(id), (ScriptableObject) o); } }
> + */
> +
> + log.debug("Loading " + json);
> + json = json.trim();
> + if (!json.endsWith("}")) {
> + json = json + "}";
> + }
> + if (!json.startsWith("{")) {
> + json = "{" + json;
> + }
> + json = "( testingObject = " + json + " )";
> +
> + Object so = null;
> + try {
> + so = ctx.evaluateString(scope, json, "test json", 0, null);
> + } catch (EvaluatorException ex) {
> + log.error("Non parseable JSON " + json);
> + }
> + log.debug("Loaded " + so);
> +
> + return validateOject(so, object, optionalFields, nullfields);
> +
> + }
> +
> + /**
> + * Validate an JSON Object extracted
> + *
> + * @param object
> + * @param string
> + * @param optional
> + * @return
> + * @throws APIValidatorExpcetion
> + */
> + public Map<String, Object> validateOject(Object jsonObject, String
> object,
> + String[] optionalFields, String[] nullFields)
> + throws APIValidatorExpcetion {
> + Map<String, String> optional = new HashMap<String, String>();
> + for (String opt : optionalFields) {
> + optional.put(opt, opt);
> + }
> + Map<String, String> nullf = new HashMap<String, String>();
> + for (String nf : nullFields) {
> + nullf.put(nf, nf);
> + }
> +
> + ScriptableObject specification = getScriptableObject(object);
> + log.debug("Looking for " + object + " found " + specification);
> + listScriptable(object, specification);
> +
> + Map<String, Object> resultFields = new HashMap<String, Object>();
> +
> + if (jsonObject instanceof ScriptableObject) {
> + ScriptableObject parsedJSONObject = (ScriptableObject) jsonObject;
> + listScriptable("testingObject", parsedJSONObject);
> + Object[] fields = specification.getIds();
> + for (Object f : fields) {
> + Object fieldName = specification.get(String.valueOf(f),
> specification);
> + Object o = parsedJSONObject.get(String.valueOf(fieldName),
> + parsedJSONObject);
> + if (o == ScriptableObject.NOT_FOUND) {
> + if (optional.containsKey(fieldName)) {
> + log.warn("Missing Optional Field " + fieldName);
> + } else if (!nullf.containsKey(fieldName)) {
> + log.error("Missing Field " + fieldName);
> + throw new APIValidatorExpcetion("Missing Field " + fieldName);
> + }
> + } else {
> + if (nullf.containsKey(fieldName)) {
> + log.error("Field should have been null and was not");
> + }
> + if (o == null) {
> + if (nullf.containsKey(fieldName)) {
> + log.error("Null Fields has been serialized " + fieldName);
> + }
> + log.debug("Got a Null object for Field " + f + ":" + fieldName
> + + " on json [[" + jsonObject + "]]");
> +
> + } else {
> +
> + log.debug("Got JSON Field Field," + f + ":" + fieldName + "
> as "
> + + o + " " + o.getClass());
> + }
> + resultFields.put(String.valueOf(fieldName), o);
> + }
> + }
> +
> + } else {
> + throw new APIValidatorExpcetion(
> + "Parsing JSON resulted in invalid Javascript object, which was "
> + + jsonObject + " JSON was [[" + jsonObject + "]]");
> + }
> + return resultFields;
> + }
> +
> + /**
> + * get an object from the json context and scope.
> + *
> + * @param object
> + * the name of the object specified as a path from the
> base
> + * object
> + * @return the json object
> + */
> + private ScriptableObject getScriptableObject(String object) {
> + String[] path = object.split("\\.");
> + log.debug("Looking up " + object + " elements " + path.length);
> +
> + ScriptableObject s = scope;
> + for (String pe : path) {
> + log.debug("Looking up " + pe + " in " + s);
> + s = (ScriptableObject) s.get(pe, s);
> + log.debug("Looking for " + pe + " in found " + s);
> + }
> + return s;
> + }
> +
> + /**
> + * List a scriptable object at log debug level, constructors will not be
> + * expanded as this loads to recursion.
> + *
> + * @param id
> + * The name of the object
> + * @param scriptableObject
> + * the scriptable Object
> + */
> + private void listScriptable(String id, ScriptableObject
> scriptableObject) {
> + log.debug("ID is Scriptable " + id);
> + if (!id.endsWith("constructor")) {
> + Object[] allIDs = scriptableObject.getAllIds();
> + for (Object oid : allIDs) {
> + log.debug(id + "." + oid);
> + Object o = scriptableObject.get(String.valueOf(oid),
> scriptableObject);
> + if (o instanceof ScriptableObject) {
> + listScriptable(id + "." + String.valueOf(oid),
> (ScriptableObject) o);
> + }
> + }
> + }
> + }
> +
> + /**
> + * Load a feature based on the spec
> + *
> + * @param spec
> + * The name of the location of the spec in the classpath,
> must
> + * not start with a '/' and must should contain a
> feature.xml
> + * file in the location
> + * @throws IOException
> + * If any of the resources cant be found
> + * @throws ParserConfigurationException
> + * If the parser has a problem being constructed
> + * @throws SAXException
> + * on a parse error on the features.xml
> + */
> + private void load(String spec) throws IOException, SAXException,
> + ParserConfigurationException {
> +
> + List<String> scripts = getScripts(spec);
> +
> + List<Script> compiled = new ArrayList<Script>();
> + for (String script : scripts) {
> + String scriptPath = spec + "/" + script;
> + InputStream in =
> this.getClass().getClassLoader().getResourceAsStream(
> + scriptPath);
> + if (in == null) {
> + in = this.getClass().getClassLoader().getResourceAsStream(
> + "features/" + scriptPath);
> + if (in == null) {
> + throw new IOException("Cant load spec " + spec + " or
> features/"+spec+" from classpath");
> + }
> + }
> + InputStreamReader reader = new InputStreamReader(in);
> + Script compiledScript = ctx.compileReader(reader, spec, 0, null);
> + compiled.add(compiledScript);
> + }
> +
> + for (Script compiledScript : compiled) {
> + compiledScript.exec(ctx, scope);
> + }
> +
> + }
> +
> + /**
> + * Add some javascript to the context, and execute it. If extra custom
> + * javascript is wanted in the context or scope then this method will
> load it.
> + *
> + * @param javascript
> + */
> + public void addScript(String javascript) {
> + Script compileScript = ctx.compileString(javascript, "AdditionalJS",
> 0,
> + null);
> + compileScript.exec(ctx, scope);
> + }
> +
> + /**
> + * Get an ordered list of javascript resources from a feature sets.
> + *
> + * @param spec
> + * The spec location
> + * @return An ordered list of javascript resources, these are relative
> to
> + * specification file.
> + * @throws IOException
> + * If any of the resources can't be loaded.
> + * @throws SAXException
> + * Where the feature.xml file is not parsable
> + * @throws ParserConfigurationException
> + * where the parser can't be constructed.
> + * @return An ordered list of script that need to be loaded and executed
> to
> + * make the feature available in the context.
> + */
> + private List<String> getScripts(String spec) throws SAXException,
> + IOException, ParserConfigurationException {
> + String features = spec + "/feature.xml";
> + InputStream in = this.getClass().getClassLoader().getResourceAsStream(
> + features);
> + if (in == null) {
> + in = this.getClass().getClassLoader().getResourceAsStream(
> + "features/"+features);
> + if (in == null) {
> + throw new IOException("Cant find " + features + " or features/" +
> features+ " in classpath ");
> + }
> + }
> + DocumentBuilderFactory builderFactory = DocumentBuilderFactory
> + .newInstance();
> + DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
> + Document doc = documentBuilder.parse(in);
> + NodeList nl = doc.getElementsByTagName("script");
> + List<String> scripts = new ArrayList<String>();
> + for (int i = 0; i < nl.getLength(); i++) {
> + Node scriptNode = nl.item(i);
> + NamedNodeMap attributes = scriptNode.getAttributes();
> + Node scriptAttr = attributes.getNamedItem("src");
> + String script = scriptAttr.getNodeValue();
> + scripts.add(script);
> + }
> + return scripts;
> + }
> +
> + /**
> + * @param nameJSON
> + */
> + public static void dump(Map<?, ?> nameJSON) {
> + if (log.isDebugEnabled()) {
> + for (Object k : nameJSON.keySet()) {
> + Object o = nameJSON.get(k);
> + log.info("Key [" + k + "] value:["
> + + (o == null ? o : o + ":" + o.getClass()) + "]");
> + }
> + }
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,42 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +/**
> + * Thrown when there is a validation exception on one of the apis
> + */
> +public class APIValidatorExpcetion extends Exception {
> +
> + private static final long serialVersionUID = -8969858718669454612L;
> +
> + public APIValidatorExpcetion() {
> + }
> +
> + public APIValidatorExpcetion(String message) {
> + super(message);
> + }
> +
> + public APIValidatorExpcetion(Throwable cause) {
> + super(cause);
> + }
> +
> + public APIValidatorExpcetion(String message, Throwable cause) {
> + super(message, cause);
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,89 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +
> +import java.io.IOException;
> +import java.util.Map;
> +
> +import javax.xml.parsers.ParserConfigurationException;
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +import org.xml.sax.SAXException;
> +
> +/**
> + * Test the api validator to make certain it behaves as is expected.
> + */
> +public class APIValidatorTest {
> +
> + /**
> + * A definition of the test json used in this unit test.
> + */
> + private static final String TEST_DEFINITION =
> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\", FIELD2 :
> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
> +
> + /**
> + * test the validator for successful validation
> + * @throws APIValidatorExpcetion
> + * @throws IOException
> + * @throws ParserConfigurationException
> + * @throws SAXException
> + */
> + @Test
> + public void testValidator() throws APIValidatorExpcetion, IOException,
> ParserConfigurationException, SAXException {
> + APIValidator apiVal = new APIValidator("opensocial-reference");
> + apiVal.addScript(TEST_DEFINITION);
> + String[] optional = {"shouldBeMissing"};
> + String[] nullfields = {};
> + Map<String, Object> result = apiVal.validate("{ json: \"A Test
> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
> + Assert.assertNotNull(result);
> + Assert.assertNotNull(result.get("json"));
> + Assert.assertNotNull(result.get("xyz"));
> + Assert.assertEquals(String.class,result.get("json").getClass());
> + Assert.assertEquals(Integer.class,result.get("xyz").getClass());
> + Assert.assertEquals("A Test JSON",result.get("json"));
> + Assert.assertEquals(123,((Integer)result.get("xyz")).intValue());
> +
> +
> + }
> +
> + /**
> + * Test for a failing validation
> + * @throws APIValidatorExpcetion
> + * @throws IOException
> + * @throws ParserConfigurationException
> + * @throws SAXException
> + */
> + @Test
> + public void testValidatorFail() throws APIValidatorExpcetion,
> IOException, ParserConfigurationException, SAXException {
> + APIValidator apiVal = new APIValidator("opensocial-reference");
> + apiVal.addScript(TEST_DEFINITION);
> + String[] optional = {};
> + String[] nullfields = {};
> + try {
> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz : 123 }",
> "TestDef.Field", optional, nullfields );
> + Assert.fail("Should have Generated an APIValidatorException ");
> + } catch ( APIValidatorExpcetion ex ) {
> +
> + }
> +
> +
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,359 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Map;
> +
> +import junit.framework.TestCase;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
> +import org.apache.shindig.social.opensocial.model.Activity;
> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
> +import org.apache.shindig.social.opensocial.model.Address;
> +import org.apache.shindig.social.opensocial.model.AddressImpl;
> +import org.apache.shindig.social.opensocial.model.Email;
> +import org.apache.shindig.social.opensocial.model.EmailImpl;
> +import org.apache.shindig.social.opensocial.model.MediaItem;
> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
> +import org.apache.shindig.social.opensocial.model.Name;
> +import org.apache.shindig.social.opensocial.model.NameImpl;
> +import org.apache.shindig.social.opensocial.model.Person;
> +import org.apache.shindig.social.opensocial.model.PersonImpl;
> +import org.apache.shindig.social.opensocial.model.Phone;
> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
> +
> +import com.google.common.collect.Lists;
> +import com.google.common.collect.Maps;
> +import com.google.inject.Guice;
> +
> +public class BeanJsonLibConverterTest extends TestCase {
> +
> + private static final Log log = LogFactory
> + .getLog(BeanJsonLibConverterTest.class);
> + private Person johnDoe;
> + private Activity activity;
> +
> + private BeanJsonLibConverter beanJsonConverter;
> + private APIValidator apiValidator;
> + // set to true to get loging output at info level
> + private boolean outputInfo = false;
> +
> + @Override
> + public void setUp() throws Exception {
> + super.setUp();
> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new PhoneImpl(
> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
> "mobile"),
> + new PhoneImpl("+33W000000000", "work")));
> +
> + johnDoe.setAddresses(Lists.<Address> newArrayList(new AddressImpl(
> + "My home address")));
> +
> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
> + "john.doe@work.bar", "work"),
> + new EmailImpl("john.doe@home.bar", "home")));
> +
> + activity = new ActivityImpl("activityId", johnDoe.getId());
> +
> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
> MediaItemImpl(
> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
> +
> + beanJsonConverter = new BeanJsonLibConverter(Guice
> + .createInjector(new JsonLibTestsGuiceModule()));
> +
> + apiValidator = new APIValidator("opensocial-reference");
> +
> + }
> +
> + public static class SpecialPerson extends PersonImpl {
> + public static final String[] OPTIONALFIELDS = {};
> + public static final String[] NULLFIELDS =
> {"jobInterests","nickname","romance","religion","timeZone",
> +
> "relationshipStatus","tags","networkPresence","books","quotes","phoneNumbers","languagesSpoken",
> +
> "activities","jobs","dateOfBirth","profileVideo","bodyType","urls","schools","music","addresses",
> +
> "livingArrangement","thumbnailUrl","humor","sports","scaredOf","movies","age","pets","hasApp","turnOffs",
> +
> "gender","fashion","drinker","aboutMe","children","sexualOrientation","heroes","profileSong","lookingFor",
> +
> "cars","turnOns","tvShows","profileUrl","status","currentLocation","smoker","happiestWhen","ethnicity",
> +
> "food","emails","politicalViews","interests","familyName","honorificSuffix","additionalName","honorificPrefix","givenName"};
> +
> + private String newfield;
> +
> + public SpecialPerson() {
> + super();
> + }
> +
> + public SpecialPerson(String id, String name, String newfield) {
> + super(id, new NameImpl(name));
> + this.newfield = newfield;
> + }
> +
> + public String getNewfield() {
> + return newfield;
> + }
> +
> + public void setNewfield(String newfield) {
> + this.newfield = newfield;
> + }
> +
> + }
> +
> + public void testToJsonOnInheritedClass() throws Exception {
> + SpecialPerson cassie = new SpecialPerson("5", "robot", "nonsense");
> +
> + String result = beanJsonConverter.convertToString(cassie);
> +
> + validatePerson(result, "5", "robot", SpecialPerson.OPTIONALFIELDS,
> SpecialPerson.NULLFIELDS);
> +
> + apiValidator.addScript(" specialPerson = { SPECIAL : \"newfield\" };
> ");
> + String[] optional = {};
> + String[] nullfields = {};
> + Map<String, Object> special = apiValidator.validate(result,
> + "specialPerson", optional,nullfields);
> + assertNotNull(special.get("newfield"));
> + assertEquals(String.class, special.get("newfield").getClass());
> + assertEquals("nonsense", special.get("newfield"));
> +
> + // convert back into an object Tree
> +
> + SpecialPerson parseCassie = beanJsonConverter.convertToObject(result,
> + SpecialPerson.class);
> +
> + assertNotNull(parseCassie);
> + assertEquals(cassie.getId(), parseCassie.getId());
> + assertEquals(cassie.getNewfield(), parseCassie.getNewfield());
> +
> + Name name = parseCassie.getName();
> + Name cassieName = cassie.getName();
> + assertNotNull(name);
> + assertEquals(cassieName.getUnstructured(), name.getUnstructured());
> + assertEquals(cassieName.getAdditionalName(),
> name.getAdditionalName());
> + assertEquals(cassieName.getFamilyName(), name.getFamilyName());
> + assertEquals(cassieName.getGivenName(), name.getGivenName());
> + assertEquals(cassieName.getHonorificPrefix(),
> name.getHonorificPrefix());
> + assertEquals(cassieName.getHonorificSuffix(),
> name.getHonorificSuffix());
> +
> + }
> +
> + /**
> + * @param result
> + * @throws APIValidatorExpcetion
> + */
> + private void validatePerson(String result, String id, String name,
> String[] optional, String[] nullfields)
> + throws APIValidatorExpcetion {
> +
> + Map<String, Object> standard = apiValidator.validate(result,
> + "opensocial.Person.Field", optional,nullfields);
> + assertNotNull(standard.get("id"));
> + assertEquals(String.class, standard.get("id").getClass());
> + assertEquals(id, standard.get("id"));
> +
> + assertNotNull(standard.get("name"));
> + Map<String, Object> nameJSON = apiValidator.validateOject(standard
> + .get("name"), "opensocial.Name.Field", optional,nullfields);
> + APIValidator.dump(nameJSON);
> +
> + assertNotNull(nameJSON.get("unstructured"));
> + assertEquals(String.class, nameJSON.get("unstructured").getClass());
> + assertEquals(name, nameJSON.get("unstructured"));
> +
> + // additional name
> + assertNull(nameJSON.get("additionalName"));
> +
> + }
> +
> + public void testPersonToJson() throws Exception {
> + String result = beanJsonConverter.convertToString(johnDoe);
> + if (outputInfo) {
> + log.info("JSON (" + result + ")");
> + }
> + Person parsedPerson = beanJsonConverter.convertToObject(result,
> + Person.class);
> +
> + assertEquals(johnDoe.getId(), parsedPerson.getId());
> + assertEquals(johnDoe.getName().getUnstructured(),
> parsedPerson.getName()
> + .getUnstructured());
> +
> + List<Address> addresses = parsedPerson.getAddresses();
> + if (outputInfo) {
> + for (Object o : addresses) {
> + log.info("Address " + o);
> + }
> + }
> +
> + assertEquals(1, addresses.size());
> + Address address = addresses.get(0);
> + String unstructured = address.getUnstructuredAddress();
> +
> + assertNotNull(unstructured);
> + assertEquals(johnDoe.getAddresses().get(0).getUnstructuredAddress(),
> + parsedPerson.getAddresses().get(0).getUnstructuredAddress());
> +
> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
> +
> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
> + assertEquals(expectedPhone.getType(), actualPhone.getType());
> + assertEquals(expectedPhone.getNumber(), actualPhone.getNumber());
> + }
> +
> + assertEquals(2, parsedPerson.getEmails().size());
> +
> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
> + Email expectedEmail = johnDoe.getEmails().get(i);
> + Email actualEmail = parsedPerson.getEmails().get(i);
> + assertEquals(expectedEmail.getType(), actualEmail.getType());
> + assertEquals(expectedEmail.getAddress(), actualEmail.getAddress());
> + }
> + }
> +
> + public void testActivityToJson() throws Exception {
> +
> + String result = beanJsonConverter.convertToString(activity);
> + if (outputInfo) {
> + log.info("JSON (" + result + ")");
> + }
> + Activity parsedActivity = beanJsonConverter.convertToObject(result,
> + Activity.class);
> + assertEquals(activity.getUserId(), parsedActivity.getUserId());
> + assertEquals(activity.getId(), parsedActivity.getId());
> +
> + assertEquals(1, parsedActivity.getMediaItems().size());
> +
> + MediaItem expectedItem = activity.getMediaItems().get(0);
> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
> +
> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
> + assertEquals(expectedItem.getMimeType(), actualItem.getMimeType());
> + assertEquals(expectedItem.getType().toString(), actualItem.getType()
> + .toString());
> + }
> +
> + public void testMapsToJson() throws Exception {
> + Map<String, Map<String, String>> map = Maps.newHashMap();
> +
> + Map<String, String> item1Map = Maps.newHashMap();
> + item1Map.put("value", "1");
> +
> + // Null values shouldn't cause exceptions
> + item1Map.put("value2", null);
> + map.put("item1", item1Map);
> +
> + Map<String, String> item2Map = Maps.newHashMap();
> + item2Map.put("value", "2");
> + map.put("item2", item2Map);
> +
> + String result = beanJsonConverter.convertToString(map);
> + if (outputInfo) {
> + log.info("JSON (" + result + ")");
> + }
> + // there is introspection that can tell jsonobject -> bean converter
> what a
> + // map should contain, so we have to tell it
> + beanJsonConverter.addMapping("item1", Map.class);
> + beanJsonConverter.addMapping("item2", Map.class);
> + Map<?, ?> parsedMap = beanJsonConverter
> + .convertToObject(result, Map.class);
> +
> + if (outputInfo) {
> + log.info("Dumping Map (" + parsedMap + ")");
> + }
> + APIValidator.dump(parsedMap);
> +
> + assertEquals("1", ((Map<?,?>)parsedMap.get("item1")).get("value"));
> + assertEquals("2", ((Map<?,?>)parsedMap.get("item2")).get("value"));
> + }
> +
> + public void testListsToJson() throws Exception {
> + Map<String, String> item1Map = Maps.newHashMap();
> + item1Map.put("value", "1");
> +
> + Map<String, String> item2Map = Maps.newHashMap();
> + item2Map.put("value", "2");
> +
> + // put the list into a container before serializing, top level lists
> dont
> + // appear
> + // to be allowed in json
> + // just check that the list is in the holder correctly
> + List<Map<String, String>> list = new ArrayList<Map<String, String>>();
> + list.add(item1Map);
> + list.add(item2Map);
> + String result = beanJsonConverter.convertToString(list);
> + if (outputInfo) {
> + log.info("JSON (" + result + ")");
> + }
> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
> + result, Map[].class);
> +
> + assertEquals("1", parsedList[0].get("value"));
> + assertEquals("2", parsedList[1].get("value"));
> + }
> +
> + public void testArrayToJson() throws Exception {
> + String[] colors = { "blue", "green", "aquamarine" };
> + String result = beanJsonConverter.convertToString(colors);
> + if (outputInfo) {
> + log.info("JSON (" + result + ")");
> + }
> + String[] parsedColors = beanJsonConverter.convertToObject(result,
> + String[].class);
> + assertEquals(colors.length, parsedColors.length);
> + assertEquals(colors[0], parsedColors[0]);
> + assertEquals(colors[1], parsedColors[1]);
> + assertEquals(colors[2], parsedColors[2]);
> + }
> +
> + public void testJsonToActivity() throws Exception {
> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}" + "]}";
> + Activity result = beanJsonConverter.convertToObject(jsonActivity,
> + Activity.class);
> +
> + assertEquals("5", result.getUserId());
> + assertEquals("6", result.getId());
> +
> + assertEquals(1, result.getMediaItems().size());
> +
> + MediaItem actualItem = result.getMediaItems().get(0);
> +
> + assertEquals("hello", actualItem.getUrl());
> + assertEquals("mimey", actualItem.getMimeType());
> + assertEquals("video", actualItem.getType().toString());
> + }
> +
> + public void testJsonToMap() throws Exception {
> + String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
> + Map<String, String> data = Maps.newHashMap();
> + data = beanJsonConverter.convertToObject(jsonActivity,
> + (Class<Map<String, String>>) data.getClass());
> +
> + assertEquals(2, data.size());
> +
> + for (String key : data.keySet()) {
> + Object value = data.get(key);
> + if (key.equals("count")) {
> + assertEquals(0, value);
> + } else if (key.equals("favoriteColor")) {
> + assertEquals("yellow", value);
> + }
> + }
> + }
> +
> +}
>
> Added:
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java?rev=678158&view=auto
>
> ==============================================================================
> ---
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
> (added)
> +++
> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
> Sat Jul 19 06:51:03 2008
> @@ -0,0 +1,271 @@
> +/*
> + * 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.social.opensocial.util;
> +
> +import junit.framework.TestCase;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
> +import org.apache.shindig.social.opensocial.model.Activity;
> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
> +import org.apache.shindig.social.opensocial.model.Address;
> +import org.apache.shindig.social.opensocial.model.AddressImpl;
> +import org.apache.shindig.social.opensocial.model.Email;
> +import org.apache.shindig.social.opensocial.model.EmailImpl;
> +import org.apache.shindig.social.opensocial.model.MediaItem;
> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
> +import org.apache.shindig.social.opensocial.model.NameImpl;
> +import org.apache.shindig.social.opensocial.model.Person;
> +import org.apache.shindig.social.opensocial.model.PersonImpl;
> +import org.apache.shindig.social.opensocial.model.Phone;
> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
> +import org.json.JSONObject;
> +
> +import com.google.common.collect.Lists;
> +import com.google.inject.Guice;
> +
> +public class JsonConverterPerformancePerf extends TestCase {
> +
> + private static final Log log = LogFactory
> + .getLog(JsonConverterPerformancePerf.class);
> + private static final int TEST_SIZE = 10000;
> + private Person johnDoe;
> + private Activity activity;
> +
> + private BeanJsonLibConverter beanJsonLibConverter;
> + private APIValidator apiValidator;
> + // set to true to get loging output at info level
> + private boolean outputInfo = false;
> + private BeanJsonConverter beanJsonConverter;
> +
> + @Override
> + public void setUp() throws Exception {
> + super.setUp();
> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new PhoneImpl(
> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
> "mobile"),
> + new PhoneImpl("+33W000000000", "work")));
> +
> + johnDoe.setAddresses(Lists.<Address> newArrayList(new AddressImpl(
> + "My home address")));
> +
> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
> + "john.doe@work.bar", "work"),
> + new EmailImpl("john.doe@home.bar", "home")));
> +
> + activity = new ActivityImpl("activityId", johnDoe.getId());
> +
> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
> MediaItemImpl(
> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
> +
> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
> + .createInjector(new JsonLibTestsGuiceModule()));
> +
> + beanJsonConverter = new BeanJsonConverter(Guice
> + .createInjector(new SocialApiTestsGuiceModule()));
> +
> + apiValidator = new APIValidator("opensocial-reference");
> +
> + }
> +
> + public static class SpecialPerson extends PersonImpl {
> + private String newfield;
> +
> + public SpecialPerson() {
> + super();
> + }
> +
> + public SpecialPerson(String id, String name, String newfield) {
> + super(id, new NameImpl(name));
> + this.newfield = newfield;
> + }
> +
> + public String getNewfield() {
> + return newfield;
> + }
> +
> + public void setNewfield(String newfield) {
> + this.newfield = newfield;
> + }
> +
> + }
> +
> + public void testToJsonLibOnInheritedClassOutput() throws Exception {
> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
> + for (int i = 0; i < TEST_SIZE; i++) {
> + spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
> + }
> + Runtime r = Runtime.getRuntime();
> + r.gc();
> + long memstart = r.totalMemory()-r.freeMemory();
> + long startOutput = System.currentTimeMillis();
> + String[] output = new String[TEST_SIZE];
> + for (int i = 0; i < TEST_SIZE; i++) {
> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
> + }
> + long endOutput = System.currentTimeMillis();
> + long memend = r.totalMemory()-r.freeMemory();
> +
> + String[] serializeOutput = new String[TEST_SIZE];
> + char[] source = output[0].toCharArray();
> + r.gc();
> +
> + long stringsizeStart = r.totalMemory()-r.freeMemory();
> + for (int i = 0; i < TEST_SIZE; i++) {
> + serializeOutput[i] = new String(source);
> + }
> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
> +
> + /*
> + * Output the time per conversion and the memory usage - the output
> per
> + * conversion.
> + *
> + */
> +
> + log.info("SF JSON Lib Output "
> + + average(startOutput, endOutput, TEST_SIZE)
> + + " ms/conversion, "
> + + (average(memstart, memend, TEST_SIZE)-average(stringsizeStart,
> stringsizeEnd, TEST_SIZE))
> + + " heap bytes/conversion, output packet consumed on average "
> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
> string length of "+output[0].length());
> + log.info("Output Was ["+output[0]+"]");
> + }
> +
> + public void testToJsonLibOnInheritedClassInput() throws Exception {
> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
> + Runtime r = Runtime.getRuntime();
> + r.gc();
> + long personStart = r.totalMemory()-r.freeMemory();
> + for (int i = 0; i < TEST_SIZE; i++) {
> + spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
> + }
> + long personEnd = r.totalMemory()-r.freeMemory();
> +
> + String[] serializeOutput = new String[TEST_SIZE];
> + r.gc();
> + for (int i = 0; i < TEST_SIZE; i++) {
> +
> + serializeOutput[i] = beanJsonLibConverter.convertToString(spa[i]);
> + }
> +
> + r.gc();
> + long memstart = r.totalMemory()-r.freeMemory();
> + long startInput = System.currentTimeMillis();
> + for (int i = 0; i < TEST_SIZE; i++) {
> + sparesult[i] = beanJsonLibConverter.convertToObject(
> + serializeOutput[i], SpecialPerson.class);
> + }
> + long endInput = System.currentTimeMillis();
> + long memend = r.totalMemory()-r.freeMemory();
> +
> + log.info("SF JSON Lib Input "
> + + average(startInput, endInput, TEST_SIZE)
> + + " ms/conversion, "
> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
> personEnd, TEST_SIZE))
> + + " heap bytes/conversion, person object consumed on average "
> + + average(personStart, personEnd, TEST_SIZE));
> + }
> +
> + public void testToJsonOnInheritedClassOutput() throws Exception {
> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
> + for (int i = 0; i < TEST_SIZE; i++) {
> + spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
> + }
> + Runtime r = Runtime.getRuntime();
> + String[] output = new String[TEST_SIZE];
> + r.gc();
> + long memstart = r.totalMemory()-r.freeMemory();
> + long startOutput = System.currentTimeMillis();
> + for (int i = 0; i < TEST_SIZE; i++) {
> + output[i] = ((JSONObject)
> beanJsonConverter.convertToJson(spa[i])).toString();
> + }
> + long endOutput = System.currentTimeMillis();
> + long memend = r.totalMemory()-r.freeMemory();
> + String[] serializeOutput = new String[TEST_SIZE];
> + char[] source = output[0].toCharArray();
> + r.gc();
> +
> + long stringsizeStart = r.totalMemory()-r.freeMemory();
> +
> + for (int i = 0; i < TEST_SIZE; i++) {
> + serializeOutput[i] = new String(source);
> + }
> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
> +
> + log.info("ORG JSON Lib Output "
> + + average(startOutput, endOutput, TEST_SIZE)
> + + " ms/conversion, "
> + + (average(memstart, memend, TEST_SIZE)-average(stringsizeStart,
> stringsizeEnd, TEST_SIZE))
> + + " heap bytes/conversion, output packet consumed on average "
> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
> string length of "+output[0].length());
> + log.info("Output Was ["+output[0]+"]");
> + }
> +
> + /**
> + * @param endOutput
> + * @param startOutput
> + * @param testSize
> + * @return
> + */
> + private float average(long start, long end, int testSize) {
> + float r = end - start;
> + r = r / testSize;
> + return r;
> + }
> +
> + public void XtestToJsonOnInheritedClassInput() throws Exception {
> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
> + Runtime r = Runtime.getRuntime();
> + r.gc();
> + long personStart = r.totalMemory()-r.freeMemory();
> + for (int i = 0; i < TEST_SIZE; i++) {
> + spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
> + }
> + long personEnd = r.totalMemory()-r.freeMemory();
> +
> + String[] serializeOutput = new String[TEST_SIZE];
> + r.gc();
> + for (int i = 0; i < TEST_SIZE; i++) {
> +
> + serializeOutput[i] = beanJsonConverter.convertToString(spa[i]);
> + }
> +
> + r.gc();
> + long memstart = r.totalMemory()-r.freeMemory();
> + long startInput = System.currentTimeMillis();
> +
> + for (int i = 0; i < TEST_SIZE; i++) {
> + sparesult[i] = beanJsonConverter.convertToObject(
> + serializeOutput[i], SpecialPerson.class);
> + }
> + long endInput = System.currentTimeMillis();
> + long memend = r.totalMemory()-r.freeMemory();
> +
> + log.info("SF JSON Lib Input "
> + + average(startInput, endInput, TEST_SIZE)
> + + " ms/conversion, "
> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
> personEnd, TEST_SIZE))
> + + " heap bytes/conversion, person object consumed on average "
> + + average(personStart, personEnd, TEST_SIZE));
> + }
> +
> +}
>
> Modified: incubator/shindig/trunk/pom.xml
> URL:
> http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>
> ==============================================================================
> --- incubator/shindig/trunk/pom.xml (original)
> +++ incubator/shindig/trunk/pom.xml Sat Jul 19 06:51:03 2008
> @@ -853,6 +853,16 @@
> <artifactId>htmlunit</artifactId>
> <version>2.1</version>
> </dependency>
> + <dependency>
> + <groupId>log4j</groupId>
> + <artifactId>log4j</artifactId>
> + <version>1.2.13</version>
> + </dependency>
> + <dependency>
> + <groupId>rhino</groupId>
> + <artifactId>js</artifactId>
> + <version>1.6R7</version>
> + </dependency>
> </dependencies>
> </dependencyManagement>
> </project>
>
>
>
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Posted by Chris Chabot <ch...@xs4all.nl>.
100% a-ok here, thanks
On Jul 20, 2008, at 12:31 PM, Ian Boston wrote:
> I am using git, which said it did a rename on svn commit.
>
> Can you verify that these did come through as moves when you update.
>
> Thanks
> Ian
>
>
>
> x43543:~/Apache/shindig/trunk ieb$ git svn dcommit
> Committing to https://svn.apache.org/repos/asf/incubator/shindig/
> trunk ...
> R java/social-api/src/main/java/org/apache/shindig/
> social/opensocial/util/JSONLibConverterUtils.java => java/social-api/
> src/main/java/org/apache/shindig/social/opensocial/util/
> JsonLibConverterUtils.java
> R java/social-api/src/main/java/org/apache/shindig/
> social/opensocial/util/JSONObjectToMapMorpher.java => java/social-
> api/src/main/java/org/apache/shindig/social/opensocial/util/
> JsonObjectToMapMorpher.java
> R java/social-api/src/test/java/org/apache/shindig/
> social/opensocial/util/APIValidator.java => java/social-api/src/test/
> java/org/apache/shindig/social/opensocial/util/ApiValidator.java
> R java/social-api/src/test/java/org/apache/shindig/
> social/opensocial/util/APIValidatorExpcetion.java => java/social-api/
> src/test/java/org/apache/shindig/social/opensocial/util/
> ApiValidatorExpcetion.java
> R java/social-api/src/test/java/org/apache/shindig/
> social/opensocial/util/APIValidatorTest.java => java/social-api/src/
> test/java/org/apache/shindig/social/opensocial/util/
> ApiValidatorTest.java
> M java/social-api/src/main/java/org/apache/shindig/
> social/opensocial/util/BeanJsonLibConverter.java
> M java/social-api/src/test/java/org/apache/shindig/
> social/opensocial/util/BeanJsonLibConverterTest.java
> M java/social-api/src/test/java/org/apache/shindig/
> social/opensocial/util/JsonConverterPerformancePerf.java
> Committed r678263
>
> On 20 Jul 2008, at 10:46, Chris Chabot wrote:
>
>> Please make sure to do proper svn move's. Last time we had 2
>> identical file names, but with different casing, everyone on a case
>> insensitive file system got into trouble :)
>>
>> -- Chris
>>
>> On Jul 20, 2008, at 11:02 AM, Ian Boston wrote:
>>
>>> Ok will fix.
>>> Ian
>>>
>>> On 19 Jul 2008, at 20:50, Kevin Brown wrote:
>>>
>>>> Hey Ian,
>>>>
>>>> The casing is inconsistent here -- it should be Json and Api for
>>>> all cases
>>>> rather than JSON or API.
>>>>
>>>> Thanks!
>>>>
>>>> On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
>>>>
>>>>> Author: ieb
>>>>> Date: Sat Jul 19 06:51:03 2008
>>>>> New Revision: 678158
>>>>>
>>>>> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
>>>>> Log:
>>>>> SHINDIG-451
>>>>> Applying patch from the JIRA.
>>>>>
>>>>> Adds a json-lib (net.sf) converter, not wired into social-api at
>>>>> present.
>>>>>
>>>>> Added:
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidator.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>>>
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>>> Modified:
>>>>> incubator/shindig/trunk/java/social-api/pom.xml
>>>>> incubator/shindig/trunk/pom.xml
>>>>>
>>>>> Modified: incubator/shindig/trunk/java/social-api/pom.xml
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
>>>>> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19
>>>>> 06:51:03
>>>>> 2008
>>>>> @@ -60,12 +60,31 @@
>>>>> <groupId>org.apache.shindig</groupId>
>>>>> <artifactId>shindig-common</artifactId>
>>>>> </dependency>
>>>>> + <!-- is this Ok, only used in test to load the features -->
>>>>> + <dependency>
>>>>> + <groupId>org.apache.shindig</groupId>
>>>>> + <artifactId>shindig-features</artifactId>
>>>>> + <scope>test</scope>
>>>>> + </dependency>
>>>>>
>>>>> <!-- external depenencies -->
>>>>> <dependency>
>>>>> <groupId>org.json</groupId>
>>>>> <artifactId>json</artifactId>
>>>>> </dependency>
>>>>> + <!-- the classifier prevents this working in dep management
>>>>> -->
>>>>> + <dependency>
>>>>> + <groupId>net.sf.json-lib</groupId>
>>>>> + <artifactId>json-lib</artifactId>
>>>>> + <version>2.2</version>
>>>>> + <classifier>jdk15</classifier>
>>>>> + <type>jar</type>
>>>>> + </dependency>
>>>>> + <dependency>
>>>>> + <groupId>rhino</groupId>
>>>>> + <artifactId>js</artifactId>
>>>>> + <scope>test</scope>
>>>>> + </dependency>
>>>>> <dependency>
>>>>> <groupId>com.google.code.guice</groupId>
>>>>> <artifactId>guice</artifactId>
>>>>> @@ -112,5 +131,10 @@
>>>>> <artifactId>core</artifactId>
>>>>> <scope>compile</scope>
>>>>> </dependency>
>>>>> + <dependency>
>>>>> + <groupId>log4j</groupId>
>>>>> + <artifactId>log4j</artifactId>
>>>>> + <scope>test</scope>
>>>>> + </dependency>
>>>>> </dependencies>
>>>>> </project>
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,43 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +/**
>>>>> + * Where a conversion exception happens in the Json Lib
>>>>> conversion, this
>>>>> + * exception is thrown.
>>>>> + */
>>>>> +public class BeanJsonLibConversionException extends
>>>>> RuntimeException {
>>>>> +
>>>>> + private static final long serialVersionUID =
>>>>> -8609384443448202372L;
>>>>> +
>>>>> + public BeanJsonLibConversionException() {
>>>>> + }
>>>>> +
>>>>> + public BeanJsonLibConversionException(String arg0) {
>>>>> + super(arg0);
>>>>> + }
>>>>> +
>>>>> + public BeanJsonLibConversionException(Throwable arg0) {
>>>>> + super(arg0);
>>>>> + }
>>>>> +
>>>>> + public BeanJsonLibConversionException(String arg0, Throwable
>>>>> arg1) {
>>>>> + super(arg0, arg1);
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,286 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import java.lang.reflect.Array;
>>>>> +import java.lang.reflect.InvocationTargetException;
>>>>> +import java.util.Collection;
>>>>> +import java.util.HashMap;
>>>>> +import java.util.List;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import net.sf.ezmorph.MorpherRegistry;
>>>>> +import net.sf.json.JSONArray;
>>>>> +import net.sf.json.JSONException;
>>>>> +import net.sf.json.JSONObject;
>>>>> +import net.sf.json.JsonConfig;
>>>>> +import net.sf.json.processors.DefaultValueProcessor;
>>>>> +import net.sf.json.util.EnumMorpher;
>>>>> +import net.sf.json.util.JSONUtils;
>>>>> +import net.sf.json.util.NewBeanInstanceStrategy;
>>>>> +import net.sf.json.util.PropertyFilter;
>>>>> +
>>>>> +import org.apache.commons.logging.Log;
>>>>> +import org.apache.commons.logging.LogFactory;
>>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>>> +import org.apache.shindig.social.opensocial.model.Enum;
>>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>>> +import org.apache.shindig.social.opensocial.model.Organization;
>>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>>> +import org.apache.shindig.social.opensocial.model.Url;
>>>>> +
>>>>> +
>>>>> +import com.google.inject.Inject;
>>>>> +import com.google.inject.Injector;
>>>>> +
>>>>> +/**
>>>>> + *
>>>>> + */
>>>>> +public class BeanJsonLibConverter implements BeanConverter {
>>>>> +
>>>>> + protected static final Log log = LogFactory
>>>>> + .getLog(BeanJsonLibConverter.class);
>>>>> + private Injector injector;
>>>>> + private JsonConfig jsonConfig;
>>>>> + private boolean debugMode = false;
>>>>> +
>>>>> + /*
>>>>> + * Register the Enum Morphers so that JSON -> Bean works
>>>>> correctly for
>>>>> enums.
>>>>> + */
>>>>> + static {
>>>>> + MorpherRegistry morpherRegistry =
>>>>> JSONUtils.getMorpherRegistry();
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Address.Field.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Phone.Field.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Email.Field.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(MediaItem.Field.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(MediaItem.Type.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Enum.Drinker.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Enum.Field.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Enum.Gender.class));
>>>>> + morpherRegistry
>>>>> + .registerMorpher(new
>>>>> EnumMorpher(Enum.NetworkPresence.class));
>>>>> + morpherRegistry.registerMorpher(new
>>>>> EnumMorpher(Enum.Smoker.class));
>>>>> +
>>>>> + morpherRegistry.registerMorpher(new
>>>>> JSONObjectToMapMorpher());
>>>>> + }
>>>>> +
>>>>> + @Inject
>>>>> + public BeanJsonLibConverter(Injector injector) {
>>>>> + this.injector = injector;
>>>>> + createJsonConfig();
>>>>> + }
>>>>> +
>>>>> + @SuppressWarnings("unchecked")
>>>>> + public <T> T convertToObject(String string, final Class<T>
>>>>> rootBeanClass) {
>>>>> +
>>>>> + if (string.startsWith("[")) {
>>>>> + JSONArray jsonArray = JSONArray.fromObject(string,
>>>>> jsonConfig);
>>>>> + if (debugMode) {
>>>>> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
>>>>> + }
>>>>> +
>>>>> + if (rootBeanClass.isArray()) {
>>>>> + Class<?> componentType =
>>>>> rootBeanClass.getComponentType();
>>>>> + Object rootObject = injector.getInstance(componentType);
>>>>> + List<?> o = JSONArray.toList(jsonArray, rootObject,
>>>>> jsonConfig);
>>>>> + Object[] result = (Object[])
>>>>> Array.newInstance(componentType,
>>>>> o.size());
>>>>> + for (int i = 0; i < o.size(); i++) {
>>>>> + result[i] = o.get(i);
>>>>> + }
>>>>> + return (T) result;
>>>>> +
>>>>> + } else {
>>>>> + T rootObject = injector.getInstance(rootBeanClass);
>>>>> + Object o = JSONArray.toArray(jsonArray, rootObject,
>>>>> jsonConfig);
>>>>> + return (T) o;
>>>>> + }
>>>>> + } else {
>>>>> + JSONObject jsonObject = JSONObject.fromObject(string,
>>>>> jsonConfig);
>>>>> +
>>>>> + if (debugMode) {
>>>>> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
>>>>> + }
>>>>> +
>>>>> + T rootObject = injector.getInstance(rootBeanClass);
>>>>> + Object o = JSONObject.toBean(jsonObject, rootObject,
>>>>> jsonConfig);
>>>>> + return (T) o;
>>>>> +
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @return
>>>>> + */
>>>>> + private void createJsonConfig() {
>>>>> +
>>>>> + jsonConfig = new JsonConfig();
>>>>> +
>>>>> + /*
>>>>> + * This hook deals with the creation of new beans in the
>>>>> JSON -> Java
>>>>> Bean
>>>>> + * conversion
>>>>> + */
>>>>> + jsonConfig.setNewBeanInstanceStrategy(new
>>>>> NewBeanInstanceStrategy() {
>>>>> +
>>>>> + @SuppressWarnings("unchecked")
>>>>> + @Override
>>>>> + public Object newInstance(Class beanClass, JSONObject
>>>>> jsonObject)
>>>>> + throws InstantiationException, IllegalAccessException,
>>>>> + SecurityException, NoSuchMethodException,
>>>>> InvocationTargetException {
>>>>> + if (beanClass != null) {
>>>>> + Object o =
>>>>> BeanJsonLibConverter.this.injector.getInstance(beanClass);
>>>>> + if (debugMode) {
>>>>> + log.info("Created Object " + o + " for " +
>>>>> beanClass + " with
>>>>> ["
>>>>> + + jsonObject + "]");
>>>>> + }
>>>>> + return o;
>>>>> + }
>>>>> + return DEFAULT.newInstance(beanClass, jsonObject);
>>>>> + }
>>>>> +
>>>>> + });
>>>>> +
>>>>> + /*
>>>>> + * We are expecting null for nulls
>>>>> + */
>>>>> + jsonConfig.registerDefaultValueProcessor(String.class,
>>>>> + new DefaultValueProcessor() {
>>>>> + @SuppressWarnings("unchecked")
>>>>> + public Object getDefaultValue(Class target) {
>>>>> + return null;
>>>>> + }
>>>>> + });
>>>>> +
>>>>> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
>>>>> +
>>>>> + public boolean apply(Object source, String name, Object
>>>>> value) {
>>>>> + return filterProperty(source, name, value);
>>>>> + }
>>>>> +
>>>>> + });
>>>>> +
>>>>> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
>>>>> +
>>>>> + public boolean apply(Object source, String name, Object
>>>>> value) {
>>>>> + return filterProperty(source,name,value);
>>>>> + }
>>>>> +
>>>>> + });
>>>>> +
>>>>> + // the classMap deals with the basic json string to bean
>>>>> conversion
>>>>> +
>>>>> + Map<String, Class<?>> classMap = new HashMap<String, Class<?
>>>>> >>();
>>>>> +
>>>>> + /*
>>>>> + * mappings are required where there is a List of objects
>>>>> in the
>>>>> interface
>>>>> + * with no indication of what type the list should contain.
>>>>> At the
>>>>> moment,
>>>>> + * we are using 1 map for all json trees, as there is no
>>>>> conflict, but
>>>>> if
>>>>> + * there is a map could be selected on the basis of the
>>>>> root object.
>>>>> It
>>>>> + * would be better to do this with generics, but this is
>>>>> good enough
>>>>> and
>>>>> + * compact enough for the moment.
>>>>> + *
>>>>> + */
>>>>> + //
>>>>> + // activity
>>>>> + classMap.put("mediaItems", MediaItem.class);
>>>>> + // this may not be necessary
>>>>> + classMap.put("templateParams", Map.class);
>>>>> + // BodyType needs no mappings
>>>>> + // Message needs no mappings
>>>>> + // Name needs no mappings
>>>>> + // Organization needs no mappings
>>>>> + // Url needs no mappings
>>>>> + // Email needs no mappings
>>>>> + // Phone Needs no mappings
>>>>> + // Address Needs no mappings
>>>>> + // MediaItem needs no mappings
>>>>> +
>>>>> + // Person map
>>>>> + classMap.put("addresses", Address.class);
>>>>> + classMap.put("phoneNumbers", Phone.class);
>>>>> + classMap.put("emails", Email.class);
>>>>> + classMap.put("mediaItems", MediaItem.class);
>>>>> + classMap.put("jobs", Organization.class);
>>>>> + classMap.put("schools", Organization.class);
>>>>> + classMap.put("urls", Url.class);
>>>>> + jsonConfig.setClassMap(classMap);
>>>>> +
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param source
>>>>> + * @param name
>>>>> + * @param value
>>>>> + * @return
>>>>> + */
>>>>> + protected boolean filterProperty(Object source, String name,
>>>>> Object
>>>>> value) {
>>>>> + if ( value == null ) {
>>>>> + return true;
>>>>> + }
>>>>> + if ( value instanceof JSONArray ) {
>>>>> + JSONArray array = (JSONArray) value;
>>>>> + if ( array.size() == 0 ) {
>>>>> + return true;
>>>>> + }
>>>>> + }
>>>>> + if ( value instanceof JSONObject ) {
>>>>> + JSONObject object = (JSONObject) value;
>>>>> + if ( object.isNullObject() || object.isEmpty() ) {
>>>>> + return true;
>>>>> + }
>>>>> + }
>>>>> + if ( value instanceof Collection) {
>>>>> + Collection<?> collection = (Collection<?>) value;
>>>>> + if ( collection.size() == 0 ) {
>>>>> + return true;
>>>>> + }
>>>>> + }
>>>>> + if ( value instanceof Object[] ) {
>>>>> + Object[] oarray = (Object[]) value;
>>>>> + if ( oarray.length == 0 ) {
>>>>> + return true;
>>>>> + }
>>>>> + }
>>>>> + return false;
>>>>> + }
>>>>> +
>>>>> + public String convertToString(Object pojo) {
>>>>> +
>>>>> + try {
>>>>> + JSONObject jsonObject = JSONObject.fromObject(pojo,
>>>>> jsonConfig);
>>>>> + return jsonObject.toString();
>>>>> + } catch (JSONException jse) {
>>>>> + Class<?> pojoClass = pojo.getClass();
>>>>> + if (JSONUtils.isArray(pojoClass)) {
>>>>> + JSONArray jsonArray = JSONArray.fromObject(pojo);
>>>>> + String result = jsonArray.toString();
>>>>> + return result;
>>>>> + }
>>>>> + throw jse;
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param string
>>>>> + * @param class1
>>>>> + */
>>>>> + public void addMapping(String key, Class<?> class1) {
>>>>> + jsonConfig.getClassMap().put(key, class1);
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,72 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import org.apache.commons.logging.Log;
>>>>> +import org.apache.commons.logging.LogFactory;
>>>>> +
>>>>> +import net.sf.json.JSONArray;
>>>>> +import net.sf.json.JSONObject;
>>>>> +
>>>>> +/**
>>>>> + *
>>>>> + */
>>>>> +public class JSONLibConverterUtils {
>>>>> + protected static final Log log = LogFactory
>>>>> + .getLog(JSONLibConverterUtils.class);
>>>>> +
>>>>> +
>>>>> + /**
>>>>> + * @param jsonObject
>>>>> + */
>>>>> + public static final void dumpJsonObject(JSONObject
>>>>> jsonObject, String
>>>>> indent) {
>>>>> + for (Object key : jsonObject.keySet()) {
>>>>> + Object value = jsonObject.get(key);
>>>>> + if (value instanceof JSONObject) {
>>>>> + log.info(indent + key + ":JSONObject");
>>>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>>>> + } else if (value instanceof JSONArray) {
>>>>> + log.info(indent + key + ":JSONArray " + ((JSONArray)
>>>>> value).size());
>>>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>>>> + } else {
>>>>> + log.info(indent + key + ":" + value + ":"
>>>>> + + (value == null ? "na" : value.getClass()));
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +
>>>>> +
>>>>> + /**
>>>>> + * @param value
>>>>> + * @param string
>>>>> + */
>>>>> + static void dumpJsonArray(JSONArray array, String indent) {
>>>>> + for (Object value : array) {
>>>>> + if (value instanceof JSONObject) {
>>>>> + log.info(indent + ":JSONObject");
>>>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>>>> + } else if (value instanceof JSONArray) {
>>>>> + log.info(indent + ":JSONArray " + ((JSONArray)
>>>>> value).size());
>>>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>>>> + } else {
>>>>> + log.info(indent + ":" + value + ":"
>>>>> + + (value == null ? "na" : value.getClass()));
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,50 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import java.util.HashMap;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import net.sf.ezmorph.Morpher;
>>>>> +import net.sf.ezmorph.ObjectMorpher;
>>>>> +import net.sf.json.JSONObject;
>>>>> +
>>>>> +/**
>>>>> + *
>>>>> + */
>>>>> +public class JSONObjectToMapMorpher implements Morpher,
>>>>> ObjectMorpher {
>>>>> +
>>>>> + public Class<?> morphsTo() {
>>>>> + return Map.class;
>>>>> + }
>>>>> +
>>>>> + @SuppressWarnings("unchecked")
>>>>> + public boolean supports(Class clazz) {
>>>>> + return (JSONObject.class.equals(clazz));
>>>>> + }
>>>>> +
>>>>> + public Object morph(Object bean) {
>>>>> + Map<Object, Object> result = new HashMap<Object, Object>();
>>>>> + JSONObject jsonObject = (JSONObject) bean;
>>>>> + for ( Object key : jsonObject.keySet()) {
>>>>> + result.put(key,jsonObject.get(key));
>>>>> + }
>>>>> + return result;
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,40 @@
>>>>> +/*
>>>>> + * 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.social;
>>>>> +
>>>>> +import java.util.ArrayList;
>>>>> +import java.util.HashMap;
>>>>> +import java.util.List;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import com.google.inject.AbstractModule;
>>>>> +
>>>>> +/**
>>>>> + * Provides social api component injection for all large tests
>>>>> + */
>>>>> +public class JsonLibTestsGuiceModule extends AbstractModule {
>>>>> + @Override
>>>>> + protected void configure() {
>>>>> +
>>>>> + bind(Map.class).to(HashMap.class);
>>>>> + bind(List.class).to(ArrayList.class);
>>>>> + bind(Map[].class).to(HashMap[].class);
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidator.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidator.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidator.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,352 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import java.io.IOException;
>>>>> +import java.io.InputStream;
>>>>> +import java.io.InputStreamReader;
>>>>> +import java.util.ArrayList;
>>>>> +import java.util.HashMap;
>>>>> +import java.util.List;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import javax.xml.parsers.DocumentBuilder;
>>>>> +import javax.xml.parsers.DocumentBuilderFactory;
>>>>> +import javax.xml.parsers.ParserConfigurationException;
>>>>> +
>>>>> +import org.apache.commons.logging.Log;
>>>>> +import org.apache.commons.logging.LogFactory;
>>>>> +import org.mozilla.javascript.Context;
>>>>> +import org.mozilla.javascript.EvaluatorException;
>>>>> +import org.mozilla.javascript.Script;
>>>>> +import org.mozilla.javascript.ScriptableObject;
>>>>> +import org.w3c.dom.Document;
>>>>> +import org.w3c.dom.NamedNodeMap;
>>>>> +import org.w3c.dom.Node;
>>>>> +import org.w3c.dom.NodeList;
>>>>> +import org.xml.sax.SAXException;
>>>>> +
>>>>> +/**
>>>>> + * A class that loads a feature set from features into a
>>>>> Javascript Parser
>>>>> to
>>>>> + * make the model available to validate JSON messages against.
>>>>> + */
>>>>> +public class APIValidator {
>>>>> +
>>>>> + private static final Log log =
>>>>> LogFactory.getLog(APIValidator.class);
>>>>> + private Context ctx;
>>>>> + private ScriptableObject scope;
>>>>> +
>>>>> + /**
>>>>> + * @param feature
>>>>> + * The name of the feature are eg "opensocial-
>>>>> reference",
>>>>> this
>>>>> + * is a classpath stub (not starting with /)
>>>>> where the
>>>>> location
>>>>> + * contains a feature.xml file.
>>>>> + * @throws SAXException
>>>>> + * if feature.xml is not parsable
>>>>> + * @throws ParserConfigurationException
>>>>> + * if the parsers are invalid
>>>>> + * @throws IOException
>>>>> + * if feature.xml or the javascript that
>>>>> represents the
>>>>> + * feature is missing
>>>>> + *
>>>>> + */
>>>>> + public APIValidator(String feature) throws IOException,
>>>>> + ParserConfigurationException, SAXException {
>>>>> + ctx = Context.enter();
>>>>> + scope = ctx.initStandardObjects();
>>>>> + load(feature);
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param json
>>>>> + * The json to validate expected in a form
>>>>> { xyz: yyy }
>>>>> form
>>>>> + * @param object
>>>>> + * The json Fields object specifying the
>>>>> structure of the
>>>>> json
>>>>> + * object, each field in this object contains
>>>>> the name of
>>>>> the
>>>>> + * json field in the json structure.
>>>>> + * @param optionalFields
>>>>> + * If any of the fields that appear in the
>>>>> json structure
>>>>> are
>>>>> + * optional, then they should be defined in this
>>>>> parameter.
>>>>> + * @param nullfields
>>>>> + * @throws APIValidatorExpcetion
>>>>> + * if there is a problem validating the json
>>>>> + * @return a map so string object pairs containing the fields
>>>>> at the top
>>>>> level
>>>>> + * of the json tree. Where these are native java
>>>>> objects, they
>>>>> will
>>>>> + * appear as native object. Complex json objects will
>>>>> appear as
>>>>> Rhino
>>>>> + * specific objects
>>>>> + */
>>>>> + public Map<String, Object> validate(String json, String object,
>>>>> + String[] optionalFields, String[] nullfields)
>>>>> + throws APIValidatorExpcetion {
>>>>> +
>>>>> + /*
>>>>> + * Object[] ids = ScriptableObject.getPropertyIds(scope);
>>>>> for (Object
>>>>> id :
>>>>> + * ids) { Object o = ScriptableObject.getProperty(scope,
>>>>> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
>>>>> id.getClass() + "
>>>>> + * is " + o); if (o instanceof ScriptableObject) {
>>>>> + * listScriptable(String.valueOf(id), (ScriptableObject)
>>>>> o); } }
>>>>> + */
>>>>> +
>>>>> + log.debug("Loading " + json);
>>>>> + json = json.trim();
>>>>> + if (!json.endsWith("}")) {
>>>>> + json = json + "}";
>>>>> + }
>>>>> + if (!json.startsWith("{")) {
>>>>> + json = "{" + json;
>>>>> + }
>>>>> + json = "( testingObject = " + json + " )";
>>>>> +
>>>>> + Object so = null;
>>>>> + try {
>>>>> + so = ctx.evaluateString(scope, json, "test json", 0, null);
>>>>> + } catch (EvaluatorException ex) {
>>>>> + log.error("Non parseable JSON " + json);
>>>>> + }
>>>>> + log.debug("Loaded " + so);
>>>>> +
>>>>> + return validateOject(so, object, optionalFields, nullfields);
>>>>> +
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * Validate an JSON Object extracted
>>>>> + *
>>>>> + * @param object
>>>>> + * @param string
>>>>> + * @param optional
>>>>> + * @return
>>>>> + * @throws APIValidatorExpcetion
>>>>> + */
>>>>> + public Map<String, Object> validateOject(Object jsonObject,
>>>>> String
>>>>> object,
>>>>> + String[] optionalFields, String[] nullFields)
>>>>> + throws APIValidatorExpcetion {
>>>>> + Map<String, String> optional = new HashMap<String, String>();
>>>>> + for (String opt : optionalFields) {
>>>>> + optional.put(opt, opt);
>>>>> + }
>>>>> + Map<String, String> nullf = new HashMap<String, String>();
>>>>> + for (String nf : nullFields) {
>>>>> + nullf.put(nf, nf);
>>>>> + }
>>>>> +
>>>>> + ScriptableObject specification = getScriptableObject(object);
>>>>> + log.debug("Looking for " + object + " found " +
>>>>> specification);
>>>>> + listScriptable(object, specification);
>>>>> +
>>>>> + Map<String, Object> resultFields = new HashMap<String,
>>>>> Object>();
>>>>> +
>>>>> + if (jsonObject instanceof ScriptableObject) {
>>>>> + ScriptableObject parsedJSONObject = (ScriptableObject)
>>>>> jsonObject;
>>>>> + listScriptable("testingObject", parsedJSONObject);
>>>>> + Object[] fields = specification.getIds();
>>>>> + for (Object f : fields) {
>>>>> + Object fieldName = specification.get(String.valueOf(f),
>>>>> specification);
>>>>> + Object o =
>>>>> parsedJSONObject.get(String.valueOf(fieldName),
>>>>> + parsedJSONObject);
>>>>> + if (o == ScriptableObject.NOT_FOUND) {
>>>>> + if (optional.containsKey(fieldName)) {
>>>>> + log.warn("Missing Optional Field " + fieldName);
>>>>> + } else if (!nullf.containsKey(fieldName)) {
>>>>> + log.error("Missing Field " + fieldName);
>>>>> + throw new APIValidatorExpcetion("Missing Field " +
>>>>> fieldName);
>>>>> + }
>>>>> + } else {
>>>>> + if (nullf.containsKey(fieldName)) {
>>>>> + log.error("Field should have been null and was not");
>>>>> + }
>>>>> + if (o == null) {
>>>>> + if (nullf.containsKey(fieldName)) {
>>>>> + log.error("Null Fields has been serialized " +
>>>>> fieldName);
>>>>> + }
>>>>> + log.debug("Got a Null object for Field " + f + ":"
>>>>> + fieldName
>>>>> + + " on json [[" + jsonObject + "]]");
>>>>> +
>>>>> + } else {
>>>>> +
>>>>> + log.debug("Got JSON Field Field," + f + ":" +
>>>>> fieldName + "
>>>>> as "
>>>>> + + o + " " + o.getClass());
>>>>> + }
>>>>> + resultFields.put(String.valueOf(fieldName), o);
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + } else {
>>>>> + throw new APIValidatorExpcetion(
>>>>> + "Parsing JSON resulted in invalid Javascript object,
>>>>> which was "
>>>>> + + jsonObject + " JSON was [[" + jsonObject + "]]");
>>>>> + }
>>>>> + return resultFields;
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * get an object from the json context and scope.
>>>>> + *
>>>>> + * @param object
>>>>> + * the name of the object specified as a path
>>>>> from the
>>>>> base
>>>>> + * object
>>>>> + * @return the json object
>>>>> + */
>>>>> + private ScriptableObject getScriptableObject(String object) {
>>>>> + String[] path = object.split("\\.");
>>>>> + log.debug("Looking up " + object + " elements " +
>>>>> path.length);
>>>>> +
>>>>> + ScriptableObject s = scope;
>>>>> + for (String pe : path) {
>>>>> + log.debug("Looking up " + pe + " in " + s);
>>>>> + s = (ScriptableObject) s.get(pe, s);
>>>>> + log.debug("Looking for " + pe + " in found " + s);
>>>>> + }
>>>>> + return s;
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * List a scriptable object at log debug level, constructors
>>>>> will not be
>>>>> + * expanded as this loads to recursion.
>>>>> + *
>>>>> + * @param id
>>>>> + * The name of the object
>>>>> + * @param scriptableObject
>>>>> + * the scriptable Object
>>>>> + */
>>>>> + private void listScriptable(String id, ScriptableObject
>>>>> scriptableObject) {
>>>>> + log.debug("ID is Scriptable " + id);
>>>>> + if (!id.endsWith("constructor")) {
>>>>> + Object[] allIDs = scriptableObject.getAllIds();
>>>>> + for (Object oid : allIDs) {
>>>>> + log.debug(id + "." + oid);
>>>>> + Object o = scriptableObject.get(String.valueOf(oid),
>>>>> scriptableObject);
>>>>> + if (o instanceof ScriptableObject) {
>>>>> + listScriptable(id + "." + String.valueOf(oid),
>>>>> (ScriptableObject) o);
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * Load a feature based on the spec
>>>>> + *
>>>>> + * @param spec
>>>>> + * The name of the location of the spec in the
>>>>> classpath,
>>>>> must
>>>>> + * not start with a '/' and must should
>>>>> contain a
>>>>> feature.xml
>>>>> + * file in the location
>>>>> + * @throws IOException
>>>>> + * If any of the resources cant be found
>>>>> + * @throws ParserConfigurationException
>>>>> + * If the parser has a problem being
>>>>> constructed
>>>>> + * @throws SAXException
>>>>> + * on a parse error on the features.xml
>>>>> + */
>>>>> + private void load(String spec) throws IOException,
>>>>> SAXException,
>>>>> + ParserConfigurationException {
>>>>> +
>>>>> + List<String> scripts = getScripts(spec);
>>>>> +
>>>>> + List<Script> compiled = new ArrayList<Script>();
>>>>> + for (String script : scripts) {
>>>>> + String scriptPath = spec + "/" + script;
>>>>> + InputStream in =
>>>>> this.getClass().getClassLoader().getResourceAsStream(
>>>>> + scriptPath);
>>>>> + if (in == null) {
>>>>> + in =
>>>>> this.getClass().getClassLoader().getResourceAsStream(
>>>>> + "features/" + scriptPath);
>>>>> + if (in == null) {
>>>>> + throw new IOException("Cant load spec " + spec + " or
>>>>> features/"+spec+" from classpath");
>>>>> + }
>>>>> + }
>>>>> + InputStreamReader reader = new InputStreamReader(in);
>>>>> + Script compiledScript = ctx.compileReader(reader, spec,
>>>>> 0, null);
>>>>> + compiled.add(compiledScript);
>>>>> + }
>>>>> +
>>>>> + for (Script compiledScript : compiled) {
>>>>> + compiledScript.exec(ctx, scope);
>>>>> + }
>>>>> +
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * Add some javascript to the context, and execute it. If
>>>>> extra custom
>>>>> + * javascript is wanted in the context or scope then this
>>>>> method will
>>>>> load it.
>>>>> + *
>>>>> + * @param javascript
>>>>> + */
>>>>> + public void addScript(String javascript) {
>>>>> + Script compileScript = ctx.compileString(javascript,
>>>>> "AdditionalJS",
>>>>> 0,
>>>>> + null);
>>>>> + compileScript.exec(ctx, scope);
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * Get an ordered list of javascript resources from a feature
>>>>> sets.
>>>>> + *
>>>>> + * @param spec
>>>>> + * The spec location
>>>>> + * @return An ordered list of javascript resources, these are
>>>>> relative
>>>>> to
>>>>> + * specification file.
>>>>> + * @throws IOException
>>>>> + * If any of the resources can't be loaded.
>>>>> + * @throws SAXException
>>>>> + * Where the feature.xml file is not parsable
>>>>> + * @throws ParserConfigurationException
>>>>> + * where the parser can't be constructed.
>>>>> + * @return An ordered list of script that need to be loaded
>>>>> and executed
>>>>> to
>>>>> + * make the feature available in the context.
>>>>> + */
>>>>> + private List<String> getScripts(String spec) throws
>>>>> SAXException,
>>>>> + IOException, ParserConfigurationException {
>>>>> + String features = spec + "/feature.xml";
>>>>> + InputStream in =
>>>>> this.getClass().getClassLoader().getResourceAsStream(
>>>>> + features);
>>>>> + if (in == null) {
>>>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>>>> + "features/"+features);
>>>>> + if (in == null) {
>>>>> + throw new IOException("Cant find " + features + " or
>>>>> features/" +
>>>>> features+ " in classpath ");
>>>>> + }
>>>>> + }
>>>>> + DocumentBuilderFactory builderFactory =
>>>>> DocumentBuilderFactory
>>>>> + .newInstance();
>>>>> + DocumentBuilder documentBuilder =
>>>>> builderFactory.newDocumentBuilder();
>>>>> + Document doc = documentBuilder.parse(in);
>>>>> + NodeList nl = doc.getElementsByTagName("script");
>>>>> + List<String> scripts = new ArrayList<String>();
>>>>> + for (int i = 0; i < nl.getLength(); i++) {
>>>>> + Node scriptNode = nl.item(i);
>>>>> + NamedNodeMap attributes = scriptNode.getAttributes();
>>>>> + Node scriptAttr = attributes.getNamedItem("src");
>>>>> + String script = scriptAttr.getNodeValue();
>>>>> + scripts.add(script);
>>>>> + }
>>>>> + return scripts;
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param nameJSON
>>>>> + */
>>>>> + public static void dump(Map<?, ?> nameJSON) {
>>>>> + if (log.isDebugEnabled()) {
>>>>> + for (Object k : nameJSON.keySet()) {
>>>>> + Object o = nameJSON.get(k);
>>>>> + log.info("Key [" + k + "] value:["
>>>>> + + (o == null ? o : o + ":" + o.getClass()) + "]");
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,42 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +/**
>>>>> + * Thrown when there is a validation exception on one of the apis
>>>>> + */
>>>>> +public class APIValidatorExpcetion extends Exception {
>>>>> +
>>>>> + private static final long serialVersionUID =
>>>>> -8969858718669454612L;
>>>>> +
>>>>> + public APIValidatorExpcetion() {
>>>>> + }
>>>>> +
>>>>> + public APIValidatorExpcetion(String message) {
>>>>> + super(message);
>>>>> + }
>>>>> +
>>>>> + public APIValidatorExpcetion(Throwable cause) {
>>>>> + super(cause);
>>>>> + }
>>>>> +
>>>>> + public APIValidatorExpcetion(String message, Throwable cause) {
>>>>> + super(message, cause);
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,89 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +
>>>>> +import java.io.IOException;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import javax.xml.parsers.ParserConfigurationException;
>>>>> +
>>>>> +import org.junit.Assert;
>>>>> +import org.junit.Test;
>>>>> +import org.xml.sax.SAXException;
>>>>> +
>>>>> +/**
>>>>> + * Test the api validator to make certain it behaves as is
>>>>> expected.
>>>>> + */
>>>>> +public class APIValidatorTest {
>>>>> +
>>>>> + /**
>>>>> + * A definition of the test json used in this unit test.
>>>>> + */
>>>>> + private static final String TEST_DEFINITION =
>>>>> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\",
>>>>> FIELD2 :
>>>>> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
>>>>> +
>>>>> + /**
>>>>> + * test the validator for successful validation
>>>>> + * @throws APIValidatorExpcetion
>>>>> + * @throws IOException
>>>>> + * @throws ParserConfigurationException
>>>>> + * @throws SAXException
>>>>> + */
>>>>> + @Test
>>>>> + public void testValidator() throws APIValidatorExpcetion,
>>>>> IOException,
>>>>> ParserConfigurationException, SAXException {
>>>>> + APIValidator apiVal = new APIValidator("opensocial-
>>>>> reference");
>>>>> + apiVal.addScript(TEST_DEFINITION);
>>>>> + String[] optional = {"shouldBeMissing"};
>>>>> + String[] nullfields = {};
>>>>> + Map<String, Object> result = apiVal.validate("{ json: \"A
>>>>> Test
>>>>> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
>>>>> + Assert.assertNotNull(result);
>>>>> + Assert.assertNotNull(result.get("json"));
>>>>> + Assert.assertNotNull(result.get("xyz"));
>>>>> +
>>>>> Assert.assertEquals(String.class,result.get("json").getClass());
>>>>> +
>>>>> Assert.assertEquals(Integer.class,result.get("xyz").getClass());
>>>>> + Assert.assertEquals("A Test JSON",result.get("json"));
>>>>> + Assert.assertEquals(123,
>>>>> ((Integer)result.get("xyz")).intValue());
>>>>> +
>>>>> +
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * Test for a failing validation
>>>>> + * @throws APIValidatorExpcetion
>>>>> + * @throws IOException
>>>>> + * @throws ParserConfigurationException
>>>>> + * @throws SAXException
>>>>> + */
>>>>> + @Test
>>>>> + public void testValidatorFail() throws APIValidatorExpcetion,
>>>>> IOException, ParserConfigurationException, SAXException {
>>>>> + APIValidator apiVal = new APIValidator("opensocial-
>>>>> reference");
>>>>> + apiVal.addScript(TEST_DEFINITION);
>>>>> + String[] optional = {};
>>>>> + String[] nullfields = {};
>>>>> + try {
>>>>> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz :
>>>>> 123 }",
>>>>> "TestDef.Field", optional, nullfields );
>>>>> + Assert.fail("Should have Generated an
>>>>> APIValidatorException ");
>>>>> + } catch ( APIValidatorExpcetion ex ) {
>>>>> +
>>>>> + }
>>>>> +
>>>>> +
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,359 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import java.util.ArrayList;
>>>>> +import java.util.List;
>>>>> +import java.util.Map;
>>>>> +
>>>>> +import junit.framework.TestCase;
>>>>> +
>>>>> +import org.apache.commons.logging.Log;
>>>>> +import org.apache.commons.logging.LogFactory;
>>>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Name;
>>>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Person;
>>>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>>>> +
>>>>> +import com.google.common.collect.Lists;
>>>>> +import com.google.common.collect.Maps;
>>>>> +import com.google.inject.Guice;
>>>>> +
>>>>> +public class BeanJsonLibConverterTest extends TestCase {
>>>>> +
>>>>> + private static final Log log = LogFactory
>>>>> + .getLog(BeanJsonLibConverterTest.class);
>>>>> + private Person johnDoe;
>>>>> + private Activity activity;
>>>>> +
>>>>> + private BeanJsonLibConverter beanJsonConverter;
>>>>> + private APIValidator apiValidator;
>>>>> + // set to true to get loging output at info level
>>>>> + private boolean outputInfo = false;
>>>>> +
>>>>> + @Override
>>>>> + public void setUp() throws Exception {
>>>>> + super.setUp();
>>>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>>>> Doe"));
>>>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>>>> PhoneImpl(
>>>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>>>> "mobile"),
>>>>> + new PhoneImpl("+33W000000000", "work")));
>>>>> +
>>>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>>>> AddressImpl(
>>>>> + "My home address")));
>>>>> +
>>>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>>>> + "john.doe@work.bar", "work"),
>>>>> + new EmailImpl("john.doe@home.bar", "home")));
>>>>> +
>>>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>>>> +
>>>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>>>> MediaItemImpl(
>>>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>>>> +
>>>>> + beanJsonConverter = new BeanJsonLibConverter(Guice
>>>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>>>> +
>>>>> + apiValidator = new APIValidator("opensocial-reference");
>>>>> +
>>>>> + }
>>>>> +
>>>>> + public static class SpecialPerson extends PersonImpl {
>>>>> + public static final String[] OPTIONALFIELDS = {};
>>>>> + public static final String[] NULLFIELDS =
>>>>> {"jobInterests","nickname","romance","religion","timeZone",
>>>>> +
>>>>> "relationshipStatus
>>>>> ","tags
>>>>> ","networkPresence
>>>>> ","books","quotes","phoneNumbers","languagesSpoken",
>>>>> +
>>>>> "activities
>>>>> ","jobs
>>>>> ","dateOfBirth
>>>>> ","profileVideo","bodyType","urls","schools","music","addresses",
>>>>> +
>>>>> "livingArrangement
>>>>> ","thumbnailUrl
>>>>> ","humor
>>>>> ","sports","scaredOf","movies","age","pets","hasApp","turnOffs",
>>>>> +
>>>>> "gender
>>>>> ","fashion
>>>>> ","drinker
>>>>> ","aboutMe
>>>>> ","children
>>>>> ","sexualOrientation","heroes","profileSong","lookingFor",
>>>>> +
>>>>> "cars
>>>>> ","turnOns
>>>>> ","tvShows
>>>>> ","profileUrl
>>>>> ","status","currentLocation","smoker","happiestWhen","ethnicity",
>>>>> +
>>>>> "food
>>>>> ","emails
>>>>> ","politicalViews
>>>>> ","interests
>>>>> ","familyName
>>>>> ","honorificSuffix
>>>>> ","additionalName","honorificPrefix","givenName"};
>>>>> +
>>>>> + private String newfield;
>>>>> +
>>>>> + public SpecialPerson() {
>>>>> + super();
>>>>> + }
>>>>> +
>>>>> + public SpecialPerson(String id, String name, String
>>>>> newfield) {
>>>>> + super(id, new NameImpl(name));
>>>>> + this.newfield = newfield;
>>>>> + }
>>>>> +
>>>>> + public String getNewfield() {
>>>>> + return newfield;
>>>>> + }
>>>>> +
>>>>> + public void setNewfield(String newfield) {
>>>>> + this.newfield = newfield;
>>>>> + }
>>>>> +
>>>>> + }
>>>>> +
>>>>> + public void testToJsonOnInheritedClass() throws Exception {
>>>>> + SpecialPerson cassie = new SpecialPerson("5", "robot",
>>>>> "nonsense");
>>>>> +
>>>>> + String result = beanJsonConverter.convertToString(cassie);
>>>>> +
>>>>> + validatePerson(result, "5", "robot",
>>>>> SpecialPerson.OPTIONALFIELDS,
>>>>> SpecialPerson.NULLFIELDS);
>>>>> +
>>>>> + apiValidator.addScript(" specialPerson = { SPECIAL :
>>>>> \"newfield\" };
>>>>> ");
>>>>> + String[] optional = {};
>>>>> + String[] nullfields = {};
>>>>> + Map<String, Object> special = apiValidator.validate(result,
>>>>> + "specialPerson", optional,nullfields);
>>>>> + assertNotNull(special.get("newfield"));
>>>>> + assertEquals(String.class,
>>>>> special.get("newfield").getClass());
>>>>> + assertEquals("nonsense", special.get("newfield"));
>>>>> +
>>>>> + // convert back into an object Tree
>>>>> +
>>>>> + SpecialPerson parseCassie =
>>>>> beanJsonConverter.convertToObject(result,
>>>>> + SpecialPerson.class);
>>>>> +
>>>>> + assertNotNull(parseCassie);
>>>>> + assertEquals(cassie.getId(), parseCassie.getId());
>>>>> + assertEquals(cassie.getNewfield(),
>>>>> parseCassie.getNewfield());
>>>>> +
>>>>> + Name name = parseCassie.getName();
>>>>> + Name cassieName = cassie.getName();
>>>>> + assertNotNull(name);
>>>>> + assertEquals(cassieName.getUnstructured(),
>>>>> name.getUnstructured());
>>>>> + assertEquals(cassieName.getAdditionalName(),
>>>>> name.getAdditionalName());
>>>>> + assertEquals(cassieName.getFamilyName(),
>>>>> name.getFamilyName());
>>>>> + assertEquals(cassieName.getGivenName(), name.getGivenName());
>>>>> + assertEquals(cassieName.getHonorificPrefix(),
>>>>> name.getHonorificPrefix());
>>>>> + assertEquals(cassieName.getHonorificSuffix(),
>>>>> name.getHonorificSuffix());
>>>>> +
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param result
>>>>> + * @throws APIValidatorExpcetion
>>>>> + */
>>>>> + private void validatePerson(String result, String id, String
>>>>> name,
>>>>> String[] optional, String[] nullfields)
>>>>> + throws APIValidatorExpcetion {
>>>>> +
>>>>> + Map<String, Object> standard = apiValidator.validate(result,
>>>>> + "opensocial.Person.Field", optional,nullfields);
>>>>> + assertNotNull(standard.get("id"));
>>>>> + assertEquals(String.class, standard.get("id").getClass());
>>>>> + assertEquals(id, standard.get("id"));
>>>>> +
>>>>> + assertNotNull(standard.get("name"));
>>>>> + Map<String, Object> nameJSON =
>>>>> apiValidator.validateOject(standard
>>>>> + .get("name"), "opensocial.Name.Field",
>>>>> optional,nullfields);
>>>>> + APIValidator.dump(nameJSON);
>>>>> +
>>>>> + assertNotNull(nameJSON.get("unstructured"));
>>>>> + assertEquals(String.class,
>>>>> nameJSON.get("unstructured").getClass());
>>>>> + assertEquals(name, nameJSON.get("unstructured"));
>>>>> +
>>>>> + // additional name
>>>>> + assertNull(nameJSON.get("additionalName"));
>>>>> +
>>>>> + }
>>>>> +
>>>>> + public void testPersonToJson() throws Exception {
>>>>> + String result = beanJsonConverter.convertToString(johnDoe);
>>>>> + if (outputInfo) {
>>>>> + log.info("JSON (" + result + ")");
>>>>> + }
>>>>> + Person parsedPerson =
>>>>> beanJsonConverter.convertToObject(result,
>>>>> + Person.class);
>>>>> +
>>>>> + assertEquals(johnDoe.getId(), parsedPerson.getId());
>>>>> + assertEquals(johnDoe.getName().getUnstructured(),
>>>>> parsedPerson.getName()
>>>>> + .getUnstructured());
>>>>> +
>>>>> + List<Address> addresses = parsedPerson.getAddresses();
>>>>> + if (outputInfo) {
>>>>> + for (Object o : addresses) {
>>>>> + log.info("Address " + o);
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + assertEquals(1, addresses.size());
>>>>> + Address address = addresses.get(0);
>>>>> + String unstructured = address.getUnstructuredAddress();
>>>>> +
>>>>> + assertNotNull(unstructured);
>>>>> +
>>>>> assertEquals
>>>>> (johnDoe.getAddresses().get(0).getUnstructuredAddress(),
>>>>> +
>>>>> parsedPerson.getAddresses().get(0).getUnstructuredAddress());
>>>>> +
>>>>> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
>>>>> +
>>>>> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
>>>>> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
>>>>> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
>>>>> + assertEquals(expectedPhone.getType(),
>>>>> actualPhone.getType());
>>>>> + assertEquals(expectedPhone.getNumber(),
>>>>> actualPhone.getNumber());
>>>>> + }
>>>>> +
>>>>> + assertEquals(2, parsedPerson.getEmails().size());
>>>>> +
>>>>> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
>>>>> + Email expectedEmail = johnDoe.getEmails().get(i);
>>>>> + Email actualEmail = parsedPerson.getEmails().get(i);
>>>>> + assertEquals(expectedEmail.getType(),
>>>>> actualEmail.getType());
>>>>> + assertEquals(expectedEmail.getAddress(),
>>>>> actualEmail.getAddress());
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + public void testActivityToJson() throws Exception {
>>>>> +
>>>>> + String result = beanJsonConverter.convertToString(activity);
>>>>> + if (outputInfo) {
>>>>> + log.info("JSON (" + result + ")");
>>>>> + }
>>>>> + Activity parsedActivity =
>>>>> beanJsonConverter.convertToObject(result,
>>>>> + Activity.class);
>>>>> + assertEquals(activity.getUserId(),
>>>>> parsedActivity.getUserId());
>>>>> + assertEquals(activity.getId(), parsedActivity.getId());
>>>>> +
>>>>> + assertEquals(1, parsedActivity.getMediaItems().size());
>>>>> +
>>>>> + MediaItem expectedItem = activity.getMediaItems().get(0);
>>>>> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
>>>>> +
>>>>> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
>>>>> + assertEquals(expectedItem.getMimeType(),
>>>>> actualItem.getMimeType());
>>>>> + assertEquals(expectedItem.getType().toString(),
>>>>> actualItem.getType()
>>>>> + .toString());
>>>>> + }
>>>>> +
>>>>> + public void testMapsToJson() throws Exception {
>>>>> + Map<String, Map<String, String>> map = Maps.newHashMap();
>>>>> +
>>>>> + Map<String, String> item1Map = Maps.newHashMap();
>>>>> + item1Map.put("value", "1");
>>>>> +
>>>>> + // Null values shouldn't cause exceptions
>>>>> + item1Map.put("value2", null);
>>>>> + map.put("item1", item1Map);
>>>>> +
>>>>> + Map<String, String> item2Map = Maps.newHashMap();
>>>>> + item2Map.put("value", "2");
>>>>> + map.put("item2", item2Map);
>>>>> +
>>>>> + String result = beanJsonConverter.convertToString(map);
>>>>> + if (outputInfo) {
>>>>> + log.info("JSON (" + result + ")");
>>>>> + }
>>>>> + // there is introspection that can tell jsonobject -> bean
>>>>> converter
>>>>> what a
>>>>> + // map should contain, so we have to tell it
>>>>> + beanJsonConverter.addMapping("item1", Map.class);
>>>>> + beanJsonConverter.addMapping("item2", Map.class);
>>>>> + Map<?, ?> parsedMap = beanJsonConverter
>>>>> + .convertToObject(result, Map.class);
>>>>> +
>>>>> + if (outputInfo) {
>>>>> + log.info("Dumping Map (" + parsedMap + ")");
>>>>> + }
>>>>> + APIValidator.dump(parsedMap);
>>>>> +
>>>>> + assertEquals("1", ((Map<?,?
>>>>> >)parsedMap.get("item1")).get("value"));
>>>>> + assertEquals("2", ((Map<?,?
>>>>> >)parsedMap.get("item2")).get("value"));
>>>>> + }
>>>>> +
>>>>> + public void testListsToJson() throws Exception {
>>>>> + Map<String, String> item1Map = Maps.newHashMap();
>>>>> + item1Map.put("value", "1");
>>>>> +
>>>>> + Map<String, String> item2Map = Maps.newHashMap();
>>>>> + item2Map.put("value", "2");
>>>>> +
>>>>> + // put the list into a container before serializing, top
>>>>> level lists
>>>>> dont
>>>>> + // appear
>>>>> + // to be allowed in json
>>>>> + // just check that the list is in the holder correctly
>>>>> + List<Map<String, String>> list = new ArrayList<Map<String,
>>>>> String>>();
>>>>> + list.add(item1Map);
>>>>> + list.add(item2Map);
>>>>> + String result = beanJsonConverter.convertToString(list);
>>>>> + if (outputInfo) {
>>>>> + log.info("JSON (" + result + ")");
>>>>> + }
>>>>> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
>>>>> + result, Map[].class);
>>>>> +
>>>>> + assertEquals("1", parsedList[0].get("value"));
>>>>> + assertEquals("2", parsedList[1].get("value"));
>>>>> + }
>>>>> +
>>>>> + public void testArrayToJson() throws Exception {
>>>>> + String[] colors = { "blue", "green", "aquamarine" };
>>>>> + String result = beanJsonConverter.convertToString(colors);
>>>>> + if (outputInfo) {
>>>>> + log.info("JSON (" + result + ")");
>>>>> + }
>>>>> + String[] parsedColors =
>>>>> beanJsonConverter.convertToObject(result,
>>>>> + String[].class);
>>>>> + assertEquals(colors.length, parsedColors.length);
>>>>> + assertEquals(colors[0], parsedColors[0]);
>>>>> + assertEquals(colors[1], parsedColors[1]);
>>>>> + assertEquals(colors[2], parsedColors[2]);
>>>>> + }
>>>>> +
>>>>> + public void testJsonToActivity() throws Exception {
>>>>> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
>>>>> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}"
>>>>> + "]}";
>>>>> + Activity result =
>>>>> beanJsonConverter.convertToObject(jsonActivity,
>>>>> + Activity.class);
>>>>> +
>>>>> + assertEquals("5", result.getUserId());
>>>>> + assertEquals("6", result.getId());
>>>>> +
>>>>> + assertEquals(1, result.getMediaItems().size());
>>>>> +
>>>>> + MediaItem actualItem = result.getMediaItems().get(0);
>>>>> +
>>>>> + assertEquals("hello", actualItem.getUrl());
>>>>> + assertEquals("mimey", actualItem.getMimeType());
>>>>> + assertEquals("video", actualItem.getType().toString());
>>>>> + }
>>>>> +
>>>>> + public void testJsonToMap() throws Exception {
>>>>> + String jsonActivity = "{count : 0, favoriteColor :
>>>>> 'yellow'}";
>>>>> + Map<String, String> data = Maps.newHashMap();
>>>>> + data = beanJsonConverter.convertToObject(jsonActivity,
>>>>> + (Class<Map<String, String>>) data.getClass());
>>>>> +
>>>>> + assertEquals(2, data.size());
>>>>> +
>>>>> + for (String key : data.keySet()) {
>>>>> + Object value = data.get(key);
>>>>> + if (key.equals("count")) {
>>>>> + assertEquals(0, value);
>>>>> + } else if (key.equals("favoriteColor")) {
>>>>> + assertEquals("yellow", value);
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Added:
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java?rev=678158&view=auto
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> ---
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>>> (added)
>>>>> +++
>>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>>> Sat Jul 19 06:51:03 2008
>>>>> @@ -0,0 +1,271 @@
>>>>> +/*
>>>>> + * 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.social.opensocial.util;
>>>>> +
>>>>> +import junit.framework.TestCase;
>>>>> +
>>>>> +import org.apache.commons.logging.Log;
>>>>> +import org.apache.commons.logging.LogFactory;
>>>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>>>> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
>>>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Person;
>>>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>>>> +import org.json.JSONObject;
>>>>> +
>>>>> +import com.google.common.collect.Lists;
>>>>> +import com.google.inject.Guice;
>>>>> +
>>>>> +public class JsonConverterPerformancePerf extends TestCase {
>>>>> +
>>>>> + private static final Log log = LogFactory
>>>>> + .getLog(JsonConverterPerformancePerf.class);
>>>>> + private static final int TEST_SIZE = 10000;
>>>>> + private Person johnDoe;
>>>>> + private Activity activity;
>>>>> +
>>>>> + private BeanJsonLibConverter beanJsonLibConverter;
>>>>> + private APIValidator apiValidator;
>>>>> + // set to true to get loging output at info level
>>>>> + private boolean outputInfo = false;
>>>>> + private BeanJsonConverter beanJsonConverter;
>>>>> +
>>>>> + @Override
>>>>> + public void setUp() throws Exception {
>>>>> + super.setUp();
>>>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>>>> Doe"));
>>>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>>>> PhoneImpl(
>>>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>>>> "mobile"),
>>>>> + new PhoneImpl("+33W000000000", "work")));
>>>>> +
>>>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>>>> AddressImpl(
>>>>> + "My home address")));
>>>>> +
>>>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>>>> + "john.doe@work.bar", "work"),
>>>>> + new EmailImpl("john.doe@home.bar", "home")));
>>>>> +
>>>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>>>> +
>>>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>>>> MediaItemImpl(
>>>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>>>> +
>>>>> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
>>>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>>>> +
>>>>> + beanJsonConverter = new BeanJsonConverter(Guice
>>>>> + .createInjector(new SocialApiTestsGuiceModule()));
>>>>> +
>>>>> + apiValidator = new APIValidator("opensocial-reference");
>>>>> +
>>>>> + }
>>>>> +
>>>>> + public static class SpecialPerson extends PersonImpl {
>>>>> + private String newfield;
>>>>> +
>>>>> + public SpecialPerson() {
>>>>> + super();
>>>>> + }
>>>>> +
>>>>> + public SpecialPerson(String id, String name, String
>>>>> newfield) {
>>>>> + super(id, new NameImpl(name));
>>>>> + this.newfield = newfield;
>>>>> + }
>>>>> +
>>>>> + public String getNewfield() {
>>>>> + return newfield;
>>>>> + }
>>>>> +
>>>>> + public void setNewfield(String newfield) {
>>>>> + this.newfield = newfield;
>>>>> + }
>>>>> +
>>>>> + }
>>>>> +
>>>>> + public void testToJsonLibOnInheritedClassOutput() throws
>>>>> Exception {
>>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>>> "nonsense");
>>>>> + }
>>>>> + Runtime r = Runtime.getRuntime();
>>>>> + r.gc();
>>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>>> + long startOutput = System.currentTimeMillis();
>>>>> + String[] output = new String[TEST_SIZE];
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
>>>>> + }
>>>>> + long endOutput = System.currentTimeMillis();
>>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>>> + char[] source = output[0].toCharArray();
>>>>> + r.gc();
>>>>> +
>>>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + serializeOutput[i] = new String(source);
>>>>> + }
>>>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + /*
>>>>> + * Output the time per conversion and the memory usage -
>>>>> the output
>>>>> per
>>>>> + * conversion.
>>>>> + *
>>>>> + */
>>>>> +
>>>>> + log.info("SF JSON Lib Output "
>>>>> + + average(startOutput, endOutput, TEST_SIZE)
>>>>> + + " ms/conversion, "
>>>>> + + (average(memstart, memend, TEST_SIZE)-
>>>>> average(stringsizeStart,
>>>>> stringsizeEnd, TEST_SIZE))
>>>>> + + " heap bytes/conversion, output packet consumed on
>>>>> average "
>>>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>>>> for a
>>>>> string length of "+output[0].length());
>>>>> + log.info("Output Was ["+output[0]+"]");
>>>>> + }
>>>>> +
>>>>> + public void testToJsonLibOnInheritedClassInput() throws
>>>>> Exception {
>>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>>>> + Runtime r = Runtime.getRuntime();
>>>>> + r.gc();
>>>>> + long personStart = r.totalMemory()-r.freeMemory();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>>> "nonsense");
>>>>> + }
>>>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>>> + r.gc();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> +
>>>>> + serializeOutput[i] =
>>>>> beanJsonLibConverter.convertToString(spa[i]);
>>>>> + }
>>>>> +
>>>>> + r.gc();
>>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>>> + long startInput = System.currentTimeMillis();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + sparesult[i] = beanJsonLibConverter.convertToObject(
>>>>> + serializeOutput[i], SpecialPerson.class);
>>>>> + }
>>>>> + long endInput = System.currentTimeMillis();
>>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + log.info("SF JSON Lib Input "
>>>>> + + average(startInput, endInput, TEST_SIZE)
>>>>> + + " ms/conversion, "
>>>>> + + (average(memstart, memend, TEST_SIZE)-
>>>>> average(personStart,
>>>>> personEnd, TEST_SIZE))
>>>>> + + " heap bytes/conversion, person object consumed on
>>>>> average "
>>>>> + + average(personStart, personEnd, TEST_SIZE));
>>>>> + }
>>>>> +
>>>>> + public void testToJsonOnInheritedClassOutput() throws
>>>>> Exception {
>>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>>> "nonsense");
>>>>> + }
>>>>> + Runtime r = Runtime.getRuntime();
>>>>> + String[] output = new String[TEST_SIZE];
>>>>> + r.gc();
>>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>>> + long startOutput = System.currentTimeMillis();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + output[i] = ((JSONObject)
>>>>> beanJsonConverter.convertToJson(spa[i])).toString();
>>>>> + }
>>>>> + long endOutput = System.currentTimeMillis();
>>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>>> + char[] source = output[0].toCharArray();
>>>>> + r.gc();
>>>>> +
>>>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + serializeOutput[i] = new String(source);
>>>>> + }
>>>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + log.info("ORG JSON Lib Output "
>>>>> + + average(startOutput, endOutput, TEST_SIZE)
>>>>> + + " ms/conversion, "
>>>>> + + (average(memstart, memend, TEST_SIZE)-
>>>>> average(stringsizeStart,
>>>>> stringsizeEnd, TEST_SIZE))
>>>>> + + " heap bytes/conversion, output packet consumed on
>>>>> average "
>>>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>>>> for a
>>>>> string length of "+output[0].length());
>>>>> + log.info("Output Was ["+output[0]+"]");
>>>>> + }
>>>>> +
>>>>> + /**
>>>>> + * @param endOutput
>>>>> + * @param startOutput
>>>>> + * @param testSize
>>>>> + * @return
>>>>> + */
>>>>> + private float average(long start, long end, int testSize) {
>>>>> + float r = end - start;
>>>>> + r = r / testSize;
>>>>> + return r;
>>>>> + }
>>>>> +
>>>>> + public void XtestToJsonOnInheritedClassInput() throws
>>>>> Exception {
>>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>>>> + Runtime r = Runtime.getRuntime();
>>>>> + r.gc();
>>>>> + long personStart = r.totalMemory()-r.freeMemory();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>>> "nonsense");
>>>>> + }
>>>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>>> + r.gc();
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> +
>>>>> + serializeOutput[i] =
>>>>> beanJsonConverter.convertToString(spa[i]);
>>>>> + }
>>>>> +
>>>>> + r.gc();
>>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>>> + long startInput = System.currentTimeMillis();
>>>>> +
>>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>>> + sparesult[i] = beanJsonConverter.convertToObject(
>>>>> + serializeOutput[i], SpecialPerson.class);
>>>>> + }
>>>>> + long endInput = System.currentTimeMillis();
>>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>>> +
>>>>> + log.info("SF JSON Lib Input "
>>>>> + + average(startInput, endInput, TEST_SIZE)
>>>>> + + " ms/conversion, "
>>>>> + + (average(memstart, memend, TEST_SIZE)-
>>>>> average(personStart,
>>>>> personEnd, TEST_SIZE))
>>>>> + + " heap bytes/conversion, person object consumed on
>>>>> average "
>>>>> + + average(personStart, personEnd, TEST_SIZE));
>>>>> + }
>>>>> +
>>>>> +}
>>>>>
>>>>> Modified: incubator/shindig/trunk/pom.xml
>>>>> URL:
>>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>>>
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> =
>>>>> ==================================================================
>>>>> --- incubator/shindig/trunk/pom.xml (original)
>>>>> +++ incubator/shindig/trunk/pom.xml Sat Jul 19 06:51:03 2008
>>>>> @@ -853,6 +853,16 @@
>>>>> <artifactId>htmlunit</artifactId>
>>>>> <version>2.1</version>
>>>>> </dependency>
>>>>> + <dependency>
>>>>> + <groupId>log4j</groupId>
>>>>> + <artifactId>log4j</artifactId>
>>>>> + <version>1.2.13</version>
>>>>> + </dependency>
>>>>> + <dependency>
>>>>> + <groupId>rhino</groupId>
>>>>> + <artifactId>js</artifactId>
>>>>> + <version>1.6R7</version>
>>>>> + </dependency>
>>>>> </dependencies>
>>>>> </dependencyManagement>
>>>>> </project>
>>>>>
>>>>>
>>>>>
>>
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Posted by Ian Boston <ie...@tfd.co.uk>.
I am using git, which said it did a rename on svn commit.
Can you verify that these did come through as moves when you update.
Thanks
Ian
x43543:~/Apache/shindig/trunk ieb$ git svn dcommit
Committing to https://svn.apache.org/repos/asf/incubator/shindig/
trunk ...
R java/social-api/src/main/java/org/apache/shindig/
social/opensocial/util/JSONLibConverterUtils.java => java/social-api/
src/main/java/org/apache/shindig/social/opensocial/util/
JsonLibConverterUtils.java
R java/social-api/src/main/java/org/apache/shindig/
social/opensocial/util/JSONObjectToMapMorpher.java => java/social-api/
src/main/java/org/apache/shindig/social/opensocial/util/
JsonObjectToMapMorpher.java
R java/social-api/src/test/java/org/apache/shindig/
social/opensocial/util/APIValidator.java => java/social-api/src/test/
java/org/apache/shindig/social/opensocial/util/ApiValidator.java
R java/social-api/src/test/java/org/apache/shindig/
social/opensocial/util/APIValidatorExpcetion.java => java/social-api/
src/test/java/org/apache/shindig/social/opensocial/util/
ApiValidatorExpcetion.java
R java/social-api/src/test/java/org/apache/shindig/
social/opensocial/util/APIValidatorTest.java => java/social-api/src/
test/java/org/apache/shindig/social/opensocial/util/
ApiValidatorTest.java
M java/social-api/src/main/java/org/apache/shindig/
social/opensocial/util/BeanJsonLibConverter.java
M java/social-api/src/test/java/org/apache/shindig/
social/opensocial/util/BeanJsonLibConverterTest.java
M java/social-api/src/test/java/org/apache/shindig/
social/opensocial/util/JsonConverterPerformancePerf.java
Committed r678263
On 20 Jul 2008, at 10:46, Chris Chabot wrote:
> Please make sure to do proper svn move's. Last time we had 2
> identical file names, but with different casing, everyone on a case
> insensitive file system got into trouble :)
>
> -- Chris
>
> On Jul 20, 2008, at 11:02 AM, Ian Boston wrote:
>
>> Ok will fix.
>> Ian
>>
>> On 19 Jul 2008, at 20:50, Kevin Brown wrote:
>>
>>> Hey Ian,
>>>
>>> The casing is inconsistent here -- it should be Json and Api for
>>> all cases
>>> rather than JSON or API.
>>>
>>> Thanks!
>>>
>>> On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
>>>
>>>> Author: ieb
>>>> Date: Sat Jul 19 06:51:03 2008
>>>> New Revision: 678158
>>>>
>>>> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
>>>> Log:
>>>> SHINDIG-451
>>>> Applying patch from the JIRA.
>>>>
>>>> Adds a json-lib (net.sf) converter, not wired into social-api at
>>>> present.
>>>>
>>>> Added:
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidator.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>>
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>> Modified:
>>>> incubator/shindig/trunk/java/social-api/pom.xml
>>>> incubator/shindig/trunk/pom.xml
>>>>
>>>> Modified: incubator/shindig/trunk/java/social-api/pom.xml
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>>
>>>> ===================================================================
>>>> ===========
>>>> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
>>>> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19
>>>> 06:51:03
>>>> 2008
>>>> @@ -60,12 +60,31 @@
>>>> <groupId>org.apache.shindig</groupId>
>>>> <artifactId>shindig-common</artifactId>
>>>> </dependency>
>>>> + <!-- is this Ok, only used in test to load the features -->
>>>> + <dependency>
>>>> + <groupId>org.apache.shindig</groupId>
>>>> + <artifactId>shindig-features</artifactId>
>>>> + <scope>test</scope>
>>>> + </dependency>
>>>>
>>>> <!-- external depenencies -->
>>>> <dependency>
>>>> <groupId>org.json</groupId>
>>>> <artifactId>json</artifactId>
>>>> </dependency>
>>>> + <!-- the classifier prevents this working in dep management
>>>> -->
>>>> + <dependency>
>>>> + <groupId>net.sf.json-lib</groupId>
>>>> + <artifactId>json-lib</artifactId>
>>>> + <version>2.2</version>
>>>> + <classifier>jdk15</classifier>
>>>> + <type>jar</type>
>>>> + </dependency>
>>>> + <dependency>
>>>> + <groupId>rhino</groupId>
>>>> + <artifactId>js</artifactId>
>>>> + <scope>test</scope>
>>>> + </dependency>
>>>> <dependency>
>>>> <groupId>com.google.code.guice</groupId>
>>>> <artifactId>guice</artifactId>
>>>> @@ -112,5 +131,10 @@
>>>> <artifactId>core</artifactId>
>>>> <scope>compile</scope>
>>>> </dependency>
>>>> + <dependency>
>>>> + <groupId>log4j</groupId>
>>>> + <artifactId>log4j</artifactId>
>>>> + <scope>test</scope>
>>>> + </dependency>
>>>> </dependencies>
>>>> </project>
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>>>> BeanJsonLibConversionException.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,43 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +/**
>>>> + * Where a conversion exception happens in the Json Lib
>>>> conversion, this
>>>> + * exception is thrown.
>>>> + */
>>>> +public class BeanJsonLibConversionException extends
>>>> RuntimeException {
>>>> +
>>>> + private static final long serialVersionUID =
>>>> -8609384443448202372L;
>>>> +
>>>> + public BeanJsonLibConversionException() {
>>>> + }
>>>> +
>>>> + public BeanJsonLibConversionException(String arg0) {
>>>> + super(arg0);
>>>> + }
>>>> +
>>>> + public BeanJsonLibConversionException(Throwable arg0) {
>>>> + super(arg0);
>>>> + }
>>>> +
>>>> + public BeanJsonLibConversionException(String arg0, Throwable
>>>> arg1) {
>>>> + super(arg0, arg1);
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>>>> BeanJsonLibConverter.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,286 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import java.lang.reflect.Array;
>>>> +import java.lang.reflect.InvocationTargetException;
>>>> +import java.util.Collection;
>>>> +import java.util.HashMap;
>>>> +import java.util.List;
>>>> +import java.util.Map;
>>>> +
>>>> +import net.sf.ezmorph.MorpherRegistry;
>>>> +import net.sf.json.JSONArray;
>>>> +import net.sf.json.JSONException;
>>>> +import net.sf.json.JSONObject;
>>>> +import net.sf.json.JsonConfig;
>>>> +import net.sf.json.processors.DefaultValueProcessor;
>>>> +import net.sf.json.util.EnumMorpher;
>>>> +import net.sf.json.util.JSONUtils;
>>>> +import net.sf.json.util.NewBeanInstanceStrategy;
>>>> +import net.sf.json.util.PropertyFilter;
>>>> +
>>>> +import org.apache.commons.logging.Log;
>>>> +import org.apache.commons.logging.LogFactory;
>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>> +import org.apache.shindig.social.opensocial.model.Enum;
>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>> +import org.apache.shindig.social.opensocial.model.Organization;
>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>> +import org.apache.shindig.social.opensocial.model.Url;
>>>> +
>>>> +
>>>> +import com.google.inject.Inject;
>>>> +import com.google.inject.Injector;
>>>> +
>>>> +/**
>>>> + *
>>>> + */
>>>> +public class BeanJsonLibConverter implements BeanConverter {
>>>> +
>>>> + protected static final Log log = LogFactory
>>>> + .getLog(BeanJsonLibConverter.class);
>>>> + private Injector injector;
>>>> + private JsonConfig jsonConfig;
>>>> + private boolean debugMode = false;
>>>> +
>>>> + /*
>>>> + * Register the Enum Morphers so that JSON -> Bean works
>>>> correctly for
>>>> enums.
>>>> + */
>>>> + static {
>>>> + MorpherRegistry morpherRegistry =
>>>> JSONUtils.getMorpherRegistry();
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Address.Field.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Phone.Field.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Email.Field.class));
>>>> + morpherRegistry.registerMorpher(new
>>>> EnumMorpher(MediaItem.Field.class));
>>>> + morpherRegistry.registerMorpher(new
>>>> EnumMorpher(MediaItem.Type.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Enum.Drinker.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Enum.Field.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Enum.Gender.class));
>>>> + morpherRegistry
>>>> + .registerMorpher(new EnumMorpher
>>>> (Enum.NetworkPresence.class));
>>>> + morpherRegistry.registerMorpher(new EnumMorpher
>>>> (Enum.Smoker.class));
>>>> +
>>>> + morpherRegistry.registerMorpher(new JSONObjectToMapMorpher());
>>>> + }
>>>> +
>>>> + @Inject
>>>> + public BeanJsonLibConverter(Injector injector) {
>>>> + this.injector = injector;
>>>> + createJsonConfig();
>>>> + }
>>>> +
>>>> + @SuppressWarnings("unchecked")
>>>> + public <T> T convertToObject(String string, final Class<T>
>>>> rootBeanClass) {
>>>> +
>>>> + if (string.startsWith("[")) {
>>>> + JSONArray jsonArray = JSONArray.fromObject(string,
>>>> jsonConfig);
>>>> + if (debugMode) {
>>>> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
>>>> + }
>>>> +
>>>> + if (rootBeanClass.isArray()) {
>>>> + Class<?> componentType = rootBeanClass.getComponentType();
>>>> + Object rootObject = injector.getInstance(componentType);
>>>> + List<?> o = JSONArray.toList(jsonArray, rootObject,
>>>> jsonConfig);
>>>> + Object[] result = (Object[]) Array.newInstance
>>>> (componentType,
>>>> o.size());
>>>> + for (int i = 0; i < o.size(); i++) {
>>>> + result[i] = o.get(i);
>>>> + }
>>>> + return (T) result;
>>>> +
>>>> + } else {
>>>> + T rootObject = injector.getInstance(rootBeanClass);
>>>> + Object o = JSONArray.toArray(jsonArray, rootObject,
>>>> jsonConfig);
>>>> + return (T) o;
>>>> + }
>>>> + } else {
>>>> + JSONObject jsonObject = JSONObject.fromObject(string,
>>>> jsonConfig);
>>>> +
>>>> + if (debugMode) {
>>>> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
>>>> + }
>>>> +
>>>> + T rootObject = injector.getInstance(rootBeanClass);
>>>> + Object o = JSONObject.toBean(jsonObject, rootObject,
>>>> jsonConfig);
>>>> + return (T) o;
>>>> +
>>>> + }
>>>> + }
>>>> +
>>>> + /**
>>>> + * @return
>>>> + */
>>>> + private void createJsonConfig() {
>>>> +
>>>> + jsonConfig = new JsonConfig();
>>>> +
>>>> + /*
>>>> + * This hook deals with the creation of new beans in the
>>>> JSON -> Java
>>>> Bean
>>>> + * conversion
>>>> + */
>>>> + jsonConfig.setNewBeanInstanceStrategy(new
>>>> NewBeanInstanceStrategy() {
>>>> +
>>>> + @SuppressWarnings("unchecked")
>>>> + @Override
>>>> + public Object newInstance(Class beanClass, JSONObject
>>>> jsonObject)
>>>> + throws InstantiationException, IllegalAccessException,
>>>> + SecurityException, NoSuchMethodException,
>>>> InvocationTargetException {
>>>> + if (beanClass != null) {
>>>> + Object o =
>>>> BeanJsonLibConverter.this.injector.getInstance(beanClass);
>>>> + if (debugMode) {
>>>> + log.info("Created Object " + o + " for " +
>>>> beanClass + " with
>>>> ["
>>>> + + jsonObject + "]");
>>>> + }
>>>> + return o;
>>>> + }
>>>> + return DEFAULT.newInstance(beanClass, jsonObject);
>>>> + }
>>>> +
>>>> + });
>>>> +
>>>> + /*
>>>> + * We are expecting null for nulls
>>>> + */
>>>> + jsonConfig.registerDefaultValueProcessor(String.class,
>>>> + new DefaultValueProcessor() {
>>>> + @SuppressWarnings("unchecked")
>>>> + public Object getDefaultValue(Class target) {
>>>> + return null;
>>>> + }
>>>> + });
>>>> +
>>>> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
>>>> +
>>>> + public boolean apply(Object source, String name, Object
>>>> value) {
>>>> + return filterProperty(source, name, value);
>>>> + }
>>>> +
>>>> + });
>>>> +
>>>> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
>>>> +
>>>> + public boolean apply(Object source, String name, Object
>>>> value) {
>>>> + return filterProperty(source,name,value);
>>>> + }
>>>> +
>>>> + });
>>>> +
>>>> + // the classMap deals with the basic json string to bean
>>>> conversion
>>>> +
>>>> + Map<String, Class<?>> classMap = new HashMap<String, Class<?
>>>> >>();
>>>> +
>>>> + /*
>>>> + * mappings are required where there is a List of objects
>>>> in the
>>>> interface
>>>> + * with no indication of what type the list should contain.
>>>> At the
>>>> moment,
>>>> + * we are using 1 map for all json trees, as there is no
>>>> conflict, but
>>>> if
>>>> + * there is a map could be selected on the basis of the
>>>> root object.
>>>> It
>>>> + * would be better to do this with generics, but this is
>>>> good enough
>>>> and
>>>> + * compact enough for the moment.
>>>> + *
>>>> + */
>>>> + //
>>>> + // activity
>>>> + classMap.put("mediaItems", MediaItem.class);
>>>> + // this may not be necessary
>>>> + classMap.put("templateParams", Map.class);
>>>> + // BodyType needs no mappings
>>>> + // Message needs no mappings
>>>> + // Name needs no mappings
>>>> + // Organization needs no mappings
>>>> + // Url needs no mappings
>>>> + // Email needs no mappings
>>>> + // Phone Needs no mappings
>>>> + // Address Needs no mappings
>>>> + // MediaItem needs no mappings
>>>> +
>>>> + // Person map
>>>> + classMap.put("addresses", Address.class);
>>>> + classMap.put("phoneNumbers", Phone.class);
>>>> + classMap.put("emails", Email.class);
>>>> + classMap.put("mediaItems", MediaItem.class);
>>>> + classMap.put("jobs", Organization.class);
>>>> + classMap.put("schools", Organization.class);
>>>> + classMap.put("urls", Url.class);
>>>> + jsonConfig.setClassMap(classMap);
>>>> +
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param source
>>>> + * @param name
>>>> + * @param value
>>>> + * @return
>>>> + */
>>>> + protected boolean filterProperty(Object source, String name,
>>>> Object
>>>> value) {
>>>> + if ( value == null ) {
>>>> + return true;
>>>> + }
>>>> + if ( value instanceof JSONArray ) {
>>>> + JSONArray array = (JSONArray) value;
>>>> + if ( array.size() == 0 ) {
>>>> + return true;
>>>> + }
>>>> + }
>>>> + if ( value instanceof JSONObject ) {
>>>> + JSONObject object = (JSONObject) value;
>>>> + if ( object.isNullObject() || object.isEmpty() ) {
>>>> + return true;
>>>> + }
>>>> + }
>>>> + if ( value instanceof Collection) {
>>>> + Collection<?> collection = (Collection<?>) value;
>>>> + if ( collection.size() == 0 ) {
>>>> + return true;
>>>> + }
>>>> + }
>>>> + if ( value instanceof Object[] ) {
>>>> + Object[] oarray = (Object[]) value;
>>>> + if ( oarray.length == 0 ) {
>>>> + return true;
>>>> + }
>>>> + }
>>>> + return false;
>>>> + }
>>>> +
>>>> + public String convertToString(Object pojo) {
>>>> +
>>>> + try {
>>>> + JSONObject jsonObject = JSONObject.fromObject(pojo,
>>>> jsonConfig);
>>>> + return jsonObject.toString();
>>>> + } catch (JSONException jse) {
>>>> + Class<?> pojoClass = pojo.getClass();
>>>> + if (JSONUtils.isArray(pojoClass)) {
>>>> + JSONArray jsonArray = JSONArray.fromObject(pojo);
>>>> + String result = jsonArray.toString();
>>>> + return result;
>>>> + }
>>>> + throw jse;
>>>> + }
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param string
>>>> + * @param class1
>>>> + */
>>>> + public void addMapping(String key, Class<?> class1) {
>>>> + jsonConfig.getClassMap().put(key, class1);
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>>>> JSONLibConverterUtils.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,72 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import org.apache.commons.logging.Log;
>>>> +import org.apache.commons.logging.LogFactory;
>>>> +
>>>> +import net.sf.json.JSONArray;
>>>> +import net.sf.json.JSONObject;
>>>> +
>>>> +/**
>>>> + *
>>>> + */
>>>> +public class JSONLibConverterUtils {
>>>> + protected static final Log log = LogFactory
>>>> + .getLog(JSONLibConverterUtils.class);
>>>> +
>>>> +
>>>> + /**
>>>> + * @param jsonObject
>>>> + */
>>>> + public static final void dumpJsonObject(JSONObject
>>>> jsonObject, String
>>>> indent) {
>>>> + for (Object key : jsonObject.keySet()) {
>>>> + Object value = jsonObject.get(key);
>>>> + if (value instanceof JSONObject) {
>>>> + log.info(indent + key + ":JSONObject");
>>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>>> + } else if (value instanceof JSONArray) {
>>>> + log.info(indent + key + ":JSONArray " + ((JSONArray)
>>>> value).size());
>>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>>> + } else {
>>>> + log.info(indent + key + ":" + value + ":"
>>>> + + (value == null ? "na" : value.getClass()));
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> +
>>>> + /**
>>>> + * @param value
>>>> + * @param string
>>>> + */
>>>> + static void dumpJsonArray(JSONArray array, String indent) {
>>>> + for (Object value : array) {
>>>> + if (value instanceof JSONObject) {
>>>> + log.info(indent + ":JSONObject");
>>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>>> + } else if (value instanceof JSONArray) {
>>>> + log.info(indent + ":JSONArray " + ((JSONArray)
>>>> value).size());
>>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>>> + } else {
>>>> + log.info(indent + ":" + value + ":"
>>>> + + (value == null ? "na" : value.getClass()));
>>>> + }
>>>> + }
>>>> + }
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>>>> JSONObjectToMapMorpher.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,50 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import java.util.HashMap;
>>>> +import java.util.Map;
>>>> +
>>>> +import net.sf.ezmorph.Morpher;
>>>> +import net.sf.ezmorph.ObjectMorpher;
>>>> +import net.sf.json.JSONObject;
>>>> +
>>>> +/**
>>>> + *
>>>> + */
>>>> +public class JSONObjectToMapMorpher implements Morpher,
>>>> ObjectMorpher {
>>>> +
>>>> + public Class<?> morphsTo() {
>>>> + return Map.class;
>>>> + }
>>>> +
>>>> + @SuppressWarnings("unchecked")
>>>> + public boolean supports(Class clazz) {
>>>> + return (JSONObject.class.equals(clazz));
>>>> + }
>>>> +
>>>> + public Object morph(Object bean) {
>>>> + Map<Object, Object> result = new HashMap<Object, Object>();
>>>> + JSONObject jsonObject = (JSONObject) bean;
>>>> + for ( Object key : jsonObject.keySet()) {
>>>> + result.put(key,jsonObject.get(key));
>>>> + }
>>>> + return result;
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/
>>>> JsonLibTestsGuiceModule.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/JsonLibTestsGuiceModule.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,40 @@
>>>> +/*
>>>> + * 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.social;
>>>> +
>>>> +import java.util.ArrayList;
>>>> +import java.util.HashMap;
>>>> +import java.util.List;
>>>> +import java.util.Map;
>>>> +
>>>> +import com.google.inject.AbstractModule;
>>>> +
>>>> +/**
>>>> + * Provides social api component injection for all large tests
>>>> + */
>>>> +public class JsonLibTestsGuiceModule extends AbstractModule {
>>>> + @Override
>>>> + protected void configure() {
>>>> +
>>>> + bind(Map.class).to(HashMap.class);
>>>> + bind(List.class).to(ArrayList.class);
>>>> + bind(Map[].class).to(HashMap[].class);
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidator.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>>>> APIValidator.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidator.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidator.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,352 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import java.io.IOException;
>>>> +import java.io.InputStream;
>>>> +import java.io.InputStreamReader;
>>>> +import java.util.ArrayList;
>>>> +import java.util.HashMap;
>>>> +import java.util.List;
>>>> +import java.util.Map;
>>>> +
>>>> +import javax.xml.parsers.DocumentBuilder;
>>>> +import javax.xml.parsers.DocumentBuilderFactory;
>>>> +import javax.xml.parsers.ParserConfigurationException;
>>>> +
>>>> +import org.apache.commons.logging.Log;
>>>> +import org.apache.commons.logging.LogFactory;
>>>> +import org.mozilla.javascript.Context;
>>>> +import org.mozilla.javascript.EvaluatorException;
>>>> +import org.mozilla.javascript.Script;
>>>> +import org.mozilla.javascript.ScriptableObject;
>>>> +import org.w3c.dom.Document;
>>>> +import org.w3c.dom.NamedNodeMap;
>>>> +import org.w3c.dom.Node;
>>>> +import org.w3c.dom.NodeList;
>>>> +import org.xml.sax.SAXException;
>>>> +
>>>> +/**
>>>> + * A class that loads a feature set from features into a
>>>> Javascript Parser
>>>> to
>>>> + * make the model available to validate JSON messages against.
>>>> + */
>>>> +public class APIValidator {
>>>> +
>>>> + private static final Log log = LogFactory.getLog
>>>> (APIValidator.class);
>>>> + private Context ctx;
>>>> + private ScriptableObject scope;
>>>> +
>>>> + /**
>>>> + * @param feature
>>>> + * The name of the feature are eg "opensocial-
>>>> reference",
>>>> this
>>>> + * is a classpath stub (not starting with /)
>>>> where the
>>>> location
>>>> + * contains a feature.xml file.
>>>> + * @throws SAXException
>>>> + * if feature.xml is not parsable
>>>> + * @throws ParserConfigurationException
>>>> + * if the parsers are invalid
>>>> + * @throws IOException
>>>> + * if feature.xml or the javascript that
>>>> represents the
>>>> + * feature is missing
>>>> + *
>>>> + */
>>>> + public APIValidator(String feature) throws IOException,
>>>> + ParserConfigurationException, SAXException {
>>>> + ctx = Context.enter();
>>>> + scope = ctx.initStandardObjects();
>>>> + load(feature);
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param json
>>>> + * The json to validate expected in a form
>>>> { xyz: yyy }
>>>> form
>>>> + * @param object
>>>> + * The json Fields object specifying the
>>>> structure of the
>>>> json
>>>> + * object, each field in this object contains
>>>> the name of
>>>> the
>>>> + * json field in the json structure.
>>>> + * @param optionalFields
>>>> + * If any of the fields that appear in the
>>>> json structure
>>>> are
>>>> + * optional, then they should be defined in this
>>>> parameter.
>>>> + * @param nullfields
>>>> + * @throws APIValidatorExpcetion
>>>> + * if there is a problem validating the json
>>>> + * @return a map so string object pairs containing the fields
>>>> at the top
>>>> level
>>>> + * of the json tree. Where these are native java
>>>> objects, they
>>>> will
>>>> + * appear as native object. Complex json objects will
>>>> appear as
>>>> Rhino
>>>> + * specific objects
>>>> + */
>>>> + public Map<String, Object> validate(String json, String object,
>>>> + String[] optionalFields, String[] nullfields)
>>>> + throws APIValidatorExpcetion {
>>>> +
>>>> + /*
>>>> + * Object[] ids = ScriptableObject.getPropertyIds(scope);
>>>> for (Object
>>>> id :
>>>> + * ids) { Object o = ScriptableObject.getProperty(scope,
>>>> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
>>>> id.getClass() + "
>>>> + * is " + o); if (o instanceof ScriptableObject) {
>>>> + * listScriptable(String.valueOf(id), (ScriptableObject)
>>>> o); } }
>>>> + */
>>>> +
>>>> + log.debug("Loading " + json);
>>>> + json = json.trim();
>>>> + if (!json.endsWith("}")) {
>>>> + json = json + "}";
>>>> + }
>>>> + if (!json.startsWith("{")) {
>>>> + json = "{" + json;
>>>> + }
>>>> + json = "( testingObject = " + json + " )";
>>>> +
>>>> + Object so = null;
>>>> + try {
>>>> + so = ctx.evaluateString(scope, json, "test json", 0, null);
>>>> + } catch (EvaluatorException ex) {
>>>> + log.error("Non parseable JSON " + json);
>>>> + }
>>>> + log.debug("Loaded " + so);
>>>> +
>>>> + return validateOject(so, object, optionalFields, nullfields);
>>>> +
>>>> + }
>>>> +
>>>> + /**
>>>> + * Validate an JSON Object extracted
>>>> + *
>>>> + * @param object
>>>> + * @param string
>>>> + * @param optional
>>>> + * @return
>>>> + * @throws APIValidatorExpcetion
>>>> + */
>>>> + public Map<String, Object> validateOject(Object jsonObject,
>>>> String
>>>> object,
>>>> + String[] optionalFields, String[] nullFields)
>>>> + throws APIValidatorExpcetion {
>>>> + Map<String, String> optional = new HashMap<String, String>();
>>>> + for (String opt : optionalFields) {
>>>> + optional.put(opt, opt);
>>>> + }
>>>> + Map<String, String> nullf = new HashMap<String, String>();
>>>> + for (String nf : nullFields) {
>>>> + nullf.put(nf, nf);
>>>> + }
>>>> +
>>>> + ScriptableObject specification = getScriptableObject(object);
>>>> + log.debug("Looking for " + object + " found " +
>>>> specification);
>>>> + listScriptable(object, specification);
>>>> +
>>>> + Map<String, Object> resultFields = new HashMap<String,
>>>> Object>();
>>>> +
>>>> + if (jsonObject instanceof ScriptableObject) {
>>>> + ScriptableObject parsedJSONObject = (ScriptableObject)
>>>> jsonObject;
>>>> + listScriptable("testingObject", parsedJSONObject);
>>>> + Object[] fields = specification.getIds();
>>>> + for (Object f : fields) {
>>>> + Object fieldName = specification.get(String.valueOf(f),
>>>> specification);
>>>> + Object o = parsedJSONObject.get(String.valueOf(fieldName),
>>>> + parsedJSONObject);
>>>> + if (o == ScriptableObject.NOT_FOUND) {
>>>> + if (optional.containsKey(fieldName)) {
>>>> + log.warn("Missing Optional Field " + fieldName);
>>>> + } else if (!nullf.containsKey(fieldName)) {
>>>> + log.error("Missing Field " + fieldName);
>>>> + throw new APIValidatorExpcetion("Missing Field " +
>>>> fieldName);
>>>> + }
>>>> + } else {
>>>> + if (nullf.containsKey(fieldName)) {
>>>> + log.error("Field should have been null and was not");
>>>> + }
>>>> + if (o == null) {
>>>> + if (nullf.containsKey(fieldName)) {
>>>> + log.error("Null Fields has been serialized " +
>>>> fieldName);
>>>> + }
>>>> + log.debug("Got a Null object for Field " + f + ":"
>>>> + fieldName
>>>> + + " on json [[" + jsonObject + "]]");
>>>> +
>>>> + } else {
>>>> +
>>>> + log.debug("Got JSON Field Field," + f + ":" +
>>>> fieldName + "
>>>> as "
>>>> + + o + " " + o.getClass());
>>>> + }
>>>> + resultFields.put(String.valueOf(fieldName), o);
>>>> + }
>>>> + }
>>>> +
>>>> + } else {
>>>> + throw new APIValidatorExpcetion(
>>>> + "Parsing JSON resulted in invalid Javascript object,
>>>> which was "
>>>> + + jsonObject + " JSON was [[" + jsonObject + "]]");
>>>> + }
>>>> + return resultFields;
>>>> + }
>>>> +
>>>> + /**
>>>> + * get an object from the json context and scope.
>>>> + *
>>>> + * @param object
>>>> + * the name of the object specified as a path
>>>> from the
>>>> base
>>>> + * object
>>>> + * @return the json object
>>>> + */
>>>> + private ScriptableObject getScriptableObject(String object) {
>>>> + String[] path = object.split("\\.");
>>>> + log.debug("Looking up " + object + " elements " +
>>>> path.length);
>>>> +
>>>> + ScriptableObject s = scope;
>>>> + for (String pe : path) {
>>>> + log.debug("Looking up " + pe + " in " + s);
>>>> + s = (ScriptableObject) s.get(pe, s);
>>>> + log.debug("Looking for " + pe + " in found " + s);
>>>> + }
>>>> + return s;
>>>> + }
>>>> +
>>>> + /**
>>>> + * List a scriptable object at log debug level, constructors
>>>> will not be
>>>> + * expanded as this loads to recursion.
>>>> + *
>>>> + * @param id
>>>> + * The name of the object
>>>> + * @param scriptableObject
>>>> + * the scriptable Object
>>>> + */
>>>> + private void listScriptable(String id, ScriptableObject
>>>> scriptableObject) {
>>>> + log.debug("ID is Scriptable " + id);
>>>> + if (!id.endsWith("constructor")) {
>>>> + Object[] allIDs = scriptableObject.getAllIds();
>>>> + for (Object oid : allIDs) {
>>>> + log.debug(id + "." + oid);
>>>> + Object o = scriptableObject.get(String.valueOf(oid),
>>>> scriptableObject);
>>>> + if (o instanceof ScriptableObject) {
>>>> + listScriptable(id + "." + String.valueOf(oid),
>>>> (ScriptableObject) o);
>>>> + }
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> + /**
>>>> + * Load a feature based on the spec
>>>> + *
>>>> + * @param spec
>>>> + * The name of the location of the spec in the
>>>> classpath,
>>>> must
>>>> + * not start with a '/' and must should contain a
>>>> feature.xml
>>>> + * file in the location
>>>> + * @throws IOException
>>>> + * If any of the resources cant be found
>>>> + * @throws ParserConfigurationException
>>>> + * If the parser has a problem being constructed
>>>> + * @throws SAXException
>>>> + * on a parse error on the features.xml
>>>> + */
>>>> + private void load(String spec) throws IOException, SAXException,
>>>> + ParserConfigurationException {
>>>> +
>>>> + List<String> scripts = getScripts(spec);
>>>> +
>>>> + List<Script> compiled = new ArrayList<Script>();
>>>> + for (String script : scripts) {
>>>> + String scriptPath = spec + "/" + script;
>>>> + InputStream in =
>>>> this.getClass().getClassLoader().getResourceAsStream(
>>>> + scriptPath);
>>>> + if (in == null) {
>>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>>> + "features/" + scriptPath);
>>>> + if (in == null) {
>>>> + throw new IOException("Cant load spec " + spec + " or
>>>> features/"+spec+" from classpath");
>>>> + }
>>>> + }
>>>> + InputStreamReader reader = new InputStreamReader(in);
>>>> + Script compiledScript = ctx.compileReader(reader, spec,
>>>> 0, null);
>>>> + compiled.add(compiledScript);
>>>> + }
>>>> +
>>>> + for (Script compiledScript : compiled) {
>>>> + compiledScript.exec(ctx, scope);
>>>> + }
>>>> +
>>>> + }
>>>> +
>>>> + /**
>>>> + * Add some javascript to the context, and execute it. If
>>>> extra custom
>>>> + * javascript is wanted in the context or scope then this
>>>> method will
>>>> load it.
>>>> + *
>>>> + * @param javascript
>>>> + */
>>>> + public void addScript(String javascript) {
>>>> + Script compileScript = ctx.compileString(javascript,
>>>> "AdditionalJS",
>>>> 0,
>>>> + null);
>>>> + compileScript.exec(ctx, scope);
>>>> + }
>>>> +
>>>> + /**
>>>> + * Get an ordered list of javascript resources from a feature
>>>> sets.
>>>> + *
>>>> + * @param spec
>>>> + * The spec location
>>>> + * @return An ordered list of javascript resources, these are
>>>> relative
>>>> to
>>>> + * specification file.
>>>> + * @throws IOException
>>>> + * If any of the resources can't be loaded.
>>>> + * @throws SAXException
>>>> + * Where the feature.xml file is not parsable
>>>> + * @throws ParserConfigurationException
>>>> + * where the parser can't be constructed.
>>>> + * @return An ordered list of script that need to be loaded
>>>> and executed
>>>> to
>>>> + * make the feature available in the context.
>>>> + */
>>>> + private List<String> getScripts(String spec) throws
>>>> SAXException,
>>>> + IOException, ParserConfigurationException {
>>>> + String features = spec + "/feature.xml";
>>>> + InputStream in = this.getClass().getClassLoader
>>>> ().getResourceAsStream(
>>>> + features);
>>>> + if (in == null) {
>>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>>> + "features/"+features);
>>>> + if (in == null) {
>>>> + throw new IOException("Cant find " + features + " or
>>>> features/" +
>>>> features+ " in classpath ");
>>>> + }
>>>> + }
>>>> + DocumentBuilderFactory builderFactory = DocumentBuilderFactory
>>>> + .newInstance();
>>>> + DocumentBuilder documentBuilder =
>>>> builderFactory.newDocumentBuilder();
>>>> + Document doc = documentBuilder.parse(in);
>>>> + NodeList nl = doc.getElementsByTagName("script");
>>>> + List<String> scripts = new ArrayList<String>();
>>>> + for (int i = 0; i < nl.getLength(); i++) {
>>>> + Node scriptNode = nl.item(i);
>>>> + NamedNodeMap attributes = scriptNode.getAttributes();
>>>> + Node scriptAttr = attributes.getNamedItem("src");
>>>> + String script = scriptAttr.getNodeValue();
>>>> + scripts.add(script);
>>>> + }
>>>> + return scripts;
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param nameJSON
>>>> + */
>>>> + public static void dump(Map<?, ?> nameJSON) {
>>>> + if (log.isDebugEnabled()) {
>>>> + for (Object k : nameJSON.keySet()) {
>>>> + Object o = nameJSON.get(k);
>>>> + log.info("Key [" + k + "] value:["
>>>> + + (o == null ? o : o + ":" + o.getClass()) + "]");
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>>>> APIValidatorExpcetion.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,42 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +/**
>>>> + * Thrown when there is a validation exception on one of the apis
>>>> + */
>>>> +public class APIValidatorExpcetion extends Exception {
>>>> +
>>>> + private static final long serialVersionUID =
>>>> -8969858718669454612L;
>>>> +
>>>> + public APIValidatorExpcetion() {
>>>> + }
>>>> +
>>>> + public APIValidatorExpcetion(String message) {
>>>> + super(message);
>>>> + }
>>>> +
>>>> + public APIValidatorExpcetion(Throwable cause) {
>>>> + super(cause);
>>>> + }
>>>> +
>>>> + public APIValidatorExpcetion(String message, Throwable cause) {
>>>> + super(message, cause);
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>>>> APIValidatorTest.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,89 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +
>>>> +import java.io.IOException;
>>>> +import java.util.Map;
>>>> +
>>>> +import javax.xml.parsers.ParserConfigurationException;
>>>> +
>>>> +import org.junit.Assert;
>>>> +import org.junit.Test;
>>>> +import org.xml.sax.SAXException;
>>>> +
>>>> +/**
>>>> + * Test the api validator to make certain it behaves as is
>>>> expected.
>>>> + */
>>>> +public class APIValidatorTest {
>>>> +
>>>> + /**
>>>> + * A definition of the test json used in this unit test.
>>>> + */
>>>> + private static final String TEST_DEFINITION =
>>>> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\",
>>>> FIELD2 :
>>>> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
>>>> +
>>>> + /**
>>>> + * test the validator for successful validation
>>>> + * @throws APIValidatorExpcetion
>>>> + * @throws IOException
>>>> + * @throws ParserConfigurationException
>>>> + * @throws SAXException
>>>> + */
>>>> + @Test
>>>> + public void testValidator() throws APIValidatorExpcetion,
>>>> IOException,
>>>> ParserConfigurationException, SAXException {
>>>> + APIValidator apiVal = new APIValidator("opensocial-
>>>> reference");
>>>> + apiVal.addScript(TEST_DEFINITION);
>>>> + String[] optional = {"shouldBeMissing"};
>>>> + String[] nullfields = {};
>>>> + Map<String, Object> result = apiVal.validate("{ json: \"A
>>>> Test
>>>> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
>>>> + Assert.assertNotNull(result);
>>>> + Assert.assertNotNull(result.get("json"));
>>>> + Assert.assertNotNull(result.get("xyz"));
>>>> + Assert.assertEquals(String.class,result.get
>>>> ("json").getClass());
>>>> + Assert.assertEquals(Integer.class,result.get
>>>> ("xyz").getClass());
>>>> + Assert.assertEquals("A Test JSON",result.get("json"));
>>>> + Assert.assertEquals(123,((Integer)result.get
>>>> ("xyz")).intValue());
>>>> +
>>>> +
>>>> + }
>>>> +
>>>> + /**
>>>> + * Test for a failing validation
>>>> + * @throws APIValidatorExpcetion
>>>> + * @throws IOException
>>>> + * @throws ParserConfigurationException
>>>> + * @throws SAXException
>>>> + */
>>>> + @Test
>>>> + public void testValidatorFail() throws APIValidatorExpcetion,
>>>> IOException, ParserConfigurationException, SAXException {
>>>> + APIValidator apiVal = new APIValidator("opensocial-
>>>> reference");
>>>> + apiVal.addScript(TEST_DEFINITION);
>>>> + String[] optional = {};
>>>> + String[] nullfields = {};
>>>> + try {
>>>> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz :
>>>> 123 }",
>>>> "TestDef.Field", optional, nullfields );
>>>> + Assert.fail("Should have Generated an
>>>> APIValidatorException ");
>>>> + } catch ( APIValidatorExpcetion ex ) {
>>>> +
>>>> + }
>>>> +
>>>> +
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>>>> BeanJsonLibConverterTest.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,359 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import java.util.ArrayList;
>>>> +import java.util.List;
>>>> +import java.util.Map;
>>>> +
>>>> +import junit.framework.TestCase;
>>>> +
>>>> +import org.apache.commons.logging.Log;
>>>> +import org.apache.commons.logging.LogFactory;
>>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Name;
>>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Person;
>>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>>> +
>>>> +import com.google.common.collect.Lists;
>>>> +import com.google.common.collect.Maps;
>>>> +import com.google.inject.Guice;
>>>> +
>>>> +public class BeanJsonLibConverterTest extends TestCase {
>>>> +
>>>> + private static final Log log = LogFactory
>>>> + .getLog(BeanJsonLibConverterTest.class);
>>>> + private Person johnDoe;
>>>> + private Activity activity;
>>>> +
>>>> + private BeanJsonLibConverter beanJsonConverter;
>>>> + private APIValidator apiValidator;
>>>> + // set to true to get loging output at info level
>>>> + private boolean outputInfo = false;
>>>> +
>>>> + @Override
>>>> + public void setUp() throws Exception {
>>>> + super.setUp();
>>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>>> Doe"));
>>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>>> PhoneImpl(
>>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>>> "mobile"),
>>>> + new PhoneImpl("+33W000000000", "work")));
>>>> +
>>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>>> AddressImpl(
>>>> + "My home address")));
>>>> +
>>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>>> + "john.doe@work.bar", "work"),
>>>> + new EmailImpl("john.doe@home.bar", "home")));
>>>> +
>>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>>> +
>>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>>> MediaItemImpl(
>>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>>> +
>>>> + beanJsonConverter = new BeanJsonLibConverter(Guice
>>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>>> +
>>>> + apiValidator = new APIValidator("opensocial-reference");
>>>> +
>>>> + }
>>>> +
>>>> + public static class SpecialPerson extends PersonImpl {
>>>> + public static final String[] OPTIONALFIELDS = {};
>>>> + public static final String[] NULLFIELDS =
>>>> {"jobInterests","nickname","romance","religion","timeZone",
>>>> +
>>>> "relationshipStatus","tags","networkPresence","books","quotes","pho
>>>> neNumbers","languagesSpoken",
>>>> +
>>>> "activities","jobs","dateOfBirth","profileVideo","bodyType","urls",
>>>> "schools","music","addresses",
>>>> +
>>>> "livingArrangement","thumbnailUrl","humor","sports","scaredOf","mov
>>>> ies","age","pets","hasApp","turnOffs",
>>>> +
>>>> "gender","fashion","drinker","aboutMe","children","sexualOrientatio
>>>> n","heroes","profileSong","lookingFor",
>>>> +
>>>> "cars","turnOns","tvShows","profileUrl","status","currentLocation",
>>>> "smoker","happiestWhen","ethnicity",
>>>> +
>>>> "food","emails","politicalViews","interests","familyName","honorifi
>>>> cSuffix","additionalName","honorificPrefix","givenName"};
>>>> +
>>>> + private String newfield;
>>>> +
>>>> + public SpecialPerson() {
>>>> + super();
>>>> + }
>>>> +
>>>> + public SpecialPerson(String id, String name, String
>>>> newfield) {
>>>> + super(id, new NameImpl(name));
>>>> + this.newfield = newfield;
>>>> + }
>>>> +
>>>> + public String getNewfield() {
>>>> + return newfield;
>>>> + }
>>>> +
>>>> + public void setNewfield(String newfield) {
>>>> + this.newfield = newfield;
>>>> + }
>>>> +
>>>> + }
>>>> +
>>>> + public void testToJsonOnInheritedClass() throws Exception {
>>>> + SpecialPerson cassie = new SpecialPerson("5", "robot",
>>>> "nonsense");
>>>> +
>>>> + String result = beanJsonConverter.convertToString(cassie);
>>>> +
>>>> + validatePerson(result, "5", "robot",
>>>> SpecialPerson.OPTIONALFIELDS,
>>>> SpecialPerson.NULLFIELDS);
>>>> +
>>>> + apiValidator.addScript(" specialPerson = { SPECIAL :
>>>> \"newfield\" };
>>>> ");
>>>> + String[] optional = {};
>>>> + String[] nullfields = {};
>>>> + Map<String, Object> special = apiValidator.validate(result,
>>>> + "specialPerson", optional,nullfields);
>>>> + assertNotNull(special.get("newfield"));
>>>> + assertEquals(String.class, special.get("newfield").getClass
>>>> ());
>>>> + assertEquals("nonsense", special.get("newfield"));
>>>> +
>>>> + // convert back into an object Tree
>>>> +
>>>> + SpecialPerson parseCassie =
>>>> beanJsonConverter.convertToObject(result,
>>>> + SpecialPerson.class);
>>>> +
>>>> + assertNotNull(parseCassie);
>>>> + assertEquals(cassie.getId(), parseCassie.getId());
>>>> + assertEquals(cassie.getNewfield(), parseCassie.getNewfield());
>>>> +
>>>> + Name name = parseCassie.getName();
>>>> + Name cassieName = cassie.getName();
>>>> + assertNotNull(name);
>>>> + assertEquals(cassieName.getUnstructured(),
>>>> name.getUnstructured());
>>>> + assertEquals(cassieName.getAdditionalName(),
>>>> name.getAdditionalName());
>>>> + assertEquals(cassieName.getFamilyName(), name.getFamilyName
>>>> ());
>>>> + assertEquals(cassieName.getGivenName(), name.getGivenName());
>>>> + assertEquals(cassieName.getHonorificPrefix(),
>>>> name.getHonorificPrefix());
>>>> + assertEquals(cassieName.getHonorificSuffix(),
>>>> name.getHonorificSuffix());
>>>> +
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param result
>>>> + * @throws APIValidatorExpcetion
>>>> + */
>>>> + private void validatePerson(String result, String id, String
>>>> name,
>>>> String[] optional, String[] nullfields)
>>>> + throws APIValidatorExpcetion {
>>>> +
>>>> + Map<String, Object> standard = apiValidator.validate(result,
>>>> + "opensocial.Person.Field", optional,nullfields);
>>>> + assertNotNull(standard.get("id"));
>>>> + assertEquals(String.class, standard.get("id").getClass());
>>>> + assertEquals(id, standard.get("id"));
>>>> +
>>>> + assertNotNull(standard.get("name"));
>>>> + Map<String, Object> nameJSON = apiValidator.validateOject
>>>> (standard
>>>> + .get("name"), "opensocial.Name.Field",
>>>> optional,nullfields);
>>>> + APIValidator.dump(nameJSON);
>>>> +
>>>> + assertNotNull(nameJSON.get("unstructured"));
>>>> + assertEquals(String.class, nameJSON.get
>>>> ("unstructured").getClass());
>>>> + assertEquals(name, nameJSON.get("unstructured"));
>>>> +
>>>> + // additional name
>>>> + assertNull(nameJSON.get("additionalName"));
>>>> +
>>>> + }
>>>> +
>>>> + public void testPersonToJson() throws Exception {
>>>> + String result = beanJsonConverter.convertToString(johnDoe);
>>>> + if (outputInfo) {
>>>> + log.info("JSON (" + result + ")");
>>>> + }
>>>> + Person parsedPerson = beanJsonConverter.convertToObject
>>>> (result,
>>>> + Person.class);
>>>> +
>>>> + assertEquals(johnDoe.getId(), parsedPerson.getId());
>>>> + assertEquals(johnDoe.getName().getUnstructured(),
>>>> parsedPerson.getName()
>>>> + .getUnstructured());
>>>> +
>>>> + List<Address> addresses = parsedPerson.getAddresses();
>>>> + if (outputInfo) {
>>>> + for (Object o : addresses) {
>>>> + log.info("Address " + o);
>>>> + }
>>>> + }
>>>> +
>>>> + assertEquals(1, addresses.size());
>>>> + Address address = addresses.get(0);
>>>> + String unstructured = address.getUnstructuredAddress();
>>>> +
>>>> + assertNotNull(unstructured);
>>>> + assertEquals(johnDoe.getAddresses().get
>>>> (0).getUnstructuredAddress(),
>>>> + parsedPerson.getAddresses().get
>>>> (0).getUnstructuredAddress());
>>>> +
>>>> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
>>>> +
>>>> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
>>>> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
>>>> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
>>>> + assertEquals(expectedPhone.getType(), actualPhone.getType
>>>> ());
>>>> + assertEquals(expectedPhone.getNumber(),
>>>> actualPhone.getNumber());
>>>> + }
>>>> +
>>>> + assertEquals(2, parsedPerson.getEmails().size());
>>>> +
>>>> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
>>>> + Email expectedEmail = johnDoe.getEmails().get(i);
>>>> + Email actualEmail = parsedPerson.getEmails().get(i);
>>>> + assertEquals(expectedEmail.getType(), actualEmail.getType
>>>> ());
>>>> + assertEquals(expectedEmail.getAddress(),
>>>> actualEmail.getAddress());
>>>> + }
>>>> + }
>>>> +
>>>> + public void testActivityToJson() throws Exception {
>>>> +
>>>> + String result = beanJsonConverter.convertToString(activity);
>>>> + if (outputInfo) {
>>>> + log.info("JSON (" + result + ")");
>>>> + }
>>>> + Activity parsedActivity = beanJsonConverter.convertToObject
>>>> (result,
>>>> + Activity.class);
>>>> + assertEquals(activity.getUserId(), parsedActivity.getUserId
>>>> ());
>>>> + assertEquals(activity.getId(), parsedActivity.getId());
>>>> +
>>>> + assertEquals(1, parsedActivity.getMediaItems().size());
>>>> +
>>>> + MediaItem expectedItem = activity.getMediaItems().get(0);
>>>> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
>>>> +
>>>> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
>>>> + assertEquals(expectedItem.getMimeType(),
>>>> actualItem.getMimeType());
>>>> + assertEquals(expectedItem.getType().toString(),
>>>> actualItem.getType()
>>>> + .toString());
>>>> + }
>>>> +
>>>> + public void testMapsToJson() throws Exception {
>>>> + Map<String, Map<String, String>> map = Maps.newHashMap();
>>>> +
>>>> + Map<String, String> item1Map = Maps.newHashMap();
>>>> + item1Map.put("value", "1");
>>>> +
>>>> + // Null values shouldn't cause exceptions
>>>> + item1Map.put("value2", null);
>>>> + map.put("item1", item1Map);
>>>> +
>>>> + Map<String, String> item2Map = Maps.newHashMap();
>>>> + item2Map.put("value", "2");
>>>> + map.put("item2", item2Map);
>>>> +
>>>> + String result = beanJsonConverter.convertToString(map);
>>>> + if (outputInfo) {
>>>> + log.info("JSON (" + result + ")");
>>>> + }
>>>> + // there is introspection that can tell jsonobject -> bean
>>>> converter
>>>> what a
>>>> + // map should contain, so we have to tell it
>>>> + beanJsonConverter.addMapping("item1", Map.class);
>>>> + beanJsonConverter.addMapping("item2", Map.class);
>>>> + Map<?, ?> parsedMap = beanJsonConverter
>>>> + .convertToObject(result, Map.class);
>>>> +
>>>> + if (outputInfo) {
>>>> + log.info("Dumping Map (" + parsedMap + ")");
>>>> + }
>>>> + APIValidator.dump(parsedMap);
>>>> +
>>>> + assertEquals("1", ((Map<?,?>)parsedMap.get("item1")).get
>>>> ("value"));
>>>> + assertEquals("2", ((Map<?,?>)parsedMap.get("item2")).get
>>>> ("value"));
>>>> + }
>>>> +
>>>> + public void testListsToJson() throws Exception {
>>>> + Map<String, String> item1Map = Maps.newHashMap();
>>>> + item1Map.put("value", "1");
>>>> +
>>>> + Map<String, String> item2Map = Maps.newHashMap();
>>>> + item2Map.put("value", "2");
>>>> +
>>>> + // put the list into a container before serializing, top
>>>> level lists
>>>> dont
>>>> + // appear
>>>> + // to be allowed in json
>>>> + // just check that the list is in the holder correctly
>>>> + List<Map<String, String>> list = new ArrayList<Map<String,
>>>> String>>();
>>>> + list.add(item1Map);
>>>> + list.add(item2Map);
>>>> + String result = beanJsonConverter.convertToString(list);
>>>> + if (outputInfo) {
>>>> + log.info("JSON (" + result + ")");
>>>> + }
>>>> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
>>>> + result, Map[].class);
>>>> +
>>>> + assertEquals("1", parsedList[0].get("value"));
>>>> + assertEquals("2", parsedList[1].get("value"));
>>>> + }
>>>> +
>>>> + public void testArrayToJson() throws Exception {
>>>> + String[] colors = { "blue", "green", "aquamarine" };
>>>> + String result = beanJsonConverter.convertToString(colors);
>>>> + if (outputInfo) {
>>>> + log.info("JSON (" + result + ")");
>>>> + }
>>>> + String[] parsedColors = beanJsonConverter.convertToObject
>>>> (result,
>>>> + String[].class);
>>>> + assertEquals(colors.length, parsedColors.length);
>>>> + assertEquals(colors[0], parsedColors[0]);
>>>> + assertEquals(colors[1], parsedColors[1]);
>>>> + assertEquals(colors[2], parsedColors[2]);
>>>> + }
>>>> +
>>>> + public void testJsonToActivity() throws Exception {
>>>> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
>>>> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}"
>>>> + "]}";
>>>> + Activity result = beanJsonConverter.convertToObject
>>>> (jsonActivity,
>>>> + Activity.class);
>>>> +
>>>> + assertEquals("5", result.getUserId());
>>>> + assertEquals("6", result.getId());
>>>> +
>>>> + assertEquals(1, result.getMediaItems().size());
>>>> +
>>>> + MediaItem actualItem = result.getMediaItems().get(0);
>>>> +
>>>> + assertEquals("hello", actualItem.getUrl());
>>>> + assertEquals("mimey", actualItem.getMimeType());
>>>> + assertEquals("video", actualItem.getType().toString());
>>>> + }
>>>> +
>>>> + public void testJsonToMap() throws Exception {
>>>> + String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
>>>> + Map<String, String> data = Maps.newHashMap();
>>>> + data = beanJsonConverter.convertToObject(jsonActivity,
>>>> + (Class<Map<String, String>>) data.getClass());
>>>> +
>>>> + assertEquals(2, data.size());
>>>> +
>>>> + for (String key : data.keySet()) {
>>>> + Object value = data.get(key);
>>>> + if (key.equals("count")) {
>>>> + assertEquals(0, value);
>>>> + } else if (key.equals("favoriteColor")) {
>>>> + assertEquals("yellow", value);
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Added:
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>>>> JsonConverterPerformancePerf.java?rev=678158&view=auto
>>>>
>>>> ===================================================================
>>>> ===========
>>>> ---
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>> (added)
>>>> +++
>>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>>> Sat Jul 19 06:51:03 2008
>>>> @@ -0,0 +1,271 @@
>>>> +/*
>>>> + * 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.social.opensocial.util;
>>>> +
>>>> +import junit.framework.TestCase;
>>>> +
>>>> +import org.apache.commons.logging.Log;
>>>> +import org.apache.commons.logging.LogFactory;
>>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>>> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
>>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Address;
>>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Email;
>>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Person;
>>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>>> +import org.json.JSONObject;
>>>> +
>>>> +import com.google.common.collect.Lists;
>>>> +import com.google.inject.Guice;
>>>> +
>>>> +public class JsonConverterPerformancePerf extends TestCase {
>>>> +
>>>> + private static final Log log = LogFactory
>>>> + .getLog(JsonConverterPerformancePerf.class);
>>>> + private static final int TEST_SIZE = 10000;
>>>> + private Person johnDoe;
>>>> + private Activity activity;
>>>> +
>>>> + private BeanJsonLibConverter beanJsonLibConverter;
>>>> + private APIValidator apiValidator;
>>>> + // set to true to get loging output at info level
>>>> + private boolean outputInfo = false;
>>>> + private BeanJsonConverter beanJsonConverter;
>>>> +
>>>> + @Override
>>>> + public void setUp() throws Exception {
>>>> + super.setUp();
>>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>>> Doe"));
>>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>>> PhoneImpl(
>>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>>> "mobile"),
>>>> + new PhoneImpl("+33W000000000", "work")));
>>>> +
>>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>>> AddressImpl(
>>>> + "My home address")));
>>>> +
>>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>>> + "john.doe@work.bar", "work"),
>>>> + new EmailImpl("john.doe@home.bar", "home")));
>>>> +
>>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>>> +
>>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>>> MediaItemImpl(
>>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>>> +
>>>> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
>>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>>> +
>>>> + beanJsonConverter = new BeanJsonConverter(Guice
>>>> + .createInjector(new SocialApiTestsGuiceModule()));
>>>> +
>>>> + apiValidator = new APIValidator("opensocial-reference");
>>>> +
>>>> + }
>>>> +
>>>> + public static class SpecialPerson extends PersonImpl {
>>>> + private String newfield;
>>>> +
>>>> + public SpecialPerson() {
>>>> + super();
>>>> + }
>>>> +
>>>> + public SpecialPerson(String id, String name, String
>>>> newfield) {
>>>> + super(id, new NameImpl(name));
>>>> + this.newfield = newfield;
>>>> + }
>>>> +
>>>> + public String getNewfield() {
>>>> + return newfield;
>>>> + }
>>>> +
>>>> + public void setNewfield(String newfield) {
>>>> + this.newfield = newfield;
>>>> + }
>>>> +
>>>> + }
>>>> +
>>>> + public void testToJsonLibOnInheritedClassOutput() throws
>>>> Exception {
>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>> "nonsense");
>>>> + }
>>>> + Runtime r = Runtime.getRuntime();
>>>> + r.gc();
>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>> + long startOutput = System.currentTimeMillis();
>>>> + String[] output = new String[TEST_SIZE];
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
>>>> + }
>>>> + long endOutput = System.currentTimeMillis();
>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>> + char[] source = output[0].toCharArray();
>>>> + r.gc();
>>>> +
>>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + serializeOutput[i] = new String(source);
>>>> + }
>>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + /*
>>>> + * Output the time per conversion and the memory usage -
>>>> the output
>>>> per
>>>> + * conversion.
>>>> + *
>>>> + */
>>>> +
>>>> + log.info("SF JSON Lib Output "
>>>> + + average(startOutput, endOutput, TEST_SIZE)
>>>> + + " ms/conversion, "
>>>> + + (average(memstart, memend, TEST_SIZE)-average
>>>> (stringsizeStart,
>>>> stringsizeEnd, TEST_SIZE))
>>>> + + " heap bytes/conversion, output packet consumed on
>>>> average "
>>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>>> for a
>>>> string length of "+output[0].length());
>>>> + log.info("Output Was ["+output[0]+"]");
>>>> + }
>>>> +
>>>> + public void testToJsonLibOnInheritedClassInput() throws
>>>> Exception {
>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>>> + Runtime r = Runtime.getRuntime();
>>>> + r.gc();
>>>> + long personStart = r.totalMemory()-r.freeMemory();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>> "nonsense");
>>>> + }
>>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>> + r.gc();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> +
>>>> + serializeOutput[i] = beanJsonLibConverter.convertToString
>>>> (spa[i]);
>>>> + }
>>>> +
>>>> + r.gc();
>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>> + long startInput = System.currentTimeMillis();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + sparesult[i] = beanJsonLibConverter.convertToObject(
>>>> + serializeOutput[i], SpecialPerson.class);
>>>> + }
>>>> + long endInput = System.currentTimeMillis();
>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + log.info("SF JSON Lib Input "
>>>> + + average(startInput, endInput, TEST_SIZE)
>>>> + + " ms/conversion, "
>>>> + + (average(memstart, memend, TEST_SIZE)-average
>>>> (personStart,
>>>> personEnd, TEST_SIZE))
>>>> + + " heap bytes/conversion, person object consumed on
>>>> average "
>>>> + + average(personStart, personEnd, TEST_SIZE));
>>>> + }
>>>> +
>>>> + public void testToJsonOnInheritedClassOutput() throws
>>>> Exception {
>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>> "nonsense");
>>>> + }
>>>> + Runtime r = Runtime.getRuntime();
>>>> + String[] output = new String[TEST_SIZE];
>>>> + r.gc();
>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>> + long startOutput = System.currentTimeMillis();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + output[i] = ((JSONObject)
>>>> beanJsonConverter.convertToJson(spa[i])).toString();
>>>> + }
>>>> + long endOutput = System.currentTimeMillis();
>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>> + char[] source = output[0].toCharArray();
>>>> + r.gc();
>>>> +
>>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + serializeOutput[i] = new String(source);
>>>> + }
>>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + log.info("ORG JSON Lib Output "
>>>> + + average(startOutput, endOutput, TEST_SIZE)
>>>> + + " ms/conversion, "
>>>> + + (average(memstart, memend, TEST_SIZE)-average
>>>> (stringsizeStart,
>>>> stringsizeEnd, TEST_SIZE))
>>>> + + " heap bytes/conversion, output packet consumed on
>>>> average "
>>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>>> for a
>>>> string length of "+output[0].length());
>>>> + log.info("Output Was ["+output[0]+"]");
>>>> + }
>>>> +
>>>> + /**
>>>> + * @param endOutput
>>>> + * @param startOutput
>>>> + * @param testSize
>>>> + * @return
>>>> + */
>>>> + private float average(long start, long end, int testSize) {
>>>> + float r = end - start;
>>>> + r = r / testSize;
>>>> + return r;
>>>> + }
>>>> +
>>>> + public void XtestToJsonOnInheritedClassInput() throws
>>>> Exception {
>>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>>> + Runtime r = Runtime.getRuntime();
>>>> + r.gc();
>>>> + long personStart = r.totalMemory()-r.freeMemory();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>>> "nonsense");
>>>> + }
>>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + String[] serializeOutput = new String[TEST_SIZE];
>>>> + r.gc();
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> +
>>>> + serializeOutput[i] = beanJsonConverter.convertToString(spa
>>>> [i]);
>>>> + }
>>>> +
>>>> + r.gc();
>>>> + long memstart = r.totalMemory()-r.freeMemory();
>>>> + long startInput = System.currentTimeMillis();
>>>> +
>>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>>> + sparesult[i] = beanJsonConverter.convertToObject(
>>>> + serializeOutput[i], SpecialPerson.class);
>>>> + }
>>>> + long endInput = System.currentTimeMillis();
>>>> + long memend = r.totalMemory()-r.freeMemory();
>>>> +
>>>> + log.info("SF JSON Lib Input "
>>>> + + average(startInput, endInput, TEST_SIZE)
>>>> + + " ms/conversion, "
>>>> + + (average(memstart, memend, TEST_SIZE)-average
>>>> (personStart,
>>>> personEnd, TEST_SIZE))
>>>> + + " heap bytes/conversion, person object consumed on
>>>> average "
>>>> + + average(personStart, personEnd, TEST_SIZE));
>>>> + }
>>>> +
>>>> +}
>>>>
>>>> Modified: incubator/shindig/trunk/pom.xml
>>>> URL:
>>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?
>>>> rev=678158&r1=678157&r2=678158&view=diff
>>>>
>>>> ===================================================================
>>>> ===========
>>>> --- incubator/shindig/trunk/pom.xml (original)
>>>> +++ incubator/shindig/trunk/pom.xml Sat Jul 19 06:51:03 2008
>>>> @@ -853,6 +853,16 @@
>>>> <artifactId>htmlunit</artifactId>
>>>> <version>2.1</version>
>>>> </dependency>
>>>> + <dependency>
>>>> + <groupId>log4j</groupId>
>>>> + <artifactId>log4j</artifactId>
>>>> + <version>1.2.13</version>
>>>> + </dependency>
>>>> + <dependency>
>>>> + <groupId>rhino</groupId>
>>>> + <artifactId>js</artifactId>
>>>> + <version>1.6R7</version>
>>>> + </dependency>
>>>> </dependencies>
>>>> </dependencyManagement>
>>>> </project>
>>>>
>>>>
>>>>
>
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Posted by Chris Chabot <ch...@xs4all.nl>.
Please make sure to do proper svn move's. Last time we had 2 identical
file names, but with different casing, everyone on a case insensitive
file system got into trouble :)
-- Chris
On Jul 20, 2008, at 11:02 AM, Ian Boston wrote:
> Ok will fix.
> Ian
>
> On 19 Jul 2008, at 20:50, Kevin Brown wrote:
>
>> Hey Ian,
>>
>> The casing is inconsistent here -- it should be Json and Api for
>> all cases
>> rather than JSON or API.
>>
>> Thanks!
>>
>> On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
>>
>>> Author: ieb
>>> Date: Sat Jul 19 06:51:03 2008
>>> New Revision: 678158
>>>
>>> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
>>> Log:
>>> SHINDIG-451
>>> Applying patch from the JIRA.
>>>
>>> Adds a json-lib (net.sf) converter, not wired into social-api at
>>> present.
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/JsonLibTestsGuiceModule.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidator.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorTest.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> Modified:
>>> incubator/shindig/trunk/java/social-api/pom.xml
>>> incubator/shindig/trunk/pom.xml
>>>
>>> Modified: incubator/shindig/trunk/java/social-api/pom.xml
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
>>> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19
>>> 06:51:03
>>> 2008
>>> @@ -60,12 +60,31 @@
>>> <groupId>org.apache.shindig</groupId>
>>> <artifactId>shindig-common</artifactId>
>>> </dependency>
>>> + <!-- is this Ok, only used in test to load the features -->
>>> + <dependency>
>>> + <groupId>org.apache.shindig</groupId>
>>> + <artifactId>shindig-features</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>>
>>> <!-- external depenencies -->
>>> <dependency>
>>> <groupId>org.json</groupId>
>>> <artifactId>json</artifactId>
>>> </dependency>
>>> + <!-- the classifier prevents this working in dep management -->
>>> + <dependency>
>>> + <groupId>net.sf.json-lib</groupId>
>>> + <artifactId>json-lib</artifactId>
>>> + <version>2.2</version>
>>> + <classifier>jdk15</classifier>
>>> + <type>jar</type>
>>> + </dependency>
>>> + <dependency>
>>> + <groupId>rhino</groupId>
>>> + <artifactId>js</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>> <dependency>
>>> <groupId>com.google.code.guice</groupId>
>>> <artifactId>guice</artifactId>
>>> @@ -112,5 +131,10 @@
>>> <artifactId>core</artifactId>
>>> <scope>compile</scope>
>>> </dependency>
>>> + <dependency>
>>> + <groupId>log4j</groupId>
>>> + <artifactId>log4j</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>> </dependencies>
>>> </project>
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,43 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +/**
>>> + * Where a conversion exception happens in the Json Lib
>>> conversion, this
>>> + * exception is thrown.
>>> + */
>>> +public class BeanJsonLibConversionException extends
>>> RuntimeException {
>>> +
>>> + private static final long serialVersionUID =
>>> -8609384443448202372L;
>>> +
>>> + public BeanJsonLibConversionException() {
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(String arg0) {
>>> + super(arg0);
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(Throwable arg0) {
>>> + super(arg0);
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(String arg0, Throwable
>>> arg1) {
>>> + super(arg0, arg1);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,286 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.lang.reflect.Array;
>>> +import java.lang.reflect.InvocationTargetException;
>>> +import java.util.Collection;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import net.sf.ezmorph.MorpherRegistry;
>>> +import net.sf.json.JSONArray;
>>> +import net.sf.json.JSONException;
>>> +import net.sf.json.JSONObject;
>>> +import net.sf.json.JsonConfig;
>>> +import net.sf.json.processors.DefaultValueProcessor;
>>> +import net.sf.json.util.EnumMorpher;
>>> +import net.sf.json.util.JSONUtils;
>>> +import net.sf.json.util.NewBeanInstanceStrategy;
>>> +import net.sf.json.util.PropertyFilter;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.Enum;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.Organization;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.Url;
>>> +
>>> +
>>> +import com.google.inject.Inject;
>>> +import com.google.inject.Injector;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class BeanJsonLibConverter implements BeanConverter {
>>> +
>>> + protected static final Log log = LogFactory
>>> + .getLog(BeanJsonLibConverter.class);
>>> + private Injector injector;
>>> + private JsonConfig jsonConfig;
>>> + private boolean debugMode = false;
>>> +
>>> + /*
>>> + * Register the Enum Morphers so that JSON -> Bean works
>>> correctly for
>>> enums.
>>> + */
>>> + static {
>>> + MorpherRegistry morpherRegistry =
>>> JSONUtils.getMorpherRegistry();
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Address.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Phone.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Email.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(MediaItem.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(MediaItem.Type.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Enum.Drinker.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Enum.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Enum.Gender.class));
>>> + morpherRegistry
>>> + .registerMorpher(new
>>> EnumMorpher(Enum.NetworkPresence.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Enum.Smoker.class));
>>> +
>>> + morpherRegistry.registerMorpher(new JSONObjectToMapMorpher());
>>> + }
>>> +
>>> + @Inject
>>> + public BeanJsonLibConverter(Injector injector) {
>>> + this.injector = injector;
>>> + createJsonConfig();
>>> + }
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + public <T> T convertToObject(String string, final Class<T>
>>> rootBeanClass) {
>>> +
>>> + if (string.startsWith("[")) {
>>> + JSONArray jsonArray = JSONArray.fromObject(string,
>>> jsonConfig);
>>> + if (debugMode) {
>>> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
>>> + }
>>> +
>>> + if (rootBeanClass.isArray()) {
>>> + Class<?> componentType = rootBeanClass.getComponentType();
>>> + Object rootObject = injector.getInstance(componentType);
>>> + List<?> o = JSONArray.toList(jsonArray, rootObject,
>>> jsonConfig);
>>> + Object[] result = (Object[])
>>> Array.newInstance(componentType,
>>> o.size());
>>> + for (int i = 0; i < o.size(); i++) {
>>> + result[i] = o.get(i);
>>> + }
>>> + return (T) result;
>>> +
>>> + } else {
>>> + T rootObject = injector.getInstance(rootBeanClass);
>>> + Object o = JSONArray.toArray(jsonArray, rootObject,
>>> jsonConfig);
>>> + return (T) o;
>>> + }
>>> + } else {
>>> + JSONObject jsonObject = JSONObject.fromObject(string,
>>> jsonConfig);
>>> +
>>> + if (debugMode) {
>>> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
>>> + }
>>> +
>>> + T rootObject = injector.getInstance(rootBeanClass);
>>> + Object o = JSONObject.toBean(jsonObject, rootObject,
>>> jsonConfig);
>>> + return (T) o;
>>> +
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * @return
>>> + */
>>> + private void createJsonConfig() {
>>> +
>>> + jsonConfig = new JsonConfig();
>>> +
>>> + /*
>>> + * This hook deals with the creation of new beans in the JSON
>>> -> Java
>>> Bean
>>> + * conversion
>>> + */
>>> + jsonConfig.setNewBeanInstanceStrategy(new
>>> NewBeanInstanceStrategy() {
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + @Override
>>> + public Object newInstance(Class beanClass, JSONObject
>>> jsonObject)
>>> + throws InstantiationException, IllegalAccessException,
>>> + SecurityException, NoSuchMethodException,
>>> InvocationTargetException {
>>> + if (beanClass != null) {
>>> + Object o =
>>> BeanJsonLibConverter.this.injector.getInstance(beanClass);
>>> + if (debugMode) {
>>> + log.info("Created Object " + o + " for " + beanClass
>>> + " with
>>> ["
>>> + + jsonObject + "]");
>>> + }
>>> + return o;
>>> + }
>>> + return DEFAULT.newInstance(beanClass, jsonObject);
>>> + }
>>> +
>>> + });
>>> +
>>> + /*
>>> + * We are expecting null for nulls
>>> + */
>>> + jsonConfig.registerDefaultValueProcessor(String.class,
>>> + new DefaultValueProcessor() {
>>> + @SuppressWarnings("unchecked")
>>> + public Object getDefaultValue(Class target) {
>>> + return null;
>>> + }
>>> + });
>>> +
>>> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
>>> +
>>> + public boolean apply(Object source, String name, Object
>>> value) {
>>> + return filterProperty(source, name, value);
>>> + }
>>> +
>>> + });
>>> +
>>> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
>>> +
>>> + public boolean apply(Object source, String name, Object
>>> value) {
>>> + return filterProperty(source,name,value);
>>> + }
>>> +
>>> + });
>>> +
>>> + // the classMap deals with the basic json string to bean
>>> conversion
>>> +
>>> + Map<String, Class<?>> classMap = new HashMap<String, Class<?
>>> >>();
>>> +
>>> + /*
>>> + * mappings are required where there is a List of objects in
>>> the
>>> interface
>>> + * with no indication of what type the list should contain.
>>> At the
>>> moment,
>>> + * we are using 1 map for all json trees, as there is no
>>> conflict, but
>>> if
>>> + * there is a map could be selected on the basis of the root
>>> object.
>>> It
>>> + * would be better to do this with generics, but this is good
>>> enough
>>> and
>>> + * compact enough for the moment.
>>> + *
>>> + */
>>> + //
>>> + // activity
>>> + classMap.put("mediaItems", MediaItem.class);
>>> + // this may not be necessary
>>> + classMap.put("templateParams", Map.class);
>>> + // BodyType needs no mappings
>>> + // Message needs no mappings
>>> + // Name needs no mappings
>>> + // Organization needs no mappings
>>> + // Url needs no mappings
>>> + // Email needs no mappings
>>> + // Phone Needs no mappings
>>> + // Address Needs no mappings
>>> + // MediaItem needs no mappings
>>> +
>>> + // Person map
>>> + classMap.put("addresses", Address.class);
>>> + classMap.put("phoneNumbers", Phone.class);
>>> + classMap.put("emails", Email.class);
>>> + classMap.put("mediaItems", MediaItem.class);
>>> + classMap.put("jobs", Organization.class);
>>> + classMap.put("schools", Organization.class);
>>> + classMap.put("urls", Url.class);
>>> + jsonConfig.setClassMap(classMap);
>>> +
>>> + }
>>> +
>>> + /**
>>> + * @param source
>>> + * @param name
>>> + * @param value
>>> + * @return
>>> + */
>>> + protected boolean filterProperty(Object source, String name,
>>> Object
>>> value) {
>>> + if ( value == null ) {
>>> + return true;
>>> + }
>>> + if ( value instanceof JSONArray ) {
>>> + JSONArray array = (JSONArray) value;
>>> + if ( array.size() == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof JSONObject ) {
>>> + JSONObject object = (JSONObject) value;
>>> + if ( object.isNullObject() || object.isEmpty() ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof Collection) {
>>> + Collection<?> collection = (Collection<?>) value;
>>> + if ( collection.size() == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof Object[] ) {
>>> + Object[] oarray = (Object[]) value;
>>> + if ( oarray.length == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + return false;
>>> + }
>>> +
>>> + public String convertToString(Object pojo) {
>>> +
>>> + try {
>>> + JSONObject jsonObject = JSONObject.fromObject(pojo,
>>> jsonConfig);
>>> + return jsonObject.toString();
>>> + } catch (JSONException jse) {
>>> + Class<?> pojoClass = pojo.getClass();
>>> + if (JSONUtils.isArray(pojoClass)) {
>>> + JSONArray jsonArray = JSONArray.fromObject(pojo);
>>> + String result = jsonArray.toString();
>>> + return result;
>>> + }
>>> + throw jse;
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * @param string
>>> + * @param class1
>>> + */
>>> + public void addMapping(String key, Class<?> class1) {
>>> + jsonConfig.getClassMap().put(key, class1);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,72 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +
>>> +import net.sf.json.JSONArray;
>>> +import net.sf.json.JSONObject;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class JSONLibConverterUtils {
>>> + protected static final Log log = LogFactory
>>> + .getLog(JSONLibConverterUtils.class);
>>> +
>>> +
>>> + /**
>>> + * @param jsonObject
>>> + */
>>> + public static final void dumpJsonObject(JSONObject jsonObject,
>>> String
>>> indent) {
>>> + for (Object key : jsonObject.keySet()) {
>>> + Object value = jsonObject.get(key);
>>> + if (value instanceof JSONObject) {
>>> + log.info(indent + key + ":JSONObject");
>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>> + } else if (value instanceof JSONArray) {
>>> + log.info(indent + key + ":JSONArray " + ((JSONArray)
>>> value).size());
>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>> + } else {
>>> + log.info(indent + key + ":" + value + ":"
>>> + + (value == null ? "na" : value.getClass()));
>>> + }
>>> + }
>>> + }
>>> +
>>> +
>>> + /**
>>> + * @param value
>>> + * @param string
>>> + */
>>> + static void dumpJsonArray(JSONArray array, String indent) {
>>> + for (Object value : array) {
>>> + if (value instanceof JSONObject) {
>>> + log.info(indent + ":JSONObject");
>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>> + } else if (value instanceof JSONArray) {
>>> + log.info(indent + ":JSONArray " + ((JSONArray)
>>> value).size());
>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>> + } else {
>>> + log.info(indent + ":" + value + ":"
>>> + + (value == null ? "na" : value.getClass()));
>>> + }
>>> + }
>>> + }
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,50 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.util.HashMap;
>>> +import java.util.Map;
>>> +
>>> +import net.sf.ezmorph.Morpher;
>>> +import net.sf.ezmorph.ObjectMorpher;
>>> +import net.sf.json.JSONObject;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class JSONObjectToMapMorpher implements Morpher,
>>> ObjectMorpher {
>>> +
>>> + public Class<?> morphsTo() {
>>> + return Map.class;
>>> + }
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + public boolean supports(Class clazz) {
>>> + return (JSONObject.class.equals(clazz));
>>> + }
>>> +
>>> + public Object morph(Object bean) {
>>> + Map<Object, Object> result = new HashMap<Object, Object>();
>>> + JSONObject jsonObject = (JSONObject) bean;
>>> + for ( Object key : jsonObject.keySet()) {
>>> + result.put(key,jsonObject.get(key));
>>> + }
>>> + return result;
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/JsonLibTestsGuiceModule.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/JsonLibTestsGuiceModule.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/JsonLibTestsGuiceModule.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,40 @@
>>> +/*
>>> + * 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.social;
>>> +
>>> +import java.util.ArrayList;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import com.google.inject.AbstractModule;
>>> +
>>> +/**
>>> + * Provides social api component injection for all large tests
>>> + */
>>> +public class JsonLibTestsGuiceModule extends AbstractModule {
>>> + @Override
>>> + protected void configure() {
>>> +
>>> + bind(Map.class).to(HashMap.class);
>>> + bind(List.class).to(ArrayList.class);
>>> + bind(Map[].class).to(HashMap[].class);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidator.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidator.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidator.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,352 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.io.IOException;
>>> +import java.io.InputStream;
>>> +import java.io.InputStreamReader;
>>> +import java.util.ArrayList;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import javax.xml.parsers.DocumentBuilder;
>>> +import javax.xml.parsers.DocumentBuilderFactory;
>>> +import javax.xml.parsers.ParserConfigurationException;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.mozilla.javascript.Context;
>>> +import org.mozilla.javascript.EvaluatorException;
>>> +import org.mozilla.javascript.Script;
>>> +import org.mozilla.javascript.ScriptableObject;
>>> +import org.w3c.dom.Document;
>>> +import org.w3c.dom.NamedNodeMap;
>>> +import org.w3c.dom.Node;
>>> +import org.w3c.dom.NodeList;
>>> +import org.xml.sax.SAXException;
>>> +
>>> +/**
>>> + * A class that loads a feature set from features into a
>>> Javascript Parser
>>> to
>>> + * make the model available to validate JSON messages against.
>>> + */
>>> +public class APIValidator {
>>> +
>>> + private static final Log log =
>>> LogFactory.getLog(APIValidator.class);
>>> + private Context ctx;
>>> + private ScriptableObject scope;
>>> +
>>> + /**
>>> + * @param feature
>>> + * The name of the feature are eg "opensocial-
>>> reference",
>>> this
>>> + * is a classpath stub (not starting with /)
>>> where the
>>> location
>>> + * contains a feature.xml file.
>>> + * @throws SAXException
>>> + * if feature.xml is not parsable
>>> + * @throws ParserConfigurationException
>>> + * if the parsers are invalid
>>> + * @throws IOException
>>> + * if feature.xml or the javascript that
>>> represents the
>>> + * feature is missing
>>> + *
>>> + */
>>> + public APIValidator(String feature) throws IOException,
>>> + ParserConfigurationException, SAXException {
>>> + ctx = Context.enter();
>>> + scope = ctx.initStandardObjects();
>>> + load(feature);
>>> + }
>>> +
>>> + /**
>>> + * @param json
>>> + * The json to validate expected in a form
>>> { xyz: yyy }
>>> form
>>> + * @param object
>>> + * The json Fields object specifying the
>>> structure of the
>>> json
>>> + * object, each field in this object contains
>>> the name of
>>> the
>>> + * json field in the json structure.
>>> + * @param optionalFields
>>> + * If any of the fields that appear in the json
>>> structure
>>> are
>>> + * optional, then they should be defined in this
>>> parameter.
>>> + * @param nullfields
>>> + * @throws APIValidatorExpcetion
>>> + * if there is a problem validating the json
>>> + * @return a map so string object pairs containing the fields
>>> at the top
>>> level
>>> + * of the json tree. Where these are native java
>>> objects, they
>>> will
>>> + * appear as native object. Complex json objects will
>>> appear as
>>> Rhino
>>> + * specific objects
>>> + */
>>> + public Map<String, Object> validate(String json, String object,
>>> + String[] optionalFields, String[] nullfields)
>>> + throws APIValidatorExpcetion {
>>> +
>>> + /*
>>> + * Object[] ids = ScriptableObject.getPropertyIds(scope); for
>>> (Object
>>> id :
>>> + * ids) { Object o = ScriptableObject.getProperty(scope,
>>> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
>>> id.getClass() + "
>>> + * is " + o); if (o instanceof ScriptableObject) {
>>> + * listScriptable(String.valueOf(id), (ScriptableObject)
>>> o); } }
>>> + */
>>> +
>>> + log.debug("Loading " + json);
>>> + json = json.trim();
>>> + if (!json.endsWith("}")) {
>>> + json = json + "}";
>>> + }
>>> + if (!json.startsWith("{")) {
>>> + json = "{" + json;
>>> + }
>>> + json = "( testingObject = " + json + " )";
>>> +
>>> + Object so = null;
>>> + try {
>>> + so = ctx.evaluateString(scope, json, "test json", 0, null);
>>> + } catch (EvaluatorException ex) {
>>> + log.error("Non parseable JSON " + json);
>>> + }
>>> + log.debug("Loaded " + so);
>>> +
>>> + return validateOject(so, object, optionalFields, nullfields);
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Validate an JSON Object extracted
>>> + *
>>> + * @param object
>>> + * @param string
>>> + * @param optional
>>> + * @return
>>> + * @throws APIValidatorExpcetion
>>> + */
>>> + public Map<String, Object> validateOject(Object jsonObject,
>>> String
>>> object,
>>> + String[] optionalFields, String[] nullFields)
>>> + throws APIValidatorExpcetion {
>>> + Map<String, String> optional = new HashMap<String, String>();
>>> + for (String opt : optionalFields) {
>>> + optional.put(opt, opt);
>>> + }
>>> + Map<String, String> nullf = new HashMap<String, String>();
>>> + for (String nf : nullFields) {
>>> + nullf.put(nf, nf);
>>> + }
>>> +
>>> + ScriptableObject specification = getScriptableObject(object);
>>> + log.debug("Looking for " + object + " found " +
>>> specification);
>>> + listScriptable(object, specification);
>>> +
>>> + Map<String, Object> resultFields = new HashMap<String,
>>> Object>();
>>> +
>>> + if (jsonObject instanceof ScriptableObject) {
>>> + ScriptableObject parsedJSONObject = (ScriptableObject)
>>> jsonObject;
>>> + listScriptable("testingObject", parsedJSONObject);
>>> + Object[] fields = specification.getIds();
>>> + for (Object f : fields) {
>>> + Object fieldName = specification.get(String.valueOf(f),
>>> specification);
>>> + Object o = parsedJSONObject.get(String.valueOf(fieldName),
>>> + parsedJSONObject);
>>> + if (o == ScriptableObject.NOT_FOUND) {
>>> + if (optional.containsKey(fieldName)) {
>>> + log.warn("Missing Optional Field " + fieldName);
>>> + } else if (!nullf.containsKey(fieldName)) {
>>> + log.error("Missing Field " + fieldName);
>>> + throw new APIValidatorExpcetion("Missing Field " +
>>> fieldName);
>>> + }
>>> + } else {
>>> + if (nullf.containsKey(fieldName)) {
>>> + log.error("Field should have been null and was not");
>>> + }
>>> + if (o == null) {
>>> + if (nullf.containsKey(fieldName)) {
>>> + log.error("Null Fields has been serialized " +
>>> fieldName);
>>> + }
>>> + log.debug("Got a Null object for Field " + f + ":" +
>>> fieldName
>>> + + " on json [[" + jsonObject + "]]");
>>> +
>>> + } else {
>>> +
>>> + log.debug("Got JSON Field Field," + f + ":" +
>>> fieldName + "
>>> as "
>>> + + o + " " + o.getClass());
>>> + }
>>> + resultFields.put(String.valueOf(fieldName), o);
>>> + }
>>> + }
>>> +
>>> + } else {
>>> + throw new APIValidatorExpcetion(
>>> + "Parsing JSON resulted in invalid Javascript object,
>>> which was "
>>> + + jsonObject + " JSON was [[" + jsonObject + "]]");
>>> + }
>>> + return resultFields;
>>> + }
>>> +
>>> + /**
>>> + * get an object from the json context and scope.
>>> + *
>>> + * @param object
>>> + * the name of the object specified as a path
>>> from the
>>> base
>>> + * object
>>> + * @return the json object
>>> + */
>>> + private ScriptableObject getScriptableObject(String object) {
>>> + String[] path = object.split("\\.");
>>> + log.debug("Looking up " + object + " elements " + path.length);
>>> +
>>> + ScriptableObject s = scope;
>>> + for (String pe : path) {
>>> + log.debug("Looking up " + pe + " in " + s);
>>> + s = (ScriptableObject) s.get(pe, s);
>>> + log.debug("Looking for " + pe + " in found " + s);
>>> + }
>>> + return s;
>>> + }
>>> +
>>> + /**
>>> + * List a scriptable object at log debug level, constructors
>>> will not be
>>> + * expanded as this loads to recursion.
>>> + *
>>> + * @param id
>>> + * The name of the object
>>> + * @param scriptableObject
>>> + * the scriptable Object
>>> + */
>>> + private void listScriptable(String id, ScriptableObject
>>> scriptableObject) {
>>> + log.debug("ID is Scriptable " + id);
>>> + if (!id.endsWith("constructor")) {
>>> + Object[] allIDs = scriptableObject.getAllIds();
>>> + for (Object oid : allIDs) {
>>> + log.debug(id + "." + oid);
>>> + Object o = scriptableObject.get(String.valueOf(oid),
>>> scriptableObject);
>>> + if (o instanceof ScriptableObject) {
>>> + listScriptable(id + "." + String.valueOf(oid),
>>> (ScriptableObject) o);
>>> + }
>>> + }
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * Load a feature based on the spec
>>> + *
>>> + * @param spec
>>> + * The name of the location of the spec in the
>>> classpath,
>>> must
>>> + * not start with a '/' and must should contain a
>>> feature.xml
>>> + * file in the location
>>> + * @throws IOException
>>> + * If any of the resources cant be found
>>> + * @throws ParserConfigurationException
>>> + * If the parser has a problem being constructed
>>> + * @throws SAXException
>>> + * on a parse error on the features.xml
>>> + */
>>> + private void load(String spec) throws IOException, SAXException,
>>> + ParserConfigurationException {
>>> +
>>> + List<String> scripts = getScripts(spec);
>>> +
>>> + List<Script> compiled = new ArrayList<Script>();
>>> + for (String script : scripts) {
>>> + String scriptPath = spec + "/" + script;
>>> + InputStream in =
>>> this.getClass().getClassLoader().getResourceAsStream(
>>> + scriptPath);
>>> + if (in == null) {
>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>> + "features/" + scriptPath);
>>> + if (in == null) {
>>> + throw new IOException("Cant load spec " + spec + " or
>>> features/"+spec+" from classpath");
>>> + }
>>> + }
>>> + InputStreamReader reader = new InputStreamReader(in);
>>> + Script compiledScript = ctx.compileReader(reader, spec, 0,
>>> null);
>>> + compiled.add(compiledScript);
>>> + }
>>> +
>>> + for (Script compiledScript : compiled) {
>>> + compiledScript.exec(ctx, scope);
>>> + }
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Add some javascript to the context, and execute it. If extra
>>> custom
>>> + * javascript is wanted in the context or scope then this
>>> method will
>>> load it.
>>> + *
>>> + * @param javascript
>>> + */
>>> + public void addScript(String javascript) {
>>> + Script compileScript = ctx.compileString(javascript,
>>> "AdditionalJS",
>>> 0,
>>> + null);
>>> + compileScript.exec(ctx, scope);
>>> + }
>>> +
>>> + /**
>>> + * Get an ordered list of javascript resources from a feature
>>> sets.
>>> + *
>>> + * @param spec
>>> + * The spec location
>>> + * @return An ordered list of javascript resources, these are
>>> relative
>>> to
>>> + * specification file.
>>> + * @throws IOException
>>> + * If any of the resources can't be loaded.
>>> + * @throws SAXException
>>> + * Where the feature.xml file is not parsable
>>> + * @throws ParserConfigurationException
>>> + * where the parser can't be constructed.
>>> + * @return An ordered list of script that need to be loaded and
>>> executed
>>> to
>>> + * make the feature available in the context.
>>> + */
>>> + private List<String> getScripts(String spec) throws SAXException,
>>> + IOException, ParserConfigurationException {
>>> + String features = spec + "/feature.xml";
>>> + InputStream in =
>>> this.getClass().getClassLoader().getResourceAsStream(
>>> + features);
>>> + if (in == null) {
>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>> + "features/"+features);
>>> + if (in == null) {
>>> + throw new IOException("Cant find " + features + " or
>>> features/" +
>>> features+ " in classpath ");
>>> + }
>>> + }
>>> + DocumentBuilderFactory builderFactory = DocumentBuilderFactory
>>> + .newInstance();
>>> + DocumentBuilder documentBuilder =
>>> builderFactory.newDocumentBuilder();
>>> + Document doc = documentBuilder.parse(in);
>>> + NodeList nl = doc.getElementsByTagName("script");
>>> + List<String> scripts = new ArrayList<String>();
>>> + for (int i = 0; i < nl.getLength(); i++) {
>>> + Node scriptNode = nl.item(i);
>>> + NamedNodeMap attributes = scriptNode.getAttributes();
>>> + Node scriptAttr = attributes.getNamedItem("src");
>>> + String script = scriptAttr.getNodeValue();
>>> + scripts.add(script);
>>> + }
>>> + return scripts;
>>> + }
>>> +
>>> + /**
>>> + * @param nameJSON
>>> + */
>>> + public static void dump(Map<?, ?> nameJSON) {
>>> + if (log.isDebugEnabled()) {
>>> + for (Object k : nameJSON.keySet()) {
>>> + Object o = nameJSON.get(k);
>>> + log.info("Key [" + k + "] value:["
>>> + + (o == null ? o : o + ":" + o.getClass()) + "]");
>>> + }
>>> + }
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,42 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +/**
>>> + * Thrown when there is a validation exception on one of the apis
>>> + */
>>> +public class APIValidatorExpcetion extends Exception {
>>> +
>>> + private static final long serialVersionUID =
>>> -8969858718669454612L;
>>> +
>>> + public APIValidatorExpcetion() {
>>> + }
>>> +
>>> + public APIValidatorExpcetion(String message) {
>>> + super(message);
>>> + }
>>> +
>>> + public APIValidatorExpcetion(Throwable cause) {
>>> + super(cause);
>>> + }
>>> +
>>> + public APIValidatorExpcetion(String message, Throwable cause) {
>>> + super(message, cause);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorTest.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/APIValidatorTest.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,89 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +
>>> +import java.io.IOException;
>>> +import java.util.Map;
>>> +
>>> +import javax.xml.parsers.ParserConfigurationException;
>>> +
>>> +import org.junit.Assert;
>>> +import org.junit.Test;
>>> +import org.xml.sax.SAXException;
>>> +
>>> +/**
>>> + * Test the api validator to make certain it behaves as is
>>> expected.
>>> + */
>>> +public class APIValidatorTest {
>>> +
>>> + /**
>>> + * A definition of the test json used in this unit test.
>>> + */
>>> + private static final String TEST_DEFINITION =
>>> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\",
>>> FIELD2 :
>>> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
>>> +
>>> + /**
>>> + * test the validator for successful validation
>>> + * @throws APIValidatorExpcetion
>>> + * @throws IOException
>>> + * @throws ParserConfigurationException
>>> + * @throws SAXException
>>> + */
>>> + @Test
>>> + public void testValidator() throws APIValidatorExpcetion,
>>> IOException,
>>> ParserConfigurationException, SAXException {
>>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>>> + apiVal.addScript(TEST_DEFINITION);
>>> + String[] optional = {"shouldBeMissing"};
>>> + String[] nullfields = {};
>>> + Map<String, Object> result = apiVal.validate("{ json: \"A Test
>>> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
>>> + Assert.assertNotNull(result);
>>> + Assert.assertNotNull(result.get("json"));
>>> + Assert.assertNotNull(result.get("xyz"));
>>> +
>>> Assert.assertEquals(String.class,result.get("json").getClass());
>>> +
>>> Assert.assertEquals(Integer.class,result.get("xyz").getClass());
>>> + Assert.assertEquals("A Test JSON",result.get("json"));
>>> + Assert.assertEquals(123,
>>> ((Integer)result.get("xyz")).intValue());
>>> +
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Test for a failing validation
>>> + * @throws APIValidatorExpcetion
>>> + * @throws IOException
>>> + * @throws ParserConfigurationException
>>> + * @throws SAXException
>>> + */
>>> + @Test
>>> + public void testValidatorFail() throws APIValidatorExpcetion,
>>> IOException, ParserConfigurationException, SAXException {
>>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>>> + apiVal.addScript(TEST_DEFINITION);
>>> + String[] optional = {};
>>> + String[] nullfields = {};
>>> + try {
>>> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz :
>>> 123 }",
>>> "TestDef.Field", optional, nullfields );
>>> + Assert.fail("Should have Generated an APIValidatorException
>>> ");
>>> + } catch ( APIValidatorExpcetion ex ) {
>>> +
>>> + }
>>> +
>>> +
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,359 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.util.ArrayList;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import junit.framework.TestCase;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>> +import org.apache.shindig.social.opensocial.model.Name;
>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>> +import org.apache.shindig.social.opensocial.model.Person;
>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>> +
>>> +import com.google.common.collect.Lists;
>>> +import com.google.common.collect.Maps;
>>> +import com.google.inject.Guice;
>>> +
>>> +public class BeanJsonLibConverterTest extends TestCase {
>>> +
>>> + private static final Log log = LogFactory
>>> + .getLog(BeanJsonLibConverterTest.class);
>>> + private Person johnDoe;
>>> + private Activity activity;
>>> +
>>> + private BeanJsonLibConverter beanJsonConverter;
>>> + private APIValidator apiValidator;
>>> + // set to true to get loging output at info level
>>> + private boolean outputInfo = false;
>>> +
>>> + @Override
>>> + public void setUp() throws Exception {
>>> + super.setUp();
>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>> Doe"));
>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>> PhoneImpl(
>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>> "mobile"),
>>> + new PhoneImpl("+33W000000000", "work")));
>>> +
>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>> AddressImpl(
>>> + "My home address")));
>>> +
>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>> + "john.doe@work.bar", "work"),
>>> + new EmailImpl("john.doe@home.bar", "home")));
>>> +
>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>> +
>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>> MediaItemImpl(
>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>> +
>>> + beanJsonConverter = new BeanJsonLibConverter(Guice
>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>> +
>>> + apiValidator = new APIValidator("opensocial-reference");
>>> +
>>> + }
>>> +
>>> + public static class SpecialPerson extends PersonImpl {
>>> + public static final String[] OPTIONALFIELDS = {};
>>> + public static final String[] NULLFIELDS =
>>> {"jobInterests","nickname","romance","religion","timeZone",
>>> +
>>> "relationshipStatus
>>> ","tags
>>> ","networkPresence
>>> ","books","quotes","phoneNumbers","languagesSpoken",
>>> +
>>> "activities
>>> ","jobs
>>> ","dateOfBirth
>>> ","profileVideo","bodyType","urls","schools","music","addresses",
>>> +
>>> "livingArrangement
>>> ","thumbnailUrl
>>> ","humor
>>> ","sports","scaredOf","movies","age","pets","hasApp","turnOffs",
>>> +
>>> "gender
>>> ","fashion
>>> ","drinker
>>> ","aboutMe
>>> ","children
>>> ","sexualOrientation","heroes","profileSong","lookingFor",
>>> +
>>> "cars
>>> ","turnOns
>>> ","tvShows
>>> ","profileUrl
>>> ","status","currentLocation","smoker","happiestWhen","ethnicity",
>>> +
>>> "food
>>> ","emails
>>> ","politicalViews
>>> ","interests
>>> ","familyName
>>> ","honorificSuffix","additionalName","honorificPrefix","givenName"};
>>> +
>>> + private String newfield;
>>> +
>>> + public SpecialPerson() {
>>> + super();
>>> + }
>>> +
>>> + public SpecialPerson(String id, String name, String newfield) {
>>> + super(id, new NameImpl(name));
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + public String getNewfield() {
>>> + return newfield;
>>> + }
>>> +
>>> + public void setNewfield(String newfield) {
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + }
>>> +
>>> + public void testToJsonOnInheritedClass() throws Exception {
>>> + SpecialPerson cassie = new SpecialPerson("5", "robot",
>>> "nonsense");
>>> +
>>> + String result = beanJsonConverter.convertToString(cassie);
>>> +
>>> + validatePerson(result, "5", "robot",
>>> SpecialPerson.OPTIONALFIELDS,
>>> SpecialPerson.NULLFIELDS);
>>> +
>>> + apiValidator.addScript(" specialPerson = { SPECIAL :
>>> \"newfield\" };
>>> ");
>>> + String[] optional = {};
>>> + String[] nullfields = {};
>>> + Map<String, Object> special = apiValidator.validate(result,
>>> + "specialPerson", optional,nullfields);
>>> + assertNotNull(special.get("newfield"));
>>> + assertEquals(String.class, special.get("newfield").getClass());
>>> + assertEquals("nonsense", special.get("newfield"));
>>> +
>>> + // convert back into an object Tree
>>> +
>>> + SpecialPerson parseCassie =
>>> beanJsonConverter.convertToObject(result,
>>> + SpecialPerson.class);
>>> +
>>> + assertNotNull(parseCassie);
>>> + assertEquals(cassie.getId(), parseCassie.getId());
>>> + assertEquals(cassie.getNewfield(), parseCassie.getNewfield());
>>> +
>>> + Name name = parseCassie.getName();
>>> + Name cassieName = cassie.getName();
>>> + assertNotNull(name);
>>> + assertEquals(cassieName.getUnstructured(),
>>> name.getUnstructured());
>>> + assertEquals(cassieName.getAdditionalName(),
>>> name.getAdditionalName());
>>> + assertEquals(cassieName.getFamilyName(), name.getFamilyName());
>>> + assertEquals(cassieName.getGivenName(), name.getGivenName());
>>> + assertEquals(cassieName.getHonorificPrefix(),
>>> name.getHonorificPrefix());
>>> + assertEquals(cassieName.getHonorificSuffix(),
>>> name.getHonorificSuffix());
>>> +
>>> + }
>>> +
>>> + /**
>>> + * @param result
>>> + * @throws APIValidatorExpcetion
>>> + */
>>> + private void validatePerson(String result, String id, String
>>> name,
>>> String[] optional, String[] nullfields)
>>> + throws APIValidatorExpcetion {
>>> +
>>> + Map<String, Object> standard = apiValidator.validate(result,
>>> + "opensocial.Person.Field", optional,nullfields);
>>> + assertNotNull(standard.get("id"));
>>> + assertEquals(String.class, standard.get("id").getClass());
>>> + assertEquals(id, standard.get("id"));
>>> +
>>> + assertNotNull(standard.get("name"));
>>> + Map<String, Object> nameJSON =
>>> apiValidator.validateOject(standard
>>> + .get("name"), "opensocial.Name.Field",
>>> optional,nullfields);
>>> + APIValidator.dump(nameJSON);
>>> +
>>> + assertNotNull(nameJSON.get("unstructured"));
>>> + assertEquals(String.class,
>>> nameJSON.get("unstructured").getClass());
>>> + assertEquals(name, nameJSON.get("unstructured"));
>>> +
>>> + // additional name
>>> + assertNull(nameJSON.get("additionalName"));
>>> +
>>> + }
>>> +
>>> + public void testPersonToJson() throws Exception {
>>> + String result = beanJsonConverter.convertToString(johnDoe);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Person parsedPerson = beanJsonConverter.convertToObject(result,
>>> + Person.class);
>>> +
>>> + assertEquals(johnDoe.getId(), parsedPerson.getId());
>>> + assertEquals(johnDoe.getName().getUnstructured(),
>>> parsedPerson.getName()
>>> + .getUnstructured());
>>> +
>>> + List<Address> addresses = parsedPerson.getAddresses();
>>> + if (outputInfo) {
>>> + for (Object o : addresses) {
>>> + log.info("Address " + o);
>>> + }
>>> + }
>>> +
>>> + assertEquals(1, addresses.size());
>>> + Address address = addresses.get(0);
>>> + String unstructured = address.getUnstructuredAddress();
>>> +
>>> + assertNotNull(unstructured);
>>> +
>>> assertEquals(johnDoe.getAddresses().get(0).getUnstructuredAddress(),
>>> +
>>> parsedPerson.getAddresses().get(0).getUnstructuredAddress());
>>> +
>>> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
>>> +
>>> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
>>> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
>>> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
>>> + assertEquals(expectedPhone.getType(), actualPhone.getType());
>>> + assertEquals(expectedPhone.getNumber(),
>>> actualPhone.getNumber());
>>> + }
>>> +
>>> + assertEquals(2, parsedPerson.getEmails().size());
>>> +
>>> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
>>> + Email expectedEmail = johnDoe.getEmails().get(i);
>>> + Email actualEmail = parsedPerson.getEmails().get(i);
>>> + assertEquals(expectedEmail.getType(), actualEmail.getType());
>>> + assertEquals(expectedEmail.getAddress(),
>>> actualEmail.getAddress());
>>> + }
>>> + }
>>> +
>>> + public void testActivityToJson() throws Exception {
>>> +
>>> + String result = beanJsonConverter.convertToString(activity);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Activity parsedActivity =
>>> beanJsonConverter.convertToObject(result,
>>> + Activity.class);
>>> + assertEquals(activity.getUserId(), parsedActivity.getUserId());
>>> + assertEquals(activity.getId(), parsedActivity.getId());
>>> +
>>> + assertEquals(1, parsedActivity.getMediaItems().size());
>>> +
>>> + MediaItem expectedItem = activity.getMediaItems().get(0);
>>> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
>>> +
>>> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
>>> + assertEquals(expectedItem.getMimeType(),
>>> actualItem.getMimeType());
>>> + assertEquals(expectedItem.getType().toString(),
>>> actualItem.getType()
>>> + .toString());
>>> + }
>>> +
>>> + public void testMapsToJson() throws Exception {
>>> + Map<String, Map<String, String>> map = Maps.newHashMap();
>>> +
>>> + Map<String, String> item1Map = Maps.newHashMap();
>>> + item1Map.put("value", "1");
>>> +
>>> + // Null values shouldn't cause exceptions
>>> + item1Map.put("value2", null);
>>> + map.put("item1", item1Map);
>>> +
>>> + Map<String, String> item2Map = Maps.newHashMap();
>>> + item2Map.put("value", "2");
>>> + map.put("item2", item2Map);
>>> +
>>> + String result = beanJsonConverter.convertToString(map);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + // there is introspection that can tell jsonobject -> bean
>>> converter
>>> what a
>>> + // map should contain, so we have to tell it
>>> + beanJsonConverter.addMapping("item1", Map.class);
>>> + beanJsonConverter.addMapping("item2", Map.class);
>>> + Map<?, ?> parsedMap = beanJsonConverter
>>> + .convertToObject(result, Map.class);
>>> +
>>> + if (outputInfo) {
>>> + log.info("Dumping Map (" + parsedMap + ")");
>>> + }
>>> + APIValidator.dump(parsedMap);
>>> +
>>> + assertEquals("1", ((Map<?,?
>>> >)parsedMap.get("item1")).get("value"));
>>> + assertEquals("2", ((Map<?,?
>>> >)parsedMap.get("item2")).get("value"));
>>> + }
>>> +
>>> + public void testListsToJson() throws Exception {
>>> + Map<String, String> item1Map = Maps.newHashMap();
>>> + item1Map.put("value", "1");
>>> +
>>> + Map<String, String> item2Map = Maps.newHashMap();
>>> + item2Map.put("value", "2");
>>> +
>>> + // put the list into a container before serializing, top
>>> level lists
>>> dont
>>> + // appear
>>> + // to be allowed in json
>>> + // just check that the list is in the holder correctly
>>> + List<Map<String, String>> list = new ArrayList<Map<String,
>>> String>>();
>>> + list.add(item1Map);
>>> + list.add(item2Map);
>>> + String result = beanJsonConverter.convertToString(list);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
>>> + result, Map[].class);
>>> +
>>> + assertEquals("1", parsedList[0].get("value"));
>>> + assertEquals("2", parsedList[1].get("value"));
>>> + }
>>> +
>>> + public void testArrayToJson() throws Exception {
>>> + String[] colors = { "blue", "green", "aquamarine" };
>>> + String result = beanJsonConverter.convertToString(colors);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + String[] parsedColors =
>>> beanJsonConverter.convertToObject(result,
>>> + String[].class);
>>> + assertEquals(colors.length, parsedColors.length);
>>> + assertEquals(colors[0], parsedColors[0]);
>>> + assertEquals(colors[1], parsedColors[1]);
>>> + assertEquals(colors[2], parsedColors[2]);
>>> + }
>>> +
>>> + public void testJsonToActivity() throws Exception {
>>> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
>>> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}" +
>>> "]}";
>>> + Activity result =
>>> beanJsonConverter.convertToObject(jsonActivity,
>>> + Activity.class);
>>> +
>>> + assertEquals("5", result.getUserId());
>>> + assertEquals("6", result.getId());
>>> +
>>> + assertEquals(1, result.getMediaItems().size());
>>> +
>>> + MediaItem actualItem = result.getMediaItems().get(0);
>>> +
>>> + assertEquals("hello", actualItem.getUrl());
>>> + assertEquals("mimey", actualItem.getMimeType());
>>> + assertEquals("video", actualItem.getType().toString());
>>> + }
>>> +
>>> + public void testJsonToMap() throws Exception {
>>> + String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
>>> + Map<String, String> data = Maps.newHashMap();
>>> + data = beanJsonConverter.convertToObject(jsonActivity,
>>> + (Class<Map<String, String>>) data.getClass());
>>> +
>>> + assertEquals(2, data.size());
>>> +
>>> + for (String key : data.keySet()) {
>>> + Object value = data.get(key);
>>> + if (key.equals("count")) {
>>> + assertEquals(0, value);
>>> + } else if (key.equals("favoriteColor")) {
>>> + assertEquals("yellow", value);
>>> + }
>>> + }
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java?rev=678158&view=auto
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> ---
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> (added)
>>> +++
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,271 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import junit.framework.TestCase;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>> +import org.apache.shindig.social.opensocial.model.Person;
>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>> +import org.json.JSONObject;
>>> +
>>> +import com.google.common.collect.Lists;
>>> +import com.google.inject.Guice;
>>> +
>>> +public class JsonConverterPerformancePerf extends TestCase {
>>> +
>>> + private static final Log log = LogFactory
>>> + .getLog(JsonConverterPerformancePerf.class);
>>> + private static final int TEST_SIZE = 10000;
>>> + private Person johnDoe;
>>> + private Activity activity;
>>> +
>>> + private BeanJsonLibConverter beanJsonLibConverter;
>>> + private APIValidator apiValidator;
>>> + // set to true to get loging output at info level
>>> + private boolean outputInfo = false;
>>> + private BeanJsonConverter beanJsonConverter;
>>> +
>>> + @Override
>>> + public void setUp() throws Exception {
>>> + super.setUp();
>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John
>>> Doe"));
>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>>> PhoneImpl(
>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>> "mobile"),
>>> + new PhoneImpl("+33W000000000", "work")));
>>> +
>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>>> AddressImpl(
>>> + "My home address")));
>>> +
>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>> + "john.doe@work.bar", "work"),
>>> + new EmailImpl("john.doe@home.bar", "home")));
>>> +
>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>> +
>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>> MediaItemImpl(
>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>> +
>>> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>> +
>>> + beanJsonConverter = new BeanJsonConverter(Guice
>>> + .createInjector(new SocialApiTestsGuiceModule()));
>>> +
>>> + apiValidator = new APIValidator("opensocial-reference");
>>> +
>>> + }
>>> +
>>> + public static class SpecialPerson extends PersonImpl {
>>> + private String newfield;
>>> +
>>> + public SpecialPerson() {
>>> + super();
>>> + }
>>> +
>>> + public SpecialPerson(String id, String name, String newfield) {
>>> + super(id, new NameImpl(name));
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + public String getNewfield() {
>>> + return newfield;
>>> + }
>>> +
>>> + public void setNewfield(String newfield) {
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + }
>>> +
>>> + public void testToJsonLibOnInheritedClassOutput() throws
>>> Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startOutput = System.currentTimeMillis();
>>> + String[] output = new String[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
>>> + }
>>> + long endOutput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + char[] source = output[0].toCharArray();
>>> + r.gc();
>>> +
>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + serializeOutput[i] = new String(source);
>>> + }
>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + /*
>>> + * Output the time per conversion and the memory usage - the
>>> output
>>> per
>>> + * conversion.
>>> + *
>>> + */
>>> +
>>> + log.info("SF JSON Lib Output "
>>> + + average(startOutput, endOutput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-
>>> average(stringsizeStart,
>>> stringsizeEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, output packet consumed on
>>> average "
>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>> for a
>>> string length of "+output[0].length());
>>> + log.info("Output Was ["+output[0]+"]");
>>> + }
>>> +
>>> + public void testToJsonLibOnInheritedClassInput() throws
>>> Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long personStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + r.gc();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> +
>>> + serializeOutput[i] =
>>> beanJsonLibConverter.convertToString(spa[i]);
>>> + }
>>> +
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startInput = System.currentTimeMillis();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + sparesult[i] = beanJsonLibConverter.convertToObject(
>>> + serializeOutput[i], SpecialPerson.class);
>>> + }
>>> + long endInput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("SF JSON Lib Input "
>>> + + average(startInput, endInput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-
>>> average(personStart,
>>> personEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, person object consumed on
>>> average "
>>> + + average(personStart, personEnd, TEST_SIZE));
>>> + }
>>> +
>>> + public void testToJsonOnInheritedClassOutput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + Runtime r = Runtime.getRuntime();
>>> + String[] output = new String[TEST_SIZE];
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startOutput = System.currentTimeMillis();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + output[i] = ((JSONObject)
>>> beanJsonConverter.convertToJson(spa[i])).toString();
>>> + }
>>> + long endOutput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + char[] source = output[0].toCharArray();
>>> + r.gc();
>>> +
>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>> +
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + serializeOutput[i] = new String(source);
>>> + }
>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("ORG JSON Lib Output "
>>> + + average(startOutput, endOutput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-
>>> average(stringsizeStart,
>>> stringsizeEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, output packet consumed on
>>> average "
>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+"
>>> for a
>>> string length of "+output[0].length());
>>> + log.info("Output Was ["+output[0]+"]");
>>> + }
>>> +
>>> + /**
>>> + * @param endOutput
>>> + * @param startOutput
>>> + * @param testSize
>>> + * @return
>>> + */
>>> + private float average(long start, long end, int testSize) {
>>> + float r = end - start;
>>> + r = r / testSize;
>>> + return r;
>>> + }
>>> +
>>> + public void XtestToJsonOnInheritedClassInput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long personStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + r.gc();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> +
>>> + serializeOutput[i] =
>>> beanJsonConverter.convertToString(spa[i]);
>>> + }
>>> +
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startInput = System.currentTimeMillis();
>>> +
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + sparesult[i] = beanJsonConverter.convertToObject(
>>> + serializeOutput[i], SpecialPerson.class);
>>> + }
>>> + long endInput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("SF JSON Lib Input "
>>> + + average(startInput, endInput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-
>>> average(personStart,
>>> personEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, person object consumed on
>>> average "
>>> + + average(personStart, personEnd, TEST_SIZE));
>>> + }
>>> +
>>> +}
>>>
>>> Modified: incubator/shindig/trunk/pom.xml
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- incubator/shindig/trunk/pom.xml (original)
>>> +++ incubator/shindig/trunk/pom.xml Sat Jul 19 06:51:03 2008
>>> @@ -853,6 +853,16 @@
>>> <artifactId>htmlunit</artifactId>
>>> <version>2.1</version>
>>> </dependency>
>>> + <dependency>
>>> + <groupId>log4j</groupId>
>>> + <artifactId>log4j</artifactId>
>>> + <version>1.2.13</version>
>>> + </dependency>
>>> + <dependency>
>>> + <groupId>rhino</groupId>
>>> + <artifactId>js</artifactId>
>>> + <version>1.6R7</version>
>>> + </dependency>
>>> </dependencies>
>>> </dependencyManagement>
>>> </project>
>>>
>>>
>>>
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Posted by Kevin Brown <et...@google.com>.
Thanks!
On Sun, Jul 20, 2008 at 2:02 AM, Ian Boston <ie...@tfd.co.uk> wrote:
> Ok will fix.
> Ian
>
>
> On 19 Jul 2008, at 20:50, Kevin Brown wrote:
>
> Hey Ian,
>>
>> The casing is inconsistent here -- it should be Json and Api for all cases
>> rather than JSON or API.
>>
>> Thanks!
>>
>> On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
>>
>> Author: ieb
>>> Date: Sat Jul 19 06:51:03 2008
>>> New Revision: 678158
>>>
>>> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
>>> Log:
>>> SHINDIG-451
>>> Applying patch from the JIRA.
>>>
>>> Adds a json-lib (net.sf) converter, not wired into social-api at present.
>>>
>>> Added:
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>>
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> Modified:
>>> incubator/shindig/trunk/java/social-api/pom.xml
>>> incubator/shindig/trunk/pom.xml
>>>
>>> Modified: incubator/shindig/trunk/java/social-api/pom.xml
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>>
>>>
>>> ==============================================================================
>>> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
>>> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19 06:51:03
>>> 2008
>>> @@ -60,12 +60,31 @@
>>> <groupId>org.apache.shindig</groupId>
>>> <artifactId>shindig-common</artifactId>
>>> </dependency>
>>> + <!-- is this Ok, only used in test to load the features -->
>>> + <dependency>
>>> + <groupId>org.apache.shindig</groupId>
>>> + <artifactId>shindig-features</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>>
>>> <!-- external depenencies -->
>>> <dependency>
>>> <groupId>org.json</groupId>
>>> <artifactId>json</artifactId>
>>> </dependency>
>>> + <!-- the classifier prevents this working in dep management -->
>>> + <dependency>
>>> + <groupId>net.sf.json-lib</groupId>
>>> + <artifactId>json-lib</artifactId>
>>> + <version>2.2</version>
>>> + <classifier>jdk15</classifier>
>>> + <type>jar</type>
>>> + </dependency>
>>> + <dependency>
>>> + <groupId>rhino</groupId>
>>> + <artifactId>js</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>> <dependency>
>>> <groupId>com.google.code.guice</groupId>
>>> <artifactId>guice</artifactId>
>>> @@ -112,5 +131,10 @@
>>> <artifactId>core</artifactId>
>>> <scope>compile</scope>
>>> </dependency>
>>> + <dependency>
>>> + <groupId>log4j</groupId>
>>> + <artifactId>log4j</artifactId>
>>> + <scope>test</scope>
>>> + </dependency>
>>> </dependencies>
>>> </project>
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,43 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +/**
>>> + * Where a conversion exception happens in the Json Lib conversion, this
>>> + * exception is thrown.
>>> + */
>>> +public class BeanJsonLibConversionException extends RuntimeException {
>>> +
>>> + private static final long serialVersionUID = -8609384443448202372L;
>>> +
>>> + public BeanJsonLibConversionException() {
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(String arg0) {
>>> + super(arg0);
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(Throwable arg0) {
>>> + super(arg0);
>>> + }
>>> +
>>> + public BeanJsonLibConversionException(String arg0, Throwable arg1) {
>>> + super(arg0, arg1);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverter.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,286 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.lang.reflect.Array;
>>> +import java.lang.reflect.InvocationTargetException;
>>> +import java.util.Collection;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import net.sf.ezmorph.MorpherRegistry;
>>> +import net.sf.json.JSONArray;
>>> +import net.sf.json.JSONException;
>>> +import net.sf.json.JSONObject;
>>> +import net.sf.json.JsonConfig;
>>> +import net.sf.json.processors.DefaultValueProcessor;
>>> +import net.sf.json.util.EnumMorpher;
>>> +import net.sf.json.util.JSONUtils;
>>> +import net.sf.json.util.NewBeanInstanceStrategy;
>>> +import net.sf.json.util.PropertyFilter;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.Enum;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.Organization;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.Url;
>>> +
>>> +
>>> +import com.google.inject.Inject;
>>> +import com.google.inject.Injector;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class BeanJsonLibConverter implements BeanConverter {
>>> +
>>> + protected static final Log log = LogFactory
>>> + .getLog(BeanJsonLibConverter.class);
>>> + private Injector injector;
>>> + private JsonConfig jsonConfig;
>>> + private boolean debugMode = false;
>>> +
>>> + /*
>>> + * Register the Enum Morphers so that JSON -> Bean works correctly for
>>> enums.
>>> + */
>>> + static {
>>> + MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Address.Field.class));
>>> + morpherRegistry.registerMorpher(new EnumMorpher(Phone.Field.class));
>>> + morpherRegistry.registerMorpher(new EnumMorpher(Email.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(MediaItem.Field.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(MediaItem.Type.class));
>>> + morpherRegistry.registerMorpher(new
>>> EnumMorpher(Enum.Drinker.class));
>>> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Field.class));
>>> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Gender.class));
>>> + morpherRegistry
>>> + .registerMorpher(new EnumMorpher(Enum.NetworkPresence.class));
>>> + morpherRegistry.registerMorpher(new EnumMorpher(Enum.Smoker.class));
>>> +
>>> + morpherRegistry.registerMorpher(new JSONObjectToMapMorpher());
>>> + }
>>> +
>>> + @Inject
>>> + public BeanJsonLibConverter(Injector injector) {
>>> + this.injector = injector;
>>> + createJsonConfig();
>>> + }
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + public <T> T convertToObject(String string, final Class<T>
>>> rootBeanClass) {
>>> +
>>> + if (string.startsWith("[")) {
>>> + JSONArray jsonArray = JSONArray.fromObject(string, jsonConfig);
>>> + if (debugMode) {
>>> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
>>> + }
>>> +
>>> + if (rootBeanClass.isArray()) {
>>> + Class<?> componentType = rootBeanClass.getComponentType();
>>> + Object rootObject = injector.getInstance(componentType);
>>> + List<?> o = JSONArray.toList(jsonArray, rootObject, jsonConfig);
>>> + Object[] result = (Object[]) Array.newInstance(componentType,
>>> o.size());
>>> + for (int i = 0; i < o.size(); i++) {
>>> + result[i] = o.get(i);
>>> + }
>>> + return (T) result;
>>> +
>>> + } else {
>>> + T rootObject = injector.getInstance(rootBeanClass);
>>> + Object o = JSONArray.toArray(jsonArray, rootObject, jsonConfig);
>>> + return (T) o;
>>> + }
>>> + } else {
>>> + JSONObject jsonObject = JSONObject.fromObject(string, jsonConfig);
>>> +
>>> + if (debugMode) {
>>> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
>>> + }
>>> +
>>> + T rootObject = injector.getInstance(rootBeanClass);
>>> + Object o = JSONObject.toBean(jsonObject, rootObject, jsonConfig);
>>> + return (T) o;
>>> +
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * @return
>>> + */
>>> + private void createJsonConfig() {
>>> +
>>> + jsonConfig = new JsonConfig();
>>> +
>>> + /*
>>> + * This hook deals with the creation of new beans in the JSON ->
>>> Java
>>> Bean
>>> + * conversion
>>> + */
>>> + jsonConfig.setNewBeanInstanceStrategy(new NewBeanInstanceStrategy()
>>> {
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + @Override
>>> + public Object newInstance(Class beanClass, JSONObject jsonObject)
>>> + throws InstantiationException, IllegalAccessException,
>>> + SecurityException, NoSuchMethodException,
>>> InvocationTargetException {
>>> + if (beanClass != null) {
>>> + Object o =
>>> BeanJsonLibConverter.this.injector.getInstance(beanClass);
>>> + if (debugMode) {
>>> + log.info("Created Object " + o + " for " + beanClass + "
>>> with
>>> ["
>>> + + jsonObject + "]");
>>> + }
>>> + return o;
>>> + }
>>> + return DEFAULT.newInstance(beanClass, jsonObject);
>>> + }
>>> +
>>> + });
>>> +
>>> + /*
>>> + * We are expecting null for nulls
>>> + */
>>> + jsonConfig.registerDefaultValueProcessor(String.class,
>>> + new DefaultValueProcessor() {
>>> + @SuppressWarnings("unchecked")
>>> + public Object getDefaultValue(Class target) {
>>> + return null;
>>> + }
>>> + });
>>> +
>>> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
>>> +
>>> + public boolean apply(Object source, String name, Object value) {
>>> + return filterProperty(source, name, value);
>>> + }
>>> +
>>> + });
>>> +
>>> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
>>> +
>>> + public boolean apply(Object source, String name, Object value) {
>>> + return filterProperty(source,name,value);
>>> + }
>>> +
>>> + });
>>> +
>>> + // the classMap deals with the basic json string to bean conversion
>>> +
>>> + Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
>>> +
>>> + /*
>>> + * mappings are required where there is a List of objects in the
>>> interface
>>> + * with no indication of what type the list should contain. At the
>>> moment,
>>> + * we are using 1 map for all json trees, as there is no conflict,
>>> but
>>> if
>>> + * there is a map could be selected on the basis of the root object.
>>> It
>>> + * would be better to do this with generics, but this is good enough
>>> and
>>> + * compact enough for the moment.
>>> + *
>>> + */
>>> + //
>>> + // activity
>>> + classMap.put("mediaItems", MediaItem.class);
>>> + // this may not be necessary
>>> + classMap.put("templateParams", Map.class);
>>> + // BodyType needs no mappings
>>> + // Message needs no mappings
>>> + // Name needs no mappings
>>> + // Organization needs no mappings
>>> + // Url needs no mappings
>>> + // Email needs no mappings
>>> + // Phone Needs no mappings
>>> + // Address Needs no mappings
>>> + // MediaItem needs no mappings
>>> +
>>> + // Person map
>>> + classMap.put("addresses", Address.class);
>>> + classMap.put("phoneNumbers", Phone.class);
>>> + classMap.put("emails", Email.class);
>>> + classMap.put("mediaItems", MediaItem.class);
>>> + classMap.put("jobs", Organization.class);
>>> + classMap.put("schools", Organization.class);
>>> + classMap.put("urls", Url.class);
>>> + jsonConfig.setClassMap(classMap);
>>> +
>>> + }
>>> +
>>> + /**
>>> + * @param source
>>> + * @param name
>>> + * @param value
>>> + * @return
>>> + */
>>> + protected boolean filterProperty(Object source, String name, Object
>>> value) {
>>> + if ( value == null ) {
>>> + return true;
>>> + }
>>> + if ( value instanceof JSONArray ) {
>>> + JSONArray array = (JSONArray) value;
>>> + if ( array.size() == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof JSONObject ) {
>>> + JSONObject object = (JSONObject) value;
>>> + if ( object.isNullObject() || object.isEmpty() ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof Collection) {
>>> + Collection<?> collection = (Collection<?>) value;
>>> + if ( collection.size() == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + if ( value instanceof Object[] ) {
>>> + Object[] oarray = (Object[]) value;
>>> + if ( oarray.length == 0 ) {
>>> + return true;
>>> + }
>>> + }
>>> + return false;
>>> + }
>>> +
>>> + public String convertToString(Object pojo) {
>>> +
>>> + try {
>>> + JSONObject jsonObject = JSONObject.fromObject(pojo, jsonConfig);
>>> + return jsonObject.toString();
>>> + } catch (JSONException jse) {
>>> + Class<?> pojoClass = pojo.getClass();
>>> + if (JSONUtils.isArray(pojoClass)) {
>>> + JSONArray jsonArray = JSONArray.fromObject(pojo);
>>> + String result = jsonArray.toString();
>>> + return result;
>>> + }
>>> + throw jse;
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * @param string
>>> + * @param class1
>>> + */
>>> + public void addMapping(String key, Class<?> class1) {
>>> + jsonConfig.getClassMap().put(key, class1);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONLibConverterUtils.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,72 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +
>>> +import net.sf.json.JSONArray;
>>> +import net.sf.json.JSONObject;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class JSONLibConverterUtils {
>>> + protected static final Log log = LogFactory
>>> + .getLog(JSONLibConverterUtils.class);
>>> +
>>> +
>>> + /**
>>> + * @param jsonObject
>>> + */
>>> + public static final void dumpJsonObject(JSONObject jsonObject, String
>>> indent) {
>>> + for (Object key : jsonObject.keySet()) {
>>> + Object value = jsonObject.get(key);
>>> + if (value instanceof JSONObject) {
>>> + log.info(indent + key + ":JSONObject");
>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>> + } else if (value instanceof JSONArray) {
>>> + log.info(indent + key + ":JSONArray " + ((JSONArray)
>>> value).size());
>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>> + } else {
>>> + log.info(indent + key + ":" + value + ":"
>>> + + (value == null ? "na" : value.getClass()));
>>> + }
>>> + }
>>> + }
>>> +
>>> +
>>> + /**
>>> + * @param value
>>> + * @param string
>>> + */
>>> + static void dumpJsonArray(JSONArray array, String indent) {
>>> + for (Object value : array) {
>>> + if (value instanceof JSONObject) {
>>> + log.info(indent + ":JSONObject");
>>> + dumpJsonObject((JSONObject) value, indent + " ");
>>> + } else if (value instanceof JSONArray) {
>>> + log.info(indent + ":JSONArray " + ((JSONArray) value).size());
>>> + dumpJsonArray((JSONArray) value, indent + " ");
>>> + } else {
>>> + log.info(indent + ":" + value + ":"
>>> + + (value == null ? "na" : value.getClass()));
>>> + }
>>> + }
>>> + }
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,50 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.util.HashMap;
>>> +import java.util.Map;
>>> +
>>> +import net.sf.ezmorph.Morpher;
>>> +import net.sf.ezmorph.ObjectMorpher;
>>> +import net.sf.json.JSONObject;
>>> +
>>> +/**
>>> + *
>>> + */
>>> +public class JSONObjectToMapMorpher implements Morpher, ObjectMorpher {
>>> +
>>> + public Class<?> morphsTo() {
>>> + return Map.class;
>>> + }
>>> +
>>> + @SuppressWarnings("unchecked")
>>> + public boolean supports(Class clazz) {
>>> + return (JSONObject.class.equals(clazz));
>>> + }
>>> +
>>> + public Object morph(Object bean) {
>>> + Map<Object, Object> result = new HashMap<Object, Object>();
>>> + JSONObject jsonObject = (JSONObject) bean;
>>> + for ( Object key : jsonObject.keySet()) {
>>> + result.put(key,jsonObject.get(key));
>>> + }
>>> + return result;
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/JsonLibTestsGuiceModule.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,40 @@
>>> +/*
>>> + * 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.social;
>>> +
>>> +import java.util.ArrayList;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import com.google.inject.AbstractModule;
>>> +
>>> +/**
>>> + * Provides social api component injection for all large tests
>>> + */
>>> +public class JsonLibTestsGuiceModule extends AbstractModule {
>>> + @Override
>>> + protected void configure() {
>>> +
>>> + bind(Map.class).to(HashMap.class);
>>> + bind(List.class).to(ArrayList.class);
>>> + bind(Map[].class).to(HashMap[].class);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidator.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,352 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.io.IOException;
>>> +import java.io.InputStream;
>>> +import java.io.InputStreamReader;
>>> +import java.util.ArrayList;
>>> +import java.util.HashMap;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import javax.xml.parsers.DocumentBuilder;
>>> +import javax.xml.parsers.DocumentBuilderFactory;
>>> +import javax.xml.parsers.ParserConfigurationException;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.mozilla.javascript.Context;
>>> +import org.mozilla.javascript.EvaluatorException;
>>> +import org.mozilla.javascript.Script;
>>> +import org.mozilla.javascript.ScriptableObject;
>>> +import org.w3c.dom.Document;
>>> +import org.w3c.dom.NamedNodeMap;
>>> +import org.w3c.dom.Node;
>>> +import org.w3c.dom.NodeList;
>>> +import org.xml.sax.SAXException;
>>> +
>>> +/**
>>> + * A class that loads a feature set from features into a Javascript
>>> Parser
>>> to
>>> + * make the model available to validate JSON messages against.
>>> + */
>>> +public class APIValidator {
>>> +
>>> + private static final Log log = LogFactory.getLog(APIValidator.class);
>>> + private Context ctx;
>>> + private ScriptableObject scope;
>>> +
>>> + /**
>>> + * @param feature
>>> + * The name of the feature are eg
>>> "opensocial-reference",
>>> this
>>> + * is a classpath stub (not starting with /) where the
>>> location
>>> + * contains a feature.xml file.
>>> + * @throws SAXException
>>> + * if feature.xml is not parsable
>>> + * @throws ParserConfigurationException
>>> + * if the parsers are invalid
>>> + * @throws IOException
>>> + * if feature.xml or the javascript that represents
>>> the
>>> + * feature is missing
>>> + *
>>> + */
>>> + public APIValidator(String feature) throws IOException,
>>> + ParserConfigurationException, SAXException {
>>> + ctx = Context.enter();
>>> + scope = ctx.initStandardObjects();
>>> + load(feature);
>>> + }
>>> +
>>> + /**
>>> + * @param json
>>> + * The json to validate expected in a form { xyz: yyy }
>>> form
>>> + * @param object
>>> + * The json Fields object specifying the structure of
>>> the
>>> json
>>> + * object, each field in this object contains the name
>>> of
>>> the
>>> + * json field in the json structure.
>>> + * @param optionalFields
>>> + * If any of the fields that appear in the json
>>> structure
>>> are
>>> + * optional, then they should be defined in this
>>> parameter.
>>> + * @param nullfields
>>> + * @throws APIValidatorExpcetion
>>> + * if there is a problem validating the json
>>> + * @return a map so string object pairs containing the fields at the
>>> top
>>> level
>>> + * of the json tree. Where these are native java objects, they
>>> will
>>> + * appear as native object. Complex json objects will appear
>>> as
>>> Rhino
>>> + * specific objects
>>> + */
>>> + public Map<String, Object> validate(String json, String object,
>>> + String[] optionalFields, String[] nullfields)
>>> + throws APIValidatorExpcetion {
>>> +
>>> + /*
>>> + * Object[] ids = ScriptableObject.getPropertyIds(scope); for
>>> (Object
>>> id :
>>> + * ids) { Object o = ScriptableObject.getProperty(scope,
>>> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
>>> id.getClass() + "
>>> + * is " + o); if (o instanceof ScriptableObject) {
>>> + * listScriptable(String.valueOf(id), (ScriptableObject) o); } }
>>> + */
>>> +
>>> + log.debug("Loading " + json);
>>> + json = json.trim();
>>> + if (!json.endsWith("}")) {
>>> + json = json + "}";
>>> + }
>>> + if (!json.startsWith("{")) {
>>> + json = "{" + json;
>>> + }
>>> + json = "( testingObject = " + json + " )";
>>> +
>>> + Object so = null;
>>> + try {
>>> + so = ctx.evaluateString(scope, json, "test json", 0, null);
>>> + } catch (EvaluatorException ex) {
>>> + log.error("Non parseable JSON " + json);
>>> + }
>>> + log.debug("Loaded " + so);
>>> +
>>> + return validateOject(so, object, optionalFields, nullfields);
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Validate an JSON Object extracted
>>> + *
>>> + * @param object
>>> + * @param string
>>> + * @param optional
>>> + * @return
>>> + * @throws APIValidatorExpcetion
>>> + */
>>> + public Map<String, Object> validateOject(Object jsonObject, String
>>> object,
>>> + String[] optionalFields, String[] nullFields)
>>> + throws APIValidatorExpcetion {
>>> + Map<String, String> optional = new HashMap<String, String>();
>>> + for (String opt : optionalFields) {
>>> + optional.put(opt, opt);
>>> + }
>>> + Map<String, String> nullf = new HashMap<String, String>();
>>> + for (String nf : nullFields) {
>>> + nullf.put(nf, nf);
>>> + }
>>> +
>>> + ScriptableObject specification = getScriptableObject(object);
>>> + log.debug("Looking for " + object + " found " + specification);
>>> + listScriptable(object, specification);
>>> +
>>> + Map<String, Object> resultFields = new HashMap<String, Object>();
>>> +
>>> + if (jsonObject instanceof ScriptableObject) {
>>> + ScriptableObject parsedJSONObject = (ScriptableObject) jsonObject;
>>> + listScriptable("testingObject", parsedJSONObject);
>>> + Object[] fields = specification.getIds();
>>> + for (Object f : fields) {
>>> + Object fieldName = specification.get(String.valueOf(f),
>>> specification);
>>> + Object o = parsedJSONObject.get(String.valueOf(fieldName),
>>> + parsedJSONObject);
>>> + if (o == ScriptableObject.NOT_FOUND) {
>>> + if (optional.containsKey(fieldName)) {
>>> + log.warn("Missing Optional Field " + fieldName);
>>> + } else if (!nullf.containsKey(fieldName)) {
>>> + log.error("Missing Field " + fieldName);
>>> + throw new APIValidatorExpcetion("Missing Field " +
>>> fieldName);
>>> + }
>>> + } else {
>>> + if (nullf.containsKey(fieldName)) {
>>> + log.error("Field should have been null and was not");
>>> + }
>>> + if (o == null) {
>>> + if (nullf.containsKey(fieldName)) {
>>> + log.error("Null Fields has been serialized " + fieldName);
>>> + }
>>> + log.debug("Got a Null object for Field " + f + ":" +
>>> fieldName
>>> + + " on json [[" + jsonObject + "]]");
>>> +
>>> + } else {
>>> +
>>> + log.debug("Got JSON Field Field," + f + ":" + fieldName + "
>>> as "
>>> + + o + " " + o.getClass());
>>> + }
>>> + resultFields.put(String.valueOf(fieldName), o);
>>> + }
>>> + }
>>> +
>>> + } else {
>>> + throw new APIValidatorExpcetion(
>>> + "Parsing JSON resulted in invalid Javascript object, which was
>>> "
>>> + + jsonObject + " JSON was [[" + jsonObject + "]]");
>>> + }
>>> + return resultFields;
>>> + }
>>> +
>>> + /**
>>> + * get an object from the json context and scope.
>>> + *
>>> + * @param object
>>> + * the name of the object specified as a path from the
>>> base
>>> + * object
>>> + * @return the json object
>>> + */
>>> + private ScriptableObject getScriptableObject(String object) {
>>> + String[] path = object.split("\\.");
>>> + log.debug("Looking up " + object + " elements " + path.length);
>>> +
>>> + ScriptableObject s = scope;
>>> + for (String pe : path) {
>>> + log.debug("Looking up " + pe + " in " + s);
>>> + s = (ScriptableObject) s.get(pe, s);
>>> + log.debug("Looking for " + pe + " in found " + s);
>>> + }
>>> + return s;
>>> + }
>>> +
>>> + /**
>>> + * List a scriptable object at log debug level, constructors will not
>>> be
>>> + * expanded as this loads to recursion.
>>> + *
>>> + * @param id
>>> + * The name of the object
>>> + * @param scriptableObject
>>> + * the scriptable Object
>>> + */
>>> + private void listScriptable(String id, ScriptableObject
>>> scriptableObject) {
>>> + log.debug("ID is Scriptable " + id);
>>> + if (!id.endsWith("constructor")) {
>>> + Object[] allIDs = scriptableObject.getAllIds();
>>> + for (Object oid : allIDs) {
>>> + log.debug(id + "." + oid);
>>> + Object o = scriptableObject.get(String.valueOf(oid),
>>> scriptableObject);
>>> + if (o instanceof ScriptableObject) {
>>> + listScriptable(id + "." + String.valueOf(oid),
>>> (ScriptableObject) o);
>>> + }
>>> + }
>>> + }
>>> + }
>>> +
>>> + /**
>>> + * Load a feature based on the spec
>>> + *
>>> + * @param spec
>>> + * The name of the location of the spec in the
>>> classpath,
>>> must
>>> + * not start with a '/' and must should contain a
>>> feature.xml
>>> + * file in the location
>>> + * @throws IOException
>>> + * If any of the resources cant be found
>>> + * @throws ParserConfigurationException
>>> + * If the parser has a problem being constructed
>>> + * @throws SAXException
>>> + * on a parse error on the features.xml
>>> + */
>>> + private void load(String spec) throws IOException, SAXException,
>>> + ParserConfigurationException {
>>> +
>>> + List<String> scripts = getScripts(spec);
>>> +
>>> + List<Script> compiled = new ArrayList<Script>();
>>> + for (String script : scripts) {
>>> + String scriptPath = spec + "/" + script;
>>> + InputStream in =
>>> this.getClass().getClassLoader().getResourceAsStream(
>>> + scriptPath);
>>> + if (in == null) {
>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>> + "features/" + scriptPath);
>>> + if (in == null) {
>>> + throw new IOException("Cant load spec " + spec + " or
>>> features/"+spec+" from classpath");
>>> + }
>>> + }
>>> + InputStreamReader reader = new InputStreamReader(in);
>>> + Script compiledScript = ctx.compileReader(reader, spec, 0, null);
>>> + compiled.add(compiledScript);
>>> + }
>>> +
>>> + for (Script compiledScript : compiled) {
>>> + compiledScript.exec(ctx, scope);
>>> + }
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Add some javascript to the context, and execute it. If extra custom
>>> + * javascript is wanted in the context or scope then this method will
>>> load it.
>>> + *
>>> + * @param javascript
>>> + */
>>> + public void addScript(String javascript) {
>>> + Script compileScript = ctx.compileString(javascript, "AdditionalJS",
>>> 0,
>>> + null);
>>> + compileScript.exec(ctx, scope);
>>> + }
>>> +
>>> + /**
>>> + * Get an ordered list of javascript resources from a feature sets.
>>> + *
>>> + * @param spec
>>> + * The spec location
>>> + * @return An ordered list of javascript resources, these are relative
>>> to
>>> + * specification file.
>>> + * @throws IOException
>>> + * If any of the resources can't be loaded.
>>> + * @throws SAXException
>>> + * Where the feature.xml file is not parsable
>>> + * @throws ParserConfigurationException
>>> + * where the parser can't be constructed.
>>> + * @return An ordered list of script that need to be loaded and
>>> executed
>>> to
>>> + * make the feature available in the context.
>>> + */
>>> + private List<String> getScripts(String spec) throws SAXException,
>>> + IOException, ParserConfigurationException {
>>> + String features = spec + "/feature.xml";
>>> + InputStream in =
>>> this.getClass().getClassLoader().getResourceAsStream(
>>> + features);
>>> + if (in == null) {
>>> + in = this.getClass().getClassLoader().getResourceAsStream(
>>> + "features/"+features);
>>> + if (in == null) {
>>> + throw new IOException("Cant find " + features + " or features/"
>>> +
>>> features+ " in classpath ");
>>> + }
>>> + }
>>> + DocumentBuilderFactory builderFactory = DocumentBuilderFactory
>>> + .newInstance();
>>> + DocumentBuilder documentBuilder =
>>> builderFactory.newDocumentBuilder();
>>> + Document doc = documentBuilder.parse(in);
>>> + NodeList nl = doc.getElementsByTagName("script");
>>> + List<String> scripts = new ArrayList<String>();
>>> + for (int i = 0; i < nl.getLength(); i++) {
>>> + Node scriptNode = nl.item(i);
>>> + NamedNodeMap attributes = scriptNode.getAttributes();
>>> + Node scriptAttr = attributes.getNamedItem("src");
>>> + String script = scriptAttr.getNodeValue();
>>> + scripts.add(script);
>>> + }
>>> + return scripts;
>>> + }
>>> +
>>> + /**
>>> + * @param nameJSON
>>> + */
>>> + public static void dump(Map<?, ?> nameJSON) {
>>> + if (log.isDebugEnabled()) {
>>> + for (Object k : nameJSON.keySet()) {
>>> + Object o = nameJSON.get(k);
>>> + log.info("Key [" + k + "] value:["
>>> + + (o == null ? o : o + ":" + o.getClass()) + "]");
>>> + }
>>> + }
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorExpcetion.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,42 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +/**
>>> + * Thrown when there is a validation exception on one of the apis
>>> + */
>>> +public class APIValidatorExpcetion extends Exception {
>>> +
>>> + private static final long serialVersionUID = -8969858718669454612L;
>>> +
>>> + public APIValidatorExpcetion() {
>>> + }
>>> +
>>> + public APIValidatorExpcetion(String message) {
>>> + super(message);
>>> + }
>>> +
>>> + public APIValidatorExpcetion(Throwable cause) {
>>> + super(cause);
>>> + }
>>> +
>>> + public APIValidatorExpcetion(String message, Throwable cause) {
>>> + super(message, cause);
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/APIValidatorTest.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,89 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +
>>> +import java.io.IOException;
>>> +import java.util.Map;
>>> +
>>> +import javax.xml.parsers.ParserConfigurationException;
>>> +
>>> +import org.junit.Assert;
>>> +import org.junit.Test;
>>> +import org.xml.sax.SAXException;
>>> +
>>> +/**
>>> + * Test the api validator to make certain it behaves as is expected.
>>> + */
>>> +public class APIValidatorTest {
>>> +
>>> + /**
>>> + * A definition of the test json used in this unit test.
>>> + */
>>> + private static final String TEST_DEFINITION =
>>> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\", FIELD2 :
>>> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
>>> +
>>> + /**
>>> + * test the validator for successful validation
>>> + * @throws APIValidatorExpcetion
>>> + * @throws IOException
>>> + * @throws ParserConfigurationException
>>> + * @throws SAXException
>>> + */
>>> + @Test
>>> + public void testValidator() throws APIValidatorExpcetion, IOException,
>>> ParserConfigurationException, SAXException {
>>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>>> + apiVal.addScript(TEST_DEFINITION);
>>> + String[] optional = {"shouldBeMissing"};
>>> + String[] nullfields = {};
>>> + Map<String, Object> result = apiVal.validate("{ json: \"A Test
>>> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
>>> + Assert.assertNotNull(result);
>>> + Assert.assertNotNull(result.get("json"));
>>> + Assert.assertNotNull(result.get("xyz"));
>>> + Assert.assertEquals(String.class,result.get("json").getClass());
>>> + Assert.assertEquals(Integer.class,result.get("xyz").getClass());
>>> + Assert.assertEquals("A Test JSON",result.get("json"));
>>> + Assert.assertEquals(123,((Integer)result.get("xyz")).intValue());
>>> +
>>> +
>>> + }
>>> +
>>> + /**
>>> + * Test for a failing validation
>>> + * @throws APIValidatorExpcetion
>>> + * @throws IOException
>>> + * @throws ParserConfigurationException
>>> + * @throws SAXException
>>> + */
>>> + @Test
>>> + public void testValidatorFail() throws APIValidatorExpcetion,
>>> IOException, ParserConfigurationException, SAXException {
>>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>>> + apiVal.addScript(TEST_DEFINITION);
>>> + String[] optional = {};
>>> + String[] nullfields = {};
>>> + try {
>>> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz : 123 }",
>>> "TestDef.Field", optional, nullfields );
>>> + Assert.fail("Should have Generated an APIValidatorException ");
>>> + } catch ( APIValidatorExpcetion ex ) {
>>> +
>>> + }
>>> +
>>> +
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,359 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import java.util.ArrayList;
>>> +import java.util.List;
>>> +import java.util.Map;
>>> +
>>> +import junit.framework.TestCase;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>> +import org.apache.shindig.social.opensocial.model.Name;
>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>> +import org.apache.shindig.social.opensocial.model.Person;
>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>> +
>>> +import com.google.common.collect.Lists;
>>> +import com.google.common.collect.Maps;
>>> +import com.google.inject.Guice;
>>> +
>>> +public class BeanJsonLibConverterTest extends TestCase {
>>> +
>>> + private static final Log log = LogFactory
>>> + .getLog(BeanJsonLibConverterTest.class);
>>> + private Person johnDoe;
>>> + private Activity activity;
>>> +
>>> + private BeanJsonLibConverter beanJsonConverter;
>>> + private APIValidator apiValidator;
>>> + // set to true to get loging output at info level
>>> + private boolean outputInfo = false;
>>> +
>>> + @Override
>>> + public void setUp() throws Exception {
>>> + super.setUp();
>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new PhoneImpl(
>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>> "mobile"),
>>> + new PhoneImpl("+33W000000000", "work")));
>>> +
>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new AddressImpl(
>>> + "My home address")));
>>> +
>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>> + "john.doe@work.bar", "work"),
>>> + new EmailImpl("john.doe@home.bar", "home")));
>>> +
>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>> +
>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>> MediaItemImpl(
>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>> +
>>> + beanJsonConverter = new BeanJsonLibConverter(Guice
>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>> +
>>> + apiValidator = new APIValidator("opensocial-reference");
>>> +
>>> + }
>>> +
>>> + public static class SpecialPerson extends PersonImpl {
>>> + public static final String[] OPTIONALFIELDS = {};
>>> + public static final String[] NULLFIELDS =
>>> {"jobInterests","nickname","romance","religion","timeZone",
>>> +
>>>
>>> "relationshipStatus","tags","networkPresence","books","quotes","phoneNumbers","languagesSpoken",
>>> +
>>>
>>> "activities","jobs","dateOfBirth","profileVideo","bodyType","urls","schools","music","addresses",
>>> +
>>>
>>> "livingArrangement","thumbnailUrl","humor","sports","scaredOf","movies","age","pets","hasApp","turnOffs",
>>> +
>>>
>>> "gender","fashion","drinker","aboutMe","children","sexualOrientation","heroes","profileSong","lookingFor",
>>> +
>>>
>>> "cars","turnOns","tvShows","profileUrl","status","currentLocation","smoker","happiestWhen","ethnicity",
>>> +
>>>
>>> "food","emails","politicalViews","interests","familyName","honorificSuffix","additionalName","honorificPrefix","givenName"};
>>> +
>>> + private String newfield;
>>> +
>>> + public SpecialPerson() {
>>> + super();
>>> + }
>>> +
>>> + public SpecialPerson(String id, String name, String newfield) {
>>> + super(id, new NameImpl(name));
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + public String getNewfield() {
>>> + return newfield;
>>> + }
>>> +
>>> + public void setNewfield(String newfield) {
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + }
>>> +
>>> + public void testToJsonOnInheritedClass() throws Exception {
>>> + SpecialPerson cassie = new SpecialPerson("5", "robot", "nonsense");
>>> +
>>> + String result = beanJsonConverter.convertToString(cassie);
>>> +
>>> + validatePerson(result, "5", "robot", SpecialPerson.OPTIONALFIELDS,
>>> SpecialPerson.NULLFIELDS);
>>> +
>>> + apiValidator.addScript(" specialPerson = { SPECIAL : \"newfield\" };
>>> ");
>>> + String[] optional = {};
>>> + String[] nullfields = {};
>>> + Map<String, Object> special = apiValidator.validate(result,
>>> + "specialPerson", optional,nullfields);
>>> + assertNotNull(special.get("newfield"));
>>> + assertEquals(String.class, special.get("newfield").getClass());
>>> + assertEquals("nonsense", special.get("newfield"));
>>> +
>>> + // convert back into an object Tree
>>> +
>>> + SpecialPerson parseCassie =
>>> beanJsonConverter.convertToObject(result,
>>> + SpecialPerson.class);
>>> +
>>> + assertNotNull(parseCassie);
>>> + assertEquals(cassie.getId(), parseCassie.getId());
>>> + assertEquals(cassie.getNewfield(), parseCassie.getNewfield());
>>> +
>>> + Name name = parseCassie.getName();
>>> + Name cassieName = cassie.getName();
>>> + assertNotNull(name);
>>> + assertEquals(cassieName.getUnstructured(), name.getUnstructured());
>>> + assertEquals(cassieName.getAdditionalName(),
>>> name.getAdditionalName());
>>> + assertEquals(cassieName.getFamilyName(), name.getFamilyName());
>>> + assertEquals(cassieName.getGivenName(), name.getGivenName());
>>> + assertEquals(cassieName.getHonorificPrefix(),
>>> name.getHonorificPrefix());
>>> + assertEquals(cassieName.getHonorificSuffix(),
>>> name.getHonorificSuffix());
>>> +
>>> + }
>>> +
>>> + /**
>>> + * @param result
>>> + * @throws APIValidatorExpcetion
>>> + */
>>> + private void validatePerson(String result, String id, String name,
>>> String[] optional, String[] nullfields)
>>> + throws APIValidatorExpcetion {
>>> +
>>> + Map<String, Object> standard = apiValidator.validate(result,
>>> + "opensocial.Person.Field", optional,nullfields);
>>> + assertNotNull(standard.get("id"));
>>> + assertEquals(String.class, standard.get("id").getClass());
>>> + assertEquals(id, standard.get("id"));
>>> +
>>> + assertNotNull(standard.get("name"));
>>> + Map<String, Object> nameJSON = apiValidator.validateOject(standard
>>> + .get("name"), "opensocial.Name.Field", optional,nullfields);
>>> + APIValidator.dump(nameJSON);
>>> +
>>> + assertNotNull(nameJSON.get("unstructured"));
>>> + assertEquals(String.class, nameJSON.get("unstructured").getClass());
>>> + assertEquals(name, nameJSON.get("unstructured"));
>>> +
>>> + // additional name
>>> + assertNull(nameJSON.get("additionalName"));
>>> +
>>> + }
>>> +
>>> + public void testPersonToJson() throws Exception {
>>> + String result = beanJsonConverter.convertToString(johnDoe);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Person parsedPerson = beanJsonConverter.convertToObject(result,
>>> + Person.class);
>>> +
>>> + assertEquals(johnDoe.getId(), parsedPerson.getId());
>>> + assertEquals(johnDoe.getName().getUnstructured(),
>>> parsedPerson.getName()
>>> + .getUnstructured());
>>> +
>>> + List<Address> addresses = parsedPerson.getAddresses();
>>> + if (outputInfo) {
>>> + for (Object o : addresses) {
>>> + log.info("Address " + o);
>>> + }
>>> + }
>>> +
>>> + assertEquals(1, addresses.size());
>>> + Address address = addresses.get(0);
>>> + String unstructured = address.getUnstructuredAddress();
>>> +
>>> + assertNotNull(unstructured);
>>> + assertEquals(johnDoe.getAddresses().get(0).getUnstructuredAddress(),
>>> + parsedPerson.getAddresses().get(0).getUnstructuredAddress());
>>> +
>>> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
>>> +
>>> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
>>> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
>>> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
>>> + assertEquals(expectedPhone.getType(), actualPhone.getType());
>>> + assertEquals(expectedPhone.getNumber(), actualPhone.getNumber());
>>> + }
>>> +
>>> + assertEquals(2, parsedPerson.getEmails().size());
>>> +
>>> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
>>> + Email expectedEmail = johnDoe.getEmails().get(i);
>>> + Email actualEmail = parsedPerson.getEmails().get(i);
>>> + assertEquals(expectedEmail.getType(), actualEmail.getType());
>>> + assertEquals(expectedEmail.getAddress(),
>>> actualEmail.getAddress());
>>> + }
>>> + }
>>> +
>>> + public void testActivityToJson() throws Exception {
>>> +
>>> + String result = beanJsonConverter.convertToString(activity);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Activity parsedActivity = beanJsonConverter.convertToObject(result,
>>> + Activity.class);
>>> + assertEquals(activity.getUserId(), parsedActivity.getUserId());
>>> + assertEquals(activity.getId(), parsedActivity.getId());
>>> +
>>> + assertEquals(1, parsedActivity.getMediaItems().size());
>>> +
>>> + MediaItem expectedItem = activity.getMediaItems().get(0);
>>> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
>>> +
>>> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
>>> + assertEquals(expectedItem.getMimeType(), actualItem.getMimeType());
>>> + assertEquals(expectedItem.getType().toString(), actualItem.getType()
>>> + .toString());
>>> + }
>>> +
>>> + public void testMapsToJson() throws Exception {
>>> + Map<String, Map<String, String>> map = Maps.newHashMap();
>>> +
>>> + Map<String, String> item1Map = Maps.newHashMap();
>>> + item1Map.put("value", "1");
>>> +
>>> + // Null values shouldn't cause exceptions
>>> + item1Map.put("value2", null);
>>> + map.put("item1", item1Map);
>>> +
>>> + Map<String, String> item2Map = Maps.newHashMap();
>>> + item2Map.put("value", "2");
>>> + map.put("item2", item2Map);
>>> +
>>> + String result = beanJsonConverter.convertToString(map);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + // there is introspection that can tell jsonobject -> bean converter
>>> what a
>>> + // map should contain, so we have to tell it
>>> + beanJsonConverter.addMapping("item1", Map.class);
>>> + beanJsonConverter.addMapping("item2", Map.class);
>>> + Map<?, ?> parsedMap = beanJsonConverter
>>> + .convertToObject(result, Map.class);
>>> +
>>> + if (outputInfo) {
>>> + log.info("Dumping Map (" + parsedMap + ")");
>>> + }
>>> + APIValidator.dump(parsedMap);
>>> +
>>> + assertEquals("1", ((Map<?,?>)parsedMap.get("item1")).get("value"));
>>> + assertEquals("2", ((Map<?,?>)parsedMap.get("item2")).get("value"));
>>> + }
>>> +
>>> + public void testListsToJson() throws Exception {
>>> + Map<String, String> item1Map = Maps.newHashMap();
>>> + item1Map.put("value", "1");
>>> +
>>> + Map<String, String> item2Map = Maps.newHashMap();
>>> + item2Map.put("value", "2");
>>> +
>>> + // put the list into a container before serializing, top level lists
>>> dont
>>> + // appear
>>> + // to be allowed in json
>>> + // just check that the list is in the holder correctly
>>> + List<Map<String, String>> list = new ArrayList<Map<String,
>>> String>>();
>>> + list.add(item1Map);
>>> + list.add(item2Map);
>>> + String result = beanJsonConverter.convertToString(list);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
>>> + result, Map[].class);
>>> +
>>> + assertEquals("1", parsedList[0].get("value"));
>>> + assertEquals("2", parsedList[1].get("value"));
>>> + }
>>> +
>>> + public void testArrayToJson() throws Exception {
>>> + String[] colors = { "blue", "green", "aquamarine" };
>>> + String result = beanJsonConverter.convertToString(colors);
>>> + if (outputInfo) {
>>> + log.info("JSON (" + result + ")");
>>> + }
>>> + String[] parsedColors = beanJsonConverter.convertToObject(result,
>>> + String[].class);
>>> + assertEquals(colors.length, parsedColors.length);
>>> + assertEquals(colors[0], parsedColors[0]);
>>> + assertEquals(colors[1], parsedColors[1]);
>>> + assertEquals(colors[2], parsedColors[2]);
>>> + }
>>> +
>>> + public void testJsonToActivity() throws Exception {
>>> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
>>> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}" + "]}";
>>> + Activity result = beanJsonConverter.convertToObject(jsonActivity,
>>> + Activity.class);
>>> +
>>> + assertEquals("5", result.getUserId());
>>> + assertEquals("6", result.getId());
>>> +
>>> + assertEquals(1, result.getMediaItems().size());
>>> +
>>> + MediaItem actualItem = result.getMediaItems().get(0);
>>> +
>>> + assertEquals("hello", actualItem.getUrl());
>>> + assertEquals("mimey", actualItem.getMimeType());
>>> + assertEquals("video", actualItem.getType().toString());
>>> + }
>>> +
>>> + public void testJsonToMap() throws Exception {
>>> + String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
>>> + Map<String, String> data = Maps.newHashMap();
>>> + data = beanJsonConverter.convertToObject(jsonActivity,
>>> + (Class<Map<String, String>>) data.getClass());
>>> +
>>> + assertEquals(2, data.size());
>>> +
>>> + for (String key : data.keySet()) {
>>> + Object value = data.get(key);
>>> + if (key.equals("count")) {
>>> + assertEquals(0, value);
>>> + } else if (key.equals("favoriteColor")) {
>>> + assertEquals("yellow", value);
>>> + }
>>> + }
>>> + }
>>> +
>>> +}
>>>
>>> Added:
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> URL:
>>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>>> api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java?rev=678158&view=auto
>>>
>>>
>>> ==============================================================================
>>> ---
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> (added)
>>> +++
>>>
>>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>>> Sat Jul 19 06:51:03 2008
>>> @@ -0,0 +1,271 @@
>>> +/*
>>> + * 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.social.opensocial.util;
>>> +
>>> +import junit.framework.TestCase;
>>> +
>>> +import org.apache.commons.logging.Log;
>>> +import org.apache.commons.logging.LogFactory;
>>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>>> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
>>> +import org.apache.shindig.social.opensocial.model.Activity;
>>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>>> +import org.apache.shindig.social.opensocial.model.Address;
>>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>>> +import org.apache.shindig.social.opensocial.model.Email;
>>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>>> +import org.apache.shindig.social.opensocial.model.Person;
>>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>>> +import org.apache.shindig.social.opensocial.model.Phone;
>>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>>> +import org.json.JSONObject;
>>> +
>>> +import com.google.common.collect.Lists;
>>> +import com.google.inject.Guice;
>>> +
>>> +public class JsonConverterPerformancePerf extends TestCase {
>>> +
>>> + private static final Log log = LogFactory
>>> + .getLog(JsonConverterPerformancePerf.class);
>>> + private static final int TEST_SIZE = 10000;
>>> + private Person johnDoe;
>>> + private Activity activity;
>>> +
>>> + private BeanJsonLibConverter beanJsonLibConverter;
>>> + private APIValidator apiValidator;
>>> + // set to true to get loging output at info level
>>> + private boolean outputInfo = false;
>>> + private BeanJsonConverter beanJsonConverter;
>>> +
>>> + @Override
>>> + public void setUp() throws Exception {
>>> + super.setUp();
>>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
>>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new PhoneImpl(
>>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>>> "mobile"),
>>> + new PhoneImpl("+33W000000000", "work")));
>>> +
>>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new AddressImpl(
>>> + "My home address")));
>>> +
>>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>>> + "john.doe@work.bar", "work"),
>>> + new EmailImpl("john.doe@home.bar", "home")));
>>> +
>>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>>> +
>>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>>> MediaItemImpl(
>>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>>> +
>>> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
>>> + .createInjector(new JsonLibTestsGuiceModule()));
>>> +
>>> + beanJsonConverter = new BeanJsonConverter(Guice
>>> + .createInjector(new SocialApiTestsGuiceModule()));
>>> +
>>> + apiValidator = new APIValidator("opensocial-reference");
>>> +
>>> + }
>>> +
>>> + public static class SpecialPerson extends PersonImpl {
>>> + private String newfield;
>>> +
>>> + public SpecialPerson() {
>>> + super();
>>> + }
>>> +
>>> + public SpecialPerson(String id, String name, String newfield) {
>>> + super(id, new NameImpl(name));
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + public String getNewfield() {
>>> + return newfield;
>>> + }
>>> +
>>> + public void setNewfield(String newfield) {
>>> + this.newfield = newfield;
>>> + }
>>> +
>>> + }
>>> +
>>> + public void testToJsonLibOnInheritedClassOutput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startOutput = System.currentTimeMillis();
>>> + String[] output = new String[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
>>> + }
>>> + long endOutput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + char[] source = output[0].toCharArray();
>>> + r.gc();
>>> +
>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + serializeOutput[i] = new String(source);
>>> + }
>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + /*
>>> + * Output the time per conversion and the memory usage - the output
>>> per
>>> + * conversion.
>>> + *
>>> + */
>>> +
>>> + log.info("SF JSON Lib Output "
>>> + + average(startOutput, endOutput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-average(stringsizeStart,
>>> stringsizeEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, output packet consumed on average "
>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
>>> string length of "+output[0].length());
>>> + log.info("Output Was ["+output[0]+"]");
>>> + }
>>> +
>>> + public void testToJsonLibOnInheritedClassInput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long personStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + r.gc();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> +
>>> + serializeOutput[i] = beanJsonLibConverter.convertToString(spa[i]);
>>> + }
>>> +
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startInput = System.currentTimeMillis();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + sparesult[i] = beanJsonLibConverter.convertToObject(
>>> + serializeOutput[i], SpecialPerson.class);
>>> + }
>>> + long endInput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("SF JSON Lib Input "
>>> + + average(startInput, endInput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
>>> personEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, person object consumed on average "
>>> + + average(personStart, personEnd, TEST_SIZE));
>>> + }
>>> +
>>> + public void testToJsonOnInheritedClassOutput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + Runtime r = Runtime.getRuntime();
>>> + String[] output = new String[TEST_SIZE];
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startOutput = System.currentTimeMillis();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + output[i] = ((JSONObject)
>>> beanJsonConverter.convertToJson(spa[i])).toString();
>>> + }
>>> + long endOutput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + char[] source = output[0].toCharArray();
>>> + r.gc();
>>> +
>>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>>> +
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + serializeOutput[i] = new String(source);
>>> + }
>>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("ORG JSON Lib Output "
>>> + + average(startOutput, endOutput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-average(stringsizeStart,
>>> stringsizeEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, output packet consumed on average "
>>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
>>> string length of "+output[0].length());
>>> + log.info("Output Was ["+output[0]+"]");
>>> + }
>>> +
>>> + /**
>>> + * @param endOutput
>>> + * @param startOutput
>>> + * @param testSize
>>> + * @return
>>> + */
>>> + private float average(long start, long end, int testSize) {
>>> + float r = end - start;
>>> + r = r / testSize;
>>> + return r;
>>> + }
>>> +
>>> + public void XtestToJsonOnInheritedClassInput() throws Exception {
>>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>>> + Runtime r = Runtime.getRuntime();
>>> + r.gc();
>>> + long personStart = r.totalMemory()-r.freeMemory();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>>> "nonsense");
>>> + }
>>> + long personEnd = r.totalMemory()-r.freeMemory();
>>> +
>>> + String[] serializeOutput = new String[TEST_SIZE];
>>> + r.gc();
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> +
>>> + serializeOutput[i] = beanJsonConverter.convertToString(spa[i]);
>>> + }
>>> +
>>> + r.gc();
>>> + long memstart = r.totalMemory()-r.freeMemory();
>>> + long startInput = System.currentTimeMillis();
>>> +
>>> + for (int i = 0; i < TEST_SIZE; i++) {
>>> + sparesult[i] = beanJsonConverter.convertToObject(
>>> + serializeOutput[i], SpecialPerson.class);
>>> + }
>>> + long endInput = System.currentTimeMillis();
>>> + long memend = r.totalMemory()-r.freeMemory();
>>> +
>>> + log.info("SF JSON Lib Input "
>>> + + average(startInput, endInput, TEST_SIZE)
>>> + + " ms/conversion, "
>>> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
>>> personEnd, TEST_SIZE))
>>> + + " heap bytes/conversion, person object consumed on average "
>>> + + average(personStart, personEnd, TEST_SIZE));
>>> + }
>>> +
>>> +}
>>>
>>> Modified: incubator/s
>>
>> ...
>
> [Message clipped]
Re: svn commit: r678158 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/ java/social-api/src/test/java/org/apache/shindig/social/ java/social-api/src/test/java/org/apache/shin
Posted by Ian Boston <ie...@tfd.co.uk>.
Ok will fix.
Ian
On 19 Jul 2008, at 20:50, Kevin Brown wrote:
> Hey Ian,
>
> The casing is inconsistent here -- it should be Json and Api for
> all cases
> rather than JSON or API.
>
> Thanks!
>
> On Sat, Jul 19, 2008 at 6:51 AM, <ie...@apache.org> wrote:
>
>> Author: ieb
>> Date: Sat Jul 19 06:51:03 2008
>> New Revision: 678158
>>
>> URL: http://svn.apache.org/viewvc?rev=678158&view=rev
>> Log:
>> SHINDIG-451
>> Applying patch from the JIRA.
>>
>> Adds a json-lib (net.sf) converter, not wired into social-api at
>> present.
>>
>> Added:
>>
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>>
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>>
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>>
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/JsonLibTestsGuiceModule.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidator.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorTest.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>>
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>> Modified:
>> incubator/shindig/trunk/java/social-api/pom.xml
>> incubator/shindig/trunk/pom.xml
>>
>> Modified: incubator/shindig/trunk/java/social-api/pom.xml
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/pom.xml?rev=678158&r1=678157&r2=678158&view=diff
>>
>> =====================================================================
>> =========
>> --- incubator/shindig/trunk/java/social-api/pom.xml (original)
>> +++ incubator/shindig/trunk/java/social-api/pom.xml Sat Jul 19
>> 06:51:03
>> 2008
>> @@ -60,12 +60,31 @@
>> <groupId>org.apache.shindig</groupId>
>> <artifactId>shindig-common</artifactId>
>> </dependency>
>> + <!-- is this Ok, only used in test to load the features -->
>> + <dependency>
>> + <groupId>org.apache.shindig</groupId>
>> + <artifactId>shindig-features</artifactId>
>> + <scope>test</scope>
>> + </dependency>
>>
>> <!-- external depenencies -->
>> <dependency>
>> <groupId>org.json</groupId>
>> <artifactId>json</artifactId>
>> </dependency>
>> + <!-- the classifier prevents this working in dep management -->
>> + <dependency>
>> + <groupId>net.sf.json-lib</groupId>
>> + <artifactId>json-lib</artifactId>
>> + <version>2.2</version>
>> + <classifier>jdk15</classifier>
>> + <type>jar</type>
>> + </dependency>
>> + <dependency>
>> + <groupId>rhino</groupId>
>> + <artifactId>js</artifactId>
>> + <scope>test</scope>
>> + </dependency>
>> <dependency>
>> <groupId>com.google.code.guice</groupId>
>> <artifactId>guice</artifactId>
>> @@ -112,5 +131,10 @@
>> <artifactId>core</artifactId>
>> <scope>compile</scope>
>> </dependency>
>> + <dependency>
>> + <groupId>log4j</groupId>
>> + <artifactId>log4j</artifactId>
>> + <scope>test</scope>
>> + </dependency>
>> </dependencies>
>> </project>
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>> BeanJsonLibConversionException.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConversionException.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,43 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +/**
>> + * Where a conversion exception happens in the Json Lib
>> conversion, this
>> + * exception is thrown.
>> + */
>> +public class BeanJsonLibConversionException extends
>> RuntimeException {
>> +
>> + private static final long serialVersionUID =
>> -8609384443448202372L;
>> +
>> + public BeanJsonLibConversionException() {
>> + }
>> +
>> + public BeanJsonLibConversionException(String arg0) {
>> + super(arg0);
>> + }
>> +
>> + public BeanJsonLibConversionException(Throwable arg0) {
>> + super(arg0);
>> + }
>> +
>> + public BeanJsonLibConversionException(String arg0, Throwable
>> arg1) {
>> + super(arg0, arg1);
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>> BeanJsonLibConverter.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverter.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,286 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import java.lang.reflect.Array;
>> +import java.lang.reflect.InvocationTargetException;
>> +import java.util.Collection;
>> +import java.util.HashMap;
>> +import java.util.List;
>> +import java.util.Map;
>> +
>> +import net.sf.ezmorph.MorpherRegistry;
>> +import net.sf.json.JSONArray;
>> +import net.sf.json.JSONException;
>> +import net.sf.json.JSONObject;
>> +import net.sf.json.JsonConfig;
>> +import net.sf.json.processors.DefaultValueProcessor;
>> +import net.sf.json.util.EnumMorpher;
>> +import net.sf.json.util.JSONUtils;
>> +import net.sf.json.util.NewBeanInstanceStrategy;
>> +import net.sf.json.util.PropertyFilter;
>> +
>> +import org.apache.commons.logging.Log;
>> +import org.apache.commons.logging.LogFactory;
>> +import org.apache.shindig.social.opensocial.model.Address;
>> +import org.apache.shindig.social.opensocial.model.Email;
>> +import org.apache.shindig.social.opensocial.model.Enum;
>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>> +import org.apache.shindig.social.opensocial.model.Organization;
>> +import org.apache.shindig.social.opensocial.model.Phone;
>> +import org.apache.shindig.social.opensocial.model.Url;
>> +
>> +
>> +import com.google.inject.Inject;
>> +import com.google.inject.Injector;
>> +
>> +/**
>> + *
>> + */
>> +public class BeanJsonLibConverter implements BeanConverter {
>> +
>> + protected static final Log log = LogFactory
>> + .getLog(BeanJsonLibConverter.class);
>> + private Injector injector;
>> + private JsonConfig jsonConfig;
>> + private boolean debugMode = false;
>> +
>> + /*
>> + * Register the Enum Morphers so that JSON -> Bean works
>> correctly for
>> enums.
>> + */
>> + static {
>> + MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry
>> ();
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Address.Field.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Phone.Field.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Email.Field.class));
>> + morpherRegistry.registerMorpher(new
>> EnumMorpher(MediaItem.Field.class));
>> + morpherRegistry.registerMorpher(new
>> EnumMorpher(MediaItem.Type.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Enum.Drinker.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Enum.Field.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Enum.Gender.class));
>> + morpherRegistry
>> + .registerMorpher(new EnumMorpher
>> (Enum.NetworkPresence.class));
>> + morpherRegistry.registerMorpher(new EnumMorpher
>> (Enum.Smoker.class));
>> +
>> + morpherRegistry.registerMorpher(new JSONObjectToMapMorpher());
>> + }
>> +
>> + @Inject
>> + public BeanJsonLibConverter(Injector injector) {
>> + this.injector = injector;
>> + createJsonConfig();
>> + }
>> +
>> + @SuppressWarnings("unchecked")
>> + public <T> T convertToObject(String string, final Class<T>
>> rootBeanClass) {
>> +
>> + if (string.startsWith("[")) {
>> + JSONArray jsonArray = JSONArray.fromObject(string,
>> jsonConfig);
>> + if (debugMode) {
>> + JSONLibConverterUtils.dumpJsonArray(jsonArray, " ");
>> + }
>> +
>> + if (rootBeanClass.isArray()) {
>> + Class<?> componentType = rootBeanClass.getComponentType();
>> + Object rootObject = injector.getInstance(componentType);
>> + List<?> o = JSONArray.toList(jsonArray, rootObject,
>> jsonConfig);
>> + Object[] result = (Object[]) Array.newInstance
>> (componentType,
>> o.size());
>> + for (int i = 0; i < o.size(); i++) {
>> + result[i] = o.get(i);
>> + }
>> + return (T) result;
>> +
>> + } else {
>> + T rootObject = injector.getInstance(rootBeanClass);
>> + Object o = JSONArray.toArray(jsonArray, rootObject,
>> jsonConfig);
>> + return (T) o;
>> + }
>> + } else {
>> + JSONObject jsonObject = JSONObject.fromObject(string,
>> jsonConfig);
>> +
>> + if (debugMode) {
>> + JSONLibConverterUtils.dumpJsonObject(jsonObject, " ");
>> + }
>> +
>> + T rootObject = injector.getInstance(rootBeanClass);
>> + Object o = JSONObject.toBean(jsonObject, rootObject,
>> jsonConfig);
>> + return (T) o;
>> +
>> + }
>> + }
>> +
>> + /**
>> + * @return
>> + */
>> + private void createJsonConfig() {
>> +
>> + jsonConfig = new JsonConfig();
>> +
>> + /*
>> + * This hook deals with the creation of new beans in the JSON
>> -> Java
>> Bean
>> + * conversion
>> + */
>> + jsonConfig.setNewBeanInstanceStrategy(new
>> NewBeanInstanceStrategy() {
>> +
>> + @SuppressWarnings("unchecked")
>> + @Override
>> + public Object newInstance(Class beanClass, JSONObject
>> jsonObject)
>> + throws InstantiationException, IllegalAccessException,
>> + SecurityException, NoSuchMethodException,
>> InvocationTargetException {
>> + if (beanClass != null) {
>> + Object o =
>> BeanJsonLibConverter.this.injector.getInstance(beanClass);
>> + if (debugMode) {
>> + log.info("Created Object " + o + " for " + beanClass
>> + " with
>> ["
>> + + jsonObject + "]");
>> + }
>> + return o;
>> + }
>> + return DEFAULT.newInstance(beanClass, jsonObject);
>> + }
>> +
>> + });
>> +
>> + /*
>> + * We are expecting null for nulls
>> + */
>> + jsonConfig.registerDefaultValueProcessor(String.class,
>> + new DefaultValueProcessor() {
>> + @SuppressWarnings("unchecked")
>> + public Object getDefaultValue(Class target) {
>> + return null;
>> + }
>> + });
>> +
>> + jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
>> +
>> + public boolean apply(Object source, String name, Object
>> value) {
>> + return filterProperty(source, name, value);
>> + }
>> +
>> + });
>> +
>> + jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
>> +
>> + public boolean apply(Object source, String name, Object
>> value) {
>> + return filterProperty(source,name,value);
>> + }
>> +
>> + });
>> +
>> + // the classMap deals with the basic json string to bean
>> conversion
>> +
>> + Map<String, Class<?>> classMap = new HashMap<String, Class<?>>
>> ();
>> +
>> + /*
>> + * mappings are required where there is a List of objects in the
>> interface
>> + * with no indication of what type the list should contain.
>> At the
>> moment,
>> + * we are using 1 map for all json trees, as there is no
>> conflict, but
>> if
>> + * there is a map could be selected on the basis of the root
>> object.
>> It
>> + * would be better to do this with generics, but this is good
>> enough
>> and
>> + * compact enough for the moment.
>> + *
>> + */
>> + //
>> + // activity
>> + classMap.put("mediaItems", MediaItem.class);
>> + // this may not be necessary
>> + classMap.put("templateParams", Map.class);
>> + // BodyType needs no mappings
>> + // Message needs no mappings
>> + // Name needs no mappings
>> + // Organization needs no mappings
>> + // Url needs no mappings
>> + // Email needs no mappings
>> + // Phone Needs no mappings
>> + // Address Needs no mappings
>> + // MediaItem needs no mappings
>> +
>> + // Person map
>> + classMap.put("addresses", Address.class);
>> + classMap.put("phoneNumbers", Phone.class);
>> + classMap.put("emails", Email.class);
>> + classMap.put("mediaItems", MediaItem.class);
>> + classMap.put("jobs", Organization.class);
>> + classMap.put("schools", Organization.class);
>> + classMap.put("urls", Url.class);
>> + jsonConfig.setClassMap(classMap);
>> +
>> + }
>> +
>> + /**
>> + * @param source
>> + * @param name
>> + * @param value
>> + * @return
>> + */
>> + protected boolean filterProperty(Object source, String name,
>> Object
>> value) {
>> + if ( value == null ) {
>> + return true;
>> + }
>> + if ( value instanceof JSONArray ) {
>> + JSONArray array = (JSONArray) value;
>> + if ( array.size() == 0 ) {
>> + return true;
>> + }
>> + }
>> + if ( value instanceof JSONObject ) {
>> + JSONObject object = (JSONObject) value;
>> + if ( object.isNullObject() || object.isEmpty() ) {
>> + return true;
>> + }
>> + }
>> + if ( value instanceof Collection) {
>> + Collection<?> collection = (Collection<?>) value;
>> + if ( collection.size() == 0 ) {
>> + return true;
>> + }
>> + }
>> + if ( value instanceof Object[] ) {
>> + Object[] oarray = (Object[]) value;
>> + if ( oarray.length == 0 ) {
>> + return true;
>> + }
>> + }
>> + return false;
>> + }
>> +
>> + public String convertToString(Object pojo) {
>> +
>> + try {
>> + JSONObject jsonObject = JSONObject.fromObject(pojo,
>> jsonConfig);
>> + return jsonObject.toString();
>> + } catch (JSONException jse) {
>> + Class<?> pojoClass = pojo.getClass();
>> + if (JSONUtils.isArray(pojoClass)) {
>> + JSONArray jsonArray = JSONArray.fromObject(pojo);
>> + String result = jsonArray.toString();
>> + return result;
>> + }
>> + throw jse;
>> + }
>> + }
>> +
>> + /**
>> + * @param string
>> + * @param class1
>> + */
>> + public void addMapping(String key, Class<?> class1) {
>> + jsonConfig.getClassMap().put(key, class1);
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>> JSONLibConverterUtils.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONLibConverterUtils.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,72 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import org.apache.commons.logging.Log;
>> +import org.apache.commons.logging.LogFactory;
>> +
>> +import net.sf.json.JSONArray;
>> +import net.sf.json.JSONObject;
>> +
>> +/**
>> + *
>> + */
>> +public class JSONLibConverterUtils {
>> + protected static final Log log = LogFactory
>> + .getLog(JSONLibConverterUtils.class);
>> +
>> +
>> + /**
>> + * @param jsonObject
>> + */
>> + public static final void dumpJsonObject(JSONObject jsonObject,
>> String
>> indent) {
>> + for (Object key : jsonObject.keySet()) {
>> + Object value = jsonObject.get(key);
>> + if (value instanceof JSONObject) {
>> + log.info(indent + key + ":JSONObject");
>> + dumpJsonObject((JSONObject) value, indent + " ");
>> + } else if (value instanceof JSONArray) {
>> + log.info(indent + key + ":JSONArray " + ((JSONArray)
>> value).size());
>> + dumpJsonArray((JSONArray) value, indent + " ");
>> + } else {
>> + log.info(indent + key + ":" + value + ":"
>> + + (value == null ? "na" : value.getClass()));
>> + }
>> + }
>> + }
>> +
>> +
>> + /**
>> + * @param value
>> + * @param string
>> + */
>> + static void dumpJsonArray(JSONArray array, String indent) {
>> + for (Object value : array) {
>> + if (value instanceof JSONObject) {
>> + log.info(indent + ":JSONObject");
>> + dumpJsonObject((JSONObject) value, indent + " ");
>> + } else if (value instanceof JSONArray) {
>> + log.info(indent + ":JSONArray " + ((JSONArray) value).size
>> ());
>> + dumpJsonArray((JSONArray) value, indent + " ");
>> + } else {
>> + log.info(indent + ":" + value + ":"
>> + + (value == null ? "na" : value.getClass()));
>> + }
>> + }
>> + }
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/main/java/org/apache/shindig/social/opensocial/util/
>> JSONObjectToMapMorpher.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/
>> shindig/social/opensocial/util/JSONObjectToMapMorpher.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,50 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import java.util.HashMap;
>> +import java.util.Map;
>> +
>> +import net.sf.ezmorph.Morpher;
>> +import net.sf.ezmorph.ObjectMorpher;
>> +import net.sf.json.JSONObject;
>> +
>> +/**
>> + *
>> + */
>> +public class JSONObjectToMapMorpher implements Morpher,
>> ObjectMorpher {
>> +
>> + public Class<?> morphsTo() {
>> + return Map.class;
>> + }
>> +
>> + @SuppressWarnings("unchecked")
>> + public boolean supports(Class clazz) {
>> + return (JSONObject.class.equals(clazz));
>> + }
>> +
>> + public Object morph(Object bean) {
>> + Map<Object, Object> result = new HashMap<Object, Object>();
>> + JSONObject jsonObject = (JSONObject) bean;
>> + for ( Object key : jsonObject.keySet()) {
>> + result.put(key,jsonObject.get(key));
>> + }
>> + return result;
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/JsonLibTestsGuiceModule.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/
>> JsonLibTestsGuiceModule.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/JsonLibTestsGuiceModule.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/JsonLibTestsGuiceModule.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,40 @@
>> +/*
>> + * 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.social;
>> +
>> +import java.util.ArrayList;
>> +import java.util.HashMap;
>> +import java.util.List;
>> +import java.util.Map;
>> +
>> +import com.google.inject.AbstractModule;
>> +
>> +/**
>> + * Provides social api component injection for all large tests
>> + */
>> +public class JsonLibTestsGuiceModule extends AbstractModule {
>> + @Override
>> + protected void configure() {
>> +
>> + bind(Map.class).to(HashMap.class);
>> + bind(List.class).to(ArrayList.class);
>> + bind(Map[].class).to(HashMap[].class);
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidator.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>> APIValidator.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidator.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidator.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,352 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import java.io.IOException;
>> +import java.io.InputStream;
>> +import java.io.InputStreamReader;
>> +import java.util.ArrayList;
>> +import java.util.HashMap;
>> +import java.util.List;
>> +import java.util.Map;
>> +
>> +import javax.xml.parsers.DocumentBuilder;
>> +import javax.xml.parsers.DocumentBuilderFactory;
>> +import javax.xml.parsers.ParserConfigurationException;
>> +
>> +import org.apache.commons.logging.Log;
>> +import org.apache.commons.logging.LogFactory;
>> +import org.mozilla.javascript.Context;
>> +import org.mozilla.javascript.EvaluatorException;
>> +import org.mozilla.javascript.Script;
>> +import org.mozilla.javascript.ScriptableObject;
>> +import org.w3c.dom.Document;
>> +import org.w3c.dom.NamedNodeMap;
>> +import org.w3c.dom.Node;
>> +import org.w3c.dom.NodeList;
>> +import org.xml.sax.SAXException;
>> +
>> +/**
>> + * A class that loads a feature set from features into a
>> Javascript Parser
>> to
>> + * make the model available to validate JSON messages against.
>> + */
>> +public class APIValidator {
>> +
>> + private static final Log log = LogFactory.getLog
>> (APIValidator.class);
>> + private Context ctx;
>> + private ScriptableObject scope;
>> +
>> + /**
>> + * @param feature
>> + * The name of the feature are eg "opensocial-
>> reference",
>> this
>> + * is a classpath stub (not starting with /)
>> where the
>> location
>> + * contains a feature.xml file.
>> + * @throws SAXException
>> + * if feature.xml is not parsable
>> + * @throws ParserConfigurationException
>> + * if the parsers are invalid
>> + * @throws IOException
>> + * if feature.xml or the javascript that
>> represents the
>> + * feature is missing
>> + *
>> + */
>> + public APIValidator(String feature) throws IOException,
>> + ParserConfigurationException, SAXException {
>> + ctx = Context.enter();
>> + scope = ctx.initStandardObjects();
>> + load(feature);
>> + }
>> +
>> + /**
>> + * @param json
>> + * The json to validate expected in a form
>> { xyz: yyy }
>> form
>> + * @param object
>> + * The json Fields object specifying the
>> structure of the
>> json
>> + * object, each field in this object contains
>> the name of
>> the
>> + * json field in the json structure.
>> + * @param optionalFields
>> + * If any of the fields that appear in the json
>> structure
>> are
>> + * optional, then they should be defined in this
>> parameter.
>> + * @param nullfields
>> + * @throws APIValidatorExpcetion
>> + * if there is a problem validating the json
>> + * @return a map so string object pairs containing the fields
>> at the top
>> level
>> + * of the json tree. Where these are native java
>> objects, they
>> will
>> + * appear as native object. Complex json objects will
>> appear as
>> Rhino
>> + * specific objects
>> + */
>> + public Map<String, Object> validate(String json, String object,
>> + String[] optionalFields, String[] nullfields)
>> + throws APIValidatorExpcetion {
>> +
>> + /*
>> + * Object[] ids = ScriptableObject.getPropertyIds(scope); for
>> (Object
>> id :
>> + * ids) { Object o = ScriptableObject.getProperty(scope,
>> + * String.valueOf(id)); log.debug("ID is " + id + " class " +
>> id.getClass() + "
>> + * is " + o); if (o instanceof ScriptableObject) {
>> + * listScriptable(String.valueOf(id), (ScriptableObject) o); } }
>> + */
>> +
>> + log.debug("Loading " + json);
>> + json = json.trim();
>> + if (!json.endsWith("}")) {
>> + json = json + "}";
>> + }
>> + if (!json.startsWith("{")) {
>> + json = "{" + json;
>> + }
>> + json = "( testingObject = " + json + " )";
>> +
>> + Object so = null;
>> + try {
>> + so = ctx.evaluateString(scope, json, "test json", 0, null);
>> + } catch (EvaluatorException ex) {
>> + log.error("Non parseable JSON " + json);
>> + }
>> + log.debug("Loaded " + so);
>> +
>> + return validateOject(so, object, optionalFields, nullfields);
>> +
>> + }
>> +
>> + /**
>> + * Validate an JSON Object extracted
>> + *
>> + * @param object
>> + * @param string
>> + * @param optional
>> + * @return
>> + * @throws APIValidatorExpcetion
>> + */
>> + public Map<String, Object> validateOject(Object jsonObject, String
>> object,
>> + String[] optionalFields, String[] nullFields)
>> + throws APIValidatorExpcetion {
>> + Map<String, String> optional = new HashMap<String, String>();
>> + for (String opt : optionalFields) {
>> + optional.put(opt, opt);
>> + }
>> + Map<String, String> nullf = new HashMap<String, String>();
>> + for (String nf : nullFields) {
>> + nullf.put(nf, nf);
>> + }
>> +
>> + ScriptableObject specification = getScriptableObject(object);
>> + log.debug("Looking for " + object + " found " + specification);
>> + listScriptable(object, specification);
>> +
>> + Map<String, Object> resultFields = new HashMap<String, Object>
>> ();
>> +
>> + if (jsonObject instanceof ScriptableObject) {
>> + ScriptableObject parsedJSONObject = (ScriptableObject)
>> jsonObject;
>> + listScriptable("testingObject", parsedJSONObject);
>> + Object[] fields = specification.getIds();
>> + for (Object f : fields) {
>> + Object fieldName = specification.get(String.valueOf(f),
>> specification);
>> + Object o = parsedJSONObject.get(String.valueOf(fieldName),
>> + parsedJSONObject);
>> + if (o == ScriptableObject.NOT_FOUND) {
>> + if (optional.containsKey(fieldName)) {
>> + log.warn("Missing Optional Field " + fieldName);
>> + } else if (!nullf.containsKey(fieldName)) {
>> + log.error("Missing Field " + fieldName);
>> + throw new APIValidatorExpcetion("Missing Field " +
>> fieldName);
>> + }
>> + } else {
>> + if (nullf.containsKey(fieldName)) {
>> + log.error("Field should have been null and was not");
>> + }
>> + if (o == null) {
>> + if (nullf.containsKey(fieldName)) {
>> + log.error("Null Fields has been serialized " +
>> fieldName);
>> + }
>> + log.debug("Got a Null object for Field " + f + ":" +
>> fieldName
>> + + " on json [[" + jsonObject + "]]");
>> +
>> + } else {
>> +
>> + log.debug("Got JSON Field Field," + f + ":" +
>> fieldName + "
>> as "
>> + + o + " " + o.getClass());
>> + }
>> + resultFields.put(String.valueOf(fieldName), o);
>> + }
>> + }
>> +
>> + } else {
>> + throw new APIValidatorExpcetion(
>> + "Parsing JSON resulted in invalid Javascript object,
>> which was "
>> + + jsonObject + " JSON was [[" + jsonObject + "]]");
>> + }
>> + return resultFields;
>> + }
>> +
>> + /**
>> + * get an object from the json context and scope.
>> + *
>> + * @param object
>> + * the name of the object specified as a path
>> from the
>> base
>> + * object
>> + * @return the json object
>> + */
>> + private ScriptableObject getScriptableObject(String object) {
>> + String[] path = object.split("\\.");
>> + log.debug("Looking up " + object + " elements " + path.length);
>> +
>> + ScriptableObject s = scope;
>> + for (String pe : path) {
>> + log.debug("Looking up " + pe + " in " + s);
>> + s = (ScriptableObject) s.get(pe, s);
>> + log.debug("Looking for " + pe + " in found " + s);
>> + }
>> + return s;
>> + }
>> +
>> + /**
>> + * List a scriptable object at log debug level, constructors
>> will not be
>> + * expanded as this loads to recursion.
>> + *
>> + * @param id
>> + * The name of the object
>> + * @param scriptableObject
>> + * the scriptable Object
>> + */
>> + private void listScriptable(String id, ScriptableObject
>> scriptableObject) {
>> + log.debug("ID is Scriptable " + id);
>> + if (!id.endsWith("constructor")) {
>> + Object[] allIDs = scriptableObject.getAllIds();
>> + for (Object oid : allIDs) {
>> + log.debug(id + "." + oid);
>> + Object o = scriptableObject.get(String.valueOf(oid),
>> scriptableObject);
>> + if (o instanceof ScriptableObject) {
>> + listScriptable(id + "." + String.valueOf(oid),
>> (ScriptableObject) o);
>> + }
>> + }
>> + }
>> + }
>> +
>> + /**
>> + * Load a feature based on the spec
>> + *
>> + * @param spec
>> + * The name of the location of the spec in the
>> classpath,
>> must
>> + * not start with a '/' and must should contain a
>> feature.xml
>> + * file in the location
>> + * @throws IOException
>> + * If any of the resources cant be found
>> + * @throws ParserConfigurationException
>> + * If the parser has a problem being constructed
>> + * @throws SAXException
>> + * on a parse error on the features.xml
>> + */
>> + private void load(String spec) throws IOException, SAXException,
>> + ParserConfigurationException {
>> +
>> + List<String> scripts = getScripts(spec);
>> +
>> + List<Script> compiled = new ArrayList<Script>();
>> + for (String script : scripts) {
>> + String scriptPath = spec + "/" + script;
>> + InputStream in =
>> this.getClass().getClassLoader().getResourceAsStream(
>> + scriptPath);
>> + if (in == null) {
>> + in = this.getClass().getClassLoader().getResourceAsStream(
>> + "features/" + scriptPath);
>> + if (in == null) {
>> + throw new IOException("Cant load spec " + spec + " or
>> features/"+spec+" from classpath");
>> + }
>> + }
>> + InputStreamReader reader = new InputStreamReader(in);
>> + Script compiledScript = ctx.compileReader(reader, spec, 0,
>> null);
>> + compiled.add(compiledScript);
>> + }
>> +
>> + for (Script compiledScript : compiled) {
>> + compiledScript.exec(ctx, scope);
>> + }
>> +
>> + }
>> +
>> + /**
>> + * Add some javascript to the context, and execute it. If extra
>> custom
>> + * javascript is wanted in the context or scope then this
>> method will
>> load it.
>> + *
>> + * @param javascript
>> + */
>> + public void addScript(String javascript) {
>> + Script compileScript = ctx.compileString(javascript,
>> "AdditionalJS",
>> 0,
>> + null);
>> + compileScript.exec(ctx, scope);
>> + }
>> +
>> + /**
>> + * Get an ordered list of javascript resources from a feature
>> sets.
>> + *
>> + * @param spec
>> + * The spec location
>> + * @return An ordered list of javascript resources, these are
>> relative
>> to
>> + * specification file.
>> + * @throws IOException
>> + * If any of the resources can't be loaded.
>> + * @throws SAXException
>> + * Where the feature.xml file is not parsable
>> + * @throws ParserConfigurationException
>> + * where the parser can't be constructed.
>> + * @return An ordered list of script that need to be loaded and
>> executed
>> to
>> + * make the feature available in the context.
>> + */
>> + private List<String> getScripts(String spec) throws SAXException,
>> + IOException, ParserConfigurationException {
>> + String features = spec + "/feature.xml";
>> + InputStream in = this.getClass().getClassLoader
>> ().getResourceAsStream(
>> + features);
>> + if (in == null) {
>> + in = this.getClass().getClassLoader().getResourceAsStream(
>> + "features/"+features);
>> + if (in == null) {
>> + throw new IOException("Cant find " + features + " or
>> features/" +
>> features+ " in classpath ");
>> + }
>> + }
>> + DocumentBuilderFactory builderFactory = DocumentBuilderFactory
>> + .newInstance();
>> + DocumentBuilder documentBuilder =
>> builderFactory.newDocumentBuilder();
>> + Document doc = documentBuilder.parse(in);
>> + NodeList nl = doc.getElementsByTagName("script");
>> + List<String> scripts = new ArrayList<String>();
>> + for (int i = 0; i < nl.getLength(); i++) {
>> + Node scriptNode = nl.item(i);
>> + NamedNodeMap attributes = scriptNode.getAttributes();
>> + Node scriptAttr = attributes.getNamedItem("src");
>> + String script = scriptAttr.getNodeValue();
>> + scripts.add(script);
>> + }
>> + return scripts;
>> + }
>> +
>> + /**
>> + * @param nameJSON
>> + */
>> + public static void dump(Map<?, ?> nameJSON) {
>> + if (log.isDebugEnabled()) {
>> + for (Object k : nameJSON.keySet()) {
>> + Object o = nameJSON.get(k);
>> + log.info("Key [" + k + "] value:["
>> + + (o == null ? o : o + ":" + o.getClass()) + "]");
>> + }
>> + }
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>> APIValidatorExpcetion.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorExpcetion.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,42 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +/**
>> + * Thrown when there is a validation exception on one of the apis
>> + */
>> +public class APIValidatorExpcetion extends Exception {
>> +
>> + private static final long serialVersionUID =
>> -8969858718669454612L;
>> +
>> + public APIValidatorExpcetion() {
>> + }
>> +
>> + public APIValidatorExpcetion(String message) {
>> + super(message);
>> + }
>> +
>> + public APIValidatorExpcetion(Throwable cause) {
>> + super(cause);
>> + }
>> +
>> + public APIValidatorExpcetion(String message, Throwable cause) {
>> + super(message, cause);
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorTest.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>> APIValidatorTest.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorTest.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/APIValidatorTest.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,89 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +
>> +import java.io.IOException;
>> +import java.util.Map;
>> +
>> +import javax.xml.parsers.ParserConfigurationException;
>> +
>> +import org.junit.Assert;
>> +import org.junit.Test;
>> +import org.xml.sax.SAXException;
>> +
>> +/**
>> + * Test the api validator to make certain it behaves as is expected.
>> + */
>> +public class APIValidatorTest {
>> +
>> + /**
>> + * A definition of the test json used in this unit test.
>> + */
>> + private static final String TEST_DEFINITION =
>> + "var TestDef = {}; TestDef.Field = { FIELD1 : \"json\", FIELD2 :
>> \"xyz\", FIELD3 : \"shouldBeMissing\" };";
>> +
>> + /**
>> + * test the validator for successful validation
>> + * @throws APIValidatorExpcetion
>> + * @throws IOException
>> + * @throws ParserConfigurationException
>> + * @throws SAXException
>> + */
>> + @Test
>> + public void testValidator() throws APIValidatorExpcetion,
>> IOException,
>> ParserConfigurationException, SAXException {
>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>> + apiVal.addScript(TEST_DEFINITION);
>> + String[] optional = {"shouldBeMissing"};
>> + String[] nullfields = {};
>> + Map<String, Object> result = apiVal.validate("{ json: \"A Test
>> JSON\", xyz : 123 }", "TestDef.Field", optional, nullfields );
>> + Assert.assertNotNull(result);
>> + Assert.assertNotNull(result.get("json"));
>> + Assert.assertNotNull(result.get("xyz"));
>> + Assert.assertEquals(String.class,result.get("json").getClass
>> ());
>> + Assert.assertEquals(Integer.class,result.get("xyz").getClass
>> ());
>> + Assert.assertEquals("A Test JSON",result.get("json"));
>> + Assert.assertEquals(123,((Integer)result.get("xyz")).intValue
>> ());
>> +
>> +
>> + }
>> +
>> + /**
>> + * Test for a failing validation
>> + * @throws APIValidatorExpcetion
>> + * @throws IOException
>> + * @throws ParserConfigurationException
>> + * @throws SAXException
>> + */
>> + @Test
>> + public void testValidatorFail() throws APIValidatorExpcetion,
>> IOException, ParserConfigurationException, SAXException {
>> + APIValidator apiVal = new APIValidator("opensocial-reference");
>> + apiVal.addScript(TEST_DEFINITION);
>> + String[] optional = {};
>> + String[] nullfields = {};
>> + try {
>> + apiVal.validate("{ jsonIsMissing: \"A Test JSON\", xyz :
>> 123 }",
>> "TestDef.Field", optional, nullfields );
>> + Assert.fail("Should have Generated an APIValidatorException
>> ");
>> + } catch ( APIValidatorExpcetion ex ) {
>> +
>> + }
>> +
>> +
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>> BeanJsonLibConverterTest.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/BeanJsonLibConverterTest.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,359 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import java.util.ArrayList;
>> +import java.util.List;
>> +import java.util.Map;
>> +
>> +import junit.framework.TestCase;
>> +
>> +import org.apache.commons.logging.Log;
>> +import org.apache.commons.logging.LogFactory;
>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>> +import org.apache.shindig.social.opensocial.model.Activity;
>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>> +import org.apache.shindig.social.opensocial.model.Address;
>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>> +import org.apache.shindig.social.opensocial.model.Email;
>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>> +import org.apache.shindig.social.opensocial.model.Name;
>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>> +import org.apache.shindig.social.opensocial.model.Person;
>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>> +import org.apache.shindig.social.opensocial.model.Phone;
>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>> +
>> +import com.google.common.collect.Lists;
>> +import com.google.common.collect.Maps;
>> +import com.google.inject.Guice;
>> +
>> +public class BeanJsonLibConverterTest extends TestCase {
>> +
>> + private static final Log log = LogFactory
>> + .getLog(BeanJsonLibConverterTest.class);
>> + private Person johnDoe;
>> + private Activity activity;
>> +
>> + private BeanJsonLibConverter beanJsonConverter;
>> + private APIValidator apiValidator;
>> + // set to true to get loging output at info level
>> + private boolean outputInfo = false;
>> +
>> + @Override
>> + public void setUp() throws Exception {
>> + super.setUp();
>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>> PhoneImpl(
>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>> "mobile"),
>> + new PhoneImpl("+33W000000000", "work")));
>> +
>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>> AddressImpl(
>> + "My home address")));
>> +
>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>> + "john.doe@work.bar", "work"),
>> + new EmailImpl("john.doe@home.bar", "home")));
>> +
>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>> +
>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>> MediaItemImpl(
>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>> +
>> + beanJsonConverter = new BeanJsonLibConverter(Guice
>> + .createInjector(new JsonLibTestsGuiceModule()));
>> +
>> + apiValidator = new APIValidator("opensocial-reference");
>> +
>> + }
>> +
>> + public static class SpecialPerson extends PersonImpl {
>> + public static final String[] OPTIONALFIELDS = {};
>> + public static final String[] NULLFIELDS =
>> {"jobInterests","nickname","romance","religion","timeZone",
>> +
>>
>> "relationshipStatus","tags","networkPresence","books","quotes","phone
>> Numbers","languagesSpoken",
>> +
>>
>> "activities","jobs","dateOfBirth","profileVideo","bodyType","urls","s
>> chools","music","addresses",
>> +
>>
>> "livingArrangement","thumbnailUrl","humor","sports","scaredOf","movie
>> s","age","pets","hasApp","turnOffs",
>> +
>>
>> "gender","fashion","drinker","aboutMe","children","sexualOrientation"
>> ,"heroes","profileSong","lookingFor",
>> +
>>
>> "cars","turnOns","tvShows","profileUrl","status","currentLocation","s
>> moker","happiestWhen","ethnicity",
>> +
>>
>> "food","emails","politicalViews","interests","familyName","honorificS
>> uffix","additionalName","honorificPrefix","givenName"};
>> +
>> + private String newfield;
>> +
>> + public SpecialPerson() {
>> + super();
>> + }
>> +
>> + public SpecialPerson(String id, String name, String newfield) {
>> + super(id, new NameImpl(name));
>> + this.newfield = newfield;
>> + }
>> +
>> + public String getNewfield() {
>> + return newfield;
>> + }
>> +
>> + public void setNewfield(String newfield) {
>> + this.newfield = newfield;
>> + }
>> +
>> + }
>> +
>> + public void testToJsonOnInheritedClass() throws Exception {
>> + SpecialPerson cassie = new SpecialPerson("5", "robot",
>> "nonsense");
>> +
>> + String result = beanJsonConverter.convertToString(cassie);
>> +
>> + validatePerson(result, "5", "robot",
>> SpecialPerson.OPTIONALFIELDS,
>> SpecialPerson.NULLFIELDS);
>> +
>> + apiValidator.addScript(" specialPerson = { SPECIAL :
>> \"newfield\" };
>> ");
>> + String[] optional = {};
>> + String[] nullfields = {};
>> + Map<String, Object> special = apiValidator.validate(result,
>> + "specialPerson", optional,nullfields);
>> + assertNotNull(special.get("newfield"));
>> + assertEquals(String.class, special.get("newfield").getClass());
>> + assertEquals("nonsense", special.get("newfield"));
>> +
>> + // convert back into an object Tree
>> +
>> + SpecialPerson parseCassie = beanJsonConverter.convertToObject
>> (result,
>> + SpecialPerson.class);
>> +
>> + assertNotNull(parseCassie);
>> + assertEquals(cassie.getId(), parseCassie.getId());
>> + assertEquals(cassie.getNewfield(), parseCassie.getNewfield());
>> +
>> + Name name = parseCassie.getName();
>> + Name cassieName = cassie.getName();
>> + assertNotNull(name);
>> + assertEquals(cassieName.getUnstructured(),
>> name.getUnstructured());
>> + assertEquals(cassieName.getAdditionalName(),
>> name.getAdditionalName());
>> + assertEquals(cassieName.getFamilyName(), name.getFamilyName());
>> + assertEquals(cassieName.getGivenName(), name.getGivenName());
>> + assertEquals(cassieName.getHonorificPrefix(),
>> name.getHonorificPrefix());
>> + assertEquals(cassieName.getHonorificSuffix(),
>> name.getHonorificSuffix());
>> +
>> + }
>> +
>> + /**
>> + * @param result
>> + * @throws APIValidatorExpcetion
>> + */
>> + private void validatePerson(String result, String id, String name,
>> String[] optional, String[] nullfields)
>> + throws APIValidatorExpcetion {
>> +
>> + Map<String, Object> standard = apiValidator.validate(result,
>> + "opensocial.Person.Field", optional,nullfields);
>> + assertNotNull(standard.get("id"));
>> + assertEquals(String.class, standard.get("id").getClass());
>> + assertEquals(id, standard.get("id"));
>> +
>> + assertNotNull(standard.get("name"));
>> + Map<String, Object> nameJSON = apiValidator.validateOject
>> (standard
>> + .get("name"), "opensocial.Name.Field", optional,nullfields);
>> + APIValidator.dump(nameJSON);
>> +
>> + assertNotNull(nameJSON.get("unstructured"));
>> + assertEquals(String.class, nameJSON.get
>> ("unstructured").getClass());
>> + assertEquals(name, nameJSON.get("unstructured"));
>> +
>> + // additional name
>> + assertNull(nameJSON.get("additionalName"));
>> +
>> + }
>> +
>> + public void testPersonToJson() throws Exception {
>> + String result = beanJsonConverter.convertToString(johnDoe);
>> + if (outputInfo) {
>> + log.info("JSON (" + result + ")");
>> + }
>> + Person parsedPerson = beanJsonConverter.convertToObject(result,
>> + Person.class);
>> +
>> + assertEquals(johnDoe.getId(), parsedPerson.getId());
>> + assertEquals(johnDoe.getName().getUnstructured(),
>> parsedPerson.getName()
>> + .getUnstructured());
>> +
>> + List<Address> addresses = parsedPerson.getAddresses();
>> + if (outputInfo) {
>> + for (Object o : addresses) {
>> + log.info("Address " + o);
>> + }
>> + }
>> +
>> + assertEquals(1, addresses.size());
>> + Address address = addresses.get(0);
>> + String unstructured = address.getUnstructuredAddress();
>> +
>> + assertNotNull(unstructured);
>> + assertEquals(johnDoe.getAddresses().get
>> (0).getUnstructuredAddress(),
>> + parsedPerson.getAddresses().get(0).getUnstructuredAddress
>> ());
>> +
>> + assertEquals(3, parsedPerson.getPhoneNumbers().size());
>> +
>> + for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) {
>> + Phone expectedPhone = johnDoe.getPhoneNumbers().get(i);
>> + Phone actualPhone = parsedPerson.getPhoneNumbers().get(i);
>> + assertEquals(expectedPhone.getType(), actualPhone.getType());
>> + assertEquals(expectedPhone.getNumber(),
>> actualPhone.getNumber());
>> + }
>> +
>> + assertEquals(2, parsedPerson.getEmails().size());
>> +
>> + for (int i = 0; i < johnDoe.getEmails().size(); i++) {
>> + Email expectedEmail = johnDoe.getEmails().get(i);
>> + Email actualEmail = parsedPerson.getEmails().get(i);
>> + assertEquals(expectedEmail.getType(), actualEmail.getType());
>> + assertEquals(expectedEmail.getAddress(),
>> actualEmail.getAddress());
>> + }
>> + }
>> +
>> + public void testActivityToJson() throws Exception {
>> +
>> + String result = beanJsonConverter.convertToString(activity);
>> + if (outputInfo) {
>> + log.info("JSON (" + result + ")");
>> + }
>> + Activity parsedActivity = beanJsonConverter.convertToObject
>> (result,
>> + Activity.class);
>> + assertEquals(activity.getUserId(), parsedActivity.getUserId());
>> + assertEquals(activity.getId(), parsedActivity.getId());
>> +
>> + assertEquals(1, parsedActivity.getMediaItems().size());
>> +
>> + MediaItem expectedItem = activity.getMediaItems().get(0);
>> + MediaItem actualItem = parsedActivity.getMediaItems().get(0);
>> +
>> + assertEquals(expectedItem.getUrl(), actualItem.getUrl());
>> + assertEquals(expectedItem.getMimeType(),
>> actualItem.getMimeType());
>> + assertEquals(expectedItem.getType().toString(),
>> actualItem.getType()
>> + .toString());
>> + }
>> +
>> + public void testMapsToJson() throws Exception {
>> + Map<String, Map<String, String>> map = Maps.newHashMap();
>> +
>> + Map<String, String> item1Map = Maps.newHashMap();
>> + item1Map.put("value", "1");
>> +
>> + // Null values shouldn't cause exceptions
>> + item1Map.put("value2", null);
>> + map.put("item1", item1Map);
>> +
>> + Map<String, String> item2Map = Maps.newHashMap();
>> + item2Map.put("value", "2");
>> + map.put("item2", item2Map);
>> +
>> + String result = beanJsonConverter.convertToString(map);
>> + if (outputInfo) {
>> + log.info("JSON (" + result + ")");
>> + }
>> + // there is introspection that can tell jsonobject -> bean
>> converter
>> what a
>> + // map should contain, so we have to tell it
>> + beanJsonConverter.addMapping("item1", Map.class);
>> + beanJsonConverter.addMapping("item2", Map.class);
>> + Map<?, ?> parsedMap = beanJsonConverter
>> + .convertToObject(result, Map.class);
>> +
>> + if (outputInfo) {
>> + log.info("Dumping Map (" + parsedMap + ")");
>> + }
>> + APIValidator.dump(parsedMap);
>> +
>> + assertEquals("1", ((Map<?,?>)parsedMap.get("item1")).get
>> ("value"));
>> + assertEquals("2", ((Map<?,?>)parsedMap.get("item2")).get
>> ("value"));
>> + }
>> +
>> + public void testListsToJson() throws Exception {
>> + Map<String, String> item1Map = Maps.newHashMap();
>> + item1Map.put("value", "1");
>> +
>> + Map<String, String> item2Map = Maps.newHashMap();
>> + item2Map.put("value", "2");
>> +
>> + // put the list into a container before serializing, top
>> level lists
>> dont
>> + // appear
>> + // to be allowed in json
>> + // just check that the list is in the holder correctly
>> + List<Map<String, String>> list = new ArrayList<Map<String,
>> String>>();
>> + list.add(item1Map);
>> + list.add(item2Map);
>> + String result = beanJsonConverter.convertToString(list);
>> + if (outputInfo) {
>> + log.info("JSON (" + result + ")");
>> + }
>> + Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(
>> + result, Map[].class);
>> +
>> + assertEquals("1", parsedList[0].get("value"));
>> + assertEquals("2", parsedList[1].get("value"));
>> + }
>> +
>> + public void testArrayToJson() throws Exception {
>> + String[] colors = { "blue", "green", "aquamarine" };
>> + String result = beanJsonConverter.convertToString(colors);
>> + if (outputInfo) {
>> + log.info("JSON (" + result + ")");
>> + }
>> + String[] parsedColors = beanJsonConverter.convertToObject
>> (result,
>> + String[].class);
>> + assertEquals(colors.length, parsedColors.length);
>> + assertEquals(colors[0], parsedColors[0]);
>> + assertEquals(colors[1], parsedColors[1]);
>> + assertEquals(colors[2], parsedColors[2]);
>> + }
>> +
>> + public void testJsonToActivity() throws Exception {
>> + String jsonActivity = "{userId : 5, id : 6, mediaItems : ["
>> + + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}" +
>> "]}";
>> + Activity result = beanJsonConverter.convertToObject
>> (jsonActivity,
>> + Activity.class);
>> +
>> + assertEquals("5", result.getUserId());
>> + assertEquals("6", result.getId());
>> +
>> + assertEquals(1, result.getMediaItems().size());
>> +
>> + MediaItem actualItem = result.getMediaItems().get(0);
>> +
>> + assertEquals("hello", actualItem.getUrl());
>> + assertEquals("mimey", actualItem.getMimeType());
>> + assertEquals("video", actualItem.getType().toString());
>> + }
>> +
>> + public void testJsonToMap() throws Exception {
>> + String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
>> + Map<String, String> data = Maps.newHashMap();
>> + data = beanJsonConverter.convertToObject(jsonActivity,
>> + (Class<Map<String, String>>) data.getClass());
>> +
>> + assertEquals(2, data.size());
>> +
>> + for (String key : data.keySet()) {
>> + Object value = data.get(key);
>> + if (key.equals("count")) {
>> + assertEquals(0, value);
>> + } else if (key.equals("favoriteColor")) {
>> + assertEquals("yellow", value);
>> + }
>> + }
>> + }
>> +
>> +}
>>
>> Added:
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-
>> api/src/test/java/org/apache/shindig/social/opensocial/util/
>> JsonConverterPerformancePerf.java?rev=678158&view=auto
>>
>> =====================================================================
>> =========
>> ---
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>> (added)
>> +++
>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/
>> shindig/social/opensocial/util/JsonConverterPerformancePerf.java
>> Sat Jul 19 06:51:03 2008
>> @@ -0,0 +1,271 @@
>> +/*
>> + * 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.social.opensocial.util;
>> +
>> +import junit.framework.TestCase;
>> +
>> +import org.apache.commons.logging.Log;
>> +import org.apache.commons.logging.LogFactory;
>> +import org.apache.shindig.social.JsonLibTestsGuiceModule;
>> +import org.apache.shindig.social.SocialApiTestsGuiceModule;
>> +import org.apache.shindig.social.opensocial.model.Activity;
>> +import org.apache.shindig.social.opensocial.model.ActivityImpl;
>> +import org.apache.shindig.social.opensocial.model.Address;
>> +import org.apache.shindig.social.opensocial.model.AddressImpl;
>> +import org.apache.shindig.social.opensocial.model.Email;
>> +import org.apache.shindig.social.opensocial.model.EmailImpl;
>> +import org.apache.shindig.social.opensocial.model.MediaItem;
>> +import org.apache.shindig.social.opensocial.model.MediaItemImpl;
>> +import org.apache.shindig.social.opensocial.model.NameImpl;
>> +import org.apache.shindig.social.opensocial.model.Person;
>> +import org.apache.shindig.social.opensocial.model.PersonImpl;
>> +import org.apache.shindig.social.opensocial.model.Phone;
>> +import org.apache.shindig.social.opensocial.model.PhoneImpl;
>> +import org.json.JSONObject;
>> +
>> +import com.google.common.collect.Lists;
>> +import com.google.inject.Guice;
>> +
>> +public class JsonConverterPerformancePerf extends TestCase {
>> +
>> + private static final Log log = LogFactory
>> + .getLog(JsonConverterPerformancePerf.class);
>> + private static final int TEST_SIZE = 10000;
>> + private Person johnDoe;
>> + private Activity activity;
>> +
>> + private BeanJsonLibConverter beanJsonLibConverter;
>> + private APIValidator apiValidator;
>> + // set to true to get loging output at info level
>> + private boolean outputInfo = false;
>> + private BeanJsonConverter beanJsonConverter;
>> +
>> + @Override
>> + public void setUp() throws Exception {
>> + super.setUp();
>> + johnDoe = new PersonImpl("johnDoeId", new NameImpl("John Doe"));
>> + johnDoe.setPhoneNumbers(Lists.<Phone> newArrayList(new
>> PhoneImpl(
>> + "+33H000000000", "home"), new PhoneImpl("+33M000000000",
>> "mobile"),
>> + new PhoneImpl("+33W000000000", "work")));
>> +
>> + johnDoe.setAddresses(Lists.<Address> newArrayList(new
>> AddressImpl(
>> + "My home address")));
>> +
>> + johnDoe.setEmails(Lists.<Email> newArrayList(new EmailImpl(
>> + "john.doe@work.bar", "work"),
>> + new EmailImpl("john.doe@home.bar", "home")));
>> +
>> + activity = new ActivityImpl("activityId", johnDoe.getId());
>> +
>> + activity.setMediaItems(Lists.<MediaItem> newArrayList(new
>> MediaItemImpl(
>> + "image/jpg", MediaItem.Type.IMAGE, "http://foo.bar")));
>> +
>> + beanJsonLibConverter = new BeanJsonLibConverter(Guice
>> + .createInjector(new JsonLibTestsGuiceModule()));
>> +
>> + beanJsonConverter = new BeanJsonConverter(Guice
>> + .createInjector(new SocialApiTestsGuiceModule()));
>> +
>> + apiValidator = new APIValidator("opensocial-reference");
>> +
>> + }
>> +
>> + public static class SpecialPerson extends PersonImpl {
>> + private String newfield;
>> +
>> + public SpecialPerson() {
>> + super();
>> + }
>> +
>> + public SpecialPerson(String id, String name, String newfield) {
>> + super(id, new NameImpl(name));
>> + this.newfield = newfield;
>> + }
>> +
>> + public String getNewfield() {
>> + return newfield;
>> + }
>> +
>> + public void setNewfield(String newfield) {
>> + this.newfield = newfield;
>> + }
>> +
>> + }
>> +
>> + public void testToJsonLibOnInheritedClassOutput() throws
>> Exception {
>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>> "nonsense");
>> + }
>> + Runtime r = Runtime.getRuntime();
>> + r.gc();
>> + long memstart = r.totalMemory()-r.freeMemory();
>> + long startOutput = System.currentTimeMillis();
>> + String[] output = new String[TEST_SIZE];
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + output[i] = beanJsonLibConverter.convertToString(spa[i]);
>> + }
>> + long endOutput = System.currentTimeMillis();
>> + long memend = r.totalMemory()-r.freeMemory();
>> +
>> + String[] serializeOutput = new String[TEST_SIZE];
>> + char[] source = output[0].toCharArray();
>> + r.gc();
>> +
>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + serializeOutput[i] = new String(source);
>> + }
>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>> +
>> + /*
>> + * Output the time per conversion and the memory usage - the
>> output
>> per
>> + * conversion.
>> + *
>> + */
>> +
>> + log.info("SF JSON Lib Output "
>> + + average(startOutput, endOutput, TEST_SIZE)
>> + + " ms/conversion, "
>> + + (average(memstart, memend, TEST_SIZE)-average
>> (stringsizeStart,
>> stringsizeEnd, TEST_SIZE))
>> + + " heap bytes/conversion, output packet consumed on
>> average "
>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
>> string length of "+output[0].length());
>> + log.info("Output Was ["+output[0]+"]");
>> + }
>> +
>> + public void testToJsonLibOnInheritedClassInput() throws
>> Exception {
>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>> + Runtime r = Runtime.getRuntime();
>> + r.gc();
>> + long personStart = r.totalMemory()-r.freeMemory();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>> "nonsense");
>> + }
>> + long personEnd = r.totalMemory()-r.freeMemory();
>> +
>> + String[] serializeOutput = new String[TEST_SIZE];
>> + r.gc();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> +
>> + serializeOutput[i] = beanJsonLibConverter.convertToString
>> (spa[i]);
>> + }
>> +
>> + r.gc();
>> + long memstart = r.totalMemory()-r.freeMemory();
>> + long startInput = System.currentTimeMillis();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + sparesult[i] = beanJsonLibConverter.convertToObject(
>> + serializeOutput[i], SpecialPerson.class);
>> + }
>> + long endInput = System.currentTimeMillis();
>> + long memend = r.totalMemory()-r.freeMemory();
>> +
>> + log.info("SF JSON Lib Input "
>> + + average(startInput, endInput, TEST_SIZE)
>> + + " ms/conversion, "
>> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
>> personEnd, TEST_SIZE))
>> + + " heap bytes/conversion, person object consumed on
>> average "
>> + + average(personStart, personEnd, TEST_SIZE));
>> + }
>> +
>> + public void testToJsonOnInheritedClassOutput() throws Exception {
>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>> "nonsense");
>> + }
>> + Runtime r = Runtime.getRuntime();
>> + String[] output = new String[TEST_SIZE];
>> + r.gc();
>> + long memstart = r.totalMemory()-r.freeMemory();
>> + long startOutput = System.currentTimeMillis();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + output[i] = ((JSONObject)
>> beanJsonConverter.convertToJson(spa[i])).toString();
>> + }
>> + long endOutput = System.currentTimeMillis();
>> + long memend = r.totalMemory()-r.freeMemory();
>> + String[] serializeOutput = new String[TEST_SIZE];
>> + char[] source = output[0].toCharArray();
>> + r.gc();
>> +
>> + long stringsizeStart = r.totalMemory()-r.freeMemory();
>> +
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + serializeOutput[i] = new String(source);
>> + }
>> + long stringsizeEnd = r.totalMemory()-r.freeMemory();
>> +
>> + log.info("ORG JSON Lib Output "
>> + + average(startOutput, endOutput, TEST_SIZE)
>> + + " ms/conversion, "
>> + + (average(memstart, memend, TEST_SIZE)-average
>> (stringsizeStart,
>> stringsizeEnd, TEST_SIZE))
>> + + " heap bytes/conversion, output packet consumed on
>> average "
>> + + average(stringsizeStart, stringsizeEnd, TEST_SIZE)+" for a
>> string length of "+output[0].length());
>> + log.info("Output Was ["+output[0]+"]");
>> + }
>> +
>> + /**
>> + * @param endOutput
>> + * @param startOutput
>> + * @param testSize
>> + * @return
>> + */
>> + private float average(long start, long end, int testSize) {
>> + float r = end - start;
>> + r = r / testSize;
>> + return r;
>> + }
>> +
>> + public void XtestToJsonOnInheritedClassInput() throws Exception {
>> + SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
>> + SpecialPerson[] sparesult = new SpecialPerson[TEST_SIZE];
>> + Runtime r = Runtime.getRuntime();
>> + r.gc();
>> + long personStart = r.totalMemory()-r.freeMemory();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + spa[i] = new SpecialPerson(String.valueOf(i), "robot",
>> "nonsense");
>> + }
>> + long personEnd = r.totalMemory()-r.freeMemory();
>> +
>> + String[] serializeOutput = new String[TEST_SIZE];
>> + r.gc();
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> +
>> + serializeOutput[i] = beanJsonConverter.convertToString(spa
>> [i]);
>> + }
>> +
>> + r.gc();
>> + long memstart = r.totalMemory()-r.freeMemory();
>> + long startInput = System.currentTimeMillis();
>> +
>> + for (int i = 0; i < TEST_SIZE; i++) {
>> + sparesult[i] = beanJsonConverter.convertToObject(
>> + serializeOutput[i], SpecialPerson.class);
>> + }
>> + long endInput = System.currentTimeMillis();
>> + long memend = r.totalMemory()-r.freeMemory();
>> +
>> + log.info("SF JSON Lib Input "
>> + + average(startInput, endInput, TEST_SIZE)
>> + + " ms/conversion, "
>> + + (average(memstart, memend, TEST_SIZE)-average(personStart,
>> personEnd, TEST_SIZE))
>> + + " heap bytes/conversion, person object consumed on
>> average "
>> + + average(personStart, personEnd, TEST_SIZE));
>> + }
>> +
>> +}
>>
>> Modified: incubator/shindig/trunk/pom.xml
>> URL:
>> http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?
>> rev=678158&r1=678157&r2=678158&view=diff
>>
>> =====================================================================
>> =========
>> --- incubator/shindig/trunk/pom.xml (original)
>> +++ incubator/shindig/trunk/pom.xml Sat Jul 19 06:51:03 2008
>> @@ -853,6 +853,16 @@
>> <artifactId>htmlunit</artifactId>
>> <version>2.1</version>
>> </dependency>
>> + <dependency>
>> + <groupId>log4j</groupId>
>> + <artifactId>log4j</artifactId>
>> + <version>1.2.13</version>
>> + </dependency>
>> + <dependency>
>> + <groupId>rhino</groupId>
>> + <artifactId>js</artifactId>
>> + <version>1.6R7</version>
>> + </dependency>
>> </dependencies>
>> </dependencyManagement>
>> </project>
>>
>>
>>