Java tutorial
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed 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.axis.message; import org.apache.axis.components.logger.LogFactory; import org.apache.axis.description.ParameterDesc; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.utils.JavaUtils; import org.apache.axis.utils.Messages; import org.apache.axis.constants.Style; import org.apache.axis.Constants; import org.apache.axis.MessageContext; import org.apache.commons.logging.Log; import javax.xml.namespace.QName; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Method; import java.util.ArrayList; /** An RPC parameter * * @author Glen Daniels (gdaniels@apache.org) */ public class RPCParam extends MessageElement implements Serializable { protected static Log log = LogFactory.getLog(RPCParam.class.getName()); private Object value = null; private int countSetCalls = 0; // counts number of calls to set private ParameterDesc paramDesc; /** * Do we definitely want (or don't want) to send xsi:types? If null * (the default), just do whatever our SerializationContext is configured * to do. If TRUE or FALSE, the SerializationContext will do what we * want. */ private Boolean wantXSIType = null; private static Method valueSetMethod; static { Class cls = RPCParam.class; try { valueSetMethod = cls.getMethod("set", new Class[] { Object.class }); } catch (NoSuchMethodException e) { log.error(Messages.getMessage("noValue00", "" + e)); throw new RuntimeException(e.getMessage()); } } /** Constructor for building up messages. */ public RPCParam(String name, Object value) { this(new QName("", name), value); } public RPCParam(QName qname, Object value) { super(qname); if (value instanceof java.lang.String) { try { this.addTextNode((String) value); } catch (SOAPException e) { throw new RuntimeException(Messages.getMessage("cannotCreateTextNode00")); } } else { this.value = value; } } public RPCParam(String namespace, String name, Object value) { this(new QName(namespace, name), value); } public void setRPCCall(RPCElement call) { parent = call; } public Object getObjectValue() { return value; } public void setObjectValue(Object value) { this.value = value; } /** * This set method is registered during deserialization * to set the deserialized value. * If the method is called multiple times, the * value is automatically changed into a container to * hold all of the values. * @param newValue is the deserialized object */ public void set(Object newValue) { countSetCalls++; // If this is the first call, // simply set the value. if (countSetCalls == 1) { this.value = newValue; return; } // If this is the second call, create an // ArrayList to hold all the values else if (countSetCalls == 2) { ArrayList list = new ArrayList(); list.add(this.value); this.value = list; } // Add the new value to the list ((ArrayList) this.value).add(newValue); } public static Method getValueSetMethod() { return valueSetMethod; } public ParameterDesc getParamDesc() { return paramDesc; } public void setParamDesc(ParameterDesc paramDesc) { this.paramDesc = paramDesc; } public void setXSITypeGeneration(Boolean value) { this.wantXSIType = value; } public Boolean getXSITypeGeneration() { return this.wantXSIType; } public void serialize(SerializationContext context) throws IOException { // Set the javaType to value's class unless // parameter description information exists. // Set the xmlType using the parameter description // information. (an xmlType=null causes the // serialize method to search for a compatible xmlType) Class javaType = value == null ? null : value.getClass(); QName xmlType = null; // we'll send a null unless our description tells us // that we may be omitted Boolean sendNull = Boolean.TRUE; if (paramDesc != null) { if (javaType == null) { javaType = paramDesc.getJavaType() != null ? paramDesc.getJavaType() : javaType; } else if (!(javaType.equals(paramDesc.getJavaType()))) { Class clazz = JavaUtils.getPrimitiveClass(javaType); if (clazz == null || !clazz.equals(paramDesc.getJavaType())) { if (!(javaType.equals(JavaUtils.getHolderValueType(paramDesc.getJavaType())))) { // This must (assumedly) be a polymorphic type - in ALL // such cases, we must send an xsi:type attribute. wantXSIType = Boolean.TRUE; } } } xmlType = paramDesc.getTypeQName(); QName itemQName = paramDesc.getItemQName(); if (itemQName == null) { MessageContext mc = context.getMessageContext(); if (mc != null && mc.getOperation() != null && mc.getOperation().getStyle() == Style.DOCUMENT) { itemQName = Constants.QNAME_LITERAL_ITEM; } } context.setItemQName(itemQName); QName itemType = paramDesc.getItemType(); context.setItemType(itemType); // don't send anything if we're able to be omitted, // although we'll prefer to send xsi:nill if possible if (paramDesc.isOmittable() && !paramDesc.isNillable()) sendNull = Boolean.FALSE; } context.serialize(getQName(), // element qname null, // no extra attrs value, // value xmlType, // java/xml type sendNull, wantXSIType); } private void writeObject(ObjectOutputStream out) throws IOException { if (getQName() == null) { out.writeBoolean(false); } else { out.writeBoolean(true); out.writeObject(getQName().getNamespaceURI()); out.writeObject(getQName().getLocalPart()); } out.defaultWriteObject(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { if (in.readBoolean()) { setQName(new QName((String) in.readObject(), (String) in.readObject())); } in.defaultReadObject(); } protected void outputImpl(SerializationContext context) throws Exception { serialize(context); } public String getValue() { return getValueDOM(); } /** * @see javax.xml.soap.SOAPElement#addTextNode(java.lang.String) */ public SOAPElement addTextNode(String s) throws SOAPException { value = s; return super.addTextNode(s); } /** * @see javax.xml.soap.Node#setValue(java.lang.String) */ public void setValue(String value) { this.value = value; super.setValue(value); } }