cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dand...@apache.org
Subject svn commit: r515734 [3/11] - in /incubator/cxf/trunk/rt: ./ core/src/main/java/org/apache/cxf/endpoint/ databinding/aegis/ databinding/aegis/src/ databinding/aegis/src/main/ databinding/aegis/src/main/java/ databinding/aegis/src/main/java/org/ databind...
Date Wed, 07 Mar 2007 20:20:15 GMT
Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,576 @@
+/**
+ * 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.cxf.aegis.type;
+
+import java.beans.PropertyDescriptor;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.aegis.DatabindingException;
+import org.apache.cxf.aegis.type.basic.BeanType;
+import org.apache.cxf.aegis.type.basic.XMLBeanTypeInfo;
+import org.apache.cxf.aegis.util.NamespaceHelper;
+import org.apache.cxf.aegis.util.jdom.StaxBuilder;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.xpath.XPath;
+
+/**
+ * Deduce mapping information from an xml file. The xml file should be in the
+ * same packages as the class, with the name <code>className.aegis.xml</code>.
+ * For example, given the following service interface: <p/>
+ * 
+ * <pre>
+ * public Collection getResultsForValues(String id, Collection values); //method 1
+ * 
+ * public Collection getResultsForValues(int id, Collection values); //method 2
+ * 
+ * public String getResultForValue(String value); //method 3
+ * </pre>
+ * 
+ * An example of the type xml is:
+ * 
+ * <pre>
+ *  &lt;mappings&gt;
+ *   &lt;mapping&gt;
+ *     &lt;method name=&quot;getResultsForValues&quot;&gt;
+ *       &lt;return-type componentType=&quot;com.acme.ResultBean&quot; /&gt;
+ *       &lt;!-- no need to specify index 0, since it's a String --&gt;
+ *       &lt;parameter index=&quot;1&quot; componentType=&quot;java.lang.String&quot; /&gt;
+ *     &lt;/method&gt;
+ *   &lt;/mapping&gt;
+ *  &lt;/mappings&gt;
+ * </pre>
+ * 
+ * <p/> Note that for values which can be easily deduced (such as the String
+ * parameter, or the second service method) no mapping need be specified in the
+ * xml descriptor, which is why no mapping is specified for method 3. <p/>
+ * However, if you have overloaded methods with different semantics, then you
+ * will need to specify enough parameters to disambiguate the method and
+ * uniquely identify it. So in the example above, the mapping specifies will
+ * apply to both method 1 and method 2, since the parameter at index 0 is not
+ * specified.
+ * 
+ * @author Hani Suleiman Date: Jun 14, 2005 Time: 7:47:56 PM
+ * @author <a href="mailto:mikagoeckel@codehaus.org">Mika Göckel</a>
+ * @author Øyvind Matheson Wergeland
+ */
+public class XMLTypeCreator extends AbstractTypeCreator {
+    private static final Log log = LogFactory.getLog(XMLTypeCreator.class);
+
+    // cache of classes to documents
+    private Map<String, Document> documents = new HashMap<String, Document>();
+
+    private static List<Class> stopClasses = new ArrayList<Class>();
+    static {
+        stopClasses.add(Object.class);
+        stopClasses.add(Exception.class);
+        stopClasses.add(RuntimeException.class);
+        stopClasses.add(Throwable.class);
+    }
+
+    protected Document getDocument(Class clazz) {
+        if (clazz == null) {
+            return null;
+        }
+        Document doc = documents.get(clazz.getName());
+        if (doc != null) {
+            return doc;
+        }
+        String path = '/' + clazz.getName().replace('.', '/') + ".aegis.xml";
+        InputStream is = clazz.getResourceAsStream(path);
+        if (is == null) {
+            log.debug("Mapping file : " + path + " not found.");
+            return null;
+        }
+        log.debug("Found mapping file : " + path);
+        try {
+            doc = new StaxBuilder().build(is);
+            documents.put(clazz.getName(), doc);
+            return doc;
+        } catch (XMLStreamException e) {
+            log.error("Error loading file " + path, e);
+        }
+        return null;
+    }
+
+    @Override
+    protected boolean isEnum(Class javaType) {
+        Element mapping = findMapping(javaType);
+        if (mapping != null) {
+            return super.isEnum(javaType);
+        } else {
+            return nextCreator.isEnum(javaType);
+        }
+    }
+
+    @Override
+    public Type createEnumType(TypeClassInfo info) {
+        Element mapping = findMapping(info.getTypeClass());
+        if (mapping != null) {
+            return super.createEnumType(info);
+        } else {
+            return nextCreator.createEnumType(info);
+        }
+    }
+
+    @Override
+    public Type createCollectionType(TypeClassInfo info) {
+        if (info.getGenericType() instanceof Class || info.getGenericType() instanceof TypeClassInfo) {
+            return createCollectionTypeFromGeneric(info);
+        }
+
+        return nextCreator.createCollectionType(info);
+    }
+
+    @Override
+    public TypeClassInfo createClassInfo(PropertyDescriptor pd) {
+        Element mapping = findMapping(pd.getReadMethod().getDeclaringClass());
+        if (mapping == null) {
+            return nextCreator.createClassInfo(pd);
+        }
+
+        Element propertyEl = getMatch(mapping, "./property[@name='" + pd.getName() + "']");
+        if (propertyEl == null) {
+            return nextCreator.createClassInfo(pd);
+        }
+
+        TypeClassInfo info = new TypeClassInfo();
+        info.setTypeClass(pd.getReadMethod().getReturnType());
+        readMetadata(info, mapping, propertyEl);
+
+        return info;
+    }
+
+    protected Element findMapping(Class clazz) {
+        Document doc = getDocument(clazz);
+        if (doc == null) {
+            return null;
+        }
+
+        Element mapping = getMatch(doc, "/mappings/mapping[@uri='" + getTypeMapping().getEncodingStyleURI()
+                                        + "']");
+        if (mapping == null) {
+            mapping = getMatch(doc, "/mappings/mapping[not(@uri)]");
+        }
+
+        return mapping;
+    }
+
+    protected List<Element> findMappings(Class clazz) {
+        List<Element> mappings = new ArrayList<Element>();
+
+        Element top = findMapping(clazz);
+        if (top != null) {
+            mappings.add(top);
+        }
+
+        Class parent = clazz;
+        while (true) {
+
+            // Read mappings for interfaces as well
+            Class[] interfaces = parent.getInterfaces();
+            for (int i = 0; i < interfaces.length; i++) {
+                Class interfaze = interfaces[i];
+                List<Element> interfaceMappings = findMappings(interfaze);
+                mappings.addAll(interfaceMappings);
+            }
+
+            Class sup = parent.getSuperclass();
+
+            if (sup == null || stopClasses.contains(sup)) {
+                break;
+            }
+
+            Element mapping = findMapping(sup);
+            if (mapping != null) {
+                mappings.add(mapping);
+            }
+
+            parent = sup;
+        }
+
+        return mappings;
+    }
+
+    @Override
+    public Type createDefaultType(TypeClassInfo info) {
+        Element mapping = findMapping(info.getTypeClass());
+        List mappings = findMappings(info.getTypeClass());
+
+        if (mapping != null || mappings.size() > 0) {
+            String typeNameAtt = null;
+            if (mapping != null) {
+                typeNameAtt = mapping.getAttributeValue("name");
+            }
+
+            String extensibleElements = null;
+            if (mapping != null) {
+                extensibleElements = mapping.getAttributeValue("extensibleElements");
+            }
+
+            String extensibleAttributes = null;
+            if (mapping != null) {
+                extensibleAttributes = mapping.getAttributeValue("extensibleAttributes");
+            }
+
+            String defaultNS = NamespaceHelper.makeNamespaceFromClassName(info.getTypeClass().getName(),
+                                                                          "http");
+            QName name = null;
+            if (typeNameAtt != null) {
+                name = NamespaceHelper.createQName(mapping, typeNameAtt, defaultNS);
+
+                defaultNS = name.getNamespaceURI();
+            }
+
+            XMLBeanTypeInfo btinfo = new XMLBeanTypeInfo(info.getTypeClass(), mappings, defaultNS);
+            btinfo.setTypeMapping(getTypeMapping());
+            btinfo.setDefaultMinOccurs(getConfiguration().getDefaultMinOccurs());
+            btinfo.setDefaultNillable(getConfiguration().isDefaultNillable());
+
+            if (extensibleElements != null) {
+                btinfo.setExtensibleElements(Boolean.valueOf(extensibleElements).booleanValue());
+            } else {
+                btinfo.setExtensibleElements(getConfiguration().isDefaultExtensibleElements());
+            }
+
+            if (extensibleAttributes != null) {
+                btinfo.setExtensibleAttributes(Boolean.valueOf(extensibleAttributes).booleanValue());
+            } else {
+                btinfo.setExtensibleAttributes(getConfiguration().isDefaultExtensibleAttributes());
+            }
+
+            BeanType type = new BeanType(btinfo);
+
+            if (name == null) {
+                name = createQName(info.getTypeClass());
+            }
+
+            type.setSchemaType(name);
+
+            type.setTypeClass(info.getTypeClass());
+            type.setTypeMapping(getTypeMapping());
+
+            return type;
+        } else {
+            return nextCreator.createDefaultType(info);
+        }
+    }
+
+    @Override
+    public TypeClassInfo createClassInfo(Method m, int index) {
+        Element mapping = findMapping(m.getDeclaringClass());
+
+        if (mapping == null) {
+            return nextCreator.createClassInfo(m, index);
+        }
+
+        // find the elements that apply to the specified method
+        TypeClassInfo info = new TypeClassInfo();
+        if (index >= 0) {
+            if (index >= m.getParameterTypes().length) {
+                throw new DatabindingException("Method " + m + " does not have a parameter at index " + index);
+            }
+            // we don't want nodes for which the specified index is not
+            // specified
+            List<Element> nodes = getMatches(mapping, "./method[@name='" + m.getName()
+                                                      + "']/parameter[@index='" + index + "']/parent::*");
+            if (nodes.size() == 0) {
+                // no mapping for this method
+                return nextCreator.createClassInfo(m, index);
+            }
+            // pick the best matching node
+            Element bestMatch = getBestMatch(mapping, m, nodes);
+
+            if (bestMatch == null) {
+                // no mapping for this method
+                return nextCreator.createClassInfo(m, index);
+            }
+            info.setTypeClass(m.getParameterTypes()[index]);
+            // info.setAnnotations(m.getParameterAnnotations()[index]);
+            Element parameter = getMatch(bestMatch, "parameter[@index='" + index + "']");
+            readMetadata(info, mapping, parameter);
+        } else {
+            List<Element> nodes = getMatches(mapping, "./method[@name='" + m.getName()
+                                                      + "']/return-type/parent::*");
+            if (nodes.size() == 0) {
+                return nextCreator.createClassInfo(m, index);
+            }
+            Element bestMatch = getBestMatch(mapping, m, nodes);
+            if (bestMatch == null) {
+                // no mapping for this method
+                return nextCreator.createClassInfo(m, index);
+            }
+            info.setTypeClass(m.getReturnType());
+            // info.setAnnotations(m.getAnnotations());
+            Element rtElement = bestMatch.getChild("return-type");
+            readMetadata(info, mapping, rtElement);
+        }
+
+        return info;
+    }
+
+    protected void readMetadata(TypeClassInfo info, Element mapping, Element parameter) {
+        info.setTypeName(createQName(parameter, parameter.getAttributeValue("typeName")));
+        info.setMappedName(createQName(parameter, parameter.getAttributeValue("mappedName")));
+        setComponentType(info, mapping, parameter);
+        setKeyType(info, mapping, parameter);
+        setType(info, parameter);
+
+        String min = parameter.getAttributeValue("minOccurs");
+        if (min != null) {
+            info.setMinOccurs(Long.parseLong(min));
+        }
+
+        String max = parameter.getAttributeValue("maxOccurs");
+        if (max != null) {
+            info.setMaxOccurs(Long.parseLong(max));
+        }
+
+        String flat = parameter.getAttributeValue("flat");
+        if (flat != null) {
+            info.setFlat(Boolean.valueOf(flat.toLowerCase()).booleanValue());
+        }
+    }
+
+    @Override
+    protected Type getOrCreateGenericType(TypeClassInfo info) {
+        Type type = null;
+        if (info.getGenericType() != null) {
+            type = createTypeFromGeneric(info.getGenericType());
+        }
+
+        if (type == null) {
+            type = super.getOrCreateGenericType(info);
+        }
+
+        return type;
+    }
+
+    private Type createTypeFromGeneric(Object cType) {
+        if (cType instanceof TypeClassInfo) {
+            return createTypeForClass((TypeClassInfo)cType);
+        } else if (cType instanceof Class) {
+            return createType((Class)cType);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    protected Type getOrCreateMapKeyType(TypeClassInfo info) {
+        Type type = null;
+        if (info.getKeyType() != null) {
+            type = createTypeFromGeneric(info.getKeyType());
+        }
+
+        if (type == null) {
+            type = super.getOrCreateMapKeyType(info);
+        }
+
+        return type;
+    }
+
+    @Override
+    protected Type getOrCreateMapValueType(TypeClassInfo info) {
+        Type type = null;
+        if (info.getGenericType() != null) {
+            type = createTypeFromGeneric(info.getGenericType());
+        }
+
+        if (type == null) {
+            type = super.getOrCreateMapValueType(info);
+        }
+
+        return type;
+    }
+
+    protected void setComponentType(TypeClassInfo info, Element mapping, Element parameter) {
+        String componentType = parameter.getAttributeValue("componentType");
+        if (componentType != null) {
+            info.setGenericType(loadGeneric(info, mapping, componentType));
+        }
+    }
+
+    private Object loadGeneric(TypeClassInfo info, Element mapping, String componentType) {
+        if (componentType.startsWith("#")) {
+            String name = componentType.substring(1);
+            Element propertyEl = getMatch(mapping, "./component[@name='" + name + "']");
+            if (propertyEl == null) {
+                throw new DatabindingException("Could not find <component> element in mapping named '" + name
+                                               + "'");
+            }
+
+            TypeClassInfo componentInfo = new TypeClassInfo();
+            readMetadata(componentInfo, mapping, propertyEl);
+            String className = propertyEl.getAttributeValue("class");
+            if (className == null) {
+                throw new DatabindingException("A 'class' attribute must be specified for <component> "
+                                               + name);
+            }
+
+            componentInfo.setTypeClass(loadComponentClass(className));
+
+            return componentInfo;
+        } else {
+            return loadComponentClass(componentType);
+        }
+    }
+
+    private Class loadComponentClass(String componentType) {
+        try {
+            return ClassLoaderUtils.loadClass(componentType, getClass());
+        } catch (ClassNotFoundException e) {
+            throw new DatabindingException("Unable to load component type class " + componentType, e);
+        }
+    }
+
+    protected void setType(TypeClassInfo info, Element parameter) {
+        String type = parameter.getAttributeValue("type");
+        if (type != null) {
+            try {
+                info.setType(ClassLoaderUtils.loadClass(type, getClass()));
+            } catch (ClassNotFoundException e) {
+                throw new DatabindingException("Unable to load type class " + type, e);
+            }
+        }
+    }
+
+    protected void setKeyType(TypeClassInfo info, Element mapping, Element parameter) {
+        String componentType = parameter.getAttributeValue("keyType");
+        if (componentType != null) {
+            info.setKeyType(loadGeneric(info, mapping, componentType));
+        }
+    }
+
+    private Element getBestMatch(Element mapping, Method method, List<Element> availableNodes) {
+        // first find all the matching method names
+        List<Element> nodes = getMatches(mapping, "./method[@name='" + method.getName() + "']");
+        // remove the ones that aren't in our acceptable set, if one is
+        // specified
+        if (availableNodes != null) {
+            nodes.retainAll(availableNodes);
+        }
+        // no name found, so no matches
+        if (nodes.size() == 0) {
+            return null;
+        }
+        // if the method has no params, then more than one mapping is pointless
+        Class[] parameterTypes = method.getParameterTypes();
+        if (parameterTypes.length == 0) {
+            return nodes.get(0);
+        }
+        // here's the fun part.
+        // we go through the method parameters, ruling out matches
+        for (int i = 0; i < parameterTypes.length; i++) {
+            Class parameterType = parameterTypes[i];
+            for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
+                Element element = (Element)iterator.next();
+                // first we check if the parameter index is specified
+                Element match = getMatch(element, "parameter[@index='" + i + "']");
+                if (match != null) {
+                    // we check if the type is specified and matches
+                    if (match.getAttributeValue("class") != null) {
+                        // if it doesn't match, then we can definitely rule out
+                        // this result
+                        if (!match.getAttributeValue("class").equals(parameterType.getName())) {
+                            iterator.remove();
+                        }
+                    }
+                }
+            }
+        }
+        // if we have just one node left, then it has to be the best match
+        if (nodes.size() == 1) {
+            return nodes.get(0);
+        }
+        // all remaining definitions could apply, so we need to now pick the
+        // best one
+        // the best one is the one with the most parameters specified
+        Element bestCandidate = null;
+        int highestSpecified = 0;
+        for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
+            Element element = (Element)iterator.next();
+            int availableParameters = element.getChildren("parameter").size();
+            if (availableParameters > highestSpecified) {
+                bestCandidate = element;
+                highestSpecified = availableParameters;
+            }
+        }
+        return bestCandidate;
+    }
+
+    private Element getMatch(Object doc, String xpath) {
+        try {
+            XPath path = XPath.newInstance(xpath);
+            return (Element)path.selectSingleNode(doc);
+        } catch (JDOMException e) {
+            throw new DatabindingException("Error evaluating xpath " + xpath, e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<Element> getMatches(Object doc, String xpath) {
+        try {
+            XPath path = XPath.newInstance(xpath);
+            List<Element> result = path.selectNodes(doc);
+            return result;
+        } catch (JDOMException e) {
+            throw new DatabindingException("Error evaluating xpath " + xpath, e);
+        }
+    }
+
+    /**
+     * Creates a QName from a string, such as "ns:Element".
+     */
+    protected QName createQName(Element e, String value) {
+        if (value == null || value.length() == 0) {
+            return null;
+        }
+
+        int index = value.indexOf(":");
+
+        if (index == -1) {
+            return new QName(getTypeMapping().getEncodingStyleURI(), value);
+        }
+
+        String prefix = value.substring(0, index);
+        String localName = value.substring(index + 1);
+        Namespace ns = e.getNamespace(prefix);
+
+        if (ns == null || localName == null) {
+            throw new DatabindingException("Invalid QName in mapping: " + value);
+        }
+
+        return new QName(ns.getURI(), localName, prefix);
+    }
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/XMLTypeCreator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,375 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.aegis.Aegis;
+import org.apache.cxf.aegis.Context;
+import org.apache.cxf.aegis.DatabindingException;
+import org.apache.cxf.aegis.type.Type;
+import org.apache.cxf.aegis.util.NamespaceHelper;
+import org.apache.cxf.aegis.util.XmlConstants;
+import org.apache.cxf.aegis.xml.MessageReader;
+import org.apache.cxf.aegis.xml.MessageWriter;
+import org.jdom.Attribute;
+import org.jdom.Element;
+
+/**
+ * An ArrayType.
+ * 
+ * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
+ */
+public class ArrayType extends Type {
+    private QName componentName;
+    private static final Log logger = LogFactory.getLog(ArrayType.class);
+    private long minOccurs = 0;
+    private long maxOccurs = Long.MAX_VALUE;
+    private boolean flat;
+
+    public ArrayType() {
+    }
+
+    @Override
+    public Object readObject(MessageReader reader, Context context) throws DatabindingException {
+        try {
+            Collection values = readCollection(reader, context);
+
+            return makeArray(getComponentType().getTypeClass(), values);
+        } catch (IllegalArgumentException e) {
+            throw new DatabindingException("Illegal argument.", e);
+        }
+    }
+
+    protected Collection<Object> createCollection() {
+        return new ArrayList<Object>();
+    }
+
+    protected Collection readCollection(MessageReader reader, Context context) throws DatabindingException {
+        Collection<Object> values = createCollection();
+
+        while (reader.hasMoreElementReaders()) {
+            MessageReader creader = reader.getNextElementReader();
+            Type compType = Aegis.getReadType(creader.getXMLStreamReader(), context,
+                                                             getComponentType());
+
+            if (creader.isXsiNil()) {
+                values.add(null);
+                creader.readToEnd();
+            } else {
+                values.add(compType.readObject(creader, context));
+            }
+
+            // check max occurs
+            int size = values.size();
+            if (size > maxOccurs) {
+                throw new DatabindingException("The number of elements in " + getSchemaType()
+                                               + " exceeds the maximum of " + maxOccurs);
+            }
+
+        }
+
+        // check min occurs
+        if (values.size() < minOccurs) {
+            throw new DatabindingException("The number of elements in " + getSchemaType()
+                                           + " does not meet the minimum of " + minOccurs);
+        }
+        return values;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected Object makeArray(Class arrayType, Collection values) {
+        if (Integer.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Integer.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Long.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Long.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Short.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Short.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Double.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Double.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Float.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Float.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Byte.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Byte.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Boolean.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Boolean.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        } else if (Character.TYPE.equals(arrayType)) {
+            Object[] objects = values.toArray();
+            Object array = Array.newInstance(Character.TYPE, objects.length);
+            for (int i = 0, n = objects.length; i < n; i++) {
+                Array.set(array, i, objects[i]);
+            }
+            return array;
+        }
+        return values.toArray((Object[])Array.newInstance(getComponentType().getTypeClass(), values.size()));
+    }
+
+    @Override
+    public void writeObject(Object values, MessageWriter writer, Context context) throws DatabindingException {
+        if (values == null) {
+            return;
+        }
+
+        Type type = getComponentType();
+
+        String ns = null;
+        if (type.isAbstract()) {
+            ns = getSchemaType().getNamespaceURI();
+        } else {
+            ns = type.getSchemaType().getNamespaceURI();
+        }
+
+        String name = type.getSchemaType().getLocalPart();
+
+        if (type == null) {
+            throw new DatabindingException("Couldn't find type for " + type.getTypeClass() + ".");
+        }
+
+        Class arrayType = type.getTypeClass();
+
+        if (Object.class.isAssignableFrom(arrayType)) {
+            Object[] objects = (Object[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(objects[i], writer, context, type, name, ns);
+            }
+        } else if (Integer.TYPE.equals(arrayType)) {
+            int[] objects = (int[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Integer(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Long.TYPE.equals(arrayType)) {
+            long[] objects = (long[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Long(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Short.TYPE.equals(arrayType)) {
+            short[] objects = (short[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Short(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Double.TYPE.equals(arrayType)) {
+            double[] objects = (double[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Double(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Float.TYPE.equals(arrayType)) {
+            float[] objects = (float[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Float(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Byte.TYPE.equals(arrayType)) {
+            byte[] objects = (byte[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Byte(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Boolean.TYPE.equals(arrayType)) {
+            boolean[] objects = (boolean[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Boolean(objects[i]), writer, context, type, name, ns);
+            }
+        } else if (Character.TYPE.equals(arrayType)) {
+            char[] objects = (char[])values;
+            for (int i = 0, n = objects.length; i < n; i++) {
+                writeValue(new Character(objects[i]), writer, context, type, name, ns);
+            }
+        }
+    }
+
+    protected void writeValue(Object value, MessageWriter writer, Context context, Type type, String name,
+                              String ns) throws DatabindingException {
+        type = Aegis.getWriteType(context, value, type);
+        MessageWriter cwriter = writer.getElementWriter(name, ns);
+
+        if (value == null && type.isNillable()) {
+            cwriter.writeXsiNil();
+        } else {
+            type.writeObject(value, cwriter, context);
+        }
+
+        cwriter.close();
+    }
+
+    @Override
+    public void writeSchema(Element root) {
+        try {
+            Element complex = new Element("complexType", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            complex.setAttribute(new Attribute("name", getSchemaType().getLocalPart()));
+            root.addContent(complex);
+
+            Element seq = new Element("sequence", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            complex.addContent(seq);
+
+            Element element = new Element("element", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            seq.addContent(element);
+
+            Type componentType = getComponentType();
+            String prefix = NamespaceHelper.getUniquePrefix(root, componentType
+                .getSchemaType().getNamespaceURI());
+
+            String typeName = prefix + ":" + componentType.getSchemaType().getLocalPart();
+
+            element.setAttribute(new Attribute("name", componentType.getSchemaType().getLocalPart()));
+            element.setAttribute(new Attribute("type", typeName));
+
+            if (componentType.isNillable()) {
+                element.setAttribute(new Attribute("nillable", "true"));
+            }
+
+            element.setAttribute(new Attribute("minOccurs", new Long(getMinOccurs()).toString()));
+
+            if (maxOccurs == Long.MAX_VALUE) {
+                element.setAttribute(new Attribute("maxOccurs", "unbounded"));
+            } else {
+                element.setAttribute(new Attribute("maxOccurs", new Long(getMaxOccurs()).toString()));
+            }
+
+        } catch (IllegalArgumentException e) {
+            throw new DatabindingException("Illegal argument.", e);
+        }
+    }
+
+    /**
+     * We need to write a complex type schema for Beans, so return true.
+     * 
+     * @see org.apache.cxf.aegis.type.Type#isComplex()
+     */
+    @Override
+    public boolean isComplex() {
+        return true;
+    }
+
+    public QName getComponentName() {
+        return componentName;
+    }
+
+    public void setComponentName(QName componentName) {
+        this.componentName = componentName;
+    }
+
+    /**
+     * @see org.apache.cxf.aegis.type.Type#getDependencies()
+     */
+    @Override
+    public Set<Type> getDependencies() {
+        Set<Type> deps = new HashSet<Type>();
+
+        deps.add(getComponentType());
+
+        return deps;
+    }
+
+    /**
+     * Get the <code>Type</code> of the elements in the array.
+     * 
+     * @return
+     */
+    public Type getComponentType() {
+        Class compType = getTypeClass().getComponentType();
+
+        Type type;
+
+        if (componentName == null) {
+            type = getTypeMapping().getType(compType);
+        } else {
+            type = getTypeMapping().getType(componentName);
+
+            // We couldn't find the type the user specified. One is created
+            // below instead.
+            if (type == null) {
+                logger.debug("Couldn't find array component type " + componentName
+                             + ". Creating one instead.");
+            }
+        }
+
+        if (type == null) {
+            type = getTypeMapping().getTypeCreator().createType(compType);
+            getTypeMapping().register(type);
+        }
+
+        return type;
+    }
+
+    public long getMaxOccurs() {
+        return maxOccurs;
+    }
+
+    public void setMaxOccurs(long maxOccurs) {
+        this.maxOccurs = maxOccurs;
+    }
+
+    public long getMinOccurs() {
+        return minOccurs;
+    }
+
+    public void setMinOccurs(long minOccurs) {
+        this.minOccurs = minOccurs;
+    }
+
+    public boolean isFlat() {
+        return flat;
+    }
+
+    public void setFlat(boolean flat) {
+        setWriteOuter(!flat);
+        this.flat = flat;
+    }
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/ArrayType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,115 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.cxf.aegis.Context;
+import org.apache.cxf.aegis.DatabindingException;
+import org.apache.cxf.aegis.type.Type;
+import org.apache.cxf.aegis.type.mtom.AbstractXOPType;
+import org.apache.cxf.aegis.type.mtom.ByteArrayType;
+import org.apache.cxf.aegis.util.Base64;
+import org.apache.cxf.aegis.util.XmlConstants;
+import org.apache.cxf.aegis.xml.MessageReader;
+import org.apache.cxf.aegis.xml.MessageWriter;
+
+/**
+ * Converts back and forth to byte[] objects.
+ * 
+ * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
+ */
+public class Base64Type extends Type {
+    private static ByteArrayType optimizedType = new ByteArrayType();
+
+    public Base64Type() {
+        super();
+    }
+
+    @Override
+    public Object readObject(MessageReader mreader, Context context) throws DatabindingException {
+        boolean mtomEnabled = Boolean.valueOf((String)context.get(XmlConstants.MTOM_ENABLED)).booleanValue();
+        XMLStreamReader reader = mreader.getXMLStreamReader();
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        try {
+            reader.next();
+            while (!reader.isCharacters() && !reader.isEndElement() && !reader.isStartElement()) {
+                reader.next();
+            }
+
+            if (reader.isStartElement() && reader.getName().equals(AbstractXOPType.XOP_INCLUDE)) {
+                if (mtomEnabled) {
+                    return optimizedType.readObject(mreader, context);
+                } else {
+                    throw new DatabindingException("Unexpected element: " + reader.getName());
+                }
+            }
+
+            if (reader.isEndElement()) {
+                return new byte[0];
+            }
+
+            int length = reader.getTextLength();
+
+            char[] myBuffer = new char[length];
+            for (int sourceStart = 0;; sourceStart += length) {
+                int nCopied = reader.getTextCharacters(sourceStart, myBuffer, 0, length);
+
+                Base64.decode(myBuffer, 0, nCopied, bos);
+
+                if (nCopied < length) {
+                    break;
+                }
+            }
+
+            while (reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
+                reader.next();
+            }
+
+            // Advance just past the end element
+            reader.next();
+
+            return bos.toByteArray();
+        } catch (IOException e) {
+            throw new DatabindingException("Could not parse base64Binary data.", e);
+        } catch (XMLStreamException e) {
+            throw new DatabindingException("Could not parse base64Binary data.", e);
+        }
+    }
+
+    @Override
+    public void writeObject(Object object, MessageWriter writer, Context context) throws DatabindingException {
+        boolean mtomEnabled = Boolean.valueOf((String)context.get(XmlConstants.MTOM_ENABLED)).booleanValue();
+        if (mtomEnabled) {
+            optimizedType.writeObject(object, writer, context);
+            return;
+        }
+
+        byte[] data = (byte[])object;
+
+        writer.writeValue(Base64.encode(data));
+    }
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/Base64Type.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,676 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.cxf.aegis.Aegis;
+import org.apache.cxf.aegis.Context;
+import org.apache.cxf.aegis.DatabindingException;
+import org.apache.cxf.aegis.type.Type;
+import org.apache.cxf.aegis.type.TypeMapping;
+import org.apache.cxf.aegis.util.NamespaceHelper;
+import org.apache.cxf.aegis.util.XmlConstants;
+import org.apache.cxf.aegis.xml.MessageReader;
+import org.apache.cxf.aegis.xml.MessageWriter;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.jdom.Attribute;
+import org.jdom.Element;
+
+/**
+ * Serializes JavaBeans.
+ * 
+ * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
+ * @author <a href="mailto:jack.xu.hong@gmail.com">Jack Hong</a>
+ */
+public class BeanType extends Type {
+    private BeanTypeInfo _info;
+
+    private boolean isInterface;
+
+    //
+    // private boolean isException = false;
+
+    public BeanType() {
+    }
+
+    public BeanType(BeanTypeInfo info) {
+        this._info = info;
+        this.typeClass = info.getTypeClass();
+        this.isInterface = typeClass.isInterface();
+    }
+
+    private QName getXsiType(MessageReader reader) {
+        XMLStreamReader xsr = reader.getXMLStreamReader();
+        String value = xsr.getAttributeValue(XmlConstants.XSI_NS, "type");
+        if (value == null) {
+            return null;
+        } else {
+            return NamespaceHelper.createQName(xsr.getNamespaceContext(), value);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.codehaus.xfire.aegis.type.Type#readObject(org.codehaus.xfire.aegis.MessageReader,
+     *      org.codehaus.xfire.MessageContext)
+     */
+    @Override
+    public Object readObject(MessageReader reader, Context context) throws DatabindingException {
+        BeanTypeInfo info = getTypeInfo();
+
+        try {
+            Class clazz = getTypeClass();
+            Object object = null;
+            InterfaceInvocationHandler delegate = null;
+            boolean isProxy = false;
+
+            if (isInterface) {
+                String impl = (String)context.get(clazz.getName() + ".implementation");
+
+                if (impl == null) {
+                    delegate = new InterfaceInvocationHandler();
+                    object = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {clazz},
+                                                    delegate);
+                    isProxy = true;
+                } else {
+                    try {
+                        clazz = ClassLoaderUtils.loadClass(impl, getClass());
+                        object = clazz.newInstance();
+                    } catch (ClassNotFoundException e) {
+                        throw new DatabindingException("Could not find implementation class " + impl
+                                                       + " for class " + clazz.getName());
+                    }
+                }
+            }
+            // else if (isException)
+            // {
+            // object = createFromFault(context);
+            // }
+            else {
+                object = clazz.newInstance();
+            }
+
+            // Read attributes
+            while (reader.hasMoreAttributeReaders()) {
+                MessageReader childReader = reader.getNextAttributeReader();
+                QName name = childReader.getName();
+
+                Type type = info.getType(name);
+
+                if (type != null) {
+                    Object writeObj = type.readObject(childReader, context);
+                    if (isProxy) {
+                        delegate.writeProperty(name.getLocalPart(), writeObj);
+                    } else {
+                        writeProperty(name, object, writeObj, clazz, info);
+                    }
+                }
+            }
+
+            // Read child elements
+            while (reader.hasMoreElementReaders()) {
+                MessageReader childReader = reader.getNextElementReader();
+                QName name = childReader.getName();
+                QName qn = getXsiType(childReader);
+
+                BeanType parent;
+                Type type = null;
+
+                // If an xsi:type has been specified, try to look it up
+                if (qn != null) {
+                    type = getTypeMapping().getType(qn);
+                }
+
+                // If the xsi:type lookup didn't work or there was none, use the
+                // normal Type.
+                if (type == null) {
+                    parent = getBeanTypeWithProperty(name);
+                    if (parent != null) {
+                        info = parent.getTypeInfo();
+                        type = info.getType(name);
+                    } else {
+                        type = null;
+                    }
+                }
+
+                if (type != null) {
+                    if (!childReader.isXsiNil()) {
+                        Object writeObj = type.readObject(childReader, context);
+
+                        if (isProxy) {
+                            delegate.writeProperty(name.getLocalPart(), writeObj);
+                        } else {
+                            writeProperty(name, object, writeObj, clazz, info);
+                        }
+                    } else {
+                        if (!info.isNillable(name)) {
+                            throw new DatabindingException(name.getLocalPart() + " is nil, but not nillable.");
+
+                        }
+                        childReader.readToEnd();
+                    }
+                } else {
+                    childReader.readToEnd();
+                }
+            }
+
+            return object;
+        } catch (IllegalAccessException e) {
+            throw new DatabindingException("Illegal access. " + e.getMessage(), e);
+        } catch (InstantiationException e) {
+            throw new DatabindingException("Couldn't instantiate class. " + e.getMessage(), e);
+        } catch (SecurityException e) {
+            throw new DatabindingException("Illegal access. " + e.getMessage(), e);
+        } catch (IllegalArgumentException e) {
+            throw new DatabindingException("Illegal argument. " + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Write the specified property to a field.
+     */
+    protected void writeProperty(QName name, Object object, Object property, Class impl, BeanTypeInfo info)
+        throws DatabindingException {
+        try {
+            PropertyDescriptor desc = info.getPropertyDescriptorFromMappedName(name);
+
+            Method m = desc.getWriteMethod();
+
+            if (m == null) {
+                if (getTypeClass().isInterface()) {
+                    m = getWriteMethodFromImplClass(impl, desc);
+                }
+
+                if (m == null) {
+                    throw new DatabindingException("No write method for property " + name + " in "
+                                                   + object.getClass());
+                }
+            }
+
+            Class propertyType = desc.getPropertyType();
+            if ((property == null && !propertyType.isPrimitive()) || (property != null)) {
+                m.invoke(object, new Object[] {property});
+            }
+        } catch (Exception e) {
+            if (e instanceof DatabindingException) {
+                throw (DatabindingException)e;
+            }
+
+            throw new DatabindingException("Couldn't set property " + name + " on " + object + ". "
+                                           + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * This is a hack to get the write method from the implementation class for
+     * an interface.
+     */
+    private Method getWriteMethodFromImplClass(Class impl, PropertyDescriptor pd) throws Exception {
+        String name = pd.getName();
+        name = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+
+        return impl.getMethod(name, new Class[] {pd.getPropertyType()});
+    }
+
+    /**
+     * @see org.apache.cxf.aegis.type.Type#writeObject(Object,
+     *      org.apache.cxf.aegis.xml.MessageWriter,
+     *      org.apache.cxf.aegis.Context)
+     */
+    @Override
+    public void writeObject(Object object, MessageWriter writer, Context context) throws DatabindingException {
+        if (object == null) {
+            return;
+        }
+
+        BeanTypeInfo info = getTypeInfo();
+
+        if (getSuperType() != null) {
+            writer.writeXsiType(getSchemaType());
+        }
+
+        /*
+         * TODO: Replace this method with one split into two pieces so that we
+         * can front-load the attributes and traverse down the list of super
+         * classes.
+         */
+        for (Iterator itr = info.getAttributes(); itr.hasNext();) {
+            QName name = (QName)itr.next();
+
+            Object value = readProperty(object, name);
+            if (value != null) {
+                Type type = getType(info, name);
+
+                if (type == null) {
+                    throw new DatabindingException("Couldn't find type for " + value.getClass()
+                                                   + " for property " + name);
+                }
+
+                MessageWriter cwriter = writer.getAttributeWriter(name);
+
+                type.writeObject(value, cwriter, context);
+
+                cwriter.close();
+            }
+        }
+
+        for (Iterator itr = info.getElements(); itr.hasNext();) {
+            QName name = (QName)itr.next();
+
+            if (info.isExtension()
+                && info.getPropertyDescriptorFromMappedName(name).getReadMethod().getDeclaringClass() != info
+                    .getTypeClass()) {
+                continue;
+            }
+            Object value = readProperty(object, name);
+
+            Type type = getType(info, name);
+            type = Aegis.getWriteType(context, value, type);
+            MessageWriter cwriter;
+
+            // Write the value if it is not null.
+            if (value != null) {
+                cwriter = getWriter(writer, name, type);
+
+                if (type == null) {
+                    throw new DatabindingException("Couldn't find type for " + value.getClass()
+                                                   + " for property " + name);
+                }
+
+                type.writeObject(value, cwriter, context);
+
+                cwriter.close();
+            } else if (info.isNillable(name)) {
+                cwriter = getWriter(writer, name, type);
+
+                // Write the xsi:nil if it is null.
+                cwriter.writeXsiNil();
+
+                cwriter.close();
+            }
+        }
+        if (info.isExtension()) {
+            Type t = getSuperType();
+            if (t != null) {
+                t.writeObject(object, writer, context);
+            }
+        }
+    }
+
+    private MessageWriter getWriter(MessageWriter writer, QName name, Type type) {
+        MessageWriter cwriter;
+        if (type.isAbstract()) {
+            cwriter = writer.getElementWriter(name);
+        } else {
+            cwriter = writer.getElementWriter(name);
+        }
+        return cwriter;
+    }
+
+    protected Object readProperty(Object object, QName name) {
+        try {
+            PropertyDescriptor desc = getTypeInfo().getPropertyDescriptorFromMappedName(name);
+
+            Method m = desc.getReadMethod();
+
+            if (m == null) {
+                throw new DatabindingException("No read method for property " + name + " in class "
+                                               + object.getClass().getName());
+            }
+
+            return m.invoke(object, new Object[0]);
+        } catch (Exception e) {
+            throw new DatabindingException("Couldn't get property " + name + " from bean " + object, e);
+        }
+    }
+
+    /**
+     * @see org.apache.cxf.aegis.type.Type#writeSchema(org.jdom.Element)
+     */
+    @Override
+    public void writeSchema(Element root) {
+        BeanTypeInfo info = getTypeInfo();
+        Element complex = new Element("complexType", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+        complex.setAttribute(new Attribute("name", getSchemaType().getLocalPart()));
+        root.addContent(complex);
+
+        Type sooperType = getSuperType();
+
+        if (info.isExtension() && sooperType != null) {
+            Element complexContent = new Element("complexContent", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            complex.addContent(complexContent);
+            complex = complexContent;
+        }
+
+        /*
+         * See Java Virtual Machine specification:
+         * http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#75734
+         */
+        if (((info.getTypeClass().getModifiers() & Modifier.ABSTRACT) != 0)
+            && !info.getTypeClass().isInterface()) {
+            complex.setAttribute(new Attribute("abstract", "true"));
+        }
+
+        /*
+         * Decide if we're going to extend another type. If we are going to
+         * defer, then make sure that we extend the type for our superclass.
+         */
+        boolean isExtension = info.isExtension();
+
+        Element dummy = complex;
+
+        if (isExtension && sooperType != null) {
+
+            Element extension = new Element("extension", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            complex.addContent(extension);
+            QName baseType = sooperType.getSchemaType();
+            extension.setAttribute(new Attribute("base", getNameWithPrefix2(extension, baseType
+                .getNamespaceURI(), baseType.getLocalPart())));
+
+            dummy = extension;
+        }
+
+        Element seq = null;
+
+        // Write out schema for elements
+        for (Iterator itr = info.getElements(); itr.hasNext();) {
+
+            QName name = (QName)itr.next();
+
+            if (isExtension) {
+                PropertyDescriptor pd = info.getPropertyDescriptorFromMappedName(name);
+
+                assert pd.getReadMethod() != null && pd.getWriteMethod() != null;
+                if (pd.getReadMethod().getDeclaringClass() != info.getTypeClass()) {
+                    continue;
+                }
+            }
+
+            if (seq == null) {
+                seq = new Element("sequence", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+                dummy.addContent(seq);
+            }
+
+            Element element = new Element("element", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            seq.addContent(element);
+
+            Type type = getType(info, name);
+
+            String nameNS = name.getNamespaceURI();
+            String nameWithPrefix = getNameWithPrefix(root, nameNS, name.getLocalPart());
+
+            String prefix = NamespaceHelper.getUniquePrefix(root, type.getSchemaType().getNamespaceURI());
+
+            writeTypeReference(name, nameWithPrefix, element, type, prefix);
+        }
+
+        /**
+         * if future proof then add <xsd:any/> element
+         */
+        if (info.isExtensibleElements()) {
+            if (seq == null) {
+                seq = new Element("sequence", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+                dummy.addContent(seq);
+            }
+            seq.addContent(createAnyElement());
+        }
+
+        // Write out schema for attributes
+        for (Iterator itr = info.getAttributes(); itr.hasNext();) {
+            QName name = (QName)itr.next();
+
+            Element element = new Element("attribute", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+            dummy.addContent(element);
+
+            Type type = getType(info, name);
+
+            String nameNS = name.getNamespaceURI();
+            String nameWithPrefix = getNameWithPrefix(root, nameNS, name.getLocalPart());
+
+            String prefix = NamespaceHelper.getUniquePrefix(root, type.getSchemaType()
+                .getNamespaceURI());
+            element.setAttribute(new Attribute("name", nameWithPrefix));
+            element.setAttribute(new Attribute("type", prefix + ':' + type.getSchemaType().getLocalPart()));
+        }
+
+        /**
+         * If extensible attributes then add <xsd:anyAttribute/>
+         */
+        if (info.isExtensibleAttributes()) {
+            dummy.addContent(createAnyAttribute());
+        }
+    }
+
+    private String getNameWithPrefix(Element root, String nameNS, String localName) {
+        if (!nameNS.equals(getSchemaType().getNamespaceURI())) {
+            String prefix = NamespaceHelper.getUniquePrefix((Element)root.getParent(), nameNS);
+
+            if (prefix == null || prefix.length() == 0) {
+                prefix = NamespaceHelper.getUniquePrefix(root, nameNS);
+            }
+
+            return prefix + ":" + localName;
+        }
+        return localName;
+    }
+
+    private String getNameWithPrefix2(Element root, String nameNS, String localName) {
+        String prefix = NamespaceHelper.getUniquePrefix((Element)root.getParent(), nameNS);
+
+        if (prefix == null || prefix.length() == 0) {
+            prefix = NamespaceHelper.getUniquePrefix(root, nameNS);
+        }
+
+        return prefix + ":" + localName;
+    }
+
+    private Type getType(BeanTypeInfo info, QName name) {
+        Type type = info.getType(name);
+
+        if (type == null) {
+            throw new NullPointerException("Couldn't find type for" + name + " in class "
+                                           + getTypeClass().getName());
+        }
+
+        return type;
+    }
+
+    private void writeTypeReference(QName name, String nameWithPrefix, Element element, Type type,
+                                    String prefix) {
+        if (type.isAbstract()) {
+            element.setAttribute(new Attribute("name", nameWithPrefix));
+            element.setAttribute(new Attribute("type", prefix + ':' + type.getSchemaType().getLocalPart()));
+
+            int minOccurs = getTypeInfo().getMinOccurs(name);
+            if (minOccurs != 1) {
+                element.setAttribute(new Attribute("minOccurs", new Integer(minOccurs).toString()));
+            }
+
+            if (getTypeInfo().isNillable(name)) {
+                element.setAttribute(new Attribute("nillable", "true"));
+            }
+        } else {
+            element.setAttribute(new Attribute("ref", prefix + ':' + type.getSchemaType().getLocalPart()));
+        }
+    }
+
+    @Override
+    public void setTypeClass(Class typeClass) {
+        super.setTypeClass(typeClass);
+
+        isInterface = typeClass.isInterface();
+        // isException = Exception.class.isAssignableFrom(typeClass);
+    }
+
+    /**
+     * We need to write a complex type schema for Beans, so return true.
+     * 
+     * @see org.apache.cxf.aegis.type.Type#isComplex()
+     */
+    @Override
+    public boolean isComplex() {
+        return true;
+    }
+
+    @Override
+    public Set<Type> getDependencies() {
+        Set<Type> deps = new HashSet<Type>();
+
+        BeanTypeInfo info = getTypeInfo();
+
+        for (Iterator itr = info.getAttributes(); itr.hasNext();) {
+            QName name = (QName)itr.next();
+            deps.add(info.getType(name));
+        }
+
+        for (Iterator itr = info.getElements(); itr.hasNext();) {
+            QName name = (QName)itr.next();
+            if (info.isExtension()
+                && info.getPropertyDescriptorFromMappedName(name).getReadMethod().getDeclaringClass() != info
+                    .getTypeClass()) {
+                continue;
+            }
+            deps.add(info.getType(name));
+        }
+
+        /*
+         * Automagically add chain of superclasses *if* this is an an extension.
+         */
+        if (info.isExtension()) {
+            Type sooperType = getSuperType();
+            if (sooperType != null) {
+                deps.add(sooperType);
+            }
+        }
+
+        return deps;
+    }
+
+    private BeanType getBeanTypeWithProperty(QName name) {
+        BeanType sooper = this;
+        Type type = null;
+
+        while (type == null && sooper != null) {
+            type = sooper.getTypeInfo().getType(name);
+
+            if (type == null) {
+                sooper = sooper.getSuperType();
+            }
+        }
+
+        return sooper;
+    }
+
+    private BeanType getSuperType() {
+        BeanTypeInfo info = getTypeInfo();
+        Class c = info.getTypeClass().getSuperclass();
+        /*
+         * Don't dig any deeper than Object or Exception
+         */
+        if (c != null && c != Object.class && c != Exception.class && c != RuntimeException.class) {
+            TypeMapping tm = info.getTypeMapping();
+            BeanType superType = (BeanType)tm.getType(c);
+            if (superType == null) {
+                superType = (BeanType)getTypeMapping().getTypeCreator().createType(c);
+                Class cParent = c.getSuperclass();
+                if (cParent != null && cParent != Object.class) {
+                    superType.getTypeInfo().setExtension(true);
+                }
+                tm.register(superType);
+            }
+            return superType;
+        } else {
+            return null;
+        }
+    }
+
+    public BeanTypeInfo getTypeInfo() {
+        if (_info == null) {
+            _info = createTypeInfo();
+        }
+
+        // Delay initialization so things work in recursive scenarios
+        // (XFIRE-117)
+        if (!_info.isInitialized()) {
+            _info.initialize();
+        }
+
+        return _info;
+    }
+
+    public BeanTypeInfo createTypeInfo() {
+        BeanTypeInfo info = new BeanTypeInfo(getTypeClass(), getSchemaType().getNamespaceURI());
+
+        info.setTypeMapping(getTypeMapping());
+
+        return info;
+    }
+
+    /**
+     * Create an element to represent any future elements that might get added
+     * to the schema <xsd:any minOccurs="0" maxOccurs="unbounded"/>
+     * 
+     * @return
+     */
+    private Element createAnyElement() {
+        Element result = new Element("any", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+        result.setAttribute(new Attribute("minOccurs", "0"));
+        result.setAttribute(new Attribute("maxOccurs", "unbounded"));
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append(": [class=");
+        Class c = getTypeClass();
+        sb.append((c == null) ? ("<null>") : (c.getName()));
+        sb.append(",\nQName=");
+        QName q = getSchemaType();
+        sb.append((q == null) ? ("<null>") : (q.toString()));
+        sb.append(",\ninfo=");
+        sb.append(getTypeInfo().toString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+    /**
+     * Create an element to represent any future attributes that might get added
+     * to the schema <xsd:anyAttribute/>
+     * 
+     * @return
+     */
+    private Element createAnyAttribute() {
+        Element result = new Element("anyAttribute", XmlConstants.XSD_PREFIX, XmlConstants.XSD);
+        return result;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,437 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.aegis.DatabindingException;
+import org.apache.cxf.aegis.type.Type;
+import org.apache.cxf.aegis.type.TypeCreator;
+import org.apache.cxf.aegis.type.TypeMapping;
+
+public class BeanTypeInfo {
+    private Map<QName, QName> mappedName2typeName = new HashMap<QName, QName>();
+
+    private Map<QName, String> mappedName2pdName = new HashMap<QName, String>();
+
+    private Map<QName, Type> mappedName2type = new HashMap<QName, Type>();
+
+    private Class<?> beanClass;
+
+    private List<QName> attributes = new ArrayList<QName>();
+
+    private List<QName> elements = new ArrayList<QName>();
+
+    private PropertyDescriptor[] descriptors;
+
+    private TypeMapping typeMapping;
+
+    private boolean initialized;
+
+    private String defaultNamespace;
+
+    private int minOccurs;
+
+    private boolean nillable = true;
+
+    private boolean isExtension;
+
+    /**
+     * extensibleElements means adding xs:any to WSDL Complex Type Definition
+     */
+    private boolean extensibleElements = true;
+
+    /**
+     * extensibleAttributes means adding xs:anyAttribute to WSDL Complex Type
+     * Definition
+     */
+    private boolean extensibleAttributes = true;
+
+    public BeanTypeInfo(Class<?> typeClass, String defaultNamespace) {
+        this.beanClass = typeClass;
+        this.defaultNamespace = defaultNamespace;
+
+        initializeProperties();
+    }
+
+    /**
+     * Create a BeanTypeInfo class.
+     * 
+     * @param typeClass
+     * @param defaultNamespace
+     * @param initiallize If true attempt default property/xml mappings.
+     */
+    public BeanTypeInfo(Class<?> typeClass, String defaultNamespace, boolean initialize) {
+        this.beanClass = typeClass;
+        this.defaultNamespace = defaultNamespace;
+
+        initializeProperties();
+        setInitialized(!initialize);
+    }
+
+    public String getDefaultNamespace() {
+        return defaultNamespace;
+    }
+
+    public void initialize() {
+        try {
+            for (int i = 0; i < descriptors.length; i++) {
+                // Don't map the property unless there is a read property
+                if (isMapped(descriptors[i])) {
+                    mapProperty(descriptors[i]);
+                }
+            }
+        } catch (Exception e) {
+            if (e instanceof DatabindingException) {
+                throw (DatabindingException)e;
+            }
+            throw new DatabindingException("Couldn't create TypeInfo.", e);
+        }
+
+        setInitialized(true);
+    }
+
+    public boolean isMapped(PropertyDescriptor pd) {
+        if (pd.getReadMethod() == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    private void setInitialized(boolean initialized) {
+        this.initialized = initialized;
+    }
+
+    protected void mapProperty(PropertyDescriptor pd) {
+        String name = pd.getName();
+
+        if (isAttribute(pd)) {
+            mapAttribute(name, createMappedName(pd));
+        } else if (isElement(pd)) {
+            mapElement(name, createMappedName(pd));
+        }
+    }
+
+    protected PropertyDescriptor[] getPropertyDescriptors() {
+        return descriptors;
+    }
+
+    protected PropertyDescriptor getPropertyDescriptor(String name) {
+        for (int i = 0; i < descriptors.length; i++) {
+            if (descriptors[i].getName().equals(name)) {
+                return descriptors[i];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the type class for the field with the specified QName.
+     */
+    public Type getType(QName name) {
+        // 1. Try a prexisting mapped type
+        Type type = mappedName2type.get(name);
+
+        // 2. Try to get the type by its name, if there is one
+        if (type == null) {
+            QName typeName = getMappedTypeName(name);
+            if (typeName != null) {
+                type = getTypeMapping().getType(typeName);
+
+                if (type != null) {
+                    mapType(name, type);
+                }
+            }
+        }
+
+        // 3. Create the type from the property descriptor and map it
+        if (type == null) {
+            PropertyDescriptor desc;
+            try {
+                desc = getPropertyDescriptorFromMappedName(name);
+            } catch (Exception e) {
+                if (e instanceof DatabindingException) {
+                    throw (DatabindingException)e;
+                }
+                throw new DatabindingException("Couldn't get properties.", e);
+            }
+
+            if (desc == null) {
+                return null;
+            }
+
+            try {
+                TypeMapping tm = getTypeMapping();
+                TypeCreator tc = tm.getTypeCreator();
+                type = tc.createType(desc);
+            } catch (DatabindingException e) {
+                e.prepend("Couldn't create type for property " + desc.getName() + " on " + getTypeClass());
+
+                throw e;
+            }
+
+            // second part is possible workaround for XFIRE-586
+            if (registerType(desc)) {
+                getTypeMapping().register(type);
+            }
+
+            mapType(name, type);
+        }
+
+        if (type == null) {
+            throw new DatabindingException("Couldn't find type for property " + name);
+        }
+
+        return type;
+    }
+
+    protected boolean registerType(PropertyDescriptor desc) {
+        return true;
+    }
+
+    public void mapType(QName name, Type type) {
+        mappedName2type.put(name, type);
+    }
+
+    private QName getMappedTypeName(QName name) {
+        return mappedName2typeName.get(name);
+    }
+
+    public TypeMapping getTypeMapping() {
+        return typeMapping;
+    }
+
+    public void setTypeMapping(TypeMapping typeMapping) {
+        this.typeMapping = typeMapping;
+    }
+
+    /**
+     * Specifies the name of the property as it shows up in the xml schema. This
+     * method just returns <code>propertyDescriptor.getName();</code>
+     * 
+     * @param desc
+     * @return
+     */
+    protected QName createMappedName(PropertyDescriptor desc) {
+        return new QName(getDefaultNamespace(), desc.getName());
+    }
+
+    public void mapAttribute(String property, QName mappedName) {
+        mappedName2pdName.put(mappedName, property);
+        attributes.add(mappedName);
+    }
+
+    public void mapElement(String property, QName mappedName) {
+        mappedName2pdName.put(mappedName, property);
+        elements.add(mappedName);
+    }
+
+    /**
+     * Specifies the SchemaType for a particular class.
+     * 
+     * @param mappedName
+     * @param type
+     */
+    public void mapTypeName(QName mappedName, QName type) {
+        mappedName2typeName.put(mappedName, type);
+    }
+
+    private void initializeProperties() {
+        BeanInfo beanInfo = null;
+        try {
+            if (beanClass.isInterface() || beanClass.isPrimitive()) {
+                descriptors = getInterfacePropertyDescriptors(beanClass);
+            } else if (beanClass == Object.class || beanClass == Throwable.class) {
+                // do nothing
+            } else if (beanClass == Throwable.class) {
+                // do nothing
+            } else if (Throwable.class.isAssignableFrom(beanClass)) {
+                beanInfo = Introspector.getBeanInfo(beanClass, Throwable.class);
+            } else if (RuntimeException.class.isAssignableFrom(beanClass)) {
+                beanInfo = Introspector.getBeanInfo(beanClass, RuntimeException.class);
+            } else if (Throwable.class.isAssignableFrom(beanClass)) {
+                beanInfo = Introspector.getBeanInfo(beanClass, Throwable.class);
+            } else {
+                beanInfo = Introspector.getBeanInfo(beanClass, Object.class);
+            }
+        } catch (IntrospectionException e) {
+            throw new DatabindingException("Couldn't introspect interface.", e);
+        }
+
+        if (beanInfo != null) {
+            descriptors = beanInfo.getPropertyDescriptors();
+        }
+
+        if (descriptors == null) {
+            descriptors = new PropertyDescriptor[0];
+        }
+    }
+
+    private PropertyDescriptor[] getInterfacePropertyDescriptors(Class<?> clazz) {
+        List<PropertyDescriptor> pds = new ArrayList<PropertyDescriptor>();
+
+        getInterfacePropertyDescriptors(clazz, pds, new HashSet<Class<?>>());
+
+        return pds.toArray(new PropertyDescriptor[pds.size()]);
+    }
+
+    private void getInterfacePropertyDescriptors(Class<?> clazz, List<PropertyDescriptor> pds,
+                                                 Set<Class<?>> classes) {
+        if (classes.contains(clazz)) {
+            return;
+        }
+
+        classes.add(clazz);
+
+        try {
+            Class[] interfaces = clazz.getInterfaces();
+
+            /**
+             * add base interface information
+             */
+            BeanInfo info = Introspector.getBeanInfo(clazz);
+            for (int j = 0; j < info.getPropertyDescriptors().length; j++) {
+                PropertyDescriptor pd = info.getPropertyDescriptors()[j];
+                if (!containsPropertyName(pds, pd.getName())) {
+                    pds.add(pd);
+                }
+            }
+
+            /**
+             * add extended interface information
+             */
+            for (int i = 0; i < interfaces.length; i++) {
+                getInterfacePropertyDescriptors(interfaces[i], pds, classes);
+            }
+        } catch (IntrospectionException e) {
+            // do nothing
+        }
+    }
+
+    private boolean containsPropertyName(List<PropertyDescriptor> pds, String name) {
+        for (Iterator<PropertyDescriptor> itr = pds.iterator(); itr.hasNext();) {
+            PropertyDescriptor pd = itr.next();
+            if (pd.getName().equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public PropertyDescriptor getPropertyDescriptorFromMappedName(QName name) {
+        return getPropertyDescriptor(getPropertyNameFromMappedName(name));
+    }
+
+    protected boolean isAttribute(PropertyDescriptor desc) {
+        return false;
+    }
+
+    protected boolean isElement(PropertyDescriptor desc) {
+        return true;
+    }
+
+    protected boolean isSerializable(PropertyDescriptor desc) {
+        return true;
+    }
+
+    protected Class<?> getTypeClass() {
+        return beanClass;
+    }
+
+    /**
+     * Nillable is only allowed if the actual property is Nullable
+     * 
+     * @param name
+     * @return
+     */
+    public boolean isNillable(QName name) {
+        Type type = getType(name);
+        if (!type.isNillable()) {
+            return false;
+        }
+        return nillable;
+    }
+
+    public int getMinOccurs(QName name) {
+        return minOccurs;
+    }
+
+    public void setDefaultMinOccurs(int m) {
+        this.minOccurs = m;
+    }
+
+    public void setDefaultNillable(boolean n) {
+        this.nillable = n;
+    }
+
+    private String getPropertyNameFromMappedName(QName name) {
+        return mappedName2pdName.get(name);
+    }
+
+    public Iterator<QName> getAttributes() {
+        return attributes.iterator();
+    }
+
+    public Iterator<QName> getElements() {
+        return elements.iterator();
+    }
+
+    public boolean isExtensibleElements() {
+        return extensibleElements;
+    }
+
+    public void setExtensibleElements(boolean futureProof) {
+        this.extensibleElements = futureProof;
+    }
+
+    public boolean isExtensibleAttributes() {
+        return extensibleAttributes;
+    }
+
+    public void setExtensibleAttributes(boolean extensibleAttributes) {
+        this.extensibleAttributes = extensibleAttributes;
+    }
+
+    public void setExtension(boolean extension) {
+        this.isExtension = extension;
+    }
+
+    public boolean isExtension() {
+        return isExtension;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,41 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+class BeanTypePropertyInfo {
+    private boolean nillable;
+
+    private int minOccurs = 1;
+
+    public int getMinOccurs() {
+        return minOccurs;
+    }
+
+    public void setMinOccurs(int minOccurs) {
+        this.minOccurs = minOccurs;
+    }
+
+    public boolean isNillable() {
+        return nillable;
+    }
+
+    public void setNillable(boolean nillable) {
+        this.nillable = nillable;
+    }
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypePropertyInfo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java?view=auto&rev=515734
==============================================================================
--- incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java (added)
+++ incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java Wed Mar  7 12:20:07 2007
@@ -0,0 +1,49 @@
+/**
+ * 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.cxf.aegis.type.basic;
+
+import java.math.BigDecimal;
+
+import org.apache.cxf.aegis.Context;
+import org.apache.cxf.aegis.type.Type;
+import org.apache.cxf.aegis.xml.MessageReader;
+import org.apache.cxf.aegis.xml.MessageWriter;
+
+/**
+ * <code>Type</code> for a <code>BigDecimal</code>
+ * 
+ * @author <a href="mailto:peter.royal@pobox.com">peter royal</a>
+ */
+public class BigDecimalType extends Type {
+    public BigDecimalType() {
+        super();
+    }
+
+    @Override
+    public Object readObject(final MessageReader reader, final Context context) {
+        final String value = reader.getValue();
+
+        return null == value ? null : new BigDecimal(value);
+    }
+
+    @Override
+    public void writeObject(final Object object, final MessageWriter writer, final Context context) {
+        writer.writeValue(object.toString());
+    }
+}

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BigDecimalType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



Mime
View raw message