
org.eclipse.persistence.internal.dbws.ProviderHelper Maven / Gradle / Ivy
/*
* Copyright (c) 1998, 2024 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
/**
*
* INTERNAL: ProviderHelper bridges between {@link DBWSAdapter}'s and JAX-WS {@link Provider}'s
*
* @author Mike Norman - [email protected]
* @since EclipseLink 1.1
*
* 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
*
*/
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 =
" " +
" " +
" ";
protected static final String XSL_POSTSCRIPT = " ";
public static final String MATCH_SCHEMA =
XSL_PREAMBLE +
"" +
" " +
" " +
"" +
"" +
" " +
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;
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;
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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy