001 /* 002 Copyright (C) 2001-2003 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 java.util.Hashtable; 021 import java.util.Map; 022 import org.apache.log4j.Logger; 023 import org.objectweb.jac.core.*; 024 import org.objectweb.jac.core.Interaction; 025 import org.objectweb.jac.core.rtti.ClassItem; 026 import org.objectweb.jac.util.ExtArrays; 027 import org.objectweb.jac.util.Log; 028 029 /** 030 * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> 031 */ 032 033 /** 034 * Handles the naming aspect within the JAC system. 035 * 036 * <p>This aspect component automatically registers all the created 037 * JAC object into the sole instance of <code>NameRepository</code>. 038 * 039 * @see NameRepository */ 040 041 public class NamingAC extends AspectComponent { 042 043 static Logger logger = Logger.getLogger("naming"); 044 static Logger loggerSerial = Logger.getLogger("serialization"); 045 046 /** 047 * Creates a naming aspect component. 048 * 049 * <p>It creates the name repository if it does not exist yet. 050 * 051 * @see NameRepository 052 */ 053 public NamingAC() { 054 055 setSystemListener(true); 056 057 NameRepository nr = (NameRepository) NameRepository.get(); 058 if (nr == null) { 059 System.out.println ("Error: cannot create name repository."); 060 System.exit(-1); 061 } 062 } 063 064 NameGenerator nameGen = new NameGenerator(); 065 066 /** 067 * Name a new instance using the <code>nameObject()</code> and 068 * <code>generateName()</code> methods. 069 * 070 * @see #nameObject(Object,String) 071 * @see NameGenerator#generateName(String) 072 */ 073 public void whenUsingNewInstance(Interaction interaction) { 074 //if (interaction.wrappee.getClass().getName().startsWith("org.objectweb.jac.lib.java.util.")) { 075 // do nothing for collections 076 // return; 077 //} 078 if (interaction.wrappee==null) { 079 // do nothing for static methods 080 return; 081 } 082 logger.debug("when using new instance "+interaction.wrappee.getClass()); 083 if (NameRepository.get().getName(interaction.wrappee)!=null) { 084 return; 085 } 086 if ( !(interaction.wrappee instanceof AspectComponent) ) { 087 nameObject(interaction.wrappee, (String)attr(Naming.FORCE_NAME)); 088 attrdef(Naming.FORCE_NAME, null); 089 } 090 //System.out.println( "EO Naming " + interaction.wrappee ); 091 } 092 093 /** 094 * This method is upcalled when a new object is instanciated from a 095 * remote site. 096 * 097 * <p>The name that is passed is the name of the remote reference 098 * that has been used to create the object. Thus, the default 099 * behavior of the naming aspect is to register the new object into 100 * the name repository. 101 * 102 * @param newInstance the remotly created new instance 103 * @param name the name that was forwarded from the creator host 104 * 105 * @see NameRepository 106 * @see org.objectweb.jac.util.Repository#register(String,Object) */ 107 108 public void whenRemoteInstantiation(Wrappee newInstance, String name) { 109 logger.debug("whenRemoteInstantiation "+newInstance+","+name); 110 NameRepository.get().register(name, newInstance); 111 } 112 113 /** 114 * Name a single object by registering it in the name repository 115 * (see the <code>NameRepository</code> class). 116 * 117 * <p>If the repository does not exist, it is created. 118 * 119 * @param object the object to name 120 * @param name the given name 121 * @return the new name of the object 122 * 123 * @see NameRepository 124 * @see org.objectweb.jac.util.Repository#register(String,Object) 125 */ 126 public String nameObject(Object object, String name) { 127 NameRepository nr = (NameRepository)NameRepository.get(); 128 if (nr==null) { 129 logger.error("Error: cannot create name repository."); 130 throw new RuntimeException("Error: cannot create name repository."); 131 } 132 if (name == null) { 133 name = nameGen.generateName(object.getClass().getName()); 134 logger.debug("generated name "+object+" -> "+name); 135 name = ACManager.getACM().whenNameObject(object,name); 136 } else { 137 logger.debug("forced name "+object+" -> "+name); 138 } 139 logger.debug("Registering "+object+" -> "+name); 140 nr.register(name, object); 141 return name; 142 } 143 144 /** 145 * Returns the counters used to generate unique names 146 */ 147 public Map getNameCounters() { 148 Hashtable counters = new Hashtable(); 149 counters.putAll(nameGen); 150 ((ACManager)ACManager.get()).getNameCounters(counters); 151 return counters; 152 } 153 154 public void updateNameCounters(Map counters) { 155 nameGen.update(counters); 156 } 157 158 /** 159 * Add the name to the <code>SerializedJacObject</code> structure 160 * when serialized. 161 * 162 * <p>This allows the name to be serialized with a JAC object so 163 * that the object can be named with the same name when deserialized 164 * (see <code>BindingAC</code>). 165 * 166 * @param finalObject the structure corresponding to the object 167 * that is being serialized 168 * 169 * @see BindingAC#whenDeserialized(SerializedJacObject,Wrappee) 170 * @see org.objectweb.jac.core.SerializedJacObject#setACInfos(String,Object) 171 */ 172 173 public Wrappee whenSerialized(Wrappee orgObject, 174 SerializedJacObject finalObject) { 175 176 if(orgObject.getClass().getName().startsWith("org.objectweb.jac.lib.java.util")) { 177 return orgObject; 178 } 179 180 NameRepository nr = (NameRepository) NameRepository.get(); 181 String name = nr.getName(orgObject); 182 if (name!=null) { 183 loggerSerial.debug("NAMING: serializing object " + name ); 184 finalObject.setACInfos(ACManager.get().getName(this), name); 185 } else { 186 if (Wrapping.isExtendedBy(orgObject,null, 187 org.objectweb.jac.wrappers.ForwardingWrapper.class)) { 188 loggerSerial.debug("NAMING: Serializing forwardee for " + orgObject ); 189 Object newOrg = Wrapping.invokeRoleMethod(orgObject, 190 "getForwardee", 191 ExtArrays.emptyObjectArray); 192 if (newOrg!=null) { 193 orgObject = (Wrappee)newOrg; 194 } else { 195 logger.warn("Oooops!! Forwardee is " + newOrg); 196 } 197 } 198 name = nr.getName(orgObject); 199 if (name!=null) { 200 loggerSerial.debug("NAMING: serializing object " + name +" (PASS 2)"); 201 finalObject.setACInfos(ACManager.get().getName(this), name); 202 } else { 203 logger.warn("Oooops!! Object is still unamed: "+orgObject); 204 //System.out.println( "NAMING: still a forwarder? => " + orgObject.isExtendedBy( jac.wrappers.ForwarderWrapper.class) ); 205 } 206 } 207 return orgObject; 208 } 209 }