001 /* 002 Copyright (C) 2001-2002 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 015 License along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 017 USA */ 018 019 package org.objectweb.jac.core; 020 021 import java.io.*; 022 import java.util.*; 023 import org.apache.log4j.Logger; 024 import org.objectweb.jac.util.*; 025 026 /** 027 * This class represents the JAC applications. 028 * 029 * <p>Before it is actually started, each application must define a 030 * name, some path informations, and a set of aspect configurations 031 * (one for each aspect the application needs to use) by instantiating 032 * and configuring this class. Then, the system registers the new 033 * application instance into the application repository of the system. 034 * 035 * <p>At a user-level, an application configuration is described in 036 * application descriptor files (*.acc). A typical application 037 * descriptor is: 038 * 039 * <pre class=code> 040 * // file myApp.acc 041 * applicationName: myApp 042 * lauchingClass: myPath.Run 043 * aspects: \ 044 * rtti rtti.acc true \ 045 * session session.acc false \ 046 * persistence persistence.acc true \ 047 * gui gui.acc true 048 * </pre> 049 * 050 * @see #Application(String,String,String,String[]) 051 * @see #addAcConfiguration(ACConfiguration) 052 * @see ACConfiguration#ACConfiguration(Application,String,String,boolean) 053 * @see ApplicationRepository */ 054 055 public class Application implements Serializable { 056 static Logger logger = Logger.getLogger("application"); 057 058 String name; 059 String path; 060 String constructorClass; 061 String[] arguments; 062 /*org.objectweb.jac.lib.java.util.*/Vector acConfigurations = 063 new /*org.objectweb.jac.lib.java.util.*/Vector(); 064 Hashtable acs = new Hashtable(); 065 boolean instantiated = false; 066 067 Properties props = new Properties(); 068 069 /** 070 * Creates a new application. 071 * 072 * @param name the name of the application 073 * @param path the path of the application (root directory). If 074 * it's null, the current directory is used 075 * @param constructorClass the path of the launching class 076 * accessible within the current class path) 077 * @param arguments the launching arguments */ 078 079 public Application(String name, String path, 080 String constructorClass, String[] arguments) { 081 this.name = name; 082 if (path==null) { 083 path = System.getProperty("user.dir"); 084 } 085 this.path = path; 086 this.constructorClass = constructorClass; 087 this.arguments = arguments; 088 // put the application in the context of this thread 089 Collaboration.get().setCurApp(name); 090 } 091 092 /** 093 * Inits the application by creating and weaving the aspects 094 * configuration that are not woven on demand. */ 095 096 public void init() { 097 Iterator it = acConfigurations.iterator(); 098 while( it.hasNext() ) { 099 ACConfiguration acConf = (ACConfiguration) it.next(); 100 if ( ! acConf.getWeaveOnDemand() ) { 101 //acConf.weave(); 102 ApplicationRepository.get().extend(name,acConf.getName()); 103 } 104 } 105 } 106 107 108 /** 109 * Gets the name of the application. 110 * 111 * @return the application's name */ 112 113 public String getName() { 114 return name; 115 } 116 117 /** 118 * Sets the application's name. 119 * 120 * @param name the application's name */ 121 122 public void setName(String name) { 123 this.name = name; 124 } 125 126 /** 127 * Gets the path of the application (its root directory). 128 * 129 * @return the application's path 130 * @see #setPath(String) */ 131 132 public String getPath() { 133 return path; 134 } 135 136 /** 137 * The path's setter. 138 * 139 * @param path the new application root directory 140 * @see #getPath() */ 141 142 public void setPath(String path) { 143 this.path = path; 144 } 145 146 /** 147 * Gets the path of the launching class (that implements the static 148 * <code>main(String[])</code> method). 149 * 150 * @return the launching class */ 151 152 public String getConstructorClass() { 153 return constructorClass; 154 } 155 156 /** 157 * Gets the path of the launching class (that implements the static 158 * <code>main(String[])</code> method). 159 * 160 * @param constructorClass the launching class */ 161 162 public void setConstructorClass(String constructorClass) { 163 this.constructorClass = constructorClass; 164 } 165 166 /** 167 * Tells if this application currently realizes a given aspect 168 * component. <b>Not available yet</b>. 169 * 170 * @param acName the aspect component name 171 * @return true if the application realizes the given aspect */ 172 173 public boolean realizes(String acName) { 174 return false; //acs.containsKey( "acName" ); 175 } 176 177 /** 178 * Tells if this application configures a given aspect 179 * component. <b>Not available yet</b>. 180 * 181 * @param acName the aspect component name 182 * @return true if the application configures the given aspect */ 183 184 public boolean configures(String acName) { 185 return false; //acs.containsKey( "acName" ); 186 } 187 188 /** 189 * Adds an aspect component configuration for this application. 190 * 191 * @param configuration the new configuration */ 192 193 public void addAcConfiguration(ACConfiguration configuration) { 194 acConfigurations.add(configuration); 195 } 196 197 /** 198 * Removes an aspect component configuration for this application. 199 * 200 * @param configuration the configuration to remove */ 201 202 public void removeAcConfiguration(ACConfiguration configuration) { 203 acConfigurations.remove(configuration.getName()); 204 } 205 206 /** 207 * Returns all the configurations for the current application. 208 * 209 * @return a collection of configurations */ 210 211 public Collection getAcConfigurations() { 212 return (org.objectweb.jac.lib.java.util.Vector)acConfigurations.clone(); 213 } 214 215 /** 216 * Gets a configurations from its name (the name of the aspect as 217 * defined in the <code>jac.prop</code> file. 218 * 219 * @param name the aspect name 220 * @return the corresponding configuration */ 221 222 public ACConfiguration getAcConfiguration(String name) { 223 Iterator i = acConfigurations.iterator(); 224 while(i.hasNext()) { 225 ACConfiguration conf = (ACConfiguration)i.next(); 226 if (conf.getName().equals(name)) 227 return conf; 228 } 229 return null; 230 } 231 232 /** 233 * Starts the application with its current aspect component 234 * configurations. 235 * 236 * <p>If the application is already instantiated or if the launching 237 * path is not found, then do nothing. 238 */ 239 240 public void start() { 241 if (instantiated) { 242 logger.warn("application '" + name + "' is already instantiated"); 243 return; 244 } 245 try { 246 logger.info("launching application "+this); 247 Class.forName(constructorClass) 248 .getMethod( "main", new Class[] { String[].class } ) 249 .invoke( null, new Object[] { arguments } ); 250 instantiated = true; 251 Iterator it = acConfigurations.iterator(); 252 while( it.hasNext() ) { 253 ACConfiguration conf = (ACConfiguration) it.next(); 254 if( ! conf.weaveOnDemand ) { 255 conf.weave(); 256 } 257 } 258 259 } catch(Exception e) { 260 logger.error("application '" + name + "' unable to start",e); 261 } 262 } 263 264 265 /** 266 * Returns a string representation of this application. 267 * @return a string */ 268 269 public String toString() { 270 return "Application " + name; 271 } 272 273 }