/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Creates a runtime model of a SEI (portClass).
*
* @author WS Developement Team
*/
public class RuntimeModeler {
// can be empty but never null
private boolean isWrapped = true;
/**
*
*/
/**
*
*/
public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull BindingID bindingId, @NotNull WebServiceFeature... features) {
}
/**
*
* creates an instance of RunTimeModeler given a <code>sei</code> and <code>binding</code>
* @param portClass The SEI class to be modeled.
* @param serviceName The ServiceName to use instead of one calculated from the implementation class
* @param wsdlPort {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLPort}
* @param features web service features
*/
public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull WSDLPortImpl wsdlPort, @NotNull WebServiceFeature... features){
}
private RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, WSDLPortImpl binding, BindingID bindingId, @NotNull WebServiceFeature... features) {
this.serviceName = serviceName;
}
/**
* sets the classloader to be used when loading classes by the <code>RuntimeModeler</code>.
* @param classLoader ClassLoader used to load classes
*/
this.classLoader = classLoader;
}
/**
* sets the PortName to be used by the <code>RuntimeModeler</code>.
* @param portName The PortName to be used instead of the PortName
* retrieved via annotations
*/
}
private static <T extends Annotation> T getPrivClassAnnotation(final Class<?> clazz, final Class<T> T) {
public T run() {
return clazz.getAnnotation(T);
}
});
}
private static <T extends Annotation> T getPrivMethodAnnotation(final Method method, final Class<T> T) {
public T run() {
return method.getAnnotation(T);
}
});
}
public Annotation[][] run() {
return method.getParameterAnnotations();
}
});
}
//currently has many local vars which will be eliminated after debugging issues
//first draft
/**
* builds the runtime model from the <code>portClass</code> using the binding ID <code>bindingId</code>.
* @return the runtime model for the <code>portClass</code>.
*/
if (webService == null) {
throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation",
}
clazz = getClass(webService.endpointInterface(), ModelerMessages.localizableRUNTIME_MODELER_CLASS_NOT_FOUND(webService.endpointInterface()));
if (seiService == null) {
throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice",
}
//check if @SOAPBinding is defined on the impl class
if(sbPortClass != null){
logger.warning(ServerMessages.RUNTIMEMODELER_INVALIDANNOTATION_ON_IMPL("@SOAPBinding", portClass.getName(), clazz.getName()));
}
}
}
if (serviceName == null)
}
throw new RuntimeModelerException("runtime.modeler.portname.servicename.namespace.mismatch",
}
throw new RuntimeModelerException("runtime.modeler.no.operations",
model.postProcess();
// TODO: this needs to be fixed properly --
// when we are building RuntimeModel first before building WSDLModel,
// we still need to do this correctyl
return model;
}
/**
* utility method to load classes
* @param className the name of the class to load
* @param errorMessage
* Error message to use when the resolution fails.
* @return the class specified by <code>className</code>
*/
try {
if (classLoader == null)
else
} catch (ClassNotFoundException e) {
throw new RuntimeModelerException(errorMessage);
}
}
ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader;
try {
} catch (ClassNotFoundException e) {
}
}
ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader;
try {
} catch (ClassNotFoundException e) {
}
}
private Class getExceptionBeanClass(String className, Class exception, String name, String namespace) {
ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader;
try {
} catch (ClassNotFoundException e) {
return WrapperBeanGenerator.createExceptionBean(className, exception, targetNamespace, name, namespace, loader);
}
}
packageName = "";
}
if (soapBinding != null) {
if (soapBinding.style() == SOAPBinding.Style.RPC && soapBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) {
throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle",
soapBinding, clazz);
}
}
/*
* if clazz != portClass then there is an SEI. If there is an
* SEI, then all methods should be processed. However, if there is
* no SEI, and the implementation class uses at least one
* WebMethod annotation, then only methods with this annotation
* will be processed.
*/
/* if (clazz == portClass) {
WebMethod webMethod;
for (Method method : clazz.getMethods()) {
webMethod = getPrivMethodAnnotation(method, WebMethod.class);
if (webMethod != null &&
!webMethod.exclude()) {
usesWebMethod = true;
break;
}
}
}*/
continue;
}
}
// TODO: binding can be null. We need to figure out how to post-process
// RuntimeModel to link to WSDLModel
}
//Add additional jaxb classes referenced by {@link XmlSeeAlso}
if(xmlSeeAlso != null)
}
/*
* Section 3.3 of spec
* Otherwise, the class implicitly defines a service endpoint interface (SEI) which
* comprises all of the public methods that satisfy one of the following conditions:
* 1. They are annotated with the javax.jws.WebMethod annotation with the exclude element set to
* false or missing (since false is the default for this annotation element).
* 2. They are not annotated with the javax.jws.WebMethod annotation but their declaring class has a
* javax.jws.WebService annotation.
*
* also the method should non-static or non-final
*/
assert !clazz.isInterface();
return false; // @WebMethod(exclude="true")
}
if (staticFinal) {
throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATICFINAL(method));
}
return true; // @WebMethod
}
if (staticFinal) {
return false;
}
}
/**
* creates a runtime model <code>SOAPBinding</code> from a <code>javax.jws.soap.SOAPBinding</code> object
* @param soapBinding the <code>javax.jws.soap.SOAPBinding</code> to model
* @return returns the runtime model SOAPBinding corresponding to <code>soapBinding</code>
*/
return rtSOAPBinding;
}
/**
* gets the namespace <code>String</code> for a given <code>packageName</code>
* @param packageName the name of the package used to find a namespace.
* can be empty.
* @return the namespace for the specified <code>packageName</code>
*/
return null;
} else {
}
}
if (i!=0)
}
}
/*
* Returns true if an exception is service specific exception as per JAX-WS rules.
* @param exception
* @return
*/
!(RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || REMOTE_EXCEPTION_CLASS.isAssignableFrom(exception));
}
/**
* creates the runtime model for a method on the <code>portClass</code>
* @param method the method to model
*/
// if the user put @WebMethod on these non-qualifying method,
// it's an error
throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATIC(method));
else
throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_PUBLIC(method));
}
return;
}
return;
//Check that oneway methods don't thorw any checked exceptions
if (isOneway) {
if(isServiceException(exception)) {
throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.checked.exceptions",
}
}
}
//Class implementorClass = portClass;
} else {
try {
} catch (NoSuchMethodException e) {
throw new RuntimeModelerException("runtime.modeler.method.not.found",
}
}
}
//override the @WebMethod.action value by the one from the WSDL
else
}
}
logger.warning(ModelerMessages.RUNTIMEMODELER_INVALID_SOAPBINDING_ON_METHOD(methodBinding, method.getName(), method.getDeclaringClass().getName()));
if (methodBinding != null && methodBinding.style() == SOAPBinding.Style.RPC && methodBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) {
throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle",
}
}
throw new RuntimeModelerException("runtime.modeler.soapbinding.conflict",
}
boolean methodIsWrapped = isWrapped;
if (methodBinding != null) {
WRAPPED);
} else {
com.sun.xml.internal.ws.model.soap.SOAPBindingImpl sb = new com.sun.xml.internal.ws.model.soap.SOAPBindingImpl(defaultBinding);
else
}
if (!methodIsWrapped) {
method);
} else {
}
}
if (m.isAnnotationPresent(Oneway.class)) {
}
return MEP.ASYNC_POLL;
return MEP.ASYNC_CALLBACK;
}
return MEP.REQUEST_RESPONSE;
}
/**
* @param javaMethod the runtime model <code>JavaMethod</code> instance being created
* @param methodName the runtime model <code>JavaMethod</code> instance being created
* @param operationName the runtime model <code>JavaMethod</code> instance being created
* @param method the <code>method</code> to model
*/
boolean methodHasHeaderParams = false;
}else{
}
}else{
}
if (reqWrapper != null) {
try {
} catch(LinkageError e) {
//2.1 API dopes n't have this method
//Do nothing, just default to "parameters"
}
}
if (!isOneway) {
if (resWrapper != null) {
try {
} catch (LinkageError e) {
//2.1 API does n't have this method
//Do nothing, just default to "parameters"
}
}
}
if (!isOneway) {
}
// return value
boolean isResultHeader = false;
throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" as the return value is bound to header");
}
// headers must have a namespace
}
}
if(javaMethod.isAsync()){
}
if (isResultHeader) {
} else {
}
}
}
//get WebParam
int pos = 0;
//String paramNamespace = "";
boolean isHeader = false;
continue;
}
//set the actual type argument of Holder in the TypeReference
if (isHolder) {
clazzType = Navigator.REFLECTION.erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]);
}
}
}
throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" parameter that is bound to header");
}
else
}
}
typeRef =
if (isHeader) {
} else {
}
if (isOneway) {
throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters",
}
}
}
}
//If the method has any parameter or return type that is bound to a header, use "result" as part name to avoid
// name collison of same input part name and output part name ("parameters") shown up as param names on the
// client mapping.
if(methodHasHeaderParams) {
resPartName = "result";
}
if(responseWrapper != null)
}
/**
* @param javaMethod the runtime model <code>JavaMethod</code> instance being created
* @param methodName the name of the <code>method</code> being modeled.
* @param operationName the WSDL operation name for this <code>method</code>
* @param method the runtime model <code>JavaMethod</code> instance being created
*/
// use Map to build parameters in the part order when they are known.
// if part is unbound, we just put them at the end, and for that we
// use a large index (10000+) to avoid colliding with ordered ones.
// this assumes that there's no operation with # of parameters > 10000,
// but I think it's a pretty safe assumption - KK.
//Lets take the service namespace and overwrite it with the one we get it from wsdl
//it cant be null, but lets not fail and try to work with service namespce
}
//it cant be null, but lets not fail and try to work with service namespce
}
}
}
if (!isOneway) {
}
if (!isOneway) {
}
boolean isResultHeader = false;
if (!isResultHeader)
} else
}
if (isResultHeader)
else
if(javaMethod.isAsync()){
}
if(isResultHeader){
}else{
if(p == null)
else
}else{
}
}
}
//get WebParam
int pos = 0;
boolean isHeader = false;
continue;
}
//set the actual type argument of Holder in the TypeReference
if (isHolder) {
clazzType = Navigator.REFLECTION.erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]);
}
break;
}
}
}
} else if (!isHeader) {
}
}
if (!isHeader) {
//its rpclit body param, set namespace to ""
} else {
}
typeRef =
}else{
if (isHeader) {
} else {
}
}
if(p == null)
else
}
if (isOneway) {
throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters",
}
if(p == null)
else
}
}else{
}
}
}
/**
* models the exceptions thrown by <code>method</code> and adds them to the <code>javaMethod</code>
* runtime model object
* @param javaMethod the runtime model object to add the exception model objects to
* @param method the <code>method</code> from which to find the exceptions to model
*/
FaultAction[] faultActions = {};
//Exclude RuntimeException, RemoteException and Error etc
continue;
if (RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || REMOTE_EXCEPTION_CLASS.isAssignableFrom(exception))
continue;
Annotation[] anns;
}
if (faultInfoMethod == null) {
} else {
}
break;
}
}
}
}
/**
* returns the method that corresponds to "getFaultInfo". Returns null if this is not an
* exception generated from a WSDL
* @param exception the class to search for the "getFaultInfo" method
* @return the method named "getFaultInfo" if this is an exception generated from WSDL or an
* exception that contains the <code>WebFault</code> annotation. Otherwise it returns null
*/
return null;
try {
} catch (NoSuchMethodException e) {
return null;
}
}
/**
* @param javaMethod the runtime model <code>JavaMethod</code> instance being created
* @param operationName the runtime model <code>JavaMethod</code> instance being created
* @param method the runtime model <code>JavaMethod</code> instance being created
*/
boolean isResultHeader = false;
}
if(javaMethod.isAsync()){
}
if (resultName != null) {
}
if(isResultHeader){
}else{
}
}
}
//get WebParam
int pos = 0;
boolean isHeader = false;
//async
continue;
}
//set the actual type argument of Holder in the TypeReference
if (isHolder) {
clazzType = Navigator.REFLECTION.erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]);
}
if(isHeader)
}
break;
}
}
pannotations[pos]);
}
}else{
if (isHeader){
}else{
}
}
}
}
// Does a conservative check if there is only one BODY part for input
// and output message. We are not considering INOUT parameters at this
// time since binding information is not applied. Also, there isn't
// anyway to represent some cases in SEI. For example, a INOUT parameter
// could be bound to body for input message, header for OUTPUT message
// in wsdl:binding
int numInBodyBindings = 0;
}
if(numInBodyBindings > 1){
throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName()));
}
}
int numOutBodyBindings = 0;
}
if(numOutBodyBindings > 1){
throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName()));
}
}
}
}else{
int i = 0;
}
i++;
}
}
return returnType;
}
/**
* utility to capitalize the first letter in a string
* @param name the string to capitalize
* @return the capitalized string
*/
return name;
}
}
/*
* Return service QName
*/
/**
* gets the <code>wsdl:serviceName</code> for a given implementation class
* @param implClass the implementation class
* @return the <code>wsdl:serviceName</code> for the <code>implClass</code>
*/
if (implClass.isInterface()) {
throw new RuntimeModelerException("runtime.modeler.cannot.get.serviceName.from.interface",
}
if (webService == null) {
throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation",
}
}
} else if (targetNamespace == null) {
throw new RuntimeModelerException("runtime.modeler.no.package",
}
}
/**
* gets the <code>wsdl:portName</code> for a given implementation class
* @param implClass the implementation class
* @param targetNamespace Namespace URI for service name
* @return the <code>wsdl:portName</code> for the <code>implClass</code>
*/
if (webService == null) {
throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation",
}
} else {
}
if (targetNamespace == null) {
} else {
}
if (targetNamespace == null) {
throw new RuntimeModelerException("runtime.modeler.no.package",
}
}
}
}
/**
* Gives portType QName from implementatorClass or SEI
* @param implOrSeiClass cant be null
* @return <code>wsdl:portType@name</code>, null if it could not find the annotated class.
*/
assert(implOrSeiClass != null);
throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation",
if (!implOrSeiClass.isInterface()) {
try {
} catch (ClassNotFoundException e) {
}
throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice",
}
}
}
}
}
}
if(isHeader)
return ParameterBinding.HEADER;
else
return ParameterBinding.BODY;
}
QName opName = new QName(binding.getBinding().getPortType().getName().getNamespaceURI(), operation);
}
}
return null;
}
}
}
throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebResult(name)="+webResultName+" are different for method " +method);
}
if (webResultName != null) {
} else if (xmlElemName != null) {
}
}
}
throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebResult(targetNamespace)="+webResultNS+" are different for method " +method);
}
if (webResultNS != null) {
ns = webResultNS;
}
}
private static QName getParameterQName(Method method, WebParam webParam, XmlElement xmlElem, String paramDefault) {
}
}
throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebParam(name)="+webParamName+" are different for method " +method);
}
if (webParamName != null) {
} else if (xmlElemName != null) {
}
}
}
throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebParam(targetNamespace)="+webParamNS+" are different for method " +method);
}
if (webParamNS != null) {
ns = webParamNS;
}
}
}