gdaniels 02/02/20 20:28:27
Modified: java/src/org/apache/axis/encoding
SerializationContextImpl.java
java/src/org/apache/axis/message MessageElement.java
RPCElement.java
java/test/encoding TestDOM.java TestSer.java
Log:
Bulletproof SerializationContextImpl a little more by always using the
default TypeMapping even if there's no MessageContext at all.
Add a unit test which exercises toString() on an RPCElement which was
dynamically created and therefore has no current MessageContext.
Revision Changes Path
1.7 +63 -62
xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java
Index: SerializationContextImpl.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SerializationContextImpl.java 19 Feb 2002 17:38:19 -0000 1.6
+++ SerializationContextImpl.java 21 Feb 2002 04:28:26 -0000 1.7
@@ -141,19 +141,19 @@
/**
* These three variables are necessary to process multi-level object graphs for
multi-ref
- * serialization.
- * While writing out nested multi-ref objects (via outputMultiRef), we
+ * serialization.
+ * While writing out nested multi-ref objects (via outputMultiRef), we
* will fill the secondLevelObjects vector with any new objects encountered.
* The outputMultiRefsFlag indicates whether we are currently within the
- * outputMultiRef() method (so that serialization() knows to update the
+ * outputMultiRef() method (so that serialization() knows to update the
* secondLevelObjects vector).
* The forceSer variable is the trigger to force actual serialization of the
indicated object.
*/
private HashSet secondLevelObjects = null;
private Object forceSer = null;
private boolean outputMultiRefsFlag = false;
-
- /**
+
+ /**
* Construct SerializationContextImpl with associated writer
* @param writer java.io.Writer
*/
@@ -161,9 +161,9 @@
{
this.writer = writer;
}
-
-
- /**
+
+
+ /**
* Construct SerializationContextImpl with associated writer and MessageContext
* @param writer java.io.Writer
* @param msgContext is the MessageContext
@@ -180,14 +180,14 @@
AxisEngine.PROP_XML_DECL);
if (shouldSendDecl != null)
sendXMLDecl = shouldSendDecl.booleanValue();
-
- Boolean shouldSendMultiRefs =
+
+ Boolean shouldSendMultiRefs =
(Boolean)msgContext.getProperty(AxisEngine.PROP_DOMULTIREFS);
-
+
if (shouldSendMultiRefs == null)
shouldSendMultiRefs =
(Boolean)engine.getOption(AxisEngine.PROP_DOMULTIREFS);
-
+
if (shouldSendMultiRefs != null)
doMultiRefs = shouldSendMultiRefs.booleanValue();
@@ -196,7 +196,7 @@
// Only turn this off is the user tells us to
if ( !msgContext.isPropertyTrue(Call.SEND_TYPE_ATTR, true ))
sendXSIType = false ;
-
+
Boolean opt = (Boolean)engine.getOption(AxisEngine.PROP_SEND_XSI);
if ((opt != null) && (opt.equals(Boolean.FALSE))) {
sendXSIType = false;
@@ -219,10 +219,10 @@
public void setPretty(boolean pretty) {
this.pretty = pretty;
}
-
+
/**
* Set whether we are doing multirefs
- */
+ */
public void setDoMultiRefs (boolean shouldDo)
{
doMultiRefs = shouldDo;
@@ -231,7 +231,7 @@
/**
* Set whether or not we should write XML declarations.
* @param sendDecl true/false
- */
+ */
public void setSendDecl(boolean sendDecl)
{
sendXMLDecl = sendDecl;
@@ -240,7 +240,7 @@
/**
* Get whether or not to write xsi:type attributes.
* @return true/false
- */
+ */
public boolean shouldSendXSIType() {
return sendXSIType;
}
@@ -248,21 +248,22 @@
/**
* Get the TypeMapping we're using.
* @return TypeMapping or null
- */
+ */
public TypeMapping getTypeMapping()
{
+ // Always allow the default mappings
if (msgContext == null)
- return null;
-
+ return DefaultTypeMappingImpl.create();
+
return (TypeMapping)
msgContext.getTypeMappingRegistry().getTypeMapping(Constants.URI_CURRENT_SOAP_ENC);
}
/**
* Get the TypeMappingRegistry we're using.
* @return TypeMapping or null
- */
+ */
public TypeMappingRegistry getTypeMappingRegistry() {
- if (msgContext == null)
+ if (msgContext == null)
return null;
return (TypeMappingRegistry) msgContext.getTypeMappingRegistry();
}
@@ -275,18 +276,18 @@
* "ns<num>".
* @param uri is the namespace uri
* @return prefix
- */
+ */
public String getPrefixForURI(String uri)
{
return getPrefixForURI(uri, null);
}
-
+
/**
* Get a prefix for the given namespace URI. If one has already been
* defined in this serialization, use that. Otherwise, map the passed
* default prefix to the URI, and return that. If a null default prefix
* is passed, use one of the form "ns<num>"
- */
+ */
public String getPrefixForURI(String uri, String defaultPrefix)
{
if ((uri == null) || (uri.equals("")))
@@ -329,7 +330,7 @@
/**
* Return the current message
- */
+ */
public Message getCurrentMessage()
{
if (msgContext == null)
@@ -369,7 +370,7 @@
/**
* Indicates whether the object should be interpretted as a primitive
* for the purposes of multi-ref processing. A primitive value
- * is serialized directly instead of using id/href pairs. Thus
+ * is serialized directly instead of using id/href pairs. Thus
* primitive serialization/deserialization is slightly faster.
* @param value to be serialized
* @param javaType is the "real" java type of value. Used to distinguish
@@ -387,7 +388,7 @@
if (Hex.class.isAssignableFrom(javaType)) return true;
if (Element.class.isAssignableFrom(javaType)) return true;
if (byte[].class.isAssignableFrom(javaType)) return true;
-
+
// There has been discussion as to whether arrays themselves should
// be regarded as multi-ref.
// Here are the three options:
@@ -397,9 +398,9 @@
// 2) Arrays are not full-fledged Objects and therefore should
// always be passed as single ref (note the elements of the array
// may be multi-ref'd.) (Pro: This seems reasonable, if a user
- // wants multi-referencing put the array in a container. Also
+ // wants multi-referencing put the array in a container. Also
// is more interop compatible. Con: Not like java serialization.)
- // 3) Arrays of primitives should be single ref, and arrays of
+ // 3) Arrays of primitives should be single ref, and arrays of
// non-primitives should be multi-ref. (Pro: Takes care of the
// looping case. Con: Seems like an obtuse rule.)
//
@@ -409,7 +410,7 @@
// Note that java.lang wrapper classes (i.e. java.lang.Integer) are
// not primitives unless the corresponding type is an xsd type.
// (If the wrapper maps to a soap encoded primitive, it can be nillable
- // and multi-ref'd).
+ // and multi-ref'd).
QName qName = getQNameForClass(javaType);
if (qName != null && Constants.isSchemaXSD(qName.getNamespaceURI())) {
if (qName.equals(Constants.XSD_BOOLEAN) ||
@@ -421,7 +422,7 @@
qName.equals(Constants.XSD_BYTE) ||
qName.equals(Constants.XSD_STRING) ||
qName.equals(Constants.XSD_INTEGER) ||
- qName.equals(Constants.XSD_DECIMAL)) {
+ qName.equals(Constants.XSD_DECIMAL)) {
return true;
}
}
@@ -430,7 +431,7 @@
}
/**
- * Serialize the indicated value as an element named qName. The attributes
object are
+ * Serialize the indicated value as an element named qName. The attributes
object are
* additional attributes that will be serialized with the qName. The value
* could be serialized directly or could be serialized as an href (with the
* actual serialize taking place later)
@@ -438,7 +439,7 @@
* @param attributes are additional attributes
* @param value is the object to serialize
* @param javaType is the "real" type of the value. For primitives, the value
is the
- * associated java.lang class. So the javaType is needed to know that the
value
+ * associated java.lang class. So the javaType is needed to know that the value
* is really a wrapped primitive.
*/
public void serialize(QName qName, Attributes attributes, Object value, Class
javaType)
@@ -471,7 +472,7 @@
//Allow an the attachment to do its own serialization.
serializeActual(qName, attributes, value, javaType);
-
+
//No need to add to mulitRefs. Attachment data stream handled by
// the message;
return;
@@ -480,7 +481,7 @@
// If multi-reference is enabled and this object value is not a primitive
// and we are not forcing serialization of the object, then generate
- // an element href (and store the object for subsequent outputMultiRef
+ // an element href (and store the object for subsequent outputMultiRef
// processing.
if (doMultiRefs && (value != forceSer) && !isPrimitive(value, javaType)) {
if (multiRefIndex == -1)
@@ -545,7 +546,7 @@
// explicitly state that this attribute is not a root
String prefix = getPrefixForURI(Constants.URI_CURRENT_SOAP_ENC);
String root = prefix + ":root";
- attrs.addAttribute(Constants.URI_CURRENT_SOAP_ENC, Constants.ATTR_ROOT,
root,
+ attrs.addAttribute(Constants.URI_CURRENT_SOAP_ENC, Constants.ATTR_ROOT,
root,
"CDATA", "0");
Iterator i = ((HashMap)multiRefValues.clone()).keySet().iterator();
@@ -556,8 +557,8 @@
attrs.setAttribute(0, "", Constants.ATTR_ID, "id", "CDATA",
id);
forceSer = val;
- // Now serialize the value. Note that it is safe to
- // set the javaType argument using value.getClass() because
+ // Now serialize the value. Note that it is safe to
+ // set the javaType argument using value.getClass() because
// values that represent primitives will never get to this point
// because they cannot be multi-ref'ed
serialize(multirefQName, attrs, val, val.getClass());
@@ -743,7 +744,7 @@
writeString(XMLUtils.xmlEncodeString(string));
}
- /**
+ /**
* Output a DOM representation to a SerializationContext
* @param el is a DOM Element
*/
@@ -802,11 +803,11 @@
* java type
* @param javaType is Class for a type to serialize
* @return Serializer
- */
+ */
public final Serializer getSerializerForJavaType(Class javaType) {
SerializerFactory dserF = null;
Serializer dser = null;
- try {
+ try {
dserF = (SerializerFactory) getTypeMapping().getSerializer(javaType);
} catch (JAXRPCException e) {
}
@@ -832,11 +833,11 @@
(attributes.getIndex(Constants.URI_CURRENT_SCHEMA_XSI,
"type") != -1)))
return attributes;
-
+
AttributesImpl attrs = new AttributesImpl();
if (attributes != null)
attrs.setAttributes(attributes);
-
+
String prefix = getPrefixForURI(Constants.URI_CURRENT_SCHEMA_XSI,
"xsi");
@@ -846,15 +847,15 @@
"CDATA", qName2String(type));
return attrs;
}
-
+
/**
* Invoked to do the actual serialization of the qName (called by serialize
above).
- * additional attributes that will be serialized with the qName.
+ * additional attributes that will be serialized with the qName.
* @param qName is the QName of the element
* @param attributes are additional attributes
* @param value is the object to serialize
* @param javaType is the "real" type of the value. For primitives, the value
is the
- * associated java.lang class. So the javaType is needed to know that the
value
+ * associated java.lang class. So the javaType is needed to know that the value
* is really a wrapped primitive.
*/
public void serializeActual(QName name, Attributes attributes, Object value,
Class javaType)
@@ -862,7 +863,7 @@
{
if (value != null) {
TypeMapping tm = getTypeMapping();
-
+
if (tm == null) {
throw new IOException(JavaUtils.getMessage("noSerializer00",
value.getClass().getName(), "" + this));
@@ -874,7 +875,7 @@
attributes = setTypeAttribute(attributes, type);
// The multiref QName is our own fake name.
- // It may be beneficial to set the name to the
+ // It may be beneficial to set the name to the
// type name, but I didn't see any improvements
// in the interop tests.
//if (name.equals(multirefQName) && type != null)
@@ -895,7 +896,7 @@
}
/**
* getSerializer
- * Attempts to get a serializer for the indicated type. Failure to
+ * Attempts to get a serializer for the indicated type. Failure to
* find a serializer causes the code to look backwards through the
* inheritance list. Continued failured results in an attempt to find
* a serializer for the type of the value.
@@ -907,43 +908,43 @@
Class_Serializer pair = null;
SerializerFactory serFactory = null ;
TypeMapping tm = getTypeMapping();
-
- // Classes is a list of the inherited interfaces to
+
+ // Classes is a list of the inherited interfaces to
// check
ArrayList classes = null;
boolean firstPass = true;
-
+
// Search for a class that has a serializer factory
- Class _class = javaType;
+ Class _class = javaType;
while( _class != null ) {
try {
serFactory = (SerializerFactory) tm.getSerializer(_class);
} catch(JAXRPCException e) {
// For now continue if JAXRPCException
}
- if (serFactory != null) {
+ if (serFactory != null) {
break ;
}
if ( classes == null ) {
classes = new ArrayList();
}
Class[] ifaces = _class.getInterfaces();
- for (int i = 0 ; i < ifaces.length ; i++ ) {
+ for (int i = 0 ; i < ifaces.length ; i++ ) {
classes.add( ifaces[i] );
}
_class = _class.getSuperclass();
-
+
// Add any non-null (and non-Object) class. We skip
// the Object class because if we reach that then
- // there's an error and this error message return
+ // there's an error and this error message return
// here is better than the one returned by the
// ObjSerializer.
if ( _class != null &&
!_class.getName().equals("java.lang.Object")) {
classes.add( _class );
}
-
- _class = (!classes.isEmpty()) ?
+
+ _class = (!classes.isEmpty()) ?
(Class) classes.remove( 0 ) :
null;
@@ -957,7 +958,7 @@
_class = value.getClass();
}
}
-
+
// Using the serialization factory, create a serializer and
// serialize the value.
Serializer ser = null;
@@ -972,7 +973,7 @@
pair.ser = ser;
pair.javaType = _class;
}
- return pair;
+ return pair;
}
}
1.76 +1 -0 xml-axis/java/src/org/apache/axis/message/MessageElement.java
Index: MessageElement.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/MessageElement.java,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -r1.75 -r1.76
--- MessageElement.java 21 Feb 2002 04:01:48 -0000 1.75
+++ MessageElement.java 21 Feb 2002 04:28:26 -0000 1.76
@@ -432,6 +432,7 @@
msgContext = MessageContext.getCurrentContext();
}
serializeContext = new SerializationContextImpl(writer, msgContext);
+ serializeContext.setSendDecl(false);
output(serializeContext);
writer.close();
1.34 +1 -1 xml-axis/java/src/org/apache/axis/message/RPCElement.java
Index: RPCElement.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCElement.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- RPCElement.java 20 Feb 2002 20:22:07 -0000 1.33
+++ RPCElement.java 21 Feb 2002 04:28:27 -0000 1.34
@@ -77,7 +77,7 @@
protected boolean needDeser = false;
// encoding style to put in soap body element
- protected String encodingStyle = null;
+ protected String encodingStyle = Constants.URI_CURRENT_SOAP_ENC;
public RPCElement(String namespace, String localName, String prefix,
Attributes attributes, DeserializationContext context)
1.9 +3 -47 xml-axis/java/test/encoding/TestDOM.java
Index: TestDOM.java
===================================================================
RCS file: /home/cvs/xml-axis/java/test/encoding/TestDOM.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TestDOM.java 4 Dec 2001 16:01:03 -0000 1.8
+++ TestDOM.java 21 Feb 2002 04:28:27 -0000 1.9
@@ -21,93 +21,50 @@
public class TestDOM extends TestCase {
-
-
public TestDOM(String name) {
-
super(name);
-
}
-
-
private String request =
-
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
-
"<SOAP-ENV:Envelope" +
-
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"" +
-
" 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:Header>\n" +
-
" <SOAP-SEC:signature SOAP-ENV:actor=\"null\"
SOAP-ENV:mustUnderstand=\"1\"" +
-
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
-
" xmlns:SOAP-SEC=\"http://schemas.xmlsoap.org/soap/security/\">\n" +
-
" <Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">\n" +
-
" </Signature>\n" +
-
" </SOAP-SEC:signature>\n" +
-
" </SOAP-ENV:Header>\n" +
-
" <SOAP-ENV:Body id=\"body\">\n" +
-
" <ns1:getQuote xmlns:ns1=\"urn:xmltoday-delayed-quotes\">\n" +
-
" <symbol xsi:type=\"xsd:string\">IBM</symbol>\n" +
-
" </ns1:getQuote>\n" +
-
" </SOAP-ENV:Body>\n" +
-
"</SOAP-ENV:Envelope>";
-
-
public void testDOM() throws Exception {
-
-
// setup
-
AxisEngine engine = new AxisServer();
-
engine.init();
-
MessageContext msgContext = new MessageContext(engine);
-
Message message = new Message(request);
-
message.setMessageContext(msgContext);
-
-
// Now completely round trip it
-
SOAPEnvelope envelope = message.getSOAPPart().getAsSOAPEnvelope();
-
// Element dom = message.getAsDOM();
-
String result = message.getSOAPPart().getAsString();
-
-
assertEquals("Request is not the same as the result.", request, result);
-
}
-
- public void testEmptyNode() throws Exception
+
+ public void testEmptyNode() throws Exception
{
SOAPBodyElement body = new
SOAPBodyElement(XMLUtils.newDocument().createElement("tmp"));
assertEquals("<tmp/>",body.toString());
@@ -120,7 +77,7 @@
SOAPBodyElement body = new SOAPBodyElement(element);
assertEquals("<tmp attrib=\"foo\"/>",body.toString());
}
-
+
public static void main(String [] args) throws Exception
{
TestDOM tester = new TestDOM("TestDOM");
@@ -128,6 +85,5 @@
tester.testEmptyNode();
tester.testDOM();
}
-
}
1.21 +16 -0 xml-axis/java/test/encoding/TestSer.java
Index: TestSer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/test/encoding/TestSer.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- TestSer.java 19 Feb 2002 17:38:22 -0000 1.20
+++ TestSer.java 21 Feb 2002 04:28:27 -0000 1.21
@@ -101,4 +101,20 @@
assertEquals("Data and Val float members are not
equal",data.floatMember.floatValue(),
val.floatMember.floatValue(), 0.00001F);
}
+
+ /**
+ * Test RPC element serialization when we have no MessageContext
+ */
+ public void testRPCElement() throws Exception
+ {
+ SOAPEnvelope env = new SOAPEnvelope();
+ RPCElement method = new RPCElement("ns",
+ "method",
+ new Object [] { "argument" });
+ env.addBodyElement(method);
+ String soapStr = env.toString();
+
+ // If there was no exception, we succeeded in serializing it.
+ }
+
}