/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.ws;
import java.util.Collections;
import java.util.List;
import javax.resource.cci.ConnectionFactory;
import javax.xml.ws.Service.Mode;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.soap.SOAPBinding;
import org.teiid.core.BundleUtil;
import org.teiid.core.util.PropertiesUtils;
import org.teiid.language.Call;
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Procedure;
import org.teiid.metadata.ProcedureParameter;
import org.teiid.metadata.ProcedureParameter.Type;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.MetadataProcessor;
import org.teiid.translator.ProcedureExecution;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TranslatorProperty;
import org.teiid.translator.TypeFacility;
import org.teiid.translator.WSConnection;
@Translator(name="ws", description="A translator for making Web Service calls")
public class WSExecutionFactory extends ExecutionFactory<ConnectionFactory, WSConnection> {
static final String INVOKE = "invoke"; //$NON-NLS-1$
static final String INVOKE_HTTP = "invokeHttp"; //$NON-NLS-1$
public enum Binding {
HTTP(HTTPBinding.HTTP_BINDING),
SOAP11(SOAPBinding.SOAP11HTTP_BINDING),
SOAP12(SOAPBinding.SOAP12HTTP_BINDING);
private String bindingId;
private Binding(String bindingId) {
this.bindingId = bindingId;
}
public String getBindingId() {
return bindingId;
}
}
public static BundleUtil UTIL = BundleUtil.getBundleUtil(WSExecutionFactory.class);
public static enum Event implements BundleUtil.Event{
TEIID15001,
TEIID15002,
TEIID15003,
TEIID15004,
TEIID15005,
TEIID15006,
TEIID15007
}
private Mode defaultServiceMode = Mode.PAYLOAD;
private Binding defaultBinding = Binding.SOAP12;
private String xmlParamName;
public WSExecutionFactory() {
setSourceRequiredForMetadata(false);
setTransactionSupport(TransactionSupport.NONE);
}
@TranslatorProperty(description="Contols request/response message wrapping - set to MESSAGE for full control over SOAP messages.", display="Default Service Mode")
public Mode getDefaultServiceMode() {
return defaultServiceMode;
}
public void setDefaultServiceMode(Mode mode) {
this.defaultServiceMode = mode;
}
@TranslatorProperty(description="Contols what SOAP or HTTP type of invocation will be used if none is specified.", display="Default Binding")
public Binding getDefaultBinding() {
return defaultBinding;
}
public void setDefaultBinding(Binding defaultInvocationType) {
this.defaultBinding = defaultInvocationType;
}
@TranslatorProperty(description="Used with the HTTP binding (typically with the GET method) to indicate that the request document should be part of the query string.", display="XML Param Name")
public String getXMLParamName() {
return xmlParamName;
}
public void setXMLParamName(String xmlParamName) {
this.xmlParamName = xmlParamName;
}
@Override
public ProcedureExecution createProcedureExecution(Call command, ExecutionContext executionContext, RuntimeMetadata metadata, WSConnection connection)
throws TranslatorException {
if (command.getProcedureName().equalsIgnoreCase(INVOKE_HTTP)) {
return new BinaryWSProcedureExecution(command, metadata, executionContext, this, connection);
}
if (command.getArguments().size() > 2 || command.getProcedureName().equalsIgnoreCase(INVOKE)) {
return new WSProcedureExecution(command, metadata, executionContext, this, connection);
}
return new WSWSDLProcedureExecution(command, metadata, executionContext, this, connection);
}
@Override
public final List<String> getSupportedFunctions() {
return Collections.emptyList();
}
@Override
public MetadataProcessor<WSConnection> getMetadataProcessor() {
return new WSDLMetadataProcessor();
}
@Override
public void getMetadata(MetadataFactory metadataFactory, WSConnection conn) throws TranslatorException {
Procedure p = metadataFactory.addProcedure(INVOKE);
p.setAnnotation("Invokes a webservice that returns an XML result"); //$NON-NLS-1$
metadataFactory.addProcedureParameter("result", TypeFacility.RUNTIME_NAMES.XML, Type.ReturnValue, p); //$NON-NLS-1$
ProcedureParameter param = metadataFactory.addProcedureParameter("binding", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The invocation binding (HTTP, SOAP11, SOAP12). May be set or allowed to default to null to use the default binding."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param = metadataFactory.addProcedureParameter("action", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("With a SOAP invocation, action sets the SOAPAction. With HTTP it sets the HTTP Method (GET, POST - default, etc.)."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
//can be one of string, xml, clob
param = metadataFactory.addProcedureParameter("request", TypeFacility.RUNTIME_NAMES.XML, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The XML document or root element that represents the request. If the ExecutionFactory is configured in with a DefaultServiceMode of MESSAGE, then the SOAP request must contain the entire SOAP message."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param = metadataFactory.addProcedureParameter("endpoint", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The relative or abolute endpoint to use. May be set or allowed to default to null to use the default endpoint address."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param = metadataFactory.addProcedureParameter("stream", TypeFacility.RUNTIME_NAMES.BOOLEAN, Type.In, p); //$NON-NLS-1$
param.setAnnotation("If the result should be streamed."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param.setDefaultValue("false"); //$NON-NLS-1$
p = metadataFactory.addProcedure(INVOKE_HTTP);
p.setAnnotation("Invokes a webservice that returns an binary result"); //$NON-NLS-1$
metadataFactory.addProcedureParameter("result", TypeFacility.RUNTIME_NAMES.BLOB, Type.ReturnValue, p); //$NON-NLS-1$
param = metadataFactory.addProcedureParameter("action", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("Sets the HTTP Method (GET, POST - default, etc.)."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
//can be one of string, xml, clob
param = metadataFactory.addProcedureParameter("request", TypeFacility.RUNTIME_NAMES.OBJECT, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The String, XML, BLOB, or CLOB value containing a payload (only for POST)."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param = metadataFactory.addProcedureParameter("endpoint", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p); //$NON-NLS-1$
param.setAnnotation("The relative or abolute endpoint to use. May be set or allowed to default to null to use the default endpoint address."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param = metadataFactory.addProcedureParameter("stream", TypeFacility.RUNTIME_NAMES.BOOLEAN, Type.In, p); //$NON-NLS-1$
param.setAnnotation("If the result should be streamed."); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
param.setDefaultValue("false"); //$NON-NLS-1$
metadataFactory.addProcedureParameter("contentType", TypeFacility.RUNTIME_NAMES.STRING, Type.Out, p); //$NON-NLS-1$
param = metadataFactory.addProcedureParameter("headers", TypeFacility.RUNTIME_NAMES.CLOB, Type.In, p); //$NON-NLS-1$
param.setAnnotation("Headers to send"); //$NON-NLS-1$
param.setNullType(NullType.Nullable);
WSDLMetadataProcessor metadataProcessor = new WSDLMetadataProcessor();
PropertiesUtils.setBeanProperties(metadataProcessor, metadataFactory.getModelProperties(), "importer"); //$NON-NLS-1$
metadataProcessor.process(metadataFactory, conn);
}
@Override
public boolean areLobsUsableAfterClose() {
return true;
}
}