001 /* 002 Copyright (C) 2002-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 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.ide; 020 021 import java.io.FilenameFilter; 022 import java.io.IOException; 023 import java.util.Arrays; 024 import java.util.Collection; 025 import java.util.HashSet; 026 import java.util.Hashtable; 027 import java.util.Iterator; 028 import java.util.LinkedList; 029 import java.util.List; 030 import java.util.Map; 031 import java.util.Set; 032 import java.util.Vector; 033 import org.apache.log4j.Level; 034 import org.objectweb.jac.core.Jac; 035 import org.objectweb.jac.util.File; 036 import org.objectweb.jac.util.Pipe; 037 import org.objectweb.jac.util.Strings; 038 039 public class Application extends ModelElement { 040 041 public Application() { 042 } 043 044 Vector hosts = new Vector(); 045 046 /** 047 * Get the value of hosts. 048 * @return value of hosts. 049 */ 050 public List getHosts() { 051 return hosts; 052 } 053 054 public void addHost(String host) { 055 hosts.add(host); 056 } 057 058 public void removeHost(String host) { 059 hosts.remove(host); 060 } 061 062 String name; 063 064 /** 065 * Get the value of name. 066 * @return value of name. 067 */ 068 public String getName() { 069 return name; 070 } 071 072 /** 073 * Set the value of name. 074 * @param v Value to assign to name. 075 */ 076 public void setName(String v) { 077 this.name = v; 078 } 079 080 Class mainClass; 081 082 /** 083 * Get the value of mainClass. 084 * @return value of mainClass. 085 */ 086 public Class getMainClass() { 087 return mainClass; 088 } 089 090 /** 091 * Set the value of mainClass. 092 * @param v Value to assign to mainClass. 093 */ 094 public void setMainClass(Class v) { 095 this.mainClass = v; 096 } 097 098 Vector aspectConfigurations = new Vector(); 099 100 /** 101 * Get the value of aspectConfigurations. 102 * @return value of aspectConfigurations. 103 */ 104 public List getAspectConfigurations() { 105 return aspectConfigurations; 106 } 107 108 public void addAspectConfiguration(AspectConfiguration a) { 109 aspectConfigurations.add(a); 110 } 111 112 public void removeAspectConfiguration(AspectConfiguration a) { 113 aspectConfigurations.remove(a); 114 } 115 116 Vector externalPaths = new Vector(); 117 /** 118 * Get the value of externalPaths. 119 * @return value of externalPaths. 120 */ 121 public List getExternalPaths() { 122 return externalPaths; 123 } 124 public void addExternalPath(String path) { 125 externalPaths.add(path); 126 } 127 public void removeExternalPath(String path) { 128 externalPaths.remove(path); 129 } 130 131 /** 132 * Classes that JAC must not translate 133 */ 134 Set ignoredClasses = new HashSet(); 135 public Set getIgnoredClasses() { 136 return ignoredClasses; 137 } 138 public void addIgnoredClass(String expr) { 139 ignoredClasses.add(expr); 140 } 141 public void removeIgnoredClass(String expr) { 142 ignoredClasses.remove(expr); 143 } 144 145 Project project; 146 /** 147 * Get the value of project. 148 * @return value of project. 149 */ 150 public Project getProject() { 151 return project; 152 } 153 /** 154 * Set the value of project. 155 * @param v Value to assign to project. 156 */ 157 public void setProject(Project v) { 158 this.project = v; 159 } 160 161 boolean startSwingGUI = false; 162 public void setStartSwingGUI(boolean value) { 163 this.startSwingGUI = value; 164 } 165 public boolean getStartSwingGUI() { 166 return startSwingGUI; 167 } 168 169 String swingGUIs; 170 public String getSwingGUIs() { 171 return swingGUIs; 172 } 173 public void setSwingGUIs(String v) { 174 this.swingGUIs = v; 175 } 176 177 String webGUIs; 178 public String getWebGUIs() { 179 return webGUIs; 180 } 181 public void setWebGUIs(String v) { 182 this.webGUIs = v; 183 } 184 185 boolean startWebGUI = false; 186 public void setStartWebGUI(boolean value) { 187 this.startWebGUI = value; 188 } 189 public boolean getStartWebGUI() { 190 return startWebGUI; 191 } 192 193 boolean enableDistribution = true; 194 public void setEnableDistribution(boolean value) { 195 this.enableDistribution = value; 196 } 197 public boolean isDistributionEnabled() { 198 return enableDistribution; 199 } 200 201 String serverName = "s1"; 202 public void setServerName(String name) { 203 this.serverName = name; 204 } 205 public String getServerName() { 206 return serverName; 207 } 208 209 String otherOptions = ""; 210 public String getOtherOption() { 211 return otherOptions; 212 } 213 public void setOtherOptions(String options) { 214 this.otherOptions = options; 215 } 216 217 String jvmOptions = ""; 218 public String getJvmOption() { 219 return jvmOptions; 220 } 221 public void setJvmOptions(String options) { 222 this.jvmOptions = options; 223 } 224 225 Map properties = new Hashtable(); 226 public Map getProperties() { 227 return properties; 228 } 229 public void addProperty(String name, String value) { 230 properties.put(name,value); 231 } 232 public void removeProperty(String name) { 233 properties.remove(name); 234 } 235 236 boolean enableDebugging; 237 public boolean isEnableDebugging() { 238 return enableDebugging; 239 } 240 public void setEnableDebugging(boolean enableDebugging) { 241 this.enableDebugging = enableDebugging; 242 } 243 244 int debugPort = 4444; 245 public int getDebugPort() { 246 return debugPort; 247 } 248 public void setDebugPort(int debugPort) { 249 this.debugPort = debugPort; 250 } 251 252 transient Process currentProcess = null; 253 public void resetCurrentProcess() { 254 currentProcess = null; 255 } 256 257 public boolean isStarted() { 258 return currentProcess!=null; 259 } 260 public boolean isNotStarted() { 261 return currentProcess==null; 262 } 263 264 public File getJacFile() { 265 return new File( 266 new File(project.getGenerationPath(),getGenerationName()), 267 getGenerationName()+".jac"); 268 } 269 270 /** 271 * Returns the command and arguments to run the application 272 */ 273 public String[] getRunCommandAndArgs() { 274 File dir = new File(project.getGenerationPath(),name); 275 Vector runCmd = new Vector(); 276 runCmd.add("java"); 277 278 runCmd.addAll(Strings.splitToList(jvmOptions," ")); 279 280 if (enableDebugging) { 281 runCmd.add("-Xdebug"); 282 runCmd.add("-Xrunjdwp:transport=dt_socket,address="+debugPort+",server=y,suspend=n"); 283 } 284 285 runCmd.add("-Djava.security.policy="+ 286 org.objectweb.jac.core.Jac.getJacRoot()+"jac.policy"); 287 288 // So that is works on MacOS X 289 runCmd.add("-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel"); 290 291 File jar = new File(org.objectweb.jac.core.Jac.getJacRoot()+"jac.jar"); 292 String jacroot = org.objectweb.jac.core.Jac.getJacRoot(); 293 String sep = System.getProperty("path.separator"); 294 295 // add the classpath defined in the project and all jars in $JAC_ROOT/lib 296 List classpath = new LinkedList(getProject().getClasspath()); 297 File libDir = new File(jacroot,"lib"); 298 classpath.add(new File(jacroot,"classes")); 299 classpath.add(new File(jacroot,"src")); 300 if (jar.exists()) 301 classpath.add(jar); 302 classpath.addAll( 303 libDir.listFilesRecursively( 304 new FilenameFilter() { 305 public boolean accept(java.io.File file, String name) { 306 return name.endsWith(".jar"); 307 } 308 } 309 )); 310 if (classpath.size()>0) { 311 runCmd.add("-classpath"); 312 runCmd.add(Strings.join(classpath,sep)); 313 } 314 315 Iterator it = properties.entrySet().iterator(); 316 while (it.hasNext()) { 317 Map.Entry entry = (Map.Entry)it.next(); 318 runCmd.add("-D"+entry.getKey()+"="+entry.getValue()); 319 } 320 321 runCmd.add("org.objectweb.jac.core.Jac"); 322 323 runCmd.add("-w"); 324 if (enableDistribution) { 325 runCmd.add("-D"); 326 if (serverName!=null && !serverName.equals("")) 327 runCmd.add(serverName); 328 } 329 330 if (!Strings.isEmpty(jacroot)) { 331 runCmd.add("-R"); 332 runCmd.add(jacroot); 333 } 334 runCmd.add("-C"); 335 runCmd.add(project.getGenerationPath().getPath()+ 336 sep+new File(project.getGenerationPath(),"classes").getPath()+ 337 sep+project.getClasspathString()); 338 339 String msg="Starting application '"+name+"'"; 340 if (startSwingGUI) { 341 runCmd.add("-G"); 342 runCmd.add(swingGUIs); 343 msg = msg+" (Swing GUIs: "+swingGUIs+")"; 344 } 345 346 if (startWebGUI) { 347 runCmd.add("-W"); 348 runCmd.add(webGUIs); 349 msg = msg+" (Web GUIs: "+webGUIs+")"; 350 } 351 352 runCmd.addAll(Strings.splitToList(otherOptions," ")); 353 354 runCmd.add(new File(dir,name+".jac").getPath()); 355 356 return (String[])runCmd.toArray(new String[] {}); 357 } 358 359 public void start() throws IOException { 360 if (!startSwingGUI && !startWebGUI) { 361 throw new RuntimeException( 362 "You should probably start a GUI (see \"Run options\""+ 363 " of the application)"); 364 } 365 366 if (isStarted()) { 367 stop(); 368 } 369 370 String msg="Starting application '"+name+"'"; 371 if (startSwingGUI) { 372 msg = msg+" (Swing GUIs: "+swingGUIs+")"; 373 } 374 if (startWebGUI) { 375 msg = msg+" (Web GUIs: "+webGUIs+")"; 376 } 377 org.objectweb.jac.aspects.gui.Actions.showStatus(msg); 378 379 String[] runCmd = getRunCommandAndArgs(); 380 //Log.trace("ide.run",0,"Run command = "+Arrays.asList(runCmd)); 381 currentProcess = Runtime.getRuntime().exec(runCmd); 382 383 Pipe outputPipe = new Pipe(currentProcess.getInputStream(),System.out); 384 outputPipe.start(); 385 Pipe errorPipe = new Pipe(currentProcess.getErrorStream(),System.out); 386 errorPipe.start(); 387 new Thread() { 388 public void run() { 389 while (currentProcess!=null) { 390 try { 391 currentProcess.waitFor(); 392 //Log.trace("ide","Current process completed"); 393 resetCurrentProcess(); 394 } catch (InterruptedException e) { 395 //Log.trace("ide","Exception while waiting for "+currentProcess); 396 } 397 } 398 } 399 }.start(); 400 } 401 402 public void stop() { 403 if (currentProcess!=null) { 404 currentProcess.destroy(); 405 currentProcess = null; 406 } 407 org.objectweb.jac.aspects.gui.Actions.showStatus("Application stopped."); 408 } 409 410 public void startSlaves() throws IOException { 411 File dir = new File(project.getGenerationPath(),name); 412 Vector runCmd = new Vector(); 413 runCmd.add("go"); 414 runCmd.add(""+getHosts().size()); 415 File jar = new File(org.objectweb.jac.core.Jac.getJacRoot()+"jac.jar"); 416 runCmd.add("-C"); 417 runCmd.add(project.getGenerationPath().getPath()+ 418 System.getProperty("path.separator")+ 419 new File(project.getGenerationPath(),"classes").getPath()); 420 421 String msg="Starting slaves..."; 422 423 org.objectweb.jac.aspects.gui.Actions.showStatus(msg); 424 425 //Log.trace("ide.run",0,"Run command = "+runCmd); 426 Runtime.getRuntime().exec( 427 (String[])runCmd.toArray(new String[] {})); 428 429 } 430 431 /** 432 * Changes a trace for the running process 433 * @param category category of the trace 434 * @param level level of the trace (0=quiet,1=verbose,2=more verbose...) 435 */ 436 public void setTrace(String category, Level level) throws Exception { 437 if (currentProcess!=null) { 438 Jac.remoteSetTrace(name,serverName,category,level.toInt()); 439 } 440 } 441 442 public boolean canStartSlaves() { 443 return getHosts().size()>0; 444 } 445 446 public void generateCode() throws CannotGenerateException, IOException 447 { 448 project.checkGenerationPath(); 449 CodeGeneration.createApplicationCode( 450 project,this,new File(project.getGenerationPath().getPath(),name)); 451 } 452 453 /** 454 * Returns available main classes (Classes wich have a static void 455 * main(String[]) method) 456 * @param application the application to return main classes for 457 */ 458 public static Collection getMainClasses(Application application) { 459 Vector mainClasses = new Vector(); 460 if (application.getProject()!=null) { 461 Iterator it = application.getProject().getPackages().iterator(); 462 while (it.hasNext()) { 463 Package pkg = (Package)it.next(); 464 mainClasses.addAll(pkg.getMainClasses()); 465 } 466 } 467 return mainClasses; 468 } 469 }