1 package org.codehaus.xfire.service.binding; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Iterator; 6 import java.util.List; 7 8 import javax.wsdl.Message; 9 import javax.wsdl.Part; 10 import javax.xml.namespace.QName; 11 import javax.xml.stream.XMLStreamWriter; 12 13 import org.codehaus.xfire.MessageContext; 14 import org.codehaus.xfire.exchange.InMessage; 15 import org.codehaus.xfire.exchange.OutMessage; 16 import org.codehaus.xfire.fault.XFireFault; 17 import org.codehaus.xfire.service.MessageInfo; 18 import org.codehaus.xfire.service.MessagePartInfo; 19 import org.codehaus.xfire.service.OperationInfo; 20 import org.codehaus.xfire.service.Service; 21 import org.codehaus.xfire.soap.SoapConstants; 22 import org.codehaus.xfire.util.DepthXMLStreamReader; 23 import org.codehaus.xfire.util.STAXUtils; 24 import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding; 25 import org.codehaus.xfire.wsdl11.builder.WSDLBuilder; 26 27 public class DocumentBinding 28 extends AbstractBinding 29 implements WSDL11ParameterBinding, Cloneable 30 { 31 public DocumentBinding() 32 { 33 setStyle(SoapConstants.STYLE_DOCUMENT); 34 setUse(SoapConstants.USE_LITERAL); 35 } 36 37 public void readMessage(InMessage inMessage, MessageContext context) 38 throws XFireFault 39 { 40 Service endpoint = context.getService(); 41 42 List parameters = new ArrayList(); 43 DepthXMLStreamReader dr = new DepthXMLStreamReader(context.getInMessage().getXMLStreamReader()); 44 45 while (STAXUtils.toNextElement(dr)) 46 { 47 MessagePartInfo p = findMessagePart(endpoint, dr.getName()); 48 49 if (p == null) 50 { 51 throw new XFireFault("Parameter " + dr.getName() + " does not exist!", 52 XFireFault.SENDER); 53 } 54 55 parameters.add( getBindingProvider().readParameter(p, dr, context) ); 56 } 57 58 if (!isClientModeOn()) 59 { 60 setOperation(findOperation(endpoint, parameters), context); 61 } 62 63 context.getInMessage().setBody(parameters); 64 } 65 66 public void writeMessage(OutMessage message, XMLStreamWriter writer, MessageContext context) 67 throws XFireFault 68 { 69 OperationInfo op = context.getExchange().getOperation(); 70 Object[] values = (Object[]) message.getBody(); 71 int i = 0; 72 73 MessageInfo msgInfo = null; 74 if (isClientModeOn()) 75 { 76 msgInfo = op.getInputMessage(); 77 } 78 else 79 { 80 msgInfo = op.getOutputMessage(); 81 } 82 83 for(Iterator itr = msgInfo.getMessageParts().iterator(); itr.hasNext();) 84 { 85 MessagePartInfo outParam = (MessagePartInfo) itr.next(); 86 87 getBindingProvider().writeParameter(outParam, writer, context, values[i]); 88 i++; 89 } 90 } 91 92 protected OperationInfo findOperation(Service endpoint, List parameters) 93 { 94 for ( Iterator itr = endpoint.getServiceInfo().getOperations().iterator(); itr.hasNext(); ) 95 { 96 OperationInfo o = (OperationInfo) itr.next(); 97 List messageParts = o.getInputMessage().getMessageParts(); 98 if ( messageParts.size() == parameters.size() ) 99 { 100 if (checkParameters(messageParts, parameters)) 101 return o; 102 } 103 } 104 105 return null; 106 } 107 108 private boolean checkParameters(List messageParts, List parameters) 109 { 110 Iterator messagePartIterator = messageParts.iterator(); 111 for (Iterator parameterIterator = parameters.iterator(); parameterIterator.hasNext();) 112 { 113 Object param = parameterIterator.next(); 114 MessagePartInfo mpi = (MessagePartInfo) messagePartIterator.next(); 115 if (!mpi.getTypeClass().isAssignableFrom(param.getClass())) 116 return false; 117 } 118 return true; 119 } 120 121 protected MessagePartInfo findMessagePart(Service endpoint, QName name) 122 { 123 124 for ( Iterator itr = endpoint.getServiceInfo().getOperations().iterator(); itr.hasNext(); ) 125 { 126 OperationInfo op = (OperationInfo) itr.next(); 127 MessageInfo msgInfo = null; 128 if (isClientModeOn()) 129 { 130 msgInfo = op.getOutputMessage(); 131 } 132 else 133 { 134 msgInfo = op.getInputMessage(); 135 } 136 137 MessagePartInfo p = msgInfo.getMessagePart(name); 138 139 if ( p != null ) 140 return p; 141 } 142 return null; 143 } 144 145 146 public void createInputParts(WSDLBuilder builder, 147 Message req, 148 OperationInfo op) 149 { 150 writeParameters(builder, req, op.getInputMessage().getMessageParts()); 151 } 152 153 public void createOutputParts(WSDLBuilder builder, 154 Message req, 155 OperationInfo op) 156 { 157 writeParameters(builder, req, op.getOutputMessage().getMessageParts()); 158 } 159 160 private void writeParameters(WSDLBuilder builder, 161 Message message, 162 Collection params) 163 { 164 for (Iterator itr = params.iterator(); itr.hasNext();) 165 { 166 MessagePartInfo param = (MessagePartInfo) itr.next(); 167 168 builder.addNamespaceImport(builder.getService().getServiceInfo().getName().getNamespaceURI(), 169 param.getSchemaType().getSchemaType().getNamespaceURI()); 170 171 Part part = builder.createPart(param); 172 173 message.addPart(part); 174 } 175 } 176 177 public Object clone() 178 { 179 DocumentBinding binding = new DocumentBinding(); 180 binding.setBindingProvider(getBindingProvider()); 181 182 return binding; 183 } 184 }