001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.core.component.proxy;
019:
020: import java.lang.reflect.InvocationHandler;
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Proxy;
023:
024: import org.sape.carbon.core.component.Component;
025:
026: /**
027: * <p>This class provides the final invocation on the targe class. This class
028: * or something similar should always be at the end of interceptor chains that
029: * are configured to execute the supplied invocations.</p>
030: *
031: * Copyright 2003 Sapient
032: * @since carbon 2.0
033: * @author Greg Hinkle, March 2003
034: * @version $Revision: 1.6 $($Author: ghinkl $ / $Date: 2003/10/14 16:40:35 $)
035: */
036: public class ProxyInvoker implements Interceptor {
037:
038: /**
039: * This method sets the next interceptor as the next in the chain from the
040: * current interceptor.
041: * @param interceptor the next interceptor in the chain
042: */
043: public void setNextInterceptor(Interceptor interceptor) {
044: throw new UnsupportedOperationException(
045: "ProxyInvoker is designed to be configured at the end of the "
046: + "interceptor chain. It makes no sense to configure it "
047: + "before the end of the chain. Please check your "
048: + "Component Template Configuration.");
049: }
050:
051: /**
052: * Handles the delegation to the target of the component call. The
053: * target will either be the Functional Implementation object or
054: * one of the interceptors (delegates).
055: *
056: * @param invocation the invocation to execute
057: * @return the results of the invocation's execution
058: * @throws Throwable indicates an error in the invokation chain
059: */
060: public Object invoke(Invocation invocation) throws Throwable {
061:
062: try {
063: // GH: There used to be a shortcut for proxy calls
064: // that would directly call the invocation handler
065: // rather than using a reflective invoke. This was
066: // removed as the component target calls are not
067: // like this and the Proxy.isProxyClass test causes
068: // too much of a slowdown.
069: return invocation.getMethod().invoke(
070: invocation.getTarget(),
071: invocation.getMethodArguments());
072: } catch (IllegalAccessException iae) {
073: throw iae;
074: } catch (InvocationTargetException ite) {
075: throw ite.getTargetException();
076: }
077:
078: }
079:
080: /**
081: * This should return the list of interfaces that a decorator wishes to
082: * expose through the component proxy. This is used by the
083: * component factory to determine what interfaces the component proxy will
084: * implement.
085: *
086: * @return Class[] an array of interfaces
087: */
088: public Class[] getExposedInterfaces() {
089: return new Class[0];
090: }
091:
092: /**
093: * Called after creation to pass a reference to the component to each of
094: * its decorators. The component reference should not be used within
095: * this method because not all other interceptors have this reference yet
096: * and they may rely on this reference thus leading to null pointer
097: * exceptions.
098: *
099: * @param component a reference to the component that this interceptor is
100: * assisting
101: */
102: public void setComponentReference(Component component) {
103: }
104:
105: }
|