📄 javaprovider.java
字号:
/* * Copyright 2001-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. */package org.apache.axis.providers.java;import org.apache.axis.AxisEngine;import org.apache.axis.AxisFault;import org.apache.axis.Constants;import org.apache.axis.Handler;import org.apache.axis.Message;import org.apache.axis.MessageContext;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.description.JavaServiceDesc;import org.apache.axis.description.OperationDesc;import org.apache.axis.constants.Scope;import org.apache.axis.handlers.soap.SOAPService;import org.apache.axis.message.SOAPEnvelope;import org.apache.axis.providers.BasicProvider;import org.apache.axis.session.Session;import org.apache.axis.utils.ClassUtils;import org.apache.axis.utils.Messages;import org.apache.axis.utils.XMLUtils;import org.apache.axis.utils.cache.ClassCache;import org.apache.axis.utils.cache.JavaClass;import org.apache.commons.logging.Log;import org.xml.sax.SAXException;import javax.xml.rpc.holders.IntHolder;import javax.xml.rpc.server.ServiceLifecycle;import javax.xml.soap.SOAPMessage;import javax.wsdl.OperationType;import java.io.Serializable;import java.util.ArrayList;import java.util.StringTokenizer;/** * Base class for Java dispatching. Fetches various fields out of envelope, * looks up service object (possibly using session state), and delegates * envelope body processing to subclass via abstract processMessage method. * * @author Doug Davis (dug@us.ibm.com) * @author Carl Woolf (cwoolf@macromedia.com) */public abstract class JavaProvider extends BasicProvider{ protected static Log log = LogFactory.getLog(JavaProvider.class.getName()); // The enterprise category is for stuff that an enterprise product might // want to track, but in a simple environment (like the AXIS build) would // be nothing more than a nuisance. protected static Log entLog = LogFactory.getLog(Constants.ENTERPRISE_LOG_CATEGORY); public static final String OPTION_CLASSNAME = "className"; public static final String OPTION_ALLOWEDMETHODS = "allowedMethods"; public static final String OPTION_SCOPE = "scope"; /** * Get the service object whose method actually provides the service. * May look up in session table. */ public Object getServiceObject (MessageContext msgContext, Handler service, String clsName, IntHolder scopeHolder) throws Exception { String serviceName = msgContext.getService().getName(); // scope can be "Request", "Session", "Application", "Factory" Scope scope = Scope.getScope((String)service.getOption(OPTION_SCOPE), Scope.DEFAULT); scopeHolder.value = scope.getValue(); if (scope == Scope.REQUEST) { // make a one-off return getNewServiceObject(msgContext, clsName); } else if (scope == Scope.SESSION) { // What do we do if serviceName is null at this point??? if (serviceName == null) serviceName = msgContext.getService().toString(); // look in incoming session Session session = msgContext.getSession(); if (session != null) { return getSessionServiceObject(session, serviceName, msgContext, clsName); } else { // was no incoming session, sigh, treat as request scope scopeHolder.value = Scope.DEFAULT.getValue(); return getNewServiceObject(msgContext, clsName); } } else if (scope == Scope.APPLICATION) { // MUST be AxisEngine here! return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder); } else if (scope == Scope.FACTORY) { String objectID = msgContext.getStrProp("objectID"); if (objectID == null) { return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder); } SOAPService svc = (SOAPService)service; Object ret = svc.serviceObjects.get(objectID); if (ret == null) { throw new AxisFault("NoSuchObject", null, null, null); } return ret; } // NOTREACHED return null; } private Object getApplicationScopedObject(MessageContext msgContext, String serviceName, String clsName, IntHolder scopeHolder) throws Exception { AxisEngine engine = msgContext.getAxisEngine(); Session appSession = engine.getApplicationSession(); if (appSession != null) { return getSessionServiceObject(appSession, serviceName, msgContext, clsName); } else { // was no application session - log an error and // treat as request scope log.error(Messages.getMessage("noAppSession")); scopeHolder.value = Scope.DEFAULT.getValue(); return getNewServiceObject(msgContext, clsName); } } /** * Simple utility class for dealing with synchronization issues. */ class LockObject implements Serializable { private boolean completed = false; synchronized void waitUntilComplete() throws InterruptedException { while (!completed) { wait(); } } synchronized void complete() { completed = true; notifyAll(); } } /** * Get a service object from a session. Handles threading / locking * issues when multiple threads might be accessing the same session * object, and ensures only one thread gets to create the service * object if there isn't one already. */ private Object getSessionServiceObject(Session session, String serviceName, MessageContext msgContext, String clsName) throws Exception { Object obj = null; boolean makeNewObject = false; // This is a little tricky. synchronized (session.getLockObject()) { // store service objects in session, indexed by class name obj = session.get(serviceName); // If nothing there, put in a placeholder object so // other threads wait for us to create the real // service object. if (obj == null) { obj = new LockObject(); makeNewObject = true; session.set(serviceName, obj); msgContext.getService().addSession(session); } } // OK, we DEFINITELY have something in obj at this point. Either // it's the service object or it's a LockObject (ours or someone // else's). if (LockObject.class == obj.getClass()) { LockObject lock = (LockObject)obj; // If we were the lucky thread who got to install the // placeholder, create a new service object and install it // instead, then notify anyone waiting on the LockObject. if (makeNewObject) { try { obj = getNewServiceObject(msgContext, clsName); session.set(serviceName, obj); msgContext.getService().addSession(session); } catch(final Exception e) { session.remove(serviceName); throw e; } finally { lock.complete(); } } else { // It's someone else's LockObject, so wait around until // it's completed. lock.waitUntilComplete(); // Now we are guaranteed there is a service object in the // session, so this next part doesn't need syncing obj = session.get(serviceName); } } return obj; } /** * Return a new service object which, if it implements the ServiceLifecycle * interface, has been init()ed. * * @param msgContext the MessageContext * @param clsName the name of the class to instantiate * @return an initialized service object */ private Object getNewServiceObject(MessageContext msgContext, String clsName) throws Exception { Object serviceObject = makeNewServiceObject(msgContext, clsName); if (serviceObject != null && serviceObject instanceof ServiceLifecycle) { ((ServiceLifecycle)serviceObject).init( msgContext.getProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT)); } return serviceObject;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -