001 /* 002 Copyright (C) 2001 Renaud Pawlak <renaud@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.naming; 019 020 import org.aopalliance.intercept.ConstructorInvocation; 021 import org.aopalliance.intercept.MethodInvocation; 022 import org.objectweb.jac.core.*; 023 import org.objectweb.jac.wrappers.ForwardingWrapper; 024 025 /** 026 * This wrapper class binds an object to the actual named object by 027 * forwarder. 028 * 029 * <p><code>BindingWrapper</code> wraps the JAC object that that has not 030 * been resolved yet by the binding aspect. When a call is performed 031 * on the wrappee, the binder wrapper gets the actual JAC object that 032 * corresponds to the logical name by asking the name repository of 033 * the naming aspect. Then, it creates a forwarding wrapper to this 034 * object and replaces itself with it. 035 * 036 * <p>The binding aspect uses the naming aspect. Do not try to use it 037 * alone. 038 * 039 * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> 040 * 041 * @see ForwardingWrapper */ 042 043 public class BindingWrapper extends Wrapper { 044 045 /** 046 * Construct a new binding wrapper. 047 * 048 * @param logicalName the name of the wrappee within the naming 049 * aspect */ 050 051 public BindingWrapper(AspectComponent ac, String logicalName) { 052 super(ac); 053 this.logicalName = logicalName; 054 } 055 056 /** The name of the Jac object the binber must bind to. */ 057 protected String logicalName; 058 059 /** 060 * The getter method for the Jac object's name (role method). 061 * 062 * @return the name 063 */ 064 065 public String getLogicalName() { 066 return logicalName; 067 } 068 069 /** 070 * This wrapping method binds the wrappee. 071 * 072 * <p>Binds the wrappee to its actual location by creating a new 073 * forwarder wrapper to wrap it. This wrapping method is called 074 * only once since the binder wrapper unwraps itself once the new 075 * wrapper is created. 076 * 077 * @see ForwardingWrapper */ 078 079 public Object bind(Interaction interaction) throws BindingErrorException { 080 081 /** Get the name repository */ 082 NameRepository repository = (NameRepository) NameRepository.get(); 083 084 if (repository == null) { 085 throw new BindingErrorException("Binding aspect cannot work without the naming aspect."); 086 } 087 088 /** Get the actual reference of the object by invoking the 089 repository. */ 090 091 Object object = repository.getObject(logicalName); 092 093 //if (true) return null; 094 095 if (object == null) { 096 throw new BindingErrorException( 097 "Object '" + logicalName + "' not found in the repository."); 098 } 099 100 // RemoteRef rr = null; 101 Object to_forward = null; 102 103 /** If their is several objects for the name, then it is a 104 replicated object. We try to bind to the local one if 105 exist. It not, we will bind to the first one. This is the 106 only interaction with the distribution aspect. */ 107 108 // if (objects.length > 1) { 109 // for (int i = 0; i < objects.length; i++) { 110 // if ( ! ((Wrappee)objects[i]).isWrappedByClass ( StubWrapper.class ) ) { 111 // to_forward = objects[i]; 112 // } else { 113 // if ( ((RemoteRef) ((Wrappee)objects[i]).invokeRoleMethod ( 114 // "org.objectweb.jac.dist.StubWrapper", "getRemoteRef", new Class[] {}, new Object[] {} )) 115 // . getRemCont().isLocal () ) { 116 // to_forward = objects[i]; 117 // } 118 // } 119 // } 120 // } 121 122 // if ( to_forward == null ) { 123 // to_forward = objects[0]; 124 // } 125 126 /** We replace the binder with a forwarder. */ 127 128 ForwardingWrapper forwarder = 129 new ForwardingWrapper(getAspectComponent(), object); 130 Wrapping.unwrapAll(interaction.wrappee, null, this); 131 Wrapping.wrapAll(interaction.wrappee, null, forwarder); 132 133 /** We redo the call (that will be forwarded this time */ 134 Object ret = 135 interaction.method.invoke(interaction.wrappee, interaction.args); 136 return ret; 137 138 } 139 140 public Object invoke(MethodInvocation invocation) throws Throwable { 141 return bind((Interaction) invocation); 142 } 143 144 public Object construct(ConstructorInvocation invocation) 145 throws Throwable { 146 throw new Exception("Wrapper "+this+" does not support construction interception."); 147 } 148 149 }