blob: aba9ffec4ac5d06dcfe8bf4da710c584499a7a3f [file] [log] [blame]
/*
* 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>");
}
}