blob: d327a9a05cc6e2c54782b0f626e813d410d7a1e0 [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.server.endpoint.lifecycle.impl;
import org.apache.axis2.Constants;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.context.WebServiceContextImpl;
import org.apache.axis2.jaxws.context.factory.MessageContextFactory;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.handler.SoapMessageContext;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.injection.ResourceInjectionException;
import org.apache.axis2.jaxws.lifecycle.BaseLifecycleManager;
import org.apache.axis2.jaxws.lifecycle.LifecycleException;
import org.apache.axis2.jaxws.runtime.description.injection.ResourceInjectionServiceRuntimeDescription;
import org.apache.axis2.jaxws.runtime.description.injection.ResourceInjectionServiceRuntimeDescriptionFactory;
import org.apache.axis2.jaxws.server.endpoint.injection.ResourceInjector;
import org.apache.axis2.jaxws.server.endpoint.injection.WebServiceContextInjector;
import org.apache.axis2.jaxws.server.endpoint.injection.factory.ResourceInjectionFactory;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager;
import org.apache.axis2.util.Loader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.ws.WebServiceContext;
import java.lang.reflect.Method;
public class EndpointLifecycleManagerImpl extends BaseLifecycleManager implements
EndpointLifecycleManager {
public static final String WEBSERVICE_MESSAGE_CONTEXT = "javax.xml.ws.WebServiceContext";
private static final Log log = LogFactory.getLog(EndpointLifecycleManagerImpl.class);
public EndpointLifecycleManagerImpl(Object endpointInstance) {
this.instance = endpointInstance;
}
public EndpointLifecycleManagerImpl() {
}
/* (non-Javadoc)
* @see org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager#createServiceInstance(org.apache.axis2.jaxws.core.MessageContext, java.lang.Class)
*/
public Object createServiceInstance(MessageContext mc, Class serviceImplClass)
throws LifecycleException,
ResourceInjectionException {
org.apache.axis2.context.MessageContext msgContext = mc.getAxisMessageContext();
// Get the ServiceDescription and injectionDesc which contain
// cached information
ServiceDescription serviceDesc = mc.getEndpointDescription().getServiceDescription();
ResourceInjectionServiceRuntimeDescription injectionDesc =
getInjectionDesc(serviceDesc, serviceImplClass);
Object serviceimpl = retrieveServiceInstance(mc);
if (serviceimpl != null) {
this.instance = serviceimpl;
if (log.isDebugEnabled()) {
log.debug("Service Instance found in the service context, reusing the instance");
}
// If resource injection is needed, create the SOAPMessageContext and update the WebServiceContext
// Create MessageContext for current invocation.
if (hasResourceAnnotation(injectionDesc)) {
performWebServiceContextUpdate(mc);
}
//since service impl is there in service context , take that from there
return serviceimpl;
} else {
// create a new service impl class for that service
serviceimpl = createServiceInstance(msgContext.getAxisService(), serviceImplClass);
this.instance = serviceimpl;
if (log.isDebugEnabled()) {
log.debug("New Service Instance created");
}
// If resource injection is needed, create the SOAPMessageContext and build the WebServiceContext
// Create MessageContext for current invocation.
if (hasResourceAnnotation(injectionDesc)) {
performWebServiceContextInjection(mc, serviceimpl);
}
//Invoke PostConstruct
if (injectionDesc != null && injectionDesc.getPostConstructMethod() != null) {
invokePostConstruct(injectionDesc.getPostConstructMethod());
}
ServiceContext serviceContext = msgContext.getServiceContext();
serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, serviceimpl);
return serviceimpl;
}
}
/**
* This method locates an existing service implementation instance if
* one has been previously stored away.
*/
protected Object retrieveServiceInstance(MessageContext mc) {
Object instance = null;
ServiceContext serviceContext = mc.getAxisMessageContext().getServiceContext();
instance = serviceContext.getProperty(ServiceContext.SERVICE_OBJECT);
return instance;
}
/**
* This method will provide the necessary function in order to inject
* a WebServiceContext instance on a member of the service implementation class.
*/
protected void performWebServiceContextInjection(MessageContext mc, Object serviceImpl)
throws ResourceInjectionException {
WebServiceContext wsContext = createWebServiceContext(mc);
// Inject WebServiceContext
injectWebServiceContext(mc, wsContext, serviceImpl);
saveWebServiceContext(mc, wsContext);
}
/**
* This method will provide the necessary function in order to update
* an existing WebServiceContext instance with a MessageContext for
* the current request.
*/
protected void performWebServiceContextUpdate(MessageContext mc)
throws ResourceInjectionException {
javax.xml.ws.handler.MessageContext soapMessageContext = createSOAPMessageContext(mc);
ServiceContext serviceContext = mc.getAxisMessageContext().getServiceContext();
//Get WebServiceContext from ServiceContext
WebServiceContext ws =
(WebServiceContext) serviceContext.getProperty(WEBSERVICE_MESSAGE_CONTEXT);
//Add the MessageContext for current invocation
if (ws != null) {
updateWebServiceContext(ws, soapMessageContext);
}
}
/**
* This method will provide the function necessary to save the WebServiceContext
* associated with the endpoint.
*/
protected void saveWebServiceContext(MessageContext mc, WebServiceContext wsContext) {
ServiceContext sc = mc.getAxisMessageContext().getServiceContext();
sc.setProperty(WEBSERVICE_MESSAGE_CONTEXT, wsContext);
}
/**
* This method will be responsible for creating an instance of a WebServiceContext
* and initializing the instance with a MessageContext.
*/
protected WebServiceContext createWebServiceContext(MessageContext mc) {
javax.xml.ws.handler.MessageContext soapMessageContext = createSOAPMessageContext(mc);
// Create WebServiceContext
WebServiceContextImpl wsContext = new WebServiceContextImpl();
//Add MessageContext for this request.
wsContext.setSoapMessageContext(soapMessageContext);
return wsContext;
}
/**
* This method will retrieve a ResourceInjectionServiceRuntimeDescription if one
* is associated with the current ServiceDescription.
*/
protected ResourceInjectionServiceRuntimeDescription getInjectionDesc(
ServiceDescription serviceDesc,
Class serviceImplClass) {
ResourceInjectionServiceRuntimeDescription injectionDesc = null;
if (serviceDesc != null) {
injectionDesc =
ResourceInjectionServiceRuntimeDescriptionFactory.get(serviceDesc,
serviceImplClass);
}
return injectionDesc;
}
/**
* This method indicates whether or not we need to perform WebServiceContext injection
* on a field within our endpoint instance.
*/
protected boolean hasResourceAnnotation(ResourceInjectionServiceRuntimeDescription injectionDesc) {
return (injectionDesc != null && injectionDesc.hasResourceAnnotation());
}
private Object createServiceInstance(AxisService service, Class serviceImplClass) {
if (log.isDebugEnabled()) {
log.debug("Creating new instance of service endpoint");
}
if (serviceImplClass == null) {
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("EndpointControllerErr5"));
}
Object instance = null;
try {
// allow alternative definition of makeNewServiceObject
if (service != null && service.getParameter(Constants.SERVICE_OBJECT_SUPPLIER) != null) {
ClassLoader classLoader = service.getClassLoader();
Parameter serviceObjectParam =
service.getParameter(Constants.SERVICE_OBJECT_SUPPLIER);
Class serviceObjectMaker =
Loader.loadClass(classLoader,
((String) serviceObjectParam.getValue()).trim());
// Find static getServiceObject() method, call it if there
Method method =
serviceObjectMaker.getMethod("getServiceObject",
new Class[] { AxisService.class });
if (method != null) {
return method.invoke(serviceObjectMaker.newInstance(), new Object[] { service });
}
}
instance = serviceImplClass.newInstance();
} catch (IllegalAccessException e) {
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("EndpointControllerErr6",
serviceImplClass.getName()));
} catch (InstantiationException e) {
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("EndpointControllerErr6",
serviceImplClass.getName()));
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("EndpointControllerErr6",
serviceImplClass.getName()));
}
return instance;
}
protected javax.xml.ws.handler.MessageContext createSOAPMessageContext(MessageContext mc) {
SoapMessageContext soapMessageContext =
(SoapMessageContext) MessageContextFactory.createSoapMessageContext(mc);
return soapMessageContext;
}
protected void injectWebServiceContext(MessageContext mc, WebServiceContext wsContext,
Object serviceInstance)
throws ResourceInjectionException {
ResourceInjector ri =
ResourceInjectionFactory.createResourceInjector(WebServiceContext.class);
ri.inject(wsContext, serviceInstance);
}
protected void updateWebServiceContext(WebServiceContext wsContext,
javax.xml.ws.handler.MessageContext soapMessageContext)
throws ResourceInjectionException {
WebServiceContextInjector wci =
(WebServiceContextInjector) ResourceInjectionFactory.createResourceInjector(WebServiceContextInjector.class);
wci.addMessageContext(wsContext, soapMessageContext);
}
}