| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| |
| package org.eclipse.persistence.internal.dbws; |
| |
| //javase imports |
| |
| import static jakarta.xml.soap.SOAPConstants.SOAP_1_2_PROTOCOL; |
| import static jakarta.xml.soap.SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE; |
| import static jakarta.xml.soap.SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE; |
| import static jakarta.xml.ws.handler.MessageContext.INBOUND_MESSAGE_ATTACHMENTS; |
| import static org.eclipse.persistence.internal.dbws.SOAPResponseWriter.RECEIVER_QNAME; |
| import static org.eclipse.persistence.internal.dbws.SOAPResponseWriter.SERVER_QNAME; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_SCHEMA_XML; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_SERVICE_XML; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_WSDL; |
| import static org.eclipse.persistence.internal.xr.Util.META_INF_PATHS; |
| import static org.eclipse.persistence.internal.xr.Util.SCHEMA_2_CLASS; |
| import static org.eclipse.persistence.internal.xr.Util.SERVICE_NAMESPACE_PREFIX; |
| import static org.eclipse.persistence.internal.xr.Util.WEB_INF_DIR; |
| import static org.eclipse.persistence.internal.xr.Util.WSDL_DIR; |
| import static org.eclipse.persistence.oxm.mappings.UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import jakarta.activation.DataHandler; |
| import jakarta.servlet.ServletContext; |
| import javax.xml.namespace.QName; |
| import jakarta.xml.soap.SOAPBodyElement; |
| import jakarta.xml.soap.SOAPElement; |
| import jakarta.xml.soap.SOAPEnvelope; |
| import jakarta.xml.soap.SOAPException; |
| import jakarta.xml.soap.SOAPFactory; |
| import jakarta.xml.soap.SOAPFault; |
| import jakarta.xml.soap.SOAPMessage; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.stream.StreamResult; |
| import javax.xml.transform.stream.StreamSource; |
| import jakarta.xml.ws.Provider; |
| import jakarta.xml.ws.WebServiceException; |
| import jakarta.xml.ws.handler.MessageContext; |
| import jakarta.xml.ws.soap.SOAPFaultException; |
| |
| import org.eclipse.persistence.dbws.DBWSModelProject; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.exceptions.DBWSException; |
| import org.eclipse.persistence.exceptions.XMLMarshalException; |
| import org.eclipse.persistence.internal.oxm.XMLConversionManager; |
| import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject; |
| import org.eclipse.persistence.internal.oxm.schema.model.ComplexType; |
| import org.eclipse.persistence.internal.oxm.schema.model.Schema; |
| import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl; |
| import org.eclipse.persistence.internal.xr.Invocation; |
| import org.eclipse.persistence.internal.xr.Operation; |
| import org.eclipse.persistence.internal.xr.Parameter; |
| import org.eclipse.persistence.internal.xr.ValueObject; |
| import org.eclipse.persistence.internal.xr.XRServiceAdapter; |
| import org.eclipse.persistence.internal.xr.XRServiceFactory; |
| import org.eclipse.persistence.internal.xr.XRServiceModel; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.mappings.AttributeAccessor; |
| import org.eclipse.persistence.oxm.NamespaceResolver; |
| import org.eclipse.persistence.oxm.XMLContext; |
| import org.eclipse.persistence.oxm.XMLDescriptor; |
| import org.eclipse.persistence.oxm.XMLRoot; |
| import org.eclipse.persistence.oxm.XMLUnmarshaller; |
| import org.eclipse.persistence.oxm.attachment.XMLAttachmentUnmarshaller; |
| import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping; |
| import org.eclipse.persistence.oxm.schema.XMLSchemaReference; |
| import org.eclipse.persistence.sessions.Project; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| // Java extension imports |
| // EclipseLink imports |
| |
| /** |
| * <p> |
| * <b>INTERNAL:</b> ProviderHelper bridges between {@link DBWSAdapter}'s and JAX-WS {@link Provider}'s |
| * |
| * @author Mike Norman - michael.norman@oracle.com |
| * @since EclipseLink 1.1 |
| * <pre> |
| * packaging required for deployment as a Web Service |
| * \--- root of war file |
| * | |
| * \---web-inf |
| * | web.xml |
| * | |
| * +---classes |
| * | +---META-INF |
| * | | eclipselink-dbws.xml |
| * | | eclipselink-dbws-sessions.xml -- name can be overridden by <sessions-file> entry in eclipselink-dbws.xml |
| * | | eclipselink-dbws-or.xml |
| * | | eclipselink-dbws-ox.xml |
| * | | |
| * | +---_dbws |
| * | | DBWSProvider.java -- (source provided as a convenience for IDE integration) |
| * | | DBWSProvider.class -- ASM-generated jakarta.xml.ws.Provider |
| * | | |
| * | \---foo -- optional domain classes |
| * | \---bar |
| * | Address.class |
| * | Employee.class |
| * | PhoneNumber.class |
| * \---wsdl |
| * swaref.xsd -- optional to handle attachments |
| * eclipselink-dbws.wsdl |
| * eclipselink-dbws-schema.xsd |
| * </pre> |
| */ |
| public class ProviderHelper extends XRServiceFactory { |
| public static final QName SENDER_QNAME = new QName(URI_NS_SOAP_1_2_ENVELOPE, "Sender"); |
| public static final QName CLIENT_QNAME = new QName(URI_NS_SOAP_1_1_ENVELOPE, "Client"); |
| |
| protected static final String XSL_PREAMBLE = |
| "<?xml version=\"1.0\"?> " + |
| "<xsl:stylesheet " + |
| "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\" " + |
| "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + |
| "xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" " + |
| "> " + |
| "<xsl:output method=\"xml\" encoding=\"UTF-8\"/> "; |
| protected static final String XSL_POSTSCRIPT = "</xsl:stylesheet>"; |
| public static final String MATCH_SCHEMA = |
| XSL_PREAMBLE + |
| "<xsl:template match=\"/\">" + |
| "<xsl:apply-templates/>" + |
| "</xsl:template>" + |
| "<xsl:template match=\"//xsd:schema\">" + |
| "<xsl:copy-of select=\".\"/>" + |
| "</xsl:template>" + |
| XSL_POSTSCRIPT; |
| public SOAPResponseWriter responseWriter = null; |
| protected boolean mtomEnabled; |
| protected MessageContext mc; |
| |
| // Default constructor required by servlet/jax-ws spec |
| public ProviderHelper() { |
| super(); |
| } |
| |
| protected void setMessageContext(MessageContext mc) { |
| this.mc = mc; |
| } |
| |
| protected InputStream initXRServiceStream(ClassLoader parentClassLoader, |
| @SuppressWarnings("unused") ServletContext sc) { |
| InputStream xrServiceStream = null; |
| for (String searchPath : META_INF_PATHS) { |
| String path = searchPath + DBWS_SERVICE_XML; |
| xrServiceStream = parentClassLoader.getResourceAsStream(path); |
| if (xrServiceStream != null) { |
| break; |
| } |
| } |
| if (xrServiceStream == null) { |
| throw new WebServiceException(DBWSException.couldNotLocateFile(DBWS_SERVICE_XML)); |
| } |
| return xrServiceStream; |
| } |
| |
| protected InputStream initXRSchemaStream(ClassLoader parentClassLoader, ServletContext sc) { |
| InputStream xrSchemaStream = null; |
| String path = WSDL_DIR + DBWS_SCHEMA_XML; |
| if (sc != null) { |
| path = "/" + WEB_INF_DIR + path; |
| xrSchemaStream = sc.getResourceAsStream(path); |
| } |
| else { |
| // if ServletContext is null, then we are running in JavaSE6 'container-less' mode |
| xrSchemaStream = parentClassLoader.getResourceAsStream(path); |
| } |
| if (xrSchemaStream == null) { |
| throw new WebServiceException(DBWSException.couldNotLocateFile(DBWS_SCHEMA_XML)); |
| } |
| return xrSchemaStream; |
| } |
| |
| protected InputStream initWSDLInputStream(ClassLoader parentClassLoader, ServletContext sc) { |
| InputStream wsdlInputStream = null; |
| String path = WSDL_DIR + DBWS_WSDL; |
| if (sc != null) { |
| path = "/" + WEB_INF_DIR + path; |
| wsdlInputStream = sc.getResourceAsStream(path); |
| } |
| else { |
| // if ServletContext is null, then we are running in JavaSE6 'container-less' mode |
| wsdlInputStream = parentClassLoader.getResourceAsStream(path); |
| } |
| if (wsdlInputStream == null) { |
| throw new WebServiceException(DBWSException.couldNotLocateFile(DBWS_WSDL)); |
| } |
| return wsdlInputStream; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public void init(ClassLoader parentClassLoader, ServletContext sc, boolean mtomEnabled) { |
| this.parentClassLoader = parentClassLoader; |
| this.mtomEnabled = mtomEnabled; |
| |
| InputStream xrServiceStream = initXRServiceStream(parentClassLoader, sc); |
| DBWSModelProject xrServiceModelProject = new DBWSModelProject(); |
| XMLContext xmlContext = new XMLContext(xrServiceModelProject); |
| XMLUnmarshaller unmarshaller = xmlContext.createUnmarshaller(); |
| XRServiceModel xrServiceModel; |
| try { |
| xrServiceModel = (XRServiceModel)unmarshaller.unmarshal(xrServiceStream); |
| } |
| catch (XMLMarshalException e) { |
| // something went wrong parsing the eclipselink-dbws.xml - can't recover from that |
| throw new WebServiceException(DBWSException.couldNotParseDBWSFile()); |
| } |
| finally { |
| try { |
| xrServiceStream.close(); |
| } |
| catch (IOException e) { |
| // ignore |
| } |
| } |
| |
| xrSchemaStream = initXRSchemaStream(parentClassLoader, sc); |
| try { |
| buildService(xrServiceModel); // inherit xrService processing from XRServiceFactory |
| } |
| catch (Exception e) { |
| // something went wrong building the service |
| throw new WebServiceException(e); |
| } |
| |
| // the xrService built by 'buildService' above is overridden to produce an |
| // instance of DBWSAdapter (a sub-class of XRService) |
| DBWSAdapter dbwsAdapter = (DBWSAdapter)xrService; |
| |
| // get inline schema from WSDL - has additional types for the operations |
| try (InputStream wsdlInputStream = initWSDLInputStream(parentClassLoader, sc)) { |
| StringWriter sw = new StringWriter(); |
| StreamSource wsdlStreamSource = new StreamSource(wsdlInputStream); |
| Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource( |
| new StringReader(MATCH_SCHEMA))); |
| StreamResult streamResult = new StreamResult(sw); |
| t.transform(wsdlStreamSource, streamResult); |
| SchemaModelProject schemaProject = new SchemaModelProject(); |
| XMLContext xmlContext2 = new XMLContext(schemaProject); |
| unmarshaller = xmlContext2.createUnmarshaller(); |
| Schema extendedSchema = (Schema)unmarshaller.unmarshal(new StringReader(sw.toString())); |
| dbwsAdapter.setExtendedSchema(extendedSchema); |
| } catch (IOException | TransformerException e) { |
| // that's Ok, WSDL may not contain inline schema |
| xmlContext.getSession().getSessionLog().log( |
| SessionLog.FINE, SessionLog.DBWS, "dbws_no_wsdl_inline_schema", e.getLocalizedMessage()); |
| } |
| |
| // an Invocation needs a mapping for its parameters - use XMLAnyCollectionMapping + |
| // custom AttributeAccessor |
| // NB - this code is NOt in it own initNNN method, cannot be overridden |
| String tns = dbwsAdapter.getExtendedSchema().getTargetNamespace(); |
| Project oxProject = dbwsAdapter.getOXSession().getProject(); |
| XMLDescriptor invocationDescriptor = new XMLDescriptor(); |
| invocationDescriptor.setJavaClass(Invocation.class); |
| NamespaceResolver nr = new NamespaceResolver(); |
| invocationDescriptor.setNamespaceResolver(nr); |
| nr.put(SERVICE_NAMESPACE_PREFIX, tns); |
| nr.setDefaultNamespaceURI(tns); |
| XMLAnyCollectionMapping parametersMapping = new XMLAnyCollectionMapping(); |
| parametersMapping.setAttributeName("parameters"); |
| parametersMapping.setAttributeAccessor(new AttributeAccessor() { |
| Project oxProject; |
| DBWSAdapter dbwsAdapter; |
| @Override |
| public Object getAttributeValueFromObject(Object object) { |
| return ((Invocation)object).getParameters(); |
| } |
| @Override |
| public void setAttributeValueInObject(Object object, Object value) { |
| Invocation invocation = (Invocation)object; |
| Vector<Object> values = (Vector<Object>)value; |
| for (Iterator<Object> i = values.iterator(); i.hasNext();) { |
| /* scan through values: |
| * if XML conforms to something mapped, it an object; else it is a DOM Element |
| * (probably a scalar). Walk through operations for the types, converting |
| * as required. The 'key' is the local name of the element - for mapped objects, |
| * have to get the element name from the schema context for the object |
| */ |
| Object o = i.next(); |
| if (o instanceof Element) { |
| Element e = (Element)o; |
| String key = e.getLocalName(); |
| if ("theInstance".equals(key)) { |
| NodeList nl = e.getChildNodes(); |
| for (int j = 0; j < nl.getLength(); j++) { |
| Node n = nl.item(j); |
| if (n.getNodeType() == Node.ELEMENT_NODE) { |
| try { |
| Object theInstance = |
| dbwsAdapter.getXMLContext().createUnmarshaller().unmarshal(n); |
| if (theInstance instanceof XMLRoot) { |
| theInstance = ((XMLRoot)theInstance).getObject(); |
| } |
| invocation.setParameter(key, theInstance); |
| break; |
| } |
| catch (XMLMarshalException xmlMarshallException) { |
| throw new WebServiceException(xmlMarshallException); |
| } |
| } |
| } |
| } |
| else { |
| ClassDescriptor desc = null; |
| for (ClassDescriptor xdesc : oxProject.getOrderedDescriptors()) { |
| XMLSchemaReference schemaReference = xdesc instanceof XMLDescriptor |
| ? ((XMLDescriptor)xdesc).getSchemaReference() : null; |
| if (schemaReference != null && schemaReference.getSchemaContext().equalsIgnoreCase(key)) { |
| desc = xdesc; |
| break; |
| } |
| } |
| if (desc != null) { |
| try { |
| Object theObject = |
| dbwsAdapter.getXMLContext().createUnmarshaller().unmarshal(e, |
| desc.getJavaClass()); |
| if (theObject instanceof XMLRoot) { |
| theObject = ((XMLRoot)theObject).getObject(); |
| } |
| invocation.setParameter(key, theObject); |
| } |
| catch (XMLMarshalException xmlMarshallException) { |
| throw new WebServiceException(xmlMarshallException); |
| } |
| } |
| else { |
| String serviceName = e.getParentNode().getLocalName(); |
| boolean found = false; |
| for (Operation op : dbwsAdapter.getOperationsList()) { |
| if (op.getName().equals(serviceName)) { |
| for (Parameter p : op.getParameters()) { |
| if (p.getName().equals(key)) { |
| desc = dbwsAdapter.getDescriptorsByQName().get(p.getType()); |
| if (desc != null) { |
| found = true; |
| } |
| break; |
| } |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| if (found) { |
| Object theObject = |
| dbwsAdapter.getXMLContext().createUnmarshaller().unmarshal(e, |
| desc.getJavaClass()); |
| if (theObject instanceof XMLRoot) { |
| theObject = ((XMLRoot)theObject).getObject(); |
| } |
| invocation.setParameter(key, theObject); |
| } |
| else { |
| // cant use e.getTextContent() - some DOM impls dont support it :-( |
| //String val = e.getTextContent(); |
| StringBuilder sb = new StringBuilder(); |
| NodeList childNodes = e.getChildNodes(); |
| for(int idx=0; idx < childNodes.getLength(); idx++ ) { |
| if (childNodes.item(idx).getNodeType() == Node.TEXT_NODE ) { |
| sb.append(childNodes.item(idx).getNodeValue()); |
| } |
| } |
| invocation.setParameter(key, sb.toString()); |
| } |
| } |
| } |
| } |
| else { |
| XMLDescriptor descriptor = (XMLDescriptor)oxProject.getDescriptor(o.getClass()); |
| String key = descriptor.getDefaultRootElement(); |
| int idx = key.indexOf(':'); |
| if (idx != -1) { |
| key = key.substring(idx+1); |
| } |
| invocation.setParameter(key, o); |
| } |
| } |
| } |
| public AttributeAccessor setProjectAndAdapter(Project oxProject, DBWSAdapter dbwsAdapter) { |
| this.oxProject = oxProject; |
| this.dbwsAdapter = dbwsAdapter; |
| return this; |
| } |
| }.setProjectAndAdapter(oxProject, dbwsAdapter)); |
| parametersMapping.setKeepAsElementPolicy(KEEP_UNKNOWN_AS_ELEMENT); |
| invocationDescriptor.addMapping(parametersMapping); |
| oxProject.addDescriptor(invocationDescriptor); |
| ((DatabaseSessionImpl)dbwsAdapter.getOXSession()).initializeDescriptorIfSessionAlive(invocationDescriptor); |
| dbwsAdapter.getXMLContext().storeXMLDescriptorByQName(invocationDescriptor); |
| |
| // create SOAP message response handler of appropriate version |
| responseWriter = new SOAPResponseWriter(dbwsAdapter); |
| responseWriter.initialize(); |
| } |
| |
| @SuppressWarnings({"unchecked"}) |
| public SOAPMessage invoke(SOAPMessage request) { |
| Map<String,DataHandler> attachments = null; |
| if (mtomEnabled) { |
| attachments = (Map<String, DataHandler>)mc.get(INBOUND_MESSAGE_ATTACHMENTS); |
| } |
| SOAPMessage response = null; |
| boolean usesSOAP12 = false; |
| DBWSAdapter dbwsAdapter = (DBWSAdapter)xrService; |
| |
| SOAPEnvelope envelope = null; |
| try { |
| envelope = request.getSOAPPart().getEnvelope(); |
| } |
| catch (SOAPException se) { |
| throw new WebServiceException(se.getMessage(), se); |
| } |
| // check soap 1.2 Namespace in envelope |
| String namespaceURI = envelope.getNamespaceURI(); |
| usesSOAP12 = namespaceURI.equals(URI_NS_SOAP_1_2_ENVELOPE); |
| |
| SOAPElement body; |
| try { |
| body = getSOAPBodyElement(envelope); |
| } |
| catch (SOAPException se) { |
| throw new WebServiceException(se.getMessage(), se); |
| } |
| |
| if (body == null) { |
| SOAPFault soapFault = null; |
| try { |
| SOAPFactory soapFactory = null; |
| if (usesSOAP12) { |
| soapFactory = SOAPFactory.newInstance(SOAP_1_2_PROTOCOL); |
| } else { |
| soapFactory = SOAPFactory.newInstance(); |
| } |
| QName faultCodeQName = null; |
| if (usesSOAP12) { |
| faultCodeQName = SENDER_QNAME; |
| } else { |
| faultCodeQName = CLIENT_QNAME; |
| } |
| soapFault = soapFactory.createFault("SOAPMessage request format error - missing body element", faultCodeQName); |
| } catch (SOAPException se) { |
| throw new WebServiceException(se.getMessage(), se); |
| } |
| throw new SOAPFaultException(soapFault); |
| } |
| |
| XMLRoot xmlRoot = null; |
| try { |
| XMLContext xmlContext = dbwsAdapter.getXMLContext(); |
| XMLUnmarshaller unmarshaller = xmlContext.createUnmarshaller(); |
| if (attachments != null && attachments.size() > 0) { |
| unmarshaller.setAttachmentUnmarshaller(new XMLAttachmentUnmarshaller() { |
| Map<String,DataHandler> attachments; |
| public XMLAttachmentUnmarshaller setAttachments(Map<String, DataHandler> attachments) { |
| this.attachments = attachments; |
| return this; |
| } |
| @Override |
| public boolean isXOPPackage() { |
| return true; |
| } |
| @Override |
| public DataHandler getAttachmentAsDataHandler(String id) { |
| // strip off 'cid:' (Is this needed?) |
| String attachmentRefId = id; |
| if (attachmentRefId.startsWith("cid:")) { |
| attachmentRefId = attachmentRefId.substring(4); |
| } |
| return attachments.get(attachmentRefId); |
| } |
| @Override |
| public byte[] getAttachmentAsByteArray(String id) { |
| ByteArrayOutputStream out = null; |
| try { |
| DataHandler dh = attachments.get(id); |
| if (dh == null) { |
| return null; |
| } |
| InputStream in = dh.getInputStream(); |
| out = new ByteArrayOutputStream(1024); |
| byte[] buf = new byte[1024]; |
| int len; |
| while ((len = in.read(buf)) > 0) { |
| out.write(buf, 0, len); |
| } |
| } |
| catch (IOException e) { |
| // e.printStackTrace(); |
| } |
| if (out != null) { |
| return out.toByteArray(); |
| } |
| return null; |
| } |
| }.setAttachments(attachments)); |
| dbwsAdapter.setCurrentAttachmentUnmarshaller(unmarshaller.getAttachmentUnmarshaller()); |
| } |
| xmlRoot = (XMLRoot)unmarshaller.unmarshal(body, Invocation.class); |
| } |
| catch (Exception e) { |
| SOAPFault soapFault = null; |
| try { |
| SOAPFactory soapFactory = null; |
| if (usesSOAP12) { |
| soapFactory = SOAPFactory.newInstance(SOAP_1_2_PROTOCOL); |
| } else { |
| soapFactory = SOAPFactory.newInstance(); |
| } |
| QName faultCodeQName = null; |
| if (usesSOAP12) { |
| faultCodeQName = SENDER_QNAME; |
| } else { |
| faultCodeQName = CLIENT_QNAME; |
| } |
| Throwable e1 = e; |
| if (e.getCause() != null) { |
| e1 = e.getCause(); |
| } |
| soapFault = soapFactory.createFault("SOAPMessage request format error - " + e1, faultCodeQName); |
| } catch (SOAPException se) { |
| throw new WebServiceException(se.getMessage(), se); |
| } |
| throw new SOAPFaultException(soapFault); |
| } |
| |
| Invocation invocation = (Invocation)xmlRoot.getObject(); |
| invocation.setName(xmlRoot.getLocalName()); |
| Operation op = dbwsAdapter.getOperation(invocation.getName()); |
| /* |
| * Fix up types for arguments - scan the extended schema for the operation's Request type. |
| * |
| * For most parameters, the textual node content is fine, but for date/time and |
| * binary objects, we must convert |
| */ |
| org.eclipse.persistence.internal.oxm.schema.model.Element invocationElement = |
| (org.eclipse.persistence.internal.oxm.schema.model.Element) |
| dbwsAdapter.getExtendedSchema().getTopLevelElements().get(invocation.getName()); |
| String typeName = invocationElement.getType(); |
| int idx = typeName.indexOf(':'); |
| if (idx != -1) { |
| // strip-off any namespace prefix |
| typeName = typeName.substring(idx+1); |
| } |
| ComplexType complexType = |
| (ComplexType)dbwsAdapter.getExtendedSchema().getTopLevelComplexTypes().get(typeName); |
| if (complexType.getSequence() != null) { |
| // for each operation, there is a corresponding top-level Request type |
| // which has the arguments to the operation |
| for (Iterator<org.eclipse.persistence.internal.oxm.schema.model.Element> i |
| = complexType.getSequence().getOrderedElements().iterator(); |
| i .hasNext();) { |
| org.eclipse.persistence.internal.oxm.schema.model.Element e = i.next(); |
| String argName = e.getName(); |
| Object argValue = invocation.getParameter(argName); |
| String argType = e.getType(); |
| if (argType != null) { |
| String argTypePrefix = null; |
| String nameSpaceURI = null; |
| idx = argType.indexOf(':'); |
| if (idx != -1) { |
| argTypePrefix = argType.substring(0,idx); |
| argType = argType.substring(idx+1); |
| nameSpaceURI = |
| dbwsAdapter.getSchema().getNamespaceResolver().resolveNamespacePrefix(argTypePrefix); |
| } |
| QName argQName = argTypePrefix == null ? new QName(nameSpaceURI, argType) : |
| new QName(nameSpaceURI, argType, argTypePrefix); |
| Class<?> clz = SCHEMA_2_CLASS.get(argQName); |
| if (clz != null) { |
| argValue = ((XMLConversionManager)dbwsAdapter.getOXSession().getDatasourcePlatform(). |
| getConversionManager()).convertObject(argValue, clz, argQName); |
| invocation.setParameter(argName, argValue); |
| } |
| } |
| // incoming attachments ? |
| } |
| } |
| Object result = null; |
| try { |
| result = op.invoke(dbwsAdapter, invocation); |
| if (result instanceof ValueObject) { |
| result = ((ValueObject)result).value; |
| } |
| response = responseWriter.generateResponse(op, usesSOAP12, result); |
| } |
| catch (SOAPException se) { |
| throw new WebServiceException(se.getMessage(), se); |
| } |
| catch (Exception e) { |
| try { |
| response = responseWriter.generateResponse(op, usesSOAP12, e); |
| } |
| catch (SOAPException soape1) { |
| SOAPFault soapFault = null; |
| try { |
| SOAPFactory soapFactory = null; |
| if (usesSOAP12) { |
| soapFactory = SOAPFactory.newInstance(SOAP_1_2_PROTOCOL); |
| } else { |
| soapFactory = SOAPFactory.newInstance(); |
| } |
| QName faultCodeQName = null; |
| if (usesSOAP12) { |
| faultCodeQName = RECEIVER_QNAME; |
| } else { |
| faultCodeQName = SERVER_QNAME; |
| } |
| soapFault = soapFactory.createFault("SOAPMessage response error - " + e.getMessage(), faultCodeQName); |
| } catch (SOAPException soape2) { |
| throw new WebServiceException(soape2.getMessage(), soape2); |
| } |
| throw new SOAPFaultException(soapFault); |
| } |
| } |
| return response; |
| } |
| |
| public void destroy() { |
| logoutSessions(); |
| responseWriter = null; |
| try { |
| xrSchemaStream.close(); |
| } |
| catch (IOException ioe) { |
| /* safe to ignore */ |
| } |
| xrSchemaStream = null; |
| parentClassLoader = null; |
| xrService.setXMLContext(null); |
| xrService = null; |
| } |
| |
| @Override |
| public XRServiceAdapter buildService(XRServiceModel xrServiceModel) { |
| xrService = new DBWSAdapter(); // use subclass to hold extended WSDL schema |
| DBWSAdapter dbws = (DBWSAdapter)xrService; |
| dbws.setName(xrServiceModel.getName()); |
| dbws.setSessionsFile(xrServiceModel.getSessionsFile()); |
| dbws.setOperations(xrServiceModel.getOperations()); |
| initializeService(parentClassLoader, xrSchemaStream); |
| return dbws; |
| } |
| |
| public static SOAPElement getSOAPBodyElement(SOAPEnvelope envelope) throws SOAPException { |
| for (@SuppressWarnings("rawtypes") |
| Iterator it = envelope.getBody().getChildElements(); it.hasNext();) { |
| Object node = it.next(); |
| if (node instanceof SOAPBodyElement) { |
| return (SOAPElement) node; |
| } |
| } |
| return null; |
| } |
| } |