001: /*
002: * Copyright 2002-2005 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.remoting.support;
018:
019: import java.lang.reflect.InvocationTargetException;
020:
021: /**
022: * Abstract base class for remote service exporters that are based on
023: * deserialization of RemoteInvocation objects. Provides a "remoteInvocationExecutor"
024: * property, with a DefaultRemoteInvocationExecutor as default.
025: *
026: * @author Juergen Hoeller
027: * @since 1.1
028: * @see RemoteInvocationExecutor
029: * @see DefaultRemoteInvocationExecutor
030: */
031: public abstract class RemoteInvocationBasedExporter extends
032: RemoteExporter {
033:
034: private RemoteInvocationExecutor remoteInvocationExecutor = new DefaultRemoteInvocationExecutor();
035:
036: /**
037: * Set the RemoteInvocationExecutor to use for this exporter.
038: * Default is a DefaultRemoteInvocationExecutor.
039: * <p>A custom invocation executor can extract further context information
040: * from the invocation, for example user credentials.
041: */
042: public void setRemoteInvocationExecutor(
043: RemoteInvocationExecutor remoteInvocationExecutor) {
044: this .remoteInvocationExecutor = remoteInvocationExecutor;
045: }
046:
047: /**
048: * Return the RemoteInvocationExecutor used by this exporter.
049: */
050: public RemoteInvocationExecutor getRemoteInvocationExecutor() {
051: return remoteInvocationExecutor;
052: }
053:
054: /**
055: * Apply the given remote invocation to the given target object.
056: * The default implementation delegates to the RemoteInvocationExecutor.
057: * <p>Can be overridden in subclasses for custom invocation behavior,
058: * possibly for applying additional invocation parameters from a
059: * custom RemoteInvocation subclass. Note that it is preferable to use
060: * a custom RemoteInvocationExecutor which is a reusable strategy.
061: * @param invocation the remote invocation
062: * @param targetObject the target object to apply the invocation to
063: * @return the invocation result
064: * @throws NoSuchMethodException if the method name could not be resolved
065: * @throws IllegalAccessException if the method could not be accessed
066: * @throws InvocationTargetException if the method invocation resulted in an exception
067: * @see RemoteInvocationExecutor#invoke
068: */
069: protected Object invoke(RemoteInvocation invocation,
070: Object targetObject) throws NoSuchMethodException,
071: IllegalAccessException, InvocationTargetException {
072:
073: if (logger.isDebugEnabled()) {
074: logger.debug("Applying " + invocation);
075: }
076: try {
077: return getRemoteInvocationExecutor().invoke(invocation,
078: targetObject);
079: } catch (NoSuchMethodException ex) {
080: if (logger.isDebugEnabled()) {
081: logger.warn("Could not find target method for "
082: + invocation, ex);
083: }
084: throw ex;
085: } catch (IllegalAccessException ex) {
086: if (logger.isDebugEnabled()) {
087: logger.warn("Could not access target method for "
088: + invocation, ex);
089: }
090: throw ex;
091: } catch (InvocationTargetException ex) {
092: if (logger.isDebugEnabled()) {
093: logger.debug("Target method failed for " + invocation,
094: ex.getTargetException());
095: }
096: throw ex;
097: }
098: }
099:
100: /**
101: * Apply the given remote invocation to the given target object, wrapping
102: * the invocation result in a serializable RemoteInvocationResult object.
103: * The default implementation creates a plain RemoteInvocationResult.
104: * <p>Can be overridden in subclasses for custom invocation behavior,
105: * for example to return additional context information. Note that this
106: * is not covered by the RemoteInvocationExecutor strategy!
107: * @param invocation the remote invocation
108: * @param targetObject the target object to apply the invocation to
109: * @return the invocation result
110: * @see #invoke
111: */
112: protected RemoteInvocationResult invokeAndCreateResult(
113: RemoteInvocation invocation, Object targetObject) {
114: try {
115: Object value = invoke(invocation, targetObject);
116: return new RemoteInvocationResult(value);
117: } catch (Throwable ex) {
118: return new RemoteInvocationResult(ex);
119: }
120: }
121:
122: }
|