You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2002/03/08 06:04:54 UTC
cvs commit: xml-axis/java/test/encoding SimpleBean.java AttributeBean.java TestAttributes.java
gdaniels 02/03/07 21:04:54
Modified: java/src/org/apache/axis/encoding
DeserializationContextImpl.java
java/src/org/apache/axis/encoding/ser
BaseSerializerFactory.java BeanDeserializer.java
BeanSerializer.java SimpleDeserializer.java
SimpleSerializer.java
java/src/org/apache/axis/wsdl/toJava
JavaComplexTypeWriter.java
java/test/encoding AttributeBean.java TestAttributes.java
Added: java/src/org/apache/axis/description AttributeDesc.java
ElementDesc.java FieldDesc.java TypeDesc.java
java/test/encoding SimpleBean.java
Log:
Implement structured type mapping metadata, part I.
* Define two new classes, TypeDesc and FieldDesc, representing
metadata about a Java<->XML mapping for a given type. FieldDesc
maps a given Java field to/from a particular XML element OR attribute,
and has two subclasses, ElementDesc and AttributeDesc. The subclasses
may be created directly, the FieldDesc root may not.
* Adjust the code in the BeanSerializer/Deserializer and SimpleSerializer/
Deserializer to look for a static "getTypeDesc()" method on classes to
obtain metadata instead of looking for the old "getAttributeNames()"
string array.
* Edit the stub generator to emit the new metadata style.
* Fix up the TestAttributes test to use the new metadata style, test
more combinations of present + missing metadata, and also add a
test for a SimpleType with an attribute.
So what does this mean?
The framework is now in place for much smoother data binding, and we
can eventually move towards supporting an xdoclet-type Javadoc
syntax for expressing these kinds of mappings.
We now support attributes which are in other namespaces than the
default.
Next steps:
Get the emitter doing the right thing for XML -> Java name mangling. In
other words, if we have to change an XML name when writing a stub
from WSDL, we should now be able to keep track of the original XML
name and add it to the metadata instead of relying on the Java -> XML
reverse name mangling to preserve fidelity.
Get the WSDL emitted for attributes to look correct. I was a little too
tired to finish this tonight.
Attempt to refactor the BeanSerializer/SimpleSerializer and equiv.
deserializers into a common family so they can share all the duplicated
code that currently lives both places.
Clean up a bit more.
Revision Changes Path
1.1 xml-axis/java/src/org/apache/axis/description/AttributeDesc.java
Index: AttributeDesc.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.description;
/**
* An AttributeDesc is a FieldDesc for an Java field mapping to an
* XML attribute
*
* @author Glen Daniels (gdaniels@apache.org)
*/
public class AttributeDesc extends FieldDesc {
public AttributeDesc() {
super(false);
}
}
1.1 xml-axis/java/src/org/apache/axis/description/ElementDesc.java
Index: ElementDesc.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.description;
/**
* An AttributeDesc is a FieldDesc for an Java field mapping to an
* XML element
*
* @author Glen Daniels (gdaniels@apache.org)
*/
public class ElementDesc extends FieldDesc {
public ElementDesc() {
super(true);
}
}
1.1 xml-axis/java/src/org/apache/axis/description/FieldDesc.java
Index: FieldDesc.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.description;
import javax.xml.rpc.namespace.QName;
/**
* FieldDescs are metadata objects which control the mapping of a given
* Java field to/from XML.
*
* @author Glen Daniels (gdaniels@apache.org)
*/
public class FieldDesc {
/** The name of the Java field in question */
private String fieldName;
/** The XML QName this field maps to */
private QName xmlName;
/** The XML Type this field maps to/from */
private QName xmlType;
/** An indication of whether this should be an element or an attribute */
// Q : should this be a boolean, or just "instanceof ElementDesc", etc.
private boolean _isElement = true;
/**
* Can't construct the base class directly, must construct either an
* ElementDesc or an AttributeDesc.
*/
protected FieldDesc(boolean isElement)
{
_isElement = isElement;
}
/**
* Obtain the field name.
*/
public String getFieldName() {
return fieldName;
}
/**
* Set the field name.
*/
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
/**
* Obtain the XML QName for this field
*/
public QName getXmlName() {
return xmlName;
}
/**
* Set the XML QName for this field
*/
public void setXmlName(QName xmlName) {
this.xmlName = xmlName;
}
/**
* Check if this is an element or an attribute.
*
* @return true if this is an ElementDesc, or false if an AttributeDesc
*/
public boolean isElement() {
return _isElement;
}
}
1.1 xml-axis/java/src/org/apache/axis/description/TypeDesc.java
Index: TypeDesc.java
===================================================================
package org.apache.axis.description;
import javax.xml.rpc.namespace.QName;
import java.util.HashMap;
import java.lang.reflect.Array;
public class TypeDesc {
private FieldDesc [] fields;
private HashMap fieldNameMap = new HashMap();
/** Are there any fields which are serialized as attributes? */
private boolean _hasAttributes = false;
public FieldDesc[] getFields() {
return fields;
}
public void setFields(FieldDesc [] newFields)
{
fieldNameMap = new HashMap();
fields = newFields;
_hasAttributes = false;
for (int i = 0; i < newFields.length; i++) {
FieldDesc field = newFields[i];
if (field.isElement()) {
fieldNameMap.put(field.getFieldName(), field);
} else {
_hasAttributes = true;
}
}
}
public void addFieldDesc(FieldDesc field)
{
if (field == null)
throw new NullPointerException();
int numFields = 0;
if (fields != null) {
numFields = fields.length;
}
FieldDesc [] newFields = new FieldDesc[numFields + 1];
if (fields != null) {
System.arraycopy(fields, 0, newFields, 0, numFields);
}
newFields[numFields] = field;
fields = newFields;
// Keep track of the field by name for fast lookup
fieldNameMap.put(field.getFieldName(), field);
if (!_hasAttributes && !field.isElement())
_hasAttributes = true;
}
public QName getElementNameForField(String fieldName)
{
FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
if (desc == null || !desc.isElement())
return null;
return desc.getXmlName();
}
public QName getAttributeNameForField(String fieldName)
{
FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
if (desc == null || desc.isElement())
return null;
return desc.getXmlName();
}
public String getFieldNameForElement(QName qname)
{
for (int i = 0; i < fields.length; i++) {
FieldDesc field = fields[i];
if (field.isElement() && qname.equals(field.getXmlName()))
return field.getFieldName();
}
return null;
}
public String getFieldNameForAttribute(QName qname)
{
String possibleMatch = null;
for (int i = 0; i < fields.length; i++) {
FieldDesc field = fields[i];
if (!field.isElement()) {
// It's an attribute, so if we have a solid match, return
// its name.
if (qname.equals(field.getXmlName())) {
return field.getFieldName();
}
// Not a solid match, but it's still possible we might match
// the default (i.e. QName("", fieldName))
if (qname.getNamespaceURI().equals("") &&
qname.getLocalPart().equals(field.getFieldName())) {
possibleMatch = field.getFieldName();
}
}
}
return possibleMatch;
}
public FieldDesc getFieldByName(String name)
{
return (FieldDesc)fieldNameMap.get(name);
}
public boolean hasAttributes() {
return _hasAttributes;
}
}
1.15 +7 -6 xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java
Index: DeserializationContextImpl.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- DeserializationContextImpl.java 6 Mar 2002 19:35:49 -0000 1.14
+++ DeserializationContextImpl.java 8 Mar 2002 05:04:54 -0000 1.15
@@ -315,6 +315,13 @@
{
QName typeQName = null;
+ // Check for type
+ String type = Constants.getValue(attrs, Constants.URI_CURRENT_SCHEMA_XSI, "type");
+ if (type != null) {
+ // Return the type attribute value converted to a QName
+ return getQNameFromString(type);
+ }
+
if (typeQName == null) {
// If the element is a SOAP-ENC element, the name of the element is the type.
@@ -351,12 +358,6 @@
if (typeQName != null)
return typeQName;
- // Check for type
- String type = Constants.getValue(attrs, Constants.URI_CURRENT_SCHEMA_XSI, "type");
- if (type != null) {
- // Return the type attribute value converted to a QName
- return getQNameFromString(type);
- }
/* Removing this code for now - Glen 2/20/02
1.2 +2 -1 xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java
Index: BaseSerializerFactory.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BaseSerializerFactory.java 26 Jan 2002 02:40:34 -0000 1.1
+++ BaseSerializerFactory.java 8 Mar 2002 05:04:54 -0000 1.2
@@ -127,7 +127,8 @@
}
ser = (Serializer)
serClassConstructor.newInstance(new Object[] {javaType, xmlType});
- } catch (Exception e) {}
+ } catch (Exception e) {
+ }
}
// If not successfull, try newInstance
if (ser == null) {
1.8 +123 -99 xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java
Index: BeanDeserializer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- BeanDeserializer.java 6 Mar 2002 19:35:49 -0000 1.7
+++ BeanDeserializer.java 8 Mar 2002 05:04:54 -0000 1.8
@@ -72,6 +72,7 @@
import org.apache.axis.encoding.TypeMapping;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.Constants;
+import org.apache.axis.description.TypeDesc;
import java.beans.IntrospectionException;
@@ -102,6 +103,9 @@
Class javaType;
private BeanPropertyDescriptor[] pd = null;
private HashMap propertyMap = new HashMap();
+
+ /** Type metadata about this class for XML deserialization */
+ private TypeDesc typeDesc = null;
// This counter is updated to deal with deserialize collection properties
protected int collectionIndex = -1;
@@ -117,6 +121,18 @@
BeanPropertyDescriptor descriptor = pd[i];
propertyMap.put(descriptor.getName(), descriptor);
}
+
+ // Get the class' TypeDesc if it provides one
+ try {
+ Method getTypeDesc =
+ javaType.getMethod("getTypeDesc",
+ new Class [] {});
+ // get string array
+ typeDesc = (TypeDesc)getTypeDesc.invoke(null,
+ BeanSerializer.noArgs);
+ } catch (Exception e) {
+ }
+
// create a value
try {
value=javaType.newInstance();
@@ -145,58 +161,74 @@
DeserializationContext context)
throws SAXException
{
+ BeanPropertyDescriptor propDesc = null;
+
+ if (typeDesc != null) {
+ QName elemQName = new QName(namespace, localName);
+ String fieldName = typeDesc.getFieldNameForElement(elemQName);
+ propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName);
+ }
- // look for a field by this name. Assumes the the number of
- // properties in a bean is (relatively) small, so uses a linear
- // search. Accept a property if it differs only by the
- // capitalization of the first character.
- String localNameUp = BeanSerializer.format(localName, BeanSerializer.FORCE_UPPER);
- String localNameLo = BeanSerializer.format(localName, BeanSerializer.FORCE_LOWER);
- String mangledName = JavaUtils.xmlNameToJava(localName);
- for (int i=0; i<pd.length; i++) {
- if (pd[i].getWriteMethod() == null ) continue ;
- if (pd[i].getName().equals(localNameUp) ||
- pd[i].getName().equals(localNameLo) ||
- pd[i].getName().equals(mangledName)) {
-
- // Determine the QName for this child element.
- // Look at the type attribute specified. If this fails,
- // use the javaType of the property to get the type qname.
- QName qn = context.getTypeFromAttributes(namespace, localName, attributes);
-
- // get the deserializer
- Deserializer dSer = context.getDeserializerForType(qn);
-
- // If no deserializer, use the base DeserializerImpl.
- // There may not be enough information yet to choose the
- // specific deserializer.
- if (dSer == null) {
- dSer = new DeserializerImpl();
- // determine a default type for this child element
- TypeMapping tm = context.getTypeMapping();
- Class type = pd[i].getType();
- dSer.setDefaultType(tm.getTypeQName(type));
- }
-
-
- if (pd[i].getWriteMethod().getParameterTypes().length == 1) {
- // Success! Register the target and deserializer.
- collectionIndex = -1;
- dSer.registerValueTarget(new BeanPropertyTarget(value, pd[i]));
- return (SOAPHandler) dSer;
- } else {
- // Success! This is a collection of properties so use the index
- collectionIndex++;
- dSer.registerValueTarget(new BeanPropertyTarget(value, pd[i], collectionIndex));
- return (SOAPHandler) dSer;
+ if (propDesc == null) {
+ // look for a field by this name. Assumes the the number of
+ // properties in a bean is (relatively) small, so uses a linear
+ // search. Accept a property if it differs only by the
+ // capitalization of the first character.
+ String localNameUp =
+ BeanSerializer.format(localName,
+ BeanSerializer.FORCE_UPPER);
+ String localNameLo =
+ BeanSerializer.format(localName,
+ BeanSerializer.FORCE_LOWER);
+ String mangledName = JavaUtils.xmlNameToJava(localName);
+ for (int i=0; i<pd.length; i++) {
+ if (pd[i].getWriteMethod() == null ) continue ;
+ if (pd[i].getName().equals(localNameUp) ||
+ pd[i].getName().equals(localNameLo) ||
+ pd[i].getName().equals(mangledName)) {
+ propDesc = pd[i];
}
-
}
}
+
+ if (propDesc == null) {
+ // No such field
+ throw new SAXException(
+ JavaUtils.getMessage("badElem00", javaType.getName(),
+ localName));
+ }
- // No such field
- throw new SAXException(
- JavaUtils.getMessage("badElem00", javaType.getName(), localName));
+ // Determine the QName for this child element.
+ // Look at the type attribute specified. If this fails,
+ // use the javaType of the property to get the type qname.
+ QName qn = context.getTypeFromAttributes(namespace, localName, attributes);
+
+ // get the deserializer
+ Deserializer dSer = context.getDeserializerForType(qn);
+
+ // If no deserializer, use the base DeserializerImpl.
+ // There may not be enough information yet to choose the
+ // specific deserializer.
+ if (dSer == null) {
+ dSer = new DeserializerImpl();
+ // determine a default type for this child element
+ TypeMapping tm = context.getTypeMapping();
+ Class type = propDesc.getType();
+ dSer.setDefaultType(tm.getTypeQName(type));
+ }
+
+ if (propDesc.getWriteMethod().getParameterTypes().length == 1) {
+ // Success! Register the target and deserializer.
+ collectionIndex = -1;
+ dSer.registerValueTarget(new BeanPropertyTarget(value, propDesc));
+ } else {
+ // Success! This is a collection of properties so use the index
+ collectionIndex++;
+ dSer.registerValueTarget(new BeanPropertyTarget(value,
+ propDesc,
+ collectionIndex));
+ }
+ return (SOAPHandler)dSer;
}
/**
@@ -215,69 +247,61 @@
DeserializationContext context)
throws SAXException {
- // get list of properties that are really attributes
- Vector beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
+ if (typeDesc == null)
+ return;
// loop through the attributes and set bean properties that
// correspond to attributes
- if (beanAttributeNames != null &&
- beanAttributeNames.size() > 0) {
- for (int i=0; i < attributes.getLength(); i++) {
- String attrName = attributes.getLocalName(i);
- String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
- String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
- String mangledName = JavaUtils.xmlNameToJava(attrName);
-
- // See if the attribute is a beanAttribute name
- if (!beanAttributeNames.contains(attrName) &&
- !beanAttributeNames.contains(attrNameUp) &&
- !beanAttributeNames.contains(attrNameLo))
- continue;
-
- // look for the attribute property
- BeanPropertyDescriptor bpd =
- (BeanPropertyDescriptor) propertyMap.get(attrNameUp);
- if (bpd == null)
- bpd = (BeanPropertyDescriptor) propertyMap.get(attrNameLo);
- if (bpd == null)
- bpd = (BeanPropertyDescriptor) propertyMap.get(mangledName);
- if (bpd != null) {
- if (bpd.getWriteMethod() == null ) continue ;
-
- // determine the QName for this child element
- TypeMapping tm = context.getTypeMapping();
- Class type = bpd.getType();
- QName qn = tm.getTypeQName(type);
- if (qn == null)
- throw new SAXException(
+ for (int i=0; i < attributes.getLength(); i++) {
+ QName attrQName = new QName(attributes.getURI(i),
+ attributes.getLocalName(i));
+ String fieldName = typeDesc.getFieldNameForAttribute(attrQName);
+ if (fieldName == null)
+ continue;
+
+ String attrName = attributes.getLocalName(i);
+ String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
+ String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
+ String mangledName = JavaUtils.xmlNameToJava(attrName);
+
+ // look for the attribute property
+ BeanPropertyDescriptor bpd =
+ (BeanPropertyDescriptor) propertyMap.get(fieldName);
+ if (bpd != null) {
+ if (bpd.getWriteMethod() == null ) continue ;
+
+ // determine the QName for this child element
+ TypeMapping tm = context.getTypeMapping();
+ Class type = bpd.getType();
+ QName qn = tm.getTypeQName(type);
+ if (qn == null)
+ throw new SAXException(
JavaUtils.getMessage("unregistered00", type.toString()));
- // get the deserializer
- Deserializer dSer = context.getDeserializerForType(qn);
- if (dSer == null)
- throw new SAXException(
+ // get the deserializer
+ Deserializer dSer = context.getDeserializerForType(qn);
+ if (dSer == null)
+ throw new SAXException(
JavaUtils.getMessage("noDeser00", type.toString()));
- if (! (dSer instanceof SimpleDeserializer))
- throw new SAXException(
+ if (! (dSer instanceof SimpleDeserializer))
+ throw new SAXException(
JavaUtils.getMessage("AttrNotSimpleType00",
bpd.getName(),
type.toString()));
- if (bpd.getWriteMethod().getParameterTypes().length == 1) {
- // Success! Create an object from the string and set
- // it in the bean
- try {
- Object val = ((SimpleDeserializer)dSer).
+ if (bpd.getWriteMethod().getParameterTypes().length == 1) {
+ // Success! Create an object from the string and set
+ // it in the bean
+ try {
+ Object val = ((SimpleDeserializer)dSer).
makeValue(attributes.getValue(i));
- bpd.getWriteMethod().invoke(value, new Object[] {val} );
- } catch (Exception e) {
- throw new SAXException(e);
- }
+ bpd.getWriteMethod().invoke(value, new Object[] {val} );
+ } catch (Exception e) {
+ throw new SAXException(e);
}
+ }
- } // if
- } // attribute loop
- } // if attributes exist
- } // onStartElement
-
+ } // if
+ } // attribute loop
+ }
}
1.14 +120 -48 xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java
Index: BeanSerializer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- BeanSerializer.java 6 Mar 2002 19:35:49 -0000 1.13
+++ BeanSerializer.java 8 Mar 2002 05:04:54 -0000 1.14
@@ -72,6 +72,8 @@
import org.apache.axis.encoding.DeserializerImpl;
import org.apache.axis.InternalException;
import org.apache.axis.AxisFault;
+import org.apache.axis.description.TypeDesc;
+import org.apache.axis.description.FieldDesc;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.wsdl.fromJava.ClassRep;
import org.apache.axis.wsdl.fromJava.FieldRep;
@@ -109,7 +111,7 @@
protected static Log log =
LogFactory.getLog(BeanSerializer.class.getName());
- private static final Object[] noArgs = new Object[] {}; // For convenience
+ public static final Object[] noArgs = new Object[] {}; // For convenience
// When serializing, the property element names passed over the wire
// are the names of the properties (format=PROPERTY_NAME).
@@ -126,7 +128,7 @@
Class javaType;
private BeanPropertyDescriptor[] propertyDescriptor = null;
- private Vector beanAttributeNames = null;
+ private TypeDesc typeDesc = null;
// Construct BeanSerializer for the indicated class/qname
@@ -134,16 +136,22 @@
this.xmlType = xmlType;
this.javaType = javaType;
propertyDescriptor = getPd(javaType);
- beanAttributeNames = getBeanAttributes(javaType);
+
+ // Get the class' TypeDesc if it provides one
+ try {
+ Method getTypeDesc =
+ javaType.getMethod("getTypeDesc",
+ new Class [] {});
+ // get string array
+ typeDesc = (TypeDesc)getTypeDesc.invoke(null, noArgs);
+ } catch (Exception e) {
+ }
}
// Construct BeanSerializer for the indicated class/qname and format
public BeanSerializer(Class javaType, QName xmlType, short format) {
- this.xmlType = xmlType;
- this.javaType = javaType;
+ this(javaType, xmlType);
setElementPropertyFormat(format);
- propertyDescriptor = getPd(javaType);
- beanAttributeNames = getBeanAttributes(javaType);
}
/**
@@ -159,10 +167,11 @@
{
boolean isSOAP_ENC = Constants.
isSOAP_ENC(context.getMessageContext().getEncodingStyle());
+
// Check for meta-data in the bean that will tell us if any of the
// properties are actually attributes, add those to the element
// attribute list
- Attributes beanAttrs = getObjectAttributes(value, attributes);
+ Attributes beanAttrs = getObjectAttributes(value, attributes, context);
context.startElement(name, beanAttrs);
try {
@@ -171,16 +180,36 @@
String propName = propertyDescriptor[i].getName();
if (propName.equals("class"))
continue;
- //if (!isSOAP_ENC && beanAttributeNames.contains(propName))
- if (beanAttributeNames.contains(Utils.xmlNameToJava(propName)))
- continue;
- propName = format(propName, elementPropertyFormat);
+ QName qname = null;
+
+ // If we have type metadata, check to see what we're doing
+ // with this field. If it's an attribute, skip it. If it's
+ // an element, use whatever qname is in there. If we can't
+ // find any of this info, use the default.
+
+ if (typeDesc != null) {
+ FieldDesc field = typeDesc.getFieldByName(propName);
+ if (field != null) {
+ if (!field.isElement())
+ continue;
+
+ qname = field.getXmlName();
+ }
+ }
+
+ if (qname == null) {
+ // Use the default...
+ propName = format(propName, elementPropertyFormat);
+ qname = new QName("", propName);
+ }
+
Method readMethod = propertyDescriptor[i].getReadMethod();
if (readMethod != null && readMethod.getParameterTypes().length == 0) {
// Normal case: serialize the value
Object propValue = propertyDescriptor[i].getReadMethod().invoke(value,noArgs);
- context.serialize(new QName("", propName), null,
+ context.serialize(qname,
+ null,
propValue,
propertyDescriptor[i].getReadMethod().getReturnType());
} else {
@@ -196,7 +225,7 @@
j = -1;
}
if (j >= 0) {
- context.serialize(new QName("", propName), null,
+ context.serialize(qname, null,
propValue,
propertyDescriptor[i].getReadMethod().getReturnType());
}
@@ -225,29 +254,46 @@
}
return pd;
}
-
+
/**
* Return a list of properties in the bean which should be attributes
*/
- static Vector getBeanAttributes(Class javaType) {
- // See if this object defined the 'getAttributeElements' function
- // which returns a Vector of property names that are attributes
- try {
- Method getAttributeElements =
- javaType.getMethod("getAttributeElements",
- new Class [] {});
- // get string array
- String[] array = (String[])getAttributeElements.invoke(null, noArgs);
-
- // convert it to a Vector
- Vector v = new Vector(array.length);
- for (int i = 0; i < array.length; i++) {
- v.add(array[i]);
+ static Vector getBeanAttributes(Class javaType, TypeDesc typeDesc) {
+ Vector ret = new Vector();
+
+ if (typeDesc == null) {
+ // !!! Support old-style beanAttributeNames for now
+
+ // See if this object defined the 'getAttributeElements' function
+ // which returns a Vector of property names that are attributes
+ try {
+ Method getAttributeElements =
+ javaType.getMethod("getAttributeElements",
+ new Class [] {});
+ // get string array
+ String[] array = (String[])getAttributeElements.invoke(null, noArgs);
+
+ // convert it to a Vector
+ ret = new Vector(array.length);
+ for (int i = 0; i < array.length; i++) {
+ ret.add(array[i]);
+ }
+ } catch (Exception e) {
+ ret.clear();
+ }
+ } else {
+ FieldDesc [] fields = typeDesc.getFields();
+ if (fields != null) {
+ for (int i = 0; i < fields.length; i++) {
+ FieldDesc field = fields[i];
+ if (!field.isElement()) {
+ ret.add(field.getFieldName());
+ }
+ }
}
- return v;
- } catch (Exception e) {
- return new Vector(); // empty vector
}
+
+ return ret;
}
@@ -342,17 +388,27 @@
Vector fields = clsRep.getFields();
for (int i=0; i < fields.size(); i++) {
FieldRep field = (FieldRep) fields.elementAt(i);
+
+ if (typeDesc != null) {
+ FieldDesc fieldDesc = typeDesc.getFieldByName(field.getName());
+ if (fieldDesc != null) {
+ if (!fieldDesc.isElement()) {
+ // !!! Need to get the QName right, and can only
+ // pass strings???
+ writeAttribute(types, field.getName(),
+ field.getType(),
+ complexType);
+ } else {
+ // MEN WORKING!!!!
+ }
+ return true;
+ }
+ }
- // if bean fields are attributes, write attribute element
- if (beanAttributeNames.contains(field.getName()))
- writeAttribute(types, field.getName(),
- field.getType(),
- complexType);
- else
- writeField(types, field.getName(),
- field.getType(),
- field.getIndexed(),
- all);
+ writeField(types, field.getName(),
+ field.getType(),
+ field.getIndexed(),
+ all);
}
// done
return true;
@@ -418,9 +474,10 @@
* @return attributes for this element, null if none
*/
private Attributes getObjectAttributes(Object value,
- Attributes attributes) {
+ Attributes attributes,
+ SerializationContext context) {
- if (beanAttributeNames.isEmpty())
+ if (typeDesc == null || !typeDesc.hasAttributes())
return attributes;
AttributesImpl attrs;
@@ -436,10 +493,17 @@
String propName = propertyDescriptor[i].getName();
if (propName.equals("class"))
continue;
- // skip it if its not in the list
- if (!beanAttributeNames.contains(Utils.xmlNameToJava(propName)))
+
+ FieldDesc field = typeDesc.getFieldByName(propName);
+ // skip it if its not an attribute
+ if (field == null || field.isElement())
continue;
- propName = format(propName, elementPropertyFormat);
+
+ QName qname = field.getXmlName();
+ if (qname == null) {
+ qname = new QName("",
+ format(propName, elementPropertyFormat));
+ }
Method readMethod = propertyDescriptor[i].getReadMethod();
if (readMethod != null &&
@@ -450,7 +514,15 @@
// NOTE: we will always set the attribute here to something,
// which we may not want (i.e. if null, omit it)
String propString = propValue != null ? propValue.toString() : "";
- attrs.addAttribute("", propName, propName, "CDATA", propString);
+
+ String namespace = qname.getNamespaceURI();
+ String localName = qname.getLocalPart();
+
+ attrs.addAttribute(namespace,
+ localName,
+ context.qName2String(qname),
+ "CDATA",
+ propString);
}
}
} catch (Exception e) {
1.5 +66 -60 xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializer.java
Index: SimpleDeserializer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleDeserializer.java 27 Feb 2002 19:19:44 -0000 1.4
+++ SimpleDeserializer.java 8 Mar 2002 05:04:54 -0000 1.5
@@ -59,12 +59,14 @@
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Vector;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import org.apache.axis.InternalException;
+import org.apache.axis.description.TypeDesc;
import org.apache.axis.message.SOAPHandler;
import org.apache.axis.utils.JavaUtils;
@@ -103,6 +105,8 @@
public QName xmlType;
public Class javaType;
+ private TypeDesc typeDesc = null;
+
/**
* The Deserializer is constructed with the xmlType and
* javaType (which could be a java primitive like int.class)
@@ -119,6 +123,17 @@
BeanPropertyDescriptor descriptor = pd[i];
propertyMap.put(descriptor.getName(), descriptor);
}
+
+ // Get the class' TypeDesc if it provides one
+ try {
+ Method getTypeDesc =
+ javaType.getMethod("getTypeDesc",
+ new Class [] {});
+ // get string array
+ typeDesc = (TypeDesc)getTypeDesc.invoke(null,
+ BeanSerializer.noArgs);
+ } catch (Exception e) {
+ }
}
}
@@ -251,76 +266,66 @@
throws SAXException
{
- // if this isn't a simpleType bean, wont have attributes
- if (! SimpleType.class.isAssignableFrom(javaType))
+ // If we have no metadata, we have no attributes. Q.E.D.
+ if (typeDesc == null)
return;
- // get list of properties that are really attributes
- Vector beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
-
- // loop through the attributes and set bean properties that
+ // loop through the attributes and set bean properties that
// correspond to attributes
- if (beanAttributeNames != null &&
- beanAttributeNames.size() > 0) {
- for (int i=0; i < attributes.getLength(); i++) {
- String attrName = attributes.getLocalName(i);
- String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
- String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
- String mangledName = JavaUtils.xmlNameToJava(attrName);
-
- // See if the attribute is a beanAttribute name
- if (!beanAttributeNames.contains(attrName) &&
- !beanAttributeNames.contains(attrNameUp) &&
- !beanAttributeNames.contains(attrNameLo))
- continue;
-
- if (attributeMap == null)
- attributeMap = new HashMap();
-
- // look for the attribute property, save the name
- attrName = attrNameUp;
- BeanPropertyDescriptor bpd =
- (BeanPropertyDescriptor) propertyMap.get(attrNameUp);
- if (bpd == null) {
- attrName = attrNameLo;
- bpd = (BeanPropertyDescriptor) propertyMap.get(attrNameLo);
- }
- if (bpd == null) {
- attrName = mangledName;
- bpd = (BeanPropertyDescriptor) propertyMap.get(mangledName);
- }
- if (bpd != null) {
- // determine the QName for this child element
- TypeMapping tm = context.getTypeMapping();
- Class type = bpd.getType();
- QName qn = tm.getTypeQName(type);
- if (qn == null)
- throw new SAXException(
+ for (int i=0; i < attributes.getLength(); i++) {
+ QName attrQName = new QName(attributes.getURI(i),
+ attributes.getLocalName(i));
+ String fieldName = typeDesc.getFieldNameForAttribute(attrQName);
+ if (fieldName == null)
+ continue;
+
+ String attrName = attributes.getLocalName(i);
+ String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
+ String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
+ String mangledName = JavaUtils.xmlNameToJava(attrName);
+
+ // look for the attribute property
+ BeanPropertyDescriptor bpd =
+ (BeanPropertyDescriptor) propertyMap.get(fieldName);
+ if (bpd != null) {
+ if (bpd.getWriteMethod() == null ) continue ;
+
+ // determine the QName for this child element
+ TypeMapping tm = context.getTypeMapping();
+ Class type = bpd.getType();
+ QName qn = tm.getTypeQName(type);
+ if (qn == null)
+ throw new SAXException(
JavaUtils.getMessage("unregistered00", type.toString()));
-
- // get the deserializer
- Deserializer dSer = context.getDeserializerForType(qn);
- if (dSer == null)
- throw new SAXException(
+
+ // get the deserializer
+ Deserializer dSer = context.getDeserializerForType(qn);
+ if (dSer == null)
+ throw new SAXException(
JavaUtils.getMessage("noDeser00", type.toString()));
- if (! (dSer instanceof SimpleDeserializer))
- throw new SAXException(
- JavaUtils.getMessage("AttrNotSimpleType00",
- bpd.getName(),
- type.toString()));
-
- // Success! Store name, value in HashMap for later
+ if (! (dSer instanceof SimpleDeserializer))
+ throw new SAXException(
+ JavaUtils.getMessage("AttrNotSimpleType00",
+ bpd.getName(),
+ type.toString()));
+
+ if (bpd.getWriteMethod().getParameterTypes().length == 1) {
+ // Success! Create an object from the string and save
+ // it in our attribute map for later.
+ if (attributeMap == null) {
+ attributeMap = new HashMap();
+ }
try {
Object val = ((SimpleDeserializer)dSer).
makeValue(attributes.getValue(i));
- attributeMap.put(attrName, val);
+ attributeMap.put(fieldName, val);
} catch (Exception e) {
throw new SAXException(e);
}
-
- } // if bpd != null
- } // attribute loop
- } // if attributes exist
+ }
+
+ } // if
+ } // attribute loop
} // onStartElement
/**
@@ -328,7 +333,8 @@
*/
private void setSimpleTypeAttributes() throws SAXException {
// if this isn't a simpleType bean, wont have attributes
- if (! SimpleType.class.isAssignableFrom(javaType))
+ if (! SimpleType.class.isAssignableFrom(javaType) ||
+ attributeMap == null)
return;
// loop through map
1.5 +55 -23 xml-axis/java/src/org/apache/axis/encoding/ser/SimpleSerializer.java
Index: SimpleSerializer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/SimpleSerializer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleSerializer.java 27 Feb 2002 23:46:32 -0000 1.4
+++ SimpleSerializer.java 8 Mar 2002 05:04:54 -0000 1.5
@@ -67,6 +67,8 @@
import org.apache.axis.Constants;
import org.apache.axis.AxisFault;
+import org.apache.axis.description.TypeDesc;
+import org.apache.axis.description.FieldDesc;
import org.apache.axis.wsdl.fromJava.Types;
import org.apache.axis.wsdl.fromJava.ClassRep;
import org.apache.axis.wsdl.fromJava.FieldRep;
@@ -94,8 +96,8 @@
public Class javaType;
private BeanPropertyDescriptor[] propertyDescriptor = null;
- private Vector beanAttributeNames = null;
-
+ private TypeDesc typeDesc = null;
+
public SimpleSerializer(Class javaType, QName xmlType) {
this.xmlType = xmlType;
this.javaType = javaType;
@@ -103,7 +105,16 @@
if (SimpleType.class.isAssignableFrom(javaType)) {
// get the bean properties and the list of attributes from the bean
propertyDescriptor = BeanSerializer.getPd(javaType);
- beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
+ // Get the class' TypeDesc if it provides one
+ try {
+ Method getTypeDesc =
+ javaType.getMethod("getTypeDesc",
+ new Class [] {});
+ // get string array
+ typeDesc = (TypeDesc)getTypeDesc.invoke(null,
+ BeanSerializer.noArgs);
+ } catch (Exception e) {
+ }
}
}
/**
@@ -123,7 +134,7 @@
// get any attributes
if (value instanceof SimpleType)
- attributes = getObjectAttributes(value, attributes);
+ attributes = getObjectAttributes(value, attributes, context);
context.startElement(name, attributes);
if (value != null) {
@@ -159,39 +170,55 @@
context.endElement();
}
- private Attributes getObjectAttributes(Object value, Attributes attributes) {
-
- // if nothing, return
- if (beanAttributeNames.isEmpty())
+ private Attributes getObjectAttributes(Object value,
+ Attributes attributes,
+ SerializationContext context) {
+ if (typeDesc == null || !typeDesc.hasAttributes())
return attributes;
-
+
AttributesImpl attrs;
if (attributes != null)
attrs = new AttributesImpl(attributes);
else
attrs = new AttributesImpl();
-
+
try {
- // Find each property that is an attribute
+ // Find each property that is an attribute
// and add it to our attribute list
for (int i=0; i<propertyDescriptor.length; i++) {
String propName = propertyDescriptor[i].getName();
if (propName.equals("class"))
continue;
- // skip it if its not in the list
- if (!beanAttributeNames.contains(Utils.xmlNameToJava(propName)))
+
+ FieldDesc field = typeDesc.getFieldByName(propName);
+ // skip it if its not an attribute
+ if (field == null || field.isElement())
continue;
-
+
+ QName qname = field.getXmlName();
+ if (qname == null) {
+ qname = new QName("", Utils.xmlNameToJava(propName));
+ }
+
Method readMethod = propertyDescriptor[i].getReadMethod();
- if (readMethod != null &&
- readMethod.getParameterTypes().length == 0) {
+ if (readMethod != null &&
+ readMethod.getParameterTypes().length == 0) {
// add to our attributes
Object propValue = propertyDescriptor[i].
- getReadMethod().invoke(value, new Object[]{});
- // NOTE: we will always set the attribute here to something,
+ getReadMethod().
+ invoke(value,BeanSerializer.noArgs);
+ // NOTE: we will always set the attribute here to something,
// which we may not want (i.e. if null, omit it)
String propString = propValue != null ? propValue.toString() : "";
- attrs.addAttribute("", propName, propName, "CDATA", propString);
+
+ String namespace = qname.getNamespaceURI();
+ String localName = qname.getLocalPart();
+
+ attrs.addAttribute(namespace,
+ localName,
+ context.qName2String(qname),
+ "CDATA",
+ propString);
}
}
} catch (Exception e) {
@@ -253,17 +280,22 @@
// allows users to provide their own field mapping.
ClassRep clsRep = types.getBeanBuilder().build(javaType);
- // Write out fields
+ // Write out fields (only attributes are allowed)
+ if (typeDesc == null || !typeDesc.hasAttributes())
+ return true;
+
Vector fields = clsRep.getFields();
for (int i=0; i < fields.size(); i++) {
FieldRep field = (FieldRep) fields.elementAt(i);
String fieldName = field.getName();
-
- // if bean fields are attributes, write attribute element
- if (!beanAttributeNames.contains(fieldName)) {
+
+ FieldDesc fieldDesc = typeDesc.getFieldByName(field.getName());
+ if (fieldDesc == null || fieldDesc.isElement()) {
+ // Really, it's an error to have element descriptors in there!
continue;
}
+
// write attribute element
Class fieldType = field.getType();
1.15 +31 -6 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaComplexTypeWriter.java
Index: JavaComplexTypeWriter.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaComplexTypeWriter.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- JavaComplexTypeWriter.java 28 Feb 2002 19:19:23 -0000 1.14
+++ JavaComplexTypeWriter.java 8 Mar 2002 05:04:54 -0000 1.15
@@ -123,6 +123,15 @@
if (type.isSimpleType())
implementsText = ", org.apache.axis.encoding.SimpleType";
+ // For now, do the imports only if we have attributes. This will
+ // need to happen for any mapping later.
+ if (attributes != null) {
+ pw.println("import org.apache.axis.description.FieldDesc;");
+ pw.println("import org.apache.axis.description.TypeDesc;");
+ pw.println("import org.apache.axis.description.AttributeDesc;");
+ pw.println();
+ }
+
pw.println("public class " + className + extendsText +
" implements java.io.Serializable" + implementsText + " {");
@@ -223,20 +232,36 @@
// if we have attributes, create metadata function which returns the
// list of properties that are attributes instead of elements
+
+ // Glen 3/7/02 : This is now using the type metadata model which
+ // provides for arbitrary mapping of XML elements or attributes
+ // <-> Java fields. We need to generalize this to support element
+ // mappings as well, but right now this is just to keep the attribute
+ // mechanism working.
+
if (attributes != null) {
- pw.println(" // List of fields that are XML attributes");
- pw.println(" private static java.lang.String[] _attrs = new String[] {");
+ pw.println(" // Type metadata");
+ pw.println(" private static org.apache.axis.description.TypeDesc typeDesc =");
+ pw.println(" new org.apache.axis.description.TypeDesc();");
+ pw.println();
+ pw.println(" static {");
for (int i = 0; i < attributes.size(); i += 2) {
- pw.println(" \"" + Utils.xmlNameToJava((String) attributes.get(i + 1)) + "\", ");
+ String fieldName =
+ Utils.xmlNameToJava((String) attributes.get(i + 1));
+ pw.print(" ");
+ if (i == 0) pw.print("org.apache.axis.description.FieldDesc ");
+ pw.println("field = new org.apache.axis.description.AttributeDesc();");
+ pw.println(" field.setFieldName(\"" + fieldName + "\");");
+ pw.println(" typeDesc.addFieldDesc(field);");
}
pw.println(" };");
pw.println();
pw.println(" /**");
- pw.println(" * Return list of bean field names that are attributes");
+ pw.println(" * Return type metadata object");
pw.println(" */");
- pw.println(" public static java.lang.String[] getAttributeElements() {");
- pw.println(" return _attrs;");
+ pw.println(" public static org.apache.axis.description.TypeDesc getTypeDesc() {");
+ pw.println(" return typeDesc;");
pw.println(" }");
pw.println();
}
1.2 +52 -13 xml-axis/java/test/encoding/AttributeBean.java
Index: AttributeBean.java
===================================================================
RCS file: /home/cvs/xml-axis/java/test/encoding/AttributeBean.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AttributeBean.java 25 Feb 2002 15:24:14 -0000 1.1
+++ AttributeBean.java 8 Mar 2002 05:04:54 -0000 1.2
@@ -53,6 +53,13 @@
* <http://www.apache.org/>.
*/
+import org.apache.axis.description.AttributeDesc;
+import org.apache.axis.description.ElementDesc;
+import org.apache.axis.description.FieldDesc;
+import org.apache.axis.description.TypeDesc;
+
+import javax.xml.rpc.namespace.QName;
+
/**
* Simple Java Bean with fields that should be serialized as attributes
*/
@@ -103,18 +110,50 @@
public void setMale(boolean male) {
this.male = male;
}
-
- // List of fields that are XML attributes
- public static java.lang.String[] _attrs = new String[] {
- "name",
- "male",
- };
-
- /**
- * Return list of bean field names that are attributes
- */
- public static java.lang.String[] getAttributeElements() {
- return _attrs;
+
+ public boolean equals(Object obj)
+ {
+ if (obj == null || !(obj instanceof AttributeBean))
+ return false;
+ AttributeBean other = (AttributeBean)obj;
+ if (other.getAge() != age)
+ return false;
+ if (other.getID() != iD)
+ return false;
+ if (other.getMale() != male)
+ return false;
+ if (name == null)
+ return other.getName() == null;
+ return name.equals(other.getName());
+ }
+
+ // Type metadata
+ private static TypeDesc typeDesc;
+
+ static {
+ typeDesc = new TypeDesc();
+ FieldDesc field;
+
+ // An attribute with a specified QName
+ field = new AttributeDesc();
+ field.setFieldName("name");
+ field.setXmlName(new QName("foo", "nameAttr"));
+ typeDesc.addFieldDesc(field);
+
+ // An attribute with a default QName
+ field = new AttributeDesc();
+ field.setFieldName("male");
+ typeDesc.addFieldDesc(field);
+
+ // An element with a specified QName
+ field = new ElementDesc();
+ field.setFieldName("age");
+ field.setXmlName(new QName("foo", "ageElement"));
+ typeDesc.addFieldDesc(field);
+ }
+
+ public static TypeDesc getTypeDesc()
+ {
+ return typeDesc;
}
-
}
1.2 +83 -52 xml-axis/java/test/encoding/TestAttributes.java
Index: TestAttributes.java
===================================================================
RCS file: /home/cvs/xml-axis/java/test/encoding/TestAttributes.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestAttributes.java 25 Feb 2002 15:24:14 -0000 1.1
+++ TestAttributes.java 8 Mar 2002 05:04:54 -0000 1.2
@@ -8,9 +8,17 @@
import org.apache.axis.encoding.SerializationContextImpl;
import org.apache.axis.encoding.TypeMappingRegistry;
import org.apache.axis.encoding.TypeMapping;
+import org.apache.axis.encoding.SimpleType;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
+import org.apache.axis.encoding.ser.SimpleDeserializerFactory;
+import org.apache.axis.encoding.ser.SimpleNonPrimitiveSerializerFactory;
import org.apache.axis.Constants;
+import org.apache.axis.Message;
+import org.apache.axis.description.TypeDesc;
+import org.apache.axis.description.FieldDesc;
+import org.apache.axis.description.OperationDesc;
+import org.apache.axis.description.ServiceDesc;
import org.apache.axis.utils.XMLUtils;
import org.apache.axis.client.Call;
import org.apache.axis.message.RPCElement;
@@ -25,6 +33,7 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Vector;
import AttributeBean;
@@ -32,6 +41,7 @@
* Test the serialization of a bean with attributes
*
* @author Tom Jordahl (tomj@macromedia.com)
+ * @author Glen Daniels (gdaniels@apache.org)
*/
public class TestAttributes extends TestCase {
static Log log =
@@ -43,35 +53,17 @@
{
TestAttributes tester = new TestAttributes("TestAttributes");
tester.testBean();
+ tester.testSimpleType();
}
public TestAttributes(String name) {
super(name);
}
- static final String expectedXML =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
- "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
- " <SOAP-ENV:Body>\n" +
- " <method1 xmlns=\"urn:myNamespace\">\n" +
- " <struct name=\"James Bond\" male=\"true\">\n" +
- " <ID>1.15</ID>\n" +
- " <age>35</age>\n" +
- " </struct>\n" +
- " </method1>\n" +
- " </SOAP-ENV:Body>\n" +
- "</SOAP-ENV:Envelope>";
-
public void testBean () throws Exception {
MessageContext msgContext = new MessageContext(new AxisServer());
SOAPEnvelope msg = new SOAPEnvelope();
- // set no encoding (use=literal)
- msgContext.setEncodingStyle(null);
- // Don't serialize xsi:type attributes
- msgContext.setProperty(Call.SEND_TYPE_ATTR, "false" );
-
-
// Create bean with data
AttributeBean bean = new AttributeBean();
bean.setAge(35);
@@ -93,8 +85,8 @@
TypeMappingRegistry reg = context.getTypeMappingRegistry();
TypeMapping tm = (TypeMapping) reg.createTypeMapping();
// The "" namespace is literal (no encoding).
- tm.setSupportedNamespaces(new String[] {""});
- reg.register("", tm);
+ tm.setSupportedNamespaces(new String[] {Constants.URI_CURRENT_SOAP_ENC});
+ reg.register(Constants.URI_CURRENT_SOAP_ENC, tm);
QName beanQName = new QName("typeNS", "TheBean");
tm.register(AttributeBean.class,
@@ -106,40 +98,79 @@
msg.output(context);
// Get the XML as a string
String msgString = stringWriter.toString();
- // verify results
- assertEquals("Serialized bean and expected results don't match",
- expectedXML, msgString);
-
+
log.debug("---");
log.debug(msgString);
log.debug("---");
-/*
- TODO: This part of the test is wrong
-
- // Now feed the XML in to the deserializer
- StringReader reader = new StringReader(msgString);
- DeserializationContext dser = new DeserializationContextImpl(
- new InputSource(reader), msgContext, org.apache.axis.Message.REQUEST);
-
- // deserialize it
- dser.parse();
-
- // get the results
- SOAPEnvelope env = dser.getEnvelope();
- RPCElement rpcElem = (RPCElement)env.getFirstBody();
- RPCParam struct = rpcElem.getParam("struct");
- assertNotNull("No <struct> param", struct);
-
- Object obj = struct.getValue();
- System.out.println(obj.toString());
- AttributeBean val = (AttributeBean)struct.getValue();
- assertNotNull("No value for struct param", val);
-
- assertEquals("Bean and Val Age members are not equal", bean.getAge(), val.getAge());
- assertEquals("Bean and Val ID members are not equal",bean.getID(), bean.getID(), 1.15F);
- assertEquals("Bean and Val boolean attributes are not equal",bean.getMale(), bean.getMale());
- assertEquals("Bean and Val name attributes are not equal",bean.getName(), bean.getName());
-*/
+
+ Message message = new Message(msgString);
+ message.setMessageContext(msgContext);
+ SOAPEnvelope env = message.getSOAPPart().getAsSOAPEnvelope();
+ RPCElement rpcEl = (RPCElement)env.getFirstBody();
+ Vector params = rpcEl.getParams();
+ assertEquals("Wrong # of params in deserialized message!",
+ 1,
+ params.size());
+
+ Object obj = ((RPCParam)params.get(0)).getValue();
+ assertTrue("Deserialized param not an AttributeBean!",
+ (obj instanceof AttributeBean));
+
+ AttributeBean deserBean = (AttributeBean)obj;
+ assertTrue("Deserialized bean not equal to expected values!",
+ (bean.equals(deserBean)));
}
+ public void testSimpleType() throws Exception {
+ SimpleBean bean = new SimpleBean("test value");
+ bean.temp = 85.0F;
+
+ MessageContext msgContext = new MessageContext(new AxisServer());
+ SOAPEnvelope msg = new SOAPEnvelope();
+
+ RPCParam arg = new RPCParam("", "simple", bean);
+ RPCElement body = new RPCElement("urn:myNamespace", "method1", new Object[]{ arg });
+ msg.addBodyElement(body);
+ body.setEncodingStyle(null);
+
+ StringWriter writer = new StringWriter();
+ SerializationContext context = new SerializationContextImpl(writer,
+ msgContext);
+ context.setDoMultiRefs(false);
+
+ // Create a TypeMapping and register the Bean serializer/deserializer
+ TypeMappingRegistry reg = context.getTypeMappingRegistry();
+ TypeMapping tm = (TypeMapping) reg.createTypeMapping();
+ // The "" namespace is literal (no encoding).
+ tm.setSupportedNamespaces(new String[] {Constants.URI_CURRENT_SOAP_ENC});
+ reg.register(Constants.URI_CURRENT_SOAP_ENC, tm);
+
+ QName beanQName = new QName("typeNS", "Bean");
+ tm.register(SimpleBean.class,
+ beanQName,
+ new SimpleNonPrimitiveSerializerFactory(SimpleBean.class, beanQName),
+ new SimpleDeserializerFactory(SimpleBean.class, beanQName));
+
+ // Serialize the bean in to XML
+ msg.output(context);
+ // Get the XML as a string
+ String msgString = writer.toString();
+
+ Message message = new Message(msgString);
+ message.setMessageContext(msgContext);
+ SOAPEnvelope env = message.getSOAPPart().getAsSOAPEnvelope();
+ RPCElement rpcEl = (RPCElement)env.getFirstBody();
+ Vector params = rpcEl.getParams();
+ assertEquals("Wrong # of params in deserialized message!",
+ 1,
+ params.size());
+
+ Object obj = ((RPCParam)params.get(0)).getValue();
+ assertTrue("Deserialized param not a SimpleBean!",
+ (obj instanceof SimpleBean));
+
+ SimpleBean deserBean = (SimpleBean)obj;
+ assertTrue("Deserialized bean not equal to expected values!",
+ (bean.equals(deserBean)));
+ }
}
1.1 xml-axis/java/test/encoding/SimpleBean.java
Index: SimpleBean.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package test.encoding;
import org.apache.axis.description.AttributeDesc;
import org.apache.axis.description.FieldDesc;
import org.apache.axis.description.TypeDesc;
import org.apache.axis.encoding.SimpleType;
import javax.xml.rpc.namespace.QName;
/**
* A simple type with attributes for testing
*/
public class SimpleBean implements SimpleType {
public String value; // Our "actual" value
public float temp; // An attribute
private static TypeDesc typeDesc = new TypeDesc();
static {
FieldDesc fd = new AttributeDesc();
fd.setFieldName("temp");
fd.setXmlName(new QName("foo", "temp"));
typeDesc.addFieldDesc(fd);
}
public static TypeDesc getTypeDesc() { return typeDesc; }
/**
* String constructor
*/
public SimpleBean(String val)
{
value = val;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public float getTemp() {
return temp;
}
public void setTemp(float temp) {
this.temp = temp;
}
public String toString() {
return value;
}
public boolean equals(Object obj)
{
if (obj == null || !(obj instanceof SimpleBean))
return false;
SimpleBean other = (SimpleBean)obj;
if (other.getTemp() != temp) {
return false;
}
if (value == null) {
return other.getValue() == null;
}
return value.equals(other.getValue());
}
}