/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you 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. | |
*/ | |
package org.apache.axis2.jaxws.description.impl; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
import javax.wsdl.Definition; | |
import org.apache.axis2.jaxws.ExceptionFactory; | |
import org.apache.axis2.jaxws.description.MethodRetriever; | |
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL; | |
import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite; | |
import org.apache.axis2.jaxws.description.builder.MDQConstants; | |
import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite; | |
import org.apache.axis2.jaxws.i18n.Messages; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
/** | |
* PostRI216MethodRetrieverImpl subclass implements the new SUN RI interpretation for | |
* annotation processing. See MethodRetriever superclass... | |
* | |
* Please refer to the following links for more info: | |
* | |
* | |
* https://jax-ws.dev.java.net/issues/show_bug.cgi?id=577 | |
* http://forums.java.net/jive/thread.jspa?threadID=61630 | |
* http://forums.java.net/jive/thread.jspa?threadID=55078 | |
* | |
* | |
*/ | |
public class PostRI216MethodRetrieverImpl extends MethodRetriever { | |
//Logging setup | |
private static final Log log = LogFactory.getLog(PostRI216MethodRetrieverImpl.class); | |
private EndpointInterfaceDescriptionImpl eid = null; | |
private DescriptionBuilderComposite dbc = null; | |
public PostRI216MethodRetrieverImpl (DescriptionBuilderComposite dbc, | |
EndpointInterfaceDescriptionImpl eid) { | |
super(); | |
this.dbc = dbc; | |
this.eid = eid; | |
} | |
/* (non-Javadoc) | |
* @see org.apache.axis2.jaxws.description.MethodRetriever#retrieveMethods() | |
*/ | |
public Iterator<MethodDescriptionComposite> retrieveMethods() { | |
/* | |
* Depending on whether this is an implicit SEI or an actual SEI, Gather up and build a | |
* list of MDC's. If this is an actual SEI, then starting with this DBC, build a list of all | |
* MDC's that are public methods in the chain of extended classes. | |
* If this is an implicit SEI, then starting with this DBC, | |
* 1. If a false exclude is found, then take only those that have false excludes | |
* 2. Assuming no false excludes, take all public methods that don't have exclude == true | |
* 3. For each super class, if 'WebService' present, take all MDC's according to rules 1&2 | |
* But, if WebService not present, grab only MDC's that are annotated. | |
*/ | |
if (log.isTraceEnabled()) { | |
log.trace("retrieveMethods: Enter"); | |
} | |
ArrayList<MethodDescriptionComposite> retrieveList = new ArrayList<MethodDescriptionComposite>(); | |
if (dbc.isInterface()) { | |
if (log.isDebugEnabled()) { | |
log.debug("Removing overridden methods for interface: " + dbc.getClassName() | |
+ " with super interface: " + dbc.getSuperClassName()); | |
} | |
// make sure we retrieve all the methods, then remove the overridden | |
// methods that exist in the base interface | |
retrieveList = retrieveSEIMethodsChain(dbc, eid); | |
retrieveList = removeOverriddenMethods(retrieveList, dbc, eid); | |
} else { | |
//this is an implied SEI...rules are more complicated | |
retrieveList = retrieveImplicitSEIMethods(dbc); | |
//Now, continue to build this list with relevent methods in the chain of | |
//superclasses. If the logic for processing superclasses is the same as for | |
//the original SEI, then we can combine this code with above code. But, its possible | |
//the logic is different for superclasses...keeping separate for now. | |
DescriptionBuilderComposite tempDBC = dbc; | |
while (!DescriptionUtils.isEmpty(tempDBC.getSuperClassName())) { | |
//verify that this superclass name is not | |
// java.lang.object, if so, then we're done processing | |
if (DescriptionUtils.javifyClassName(tempDBC.getSuperClassName()).equals( | |
MDQConstants.OBJECT_CLASS_NAME)) | |
break; | |
DescriptionBuilderComposite superDBC = eid.getEndpointDescriptionImpl() | |
.getServiceDescriptionImpl().getDBCMap().get(tempDBC.getSuperClassName()); | |
if (log.isTraceEnabled()) | |
log.trace("superclass name for this DBC is:" + tempDBC.getSuperClassName()); | |
//Verify that we can find the SEI in the composite list | |
if (superDBC == null) { | |
throw ExceptionFactory.makeWebServiceException(Messages | |
.getMessage("seiNotFoundErr")); | |
} | |
// Now, gather the list of Methods just like we do for | |
// the lowest subclass | |
retrieveList.addAll(retrieveImplicitSEIMethods(superDBC)); | |
tempDBC = superDBC; | |
} //Done with implied SEI's superclasses | |
retrieveList = removeOverriddenMethods(retrieveList, dbc, eid); | |
//Let check to see if there where any operations with @Webmethod | |
//If LeagcyWebmethod is NOT defined i.e default and if there | |
//are operations with @Webmethod annotation, then lets warn the | |
//user that we may be exposing public operation that they did not | |
//intend to expose, this can happen if user is migrating application | |
//from old JAX-WS tooling version. | |
//Let also inform user that if they can use LegacyWebmethod to expose | |
//Only those operations that have @webmethod(exclude=false) annotation on them. | |
boolean isWebmethodDefined = DescriptionUtils.isWebmethodDefined(dbc); | |
Iterator<MethodDescriptionComposite> iter = retrieveList.iterator(); | |
while(iter.hasNext()){ | |
MethodDescriptionComposite mdc = iter.next(); | |
//If user defined a legacyWemethod with no wsdl, has atleast one operation with @Wemethod annotation | |
//and this is a public operation with no @Webmethod operation that is being exposed then | |
//lets warn user of possible security exposure. | |
Definition wsdlDef = ((ServiceDescriptionWSDL)eid.getEndpointDescription().getServiceDescription()).getWSDLDefinition(); | |
if(getLegacyWebMethod()==null && wsdlDef == null && isWebmethodDefined && mdc.getWebMethodAnnot()==null && !isConstructor(mdc)){ | |
log.warn(Messages.getMessage("MethodRetrieverWarning1", mdc.getMethodName())); | |
} | |
} | |
}//Done with implied SEI's | |
return retrieveList.iterator(); | |
} | |
/* | |
* This is called when we know that this DBC is an implicit SEI and the user has set the | |
* property for using Suns new behavior in JDK 1.6. We will retrieve all the public methods | |
* that do not have @WebMethod(exclude == true). | |
*/ | |
private ArrayList<MethodDescriptionComposite> retrieveImplicitSEIMethods( | |
DescriptionBuilderComposite dbc) { | |
ArrayList<MethodDescriptionComposite> retrieveList = new ArrayList<MethodDescriptionComposite>(); | |
Iterator<MethodDescriptionComposite> iter = null; | |
List<MethodDescriptionComposite> mdcList = dbc.getMethodDescriptionsList(); | |
if (mdcList != null) { | |
iter = dbc.getMethodDescriptionsList().iterator(); | |
boolean isWebmethodDefined = DescriptionUtils.isWebmethodDefined(dbc); | |
while (iter.hasNext()) { | |
MethodDescriptionComposite mdc = iter.next(); | |
//flag to check if the method can be exposed as webservice. | |
boolean isWebservice = !DescriptionUtils.isExcludeTrue(mdc) && !mdc.isStatic() && !mdc.isFinal(); | |
if(!isWebservice){ | |
if(log.isDebugEnabled()){ | |
log.debug(mdc.getMethodName() + " has static or final modifiers in method signature or has @Webmethod(exclude=true) set"); | |
log.debug(mdc.getMethodName() + " cannot be exposed as a webservice"); | |
} | |
} | |
if (isWebservice) { | |
mdc.setDeclaringClass(dbc.getClassName()); | |
retrieveList.add(mdc); | |
} | |
} | |
} | |
return retrieveList; | |
} | |
private boolean isConstructor(MethodDescriptionComposite mdc){ | |
return mdc.getMethodName().equals("<init>"); | |
} | |
} |