You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2007/09/01 07:00:11 UTC

svn commit: r571688 - in /incubator/abdera/java/trunk: build/ core/src/main/java/org/apache/abdera/converter/ core/src/main/java/org/apache/abdera/converter/annotation/ core/src/main/java/org/apache/abdera/util/ core/src/test/java/org/apache/abdera/tes...

Author: jmsnell
Date: Fri Aug 31 22:00:10 2007
New Revision: 571688

URL: http://svn.apache.org/viewvc?rev=571688&view=rev
Log:
Initial... and experimental... attempt at a core Converter API.  A Converter takes one kind of object and converts it
into another kind of object, e.g. a Java Bean into an Abdera
Entry.

I am working on a default converter implementation that uses
conventions and annotations to convert a pojo model to Atom.
Other converters can be plugged in.

Did I mention that this is still experimental?

Added:
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/AbstractConversionContext.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionContext.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionException.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/Converter.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConverterProvider.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/DefaultConversionContext.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ObjectContext.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/Converter.java
    incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/ConversionTest.java
    incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/FooConverterProvider.java
    incubator/abdera/java/trunk/core/src/test/resources/
    incubator/abdera/java/trunk/core/src/test/resources/META-INF/
    incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/
    incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/org.apache.abdera.converter.ConverterProvider
Modified:
    incubator/abdera/java/trunk/build/build.xml
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbderaConfiguration.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/ServiceUtil.java
    incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/TestSuite.java

Modified: incubator/abdera/java/trunk/build/build.xml
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/build/build.xml?rev=571688&r1=571687&r2=571688&view=diff
==============================================================================
--- incubator/abdera/java/trunk/build/build.xml (original)
+++ incubator/abdera/java/trunk/build/build.xml Fri Aug 31 22:00:10 2007
@@ -41,6 +41,7 @@
   <property name="core.src" value="${core}/src/main/java" />
   <property name="core.resources" value="${core}/src/main/resources" />
   <property name="core.test" value="${core}/src/test/java" />
+  <property name="core.test.resources" value="${core}/src/test/resources" />
   <property name="core.work" value="${work}/core" />
   <property name="core.jar" value="${dist}/${ant.project.name}.core.${version}.jar" />
   <property name="protocol" value="${basedir}/protocol" />
@@ -235,6 +236,11 @@
     <mkdir dir="${core.work}/META-INF" />
     <copy todir="${core.work}">
       <fileset dir="${core.resources}" includes="**/*" />
+    </copy>
+    <copy todir="${test}">
+      <fileset dir="${core.test.resources}">
+        <include name="**" />
+      </fileset>
     </copy>
     <copy todir="${core.work}/META-INF">
       <fileset dir="${basedir}">

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/AbstractConversionContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/AbstractConversionContext.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/AbstractConversionContext.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/AbstractConversionContext.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,124 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractConversionContext
+  implements ConversionContext {
+
+  private transient final Abdera abdera;
+  private final Map<Class,Converter> converters = 
+    new HashMap<Class,Converter>();
+  
+  protected AbstractConversionContext() {
+    this(new Abdera());
+  }
+  
+  protected AbstractConversionContext(Abdera abdera) {
+    this.abdera = abdera;
+  }
+  
+  public Abdera getAbdera() {
+    return abdera;
+  }
+  
+  public <T> Converter<T> getConverter(ObjectContext objectContext) {
+    try {
+      Class type = objectContext.getObjectType();
+      Converter<T> converter = converters.get(type);
+      if (converter == null) converter = objectContext.getConverter();
+      if (converter == null) {
+        for (Annotation annotation : objectContext.getAnnotations()) {
+          converter = converters.get(annotation.annotationType());
+          if (converter != null) return converter;
+        }
+      }
+      if (converter == null && !type.isAnnotation()) {
+        for (Class knownType : converters.keySet()) {
+          if (knownType.isAssignableFrom(type)) {
+            return converters.get(knownType);
+          }
+        }
+      }
+      return converter;
+    } catch (Throwable t) {
+      throw new ConversionException(t);
+    }
+  }
+
+  public boolean hasConverter(ObjectContext objectContext) {
+    return getConverter(objectContext) != null;
+  }
+
+  public void setConverter(Class<?> type, Converter<?> converter) {
+    converters.put(type, converter);
+  }
+
+  public <T> T convert(Object object) {
+    return convert(object,new ObjectContext(object));
+  }
+
+  public <T> T convert(Object object, ObjectContext objectContext) {
+    if (objectContext == null) objectContext = new ObjectContext(object);
+    Converter<T> converter = getConverter(objectContext);
+    if (converter != null)
+      return convert(object,objectContext,converter);
+    else 
+      throw new ConversionException(
+        "No converter available for " + 
+        objectContext.getObjectType());
+  }
+
+  public <T> T convert(Object object, Converter<T> converter) {
+    return convert(object,new ObjectContext(object),converter);
+  }
+
+  public <T> T convert(
+    Object object, 
+    ObjectContext objectContext, 
+    Converter<T> converter) {
+      if (objectContext == null) objectContext = new ObjectContext(object);
+      Converter<T> overrideConverter = getConverter(objectContext);
+      if (overrideConverter != null) converter = overrideConverter;
+      if (converter != null) {
+        return converter.convert(object, objectContext, this);
+      } else {
+        throw new ConversionException(
+          "No converter available for " + 
+          objectContext.getObjectType());
+      }
+  }
+  
+  public Object clone() {
+    try {
+      return super.clone();
+    } catch (CloneNotSupportedException e) {
+      return copy();
+    }
+  }
+  
+  protected Object copy() {
+    return new RuntimeException(new CloneNotSupportedException());
+  }
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionContext.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionContext.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionContext.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,66 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+import java.io.Serializable;
+
+import org.apache.abdera.Abdera;
+
+public interface ConversionContext
+  extends Cloneable, 
+          Serializable {
+
+  Abdera getAbdera();
+  
+  /**
+   * Convert using the appropriate detected converter
+   */
+  <T>T convert(Object object);
+  
+  /**
+   * Convert using the appropriate detected converter
+   */
+  <T>T convert(Object object, ObjectContext objectContext);
+  
+  /**
+   * Convert using the specified converter
+   */
+  <T>T convert(Object object, Converter<T> converter);
+  
+  /**
+   * Convert using the specified converter
+   */
+  <T>T convert(Object object, ObjectContext objectContext, Converter<T> converter);
+  
+  /**
+   * Specify the appropriate converter for the given object or annotation type
+   */
+  void setConverter(Class<?> type, Converter<?> converter);
+  
+  /**
+   * Get the appropriate converter for the given object or annotation type
+   */
+  <T>Converter<T> getConverter(ObjectContext objectContext);
+  
+  /**
+   * True if a converter for the specified object or annotation type has been set
+   */
+  boolean hasConverter(ObjectContext objectContext);
+
+  Object clone();
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionException.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionException.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionException.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConversionException.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+public class ConversionException
+    extends RuntimeException {
+
+  private static final long serialVersionUID = 3399703987771955406L;
+
+  public ConversionException() {
+    super();
+  }
+
+  public ConversionException(
+    String message, 
+    Throwable cause) {
+      super(message, cause);
+  }
+
+  public ConversionException(
+    String message) {
+      super(message);
+  }
+
+  public ConversionException(
+    Throwable cause) {
+      super(cause);
+  }
+  
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/Converter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/Converter.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/Converter.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/Converter.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,36 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+public abstract class Converter<T> {
+
+  public T convert(
+    Object source, 
+    ConversionContext context) {
+      return convert(
+        source, 
+        new ObjectContext(source), 
+        context);
+  }
+  
+  public abstract T convert(
+    Object source,
+    ObjectContext objectContext,
+    ConversionContext context);
+  
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConverterProvider.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConverterProvider.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConverterProvider.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ConverterProvider.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,41 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public abstract class ConverterProvider 
+  implements Iterable<Map.Entry<Class<?>,Converter<?>>>{
+
+  protected Map<Class<?>,Converter<?>> converters = 
+    new HashMap<Class<?>,Converter<?>>();
+  
+  protected void setConverter(
+    Class<?> type, 
+    Converter<?> converter) {
+      converters.put(type, converter);
+  }
+
+  public Iterator<Entry<Class<?>, Converter<?>>> iterator() {
+    return converters.entrySet().iterator();
+  }
+  
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/DefaultConversionContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/DefaultConversionContext.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/DefaultConversionContext.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/DefaultConversionContext.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,50 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+
+public class DefaultConversionContext 
+  extends AbstractConversionContext {
+
+  private static final long serialVersionUID = 740460842415905883L;
+
+  public DefaultConversionContext() {
+    super();   
+    initConverters();
+  }
+  
+  public DefaultConversionContext(Abdera abdera) {
+    super(abdera);
+    initConverters();
+  }
+  
+  private void initConverters() {
+    List<ConverterProvider> providers = 
+      getAbdera().getConfiguration().getConverterProviders();
+    for (ConverterProvider provider : providers) {
+      for (Map.Entry<Class<?>,Converter<?>> entry : provider) {
+        setConverter(entry.getKey(), entry.getValue());
+      }
+    }
+  }
+  
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ObjectContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ObjectContext.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ObjectContext.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/ObjectContext.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,164 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@SuppressWarnings("unchecked")
+public class ObjectContext {
+
+  private final Class objectType;
+  private final Object parent;
+  private final AccessibleObject accessor;
+  private final Annotation[] annotations;
+  private final Converter<?> converter;
+  private final Field[] fields;
+  private final Method[] methods;
+  
+  public ObjectContext(Object object) {
+    this(object,null,null);
+  }
+  
+  public ObjectContext(
+    Object object, 
+    Object parent, 
+    AccessibleObject accessor) {
+      this.objectType = object != null ? object.getClass() : null;
+      this.parent = parent;
+      this.accessor = accessor;
+      this.annotations = initAnnotations();
+      this.converter = initConverter();
+      this.fields = initFields();
+      this.methods = initMethods();
+  }
+  
+  private Field[] initFields() {
+    Field[] fields = objectType.getFields();
+    List<Field> list = new ArrayList<Field>();
+    for (Field field : fields) {
+      int mods = field.getModifiers();
+      // ignore static fields
+      if (!Modifier.isStatic(mods)) {
+        list.add(field);
+      }
+    }
+    return list.toArray(new Field[list.size()]);
+  }
+  
+  private Method[] initMethods() {
+    Method[] methods = objectType.getMethods();
+    List<Method> list = new ArrayList<Method>();
+    for (Method method : methods) {
+      // only methods that have no parameters, return a value, are not
+      // abstract and are not static
+      int mods = method.getModifiers();
+      if (!Modifier.isStatic(mods) &&
+          !Modifier.isAbstract(mods) && 
+          method.getParameterTypes().length == 0 && 
+          method.getReturnType() != Void.class) {
+        list.add(method);
+      }
+    }
+    return list.toArray(new Method[list.size()]);
+  }
+  
+  private Annotation[] initAnnotations() {
+    Map<Class<? extends Annotation>, Annotation> annotations = new 
+    HashMap<Class<? extends Annotation>, Annotation>();
+    if (objectType != null) {
+      for (Annotation annotation : objectType.getAnnotations()) {
+        annotations.put(annotation.annotationType(),annotation);
+      }
+    }
+    if (accessor != null) {
+      for (Annotation annotation : accessor.getAnnotations()) {
+        annotations.put(annotation.annotationType(), annotation);
+      }
+    }
+    return annotations.values().toArray(new Annotation[annotations.size()]);
+  }
+  
+  private Converter initConverter() {
+    try {
+      org.apache.abdera.converter.annotation.Converter conv = 
+        getAnnotation(
+          org.apache.abdera.converter.annotation.Converter.class);
+      if (conv != null) {
+        Class<? extends Converter> convclass = conv.value();
+        return convclass.newInstance();
+      }
+      return null;
+    } catch (Throwable t) {
+      throw new ConversionException(t);
+    }
+  }
+  
+  public AccessibleObject getAccessor() {
+    return accessor;
+  }
+  
+  public Object getParent() {
+    return parent;
+  }
+  
+  public Class getObjectType() {
+    return objectType;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public <X extends Annotation>X getAnnotation(
+    Class<X> annotationType) {
+      for (Annotation annotation : annotations) {
+        if (annotation.annotationType() == annotationType)
+          return (X)annotation;
+      }
+      return null;
+  }
+  
+  public Annotation[] getAnnotations() {
+    return annotations;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public <X>Converter<X> getConverter() {
+    return (Converter<X>) converter;
+  }
+  
+  public Field[] getFields() {
+    return fields;
+  }
+  
+  public Method[] getMethods() {
+    return methods;
+  }
+  
+  public AccessibleObject[] getAccessors() {
+    List<AccessibleObject> list = new ArrayList<AccessibleObject>();
+    for (Method method : methods) list.add(method);
+    for (Field field : fields) list.add(field);
+    return list.toArray(new AccessibleObject[list.size()]);
+  }
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/Converter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/Converter.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/Converter.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/converter/annotation/Converter.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,32 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.converter.annotation;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target({TYPE,METHOD,FIELD})
+public @interface Converter {
+  Class<? extends org.apache.abdera.converter.Converter<?>> value();
+}

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbderaConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbderaConfiguration.java?rev=571688&r1=571687&r2=571688&view=diff
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbderaConfiguration.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/AbderaConfiguration.java Fri Aug 31 22:00:10 2007
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.ResourceBundle;
 
+import org.apache.abdera.converter.ConverterProvider;
 import org.apache.abdera.factory.ExtensionFactory;
 import org.apache.abdera.parser.NamedParser;
 import org.apache.abdera.writer.NamedWriter;
@@ -74,6 +75,7 @@
   private final String writerFactory;
   private final String writer;
   private final List<ExtensionFactory> factories;
+  private final List<ConverterProvider> providers;
   private final Map<String,NamedWriter> writers;
   private final Map<String,NamedParser> parsers;
   
@@ -93,6 +95,7 @@
     writerFactory = getConfigurationOption(CONFIG_WRITERFACTORY, DEFAULT_WRITERFACTORY);
     writer = getConfigurationOption(CONFIG_WRITER, DEFAULT_WRITER);
     factories = ServiceUtil.loadExtensionFactories();
+    providers = ServiceUtil.loadConverterProviders();
     writers = initNamedWriters();
     parsers = initNamedParsers();
   }  
@@ -184,6 +187,13 @@
    */
   public List<ExtensionFactory> getExtensionFactories() {
     return factories;
+  }
+  
+  /**
+   * Returns the listing of registered ConverterProvider implementations
+   */
+  public List<ConverterProvider> getConverterProviders() {
+    return providers;
   }
   
   /**

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/ServiceUtil.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/ServiceUtil.java?rev=571688&r1=571687&r2=571688&view=diff
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/ServiceUtil.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/util/ServiceUtil.java Fri Aug 31 22:00:10 2007
@@ -29,6 +29,7 @@
 import java.util.List;
 
 import org.apache.abdera.Abdera;
+import org.apache.abdera.converter.ConverterProvider;
 import org.apache.abdera.factory.ExtensionFactory;
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.parser.Parser;
@@ -303,6 +304,13 @@
         _loadimpls(
           "META-INF/services/org.apache.abdera.factory.ExtensionFactory");
       return factories;
+  }
+  
+  protected static synchronized List<ConverterProvider> loadConverterProviders() {
+    List<ConverterProvider> providers =
+      _loadimpls(
+        "META-INF/services/org.apache.abdera.converter.ConverterProvider");
+    return providers;    
   }
   
   @SuppressWarnings("unchecked")

Added: incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/ConversionTest.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/ConversionTest.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/ConversionTest.java (added)
+++ incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/ConversionTest.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,122 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.test.core;
+
+import junit.framework.TestCase;
+
+import org.apache.abdera.converter.ConversionContext;
+import org.apache.abdera.converter.Converter;
+import org.apache.abdera.converter.DefaultConversionContext;
+import org.apache.abdera.converter.ObjectContext;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
+
+public class ConversionTest extends TestCase {
+
+  public static void testConverter() 
+    throws Exception {
+    
+    ConversionContext context = new DefaultConversionContext();
+    context.setConverter(Foo.class, new FooConverter());
+    Foo foo = new Foo();
+    
+    ObjectContext fooContext = new ObjectContext(foo);
+    Converter<Element> converter = context.getConverter(fooContext);
+    
+    assertNotNull(converter);
+    assertTrue(converter instanceof FooConverter);
+    
+    Element fooEl = context.convert(foo);
+    
+    assertNotNull(fooEl);
+    
+  }
+  
+  public static void testConverterProvider()
+    throws Exception {
+    
+    ConversionContext context = new DefaultConversionContext();
+    Bar bar = new Bar();
+    
+    ObjectContext barContext = new ObjectContext(bar);
+    Converter<Element> converter = context.getConverter(barContext);
+    
+    assertNotNull(converter);
+    assertTrue(converter instanceof FooConverter);
+    
+    Element barEl = context.convert(bar);
+    
+    assertNotNull(barEl);
+    
+  }
+  
+  public static void testConverterAnnotation() 
+    throws Exception {
+    
+    ConversionContext context = new DefaultConversionContext();
+    Baz baz = new Baz();
+    
+    ObjectContext bazContext = new ObjectContext(baz);
+    Converter<Element> converter = context.getConverter(bazContext);
+    
+    assertNotNull(converter);
+    assertTrue(converter instanceof FooConverter);
+    
+    Element bazEl = context.convert(baz);
+    
+    assertNotNull(bazEl);
+    
+  }
+  
+  public static void testNoConverter() 
+    throws Exception {
+
+    ConversionContext context = new DefaultConversionContext();
+    Foo foo = new Foo();
+    
+    ObjectContext fooContext = new ObjectContext(foo);
+    Converter<Element> converter = context.getConverter(fooContext);
+    
+    assertNull(converter);
+    
+    try {
+      context.convert(foo);
+      fail("Expected error not thrown");
+    } catch (Exception e) {}
+   
+  }
+  
+  
+  public static class Foo {}
+  
+  public static class Bar {}
+  
+  @org.apache.abdera.converter.annotation.Converter(FooConverter.class) 
+  public static class Baz {}
+  
+  public static class FooConverter 
+    extends Converter<Element> {
+      public Element convert(
+        Object source,
+        ObjectContext objectContext, 
+        ConversionContext context) {
+          Element el = new ElementWrapper(null) {};
+          return el;
+    }
+  }
+}

Added: incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/FooConverterProvider.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/FooConverterProvider.java?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/FooConverterProvider.java (added)
+++ incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/FooConverterProvider.java Fri Aug 31 22:00:10 2007
@@ -0,0 +1,31 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.test.core;
+
+import org.apache.abdera.converter.ConverterProvider;
+import org.apache.abdera.test.core.ConversionTest.Bar;
+import org.apache.abdera.test.core.ConversionTest.FooConverter;
+
+public class FooConverterProvider 
+  extends ConverterProvider {
+  
+  public FooConverterProvider() {
+    setConverter(Bar.class,new FooConverter());
+  }
+      
+}
\ No newline at end of file

Modified: incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/TestSuite.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/TestSuite.java?rev=571688&r1=571687&r2=571688&view=diff
==============================================================================
--- incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/TestSuite.java (original)
+++ incubator/abdera/java/trunk/core/src/test/java/org/apache/abdera/test/core/TestSuite.java Fri Aug 31 22:00:10 2007
@@ -17,7 +17,6 @@
 */
 package org.apache.abdera.test.core;
 
-import org.apache.abdera.test.core.CoreTest;
 
 public class TestSuite extends junit.framework.TestSuite {
   public static void main(String[] args) {
@@ -26,5 +25,6 @@
 
   public TestSuite() {
     addTestSuite(CoreTest.class);
+    addTestSuite(ConversionTest.class);
   }
 }

Added: incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/org.apache.abdera.converter.ConverterProvider
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/org.apache.abdera.converter.ConverterProvider?rev=571688&view=auto
==============================================================================
--- incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/org.apache.abdera.converter.ConverterProvider (added)
+++ incubator/abdera/java/trunk/core/src/test/resources/META-INF/services/org.apache.abdera.converter.ConverterProvider Fri Aug 31 22:00:10 2007
@@ -0,0 +1 @@
+org.apache.abdera.test.core.FooConverterProvider
\ No newline at end of file