package org.apache.beehive.wsm.model.jsr181;
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.xml.namespace.QName; // todo (mmerz@apache.org, 01/25/05): this needs to go...
import org.apache.beehive.wsm.model.BeehiveWsMethodMetadata;
import org.apache.beehive.wsm.model.BeehiveWsParameterMetadata;
import org.apache.beehive.wsm.model.ValidationException;
import org.apache.beehive.wsm.model.java.JavaMethodInfo;
import org.apache.beehive.wsm.model.java.JavaParameterInfo;
public class Jsr181MethodMetadataImpl implements BeehiveWsMethodMetadata, java.io.Serializable {
private static final long serialVersionUID = 1L;
private static final String DEFAULT_WRNAME = "return";
private String wmOperationName;
private String wmAction;
private boolean oneway = false;
private List<BeehiveWsParameterMetadata> params =
new ArrayList<BeehiveWsParameterMetadata>();
private String wrName;
private String wrTargetNamespace;
private String javaMethodName;
private Class javaReturnType;
private QName mXMLReturnType;
public void validate() throws ValidationException {
return; // no validation required
}
public Jsr181MethodMetadataImpl(
String operationName,
Class javaType,
QName xmlReturnType)
{
this(operationName, javaType);
setXmlReturnType(xmlReturnType);
}
public Jsr181MethodMetadataImpl(String methodName, Class returnType) {
super();
javaMethodName = methodName;
javaReturnType = returnType;
}
public Jsr181MethodMetadataImpl(JavaMethodInfo jm) {
super();
// check input param
if (null == jm) {
jm.logError("illegal java method info: <null>");
return;
}
javaMethodName = jm.getMethodName();
javaReturnType = jm.getReturnType();
// get webMethod's webParams
List<BeehiveWsParameterMetadata> webParams =
new ArrayList<BeehiveWsParameterMetadata>();
for (JavaParameterInfo param : jm.getParameters()) {
BeehiveWsParameterMetadata wspm = new Jsr181ParameterMetadataImpl(param);
if (null == wspm) {
jm.logError("cannot create metadata for web param: " + param.getName());
}
webParams.add(wspm);
}
// set defaults
setWrName(DEFAULT_WRNAME);
// enforce JSR-181 rules
if (! jm.isPublic()) {
jm.logError("@WebMethod must be public: " + javaMethodName);
}
if (null != jm.getAnnotation(Oneway.class)) {
// prohibit @Oneway with @WebResult
if (null != jm.getAnnotation(WebResult.class)) {
jm.logError("@Oneway method " + javaMethodName + " has incompatible annotation: @WebResult");
}
// prohibit @Oneway with return types other than <code>void</code>
if (void.class != javaReturnType) {
jm.logError("@Oneway method " + javaMethodName + " has illegal non-void return type: " + javaReturnType);
}
// prohibit @Oneway methods that throw Exceptions
if (jm.throwsExceptions()) {
jm.logError("@Oneway method " + javaMethodName + " must not throw checked exceptions");
}
// todo??? prohibit @Oneway with "OUT" and "INOUT" parameters
if (null != webParams) {
for (BeehiveWsParameterMetadata param : webParams) {
if ((WebParam.Mode.OUT == param.getWpMode()) || (WebParam.Mode.INOUT == param.getWpMode())) {
jm.logError("@Oneway method " + javaMethodName + " has illegal INOUT or OUT parameter: " + param.getWpName());
}
}
}
}
// set optional annotations
Collection<Annotation> annotations = jm.getAnnotations();
if (null != annotations) {
for (Annotation a : annotations) {
if (a.annotationType() == javax.jws.WebMethod.class) {
initFromAnnotation((javax.jws.WebMethod) a);
}
else if (a.annotationType() == javax.jws.Oneway.class) {
initFromAnnotation((javax.jws.Oneway) a);
}
else if (a.annotationType() == javax.jws.WebResult.class) {
initFromAnnotation((javax.jws.WebResult) a);
}
else {
// unknown annotation
}
}
}
// set default values
if ((null == getWmOperationName()) || (0 == getWmOperationName().length())) {
setWmOperationName(javaMethodName);
}
if ((null == getWmAction()) || (0 == getWmAction().length())) {
setWmAction("");
}
// set WebServicePARAMETERMetadata
addParams(webParams);
}
private void initFromAnnotation(WebResult annotation) {
if (null != annotation) {
setWrName(annotation.name());
setWrTargetNamespace(annotation.targetNamespace());
}
}
private void initFromAnnotation(Oneway annotation) {
setOneWay(null != annotation);
}
private void initFromAnnotation(WebMethod annotation) {
if (null != annotation) {
setWmAction(annotation.action());
setWmOperationName(annotation.operationName());
}
}
public boolean isOneWay() {
return oneway;
}
public void setOneWay(boolean oneway) {
this.oneway = oneway;
}
public String getWmAction() {
return wmAction;
}
public void setWmAction(String wmAction) {
this.wmAction = wmAction;
}
public String getWmOperationName() {
return wmOperationName;
}
public void setWmOperationName(String wmOperationName) {
this.wmOperationName = wmOperationName;
}
public String getWrName() {
return wrName;
}
public void setWrName(String wrName) {
this.wrName = wrName;
}
public String getWrTargetNamespace() {
return wrTargetNamespace;
}
public void setWrTargetNamespace(String wrTargetNamespace) {
this.wrTargetNamespace = wrTargetNamespace;
}
public List<BeehiveWsParameterMetadata> getParams() {
return Collections.unmodifiableList(params);
}
public void addParams(List<? extends BeehiveWsParameterMetadata> parameters) {
if (null != parameters) {
params.addAll(parameters);
}
// todo: checks
}
public void addParam(BeehiveWsParameterMetadata parameter) {
if (null != parameter) {
params.add(parameter);
}
// todo: checks
}
public String getJavaMethodName() {
return javaMethodName;
}
public Class getJavaReturnType() {
return javaReturnType;
}
public String getSignature() {
StringBuilder sb = new StringBuilder(getJavaMethodName());
sb.append('(');
boolean firstParam = true;
if (null != params) {
for (BeehiveWsParameterMetadata p : params) {
if (firstParam) {
firstParam = false;
}
else {
sb.append(',');
}
sb.append(p.getJavaType());
}
}
sb.append(')');
return sb.toString();
}
public String toString() {
String signature = getJavaReturnType().toString() + " " + getJavaMethodName() + "( ";
for (BeehiveWsParameterMetadata p : params) {
signature += p.getJavaType().toString() + " ";
}
return signature + ")";
}
public boolean equals(Object o) {
if (! (o instanceof Jsr181MethodMetadataImpl)) {
return false;
}
Jsr181MethodMetadataImpl m = (Jsr181MethodMetadataImpl) o;
// check name
if (! getJavaMethodName().equals(m.getJavaMethodName())) {
return false;
}
// check return type
if (! getJavaReturnType().equals(m.getJavaReturnType())) {
return false;
}
// check all parameters (types, not names!)
if (params.size() != m.params.size()) {
return false;
}
for (int i = 0; i < params.size(); i++) {
if (! m.params.get(i).getJavaType().equals(params.get(i).getJavaType())) {
return false;
}
}
// check exceptions?
return true;
}
/* (non-Javadoc)
* @see org.apache.beehive.wsm.jsr181.model.Jsr181MethodMetadata#getJavaReturnTypeFullName()
*
* NOTE THIS METHOD AND SUPPORTING METHOD SHOULD BE MOVED OUT TO A ELEMENT CLASS
* THAT ENCAPSULATES QNAME AND CLASS
*/
public String getJavaReturnTypeFullName() {
return getClassName(getJavaReturnType());
}
private String getClassName(Class cls) {
if (cls.isArray()) {
return getClassName(cls.getComponentType()) + "[]";
}
else {
return cls.getName().replace('$', '.');
}
}
public QName getXmlReturnType() {
return mXMLReturnType;
}
public void setXmlReturnType(QName xmlReturnType) {
mXMLReturnType = xmlReturnType;
}
/* (non-Javadoc)
* @see org.apache.beehive.wsm.jsr181.model.Jsr181MethodMetadata#setReturnType(java.lang.Class)
*/
public void setReturnType(Class javaType) {
this.javaReturnType = javaType;
}
/* (non-Javadoc)
* @see org.apache.beehive.wsm.jsr181.model.BeehiveWsMethodMetadata#findParam(java.lang.String)
*/
public BeehiveWsParameterMetadata findParam(String parmName) {
// walk the list of parameters until the parameter with paramName is found
// there are small number of parameters, so walking the list should be ok
if( null == parmName) return null;
BeehiveWsParameterMetadata res = null;
for(BeehiveWsParameterMetadata nxtParam : params) {
if( parmName.equals(nxtParam.getWpName())) {
res = nxtParam;
break;
}
}
return res;
}
}