// $Id: Main.java 132 2010-09-26 23:32:33Z marcusvnac $
// Copyright (c) 1996-2009 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies. This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason. IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package org.argouml.application;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Import
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
//#endif
import org.apache.log4j.PropertyConfigurator;
import org.argouml.application.api.Argo;
import org.argouml.application.api.CommandLineInterface;
import org.argouml.application.security.ArgoAwtExceptionHandler;
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Import
import org.argouml.cognitive.AbstractCognitiveTranslator;
import org.argouml.cognitive.Designer;
import org.argouml.cognitive.checklist.ui.InitCheckListUI;
import org.argouml.cognitive.ui.InitCognitiveUI;
import org.argouml.cognitive.ui.ToDoPane;
//#endif
import org.argouml.configuration.Configuration;
import org.argouml.i18n.Translator;
import org.argouml.kernel.ProjectManager;
import org.argouml.model.Model;
import org.argouml.moduleloader.InitModuleLoader;
import org.argouml.moduleloader.ModuleLoader2;
import org.argouml.notation.InitNotation;
import org.argouml.notation.providers.java.InitNotationJava;
import org.argouml.notation.providers.uml.InitNotationUml;
import org.argouml.notation.ui.InitNotationUI;
import org.argouml.persistence.PersistenceManager;
import org.argouml.profile.init.InitProfileSubsystem;
import org.argouml.ui.LookAndFeelMgr;
import org.argouml.ui.ProjectBrowser;
import org.argouml.ui.SplashScreen;
import org.argouml.ui.cmd.ActionExit;
import org.argouml.ui.cmd.InitUiCmdSubsystem;
import org.argouml.ui.cmd.PrintManager;
//#if defined(ACTIVITYDIAGRAM)
//@#$LPS-ACTIVITYDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.activity.ui.InitActivityDiagram;
//#endif
//#if defined(COLLABORATIONDIAGRAM)
//@#$LPS-COLLABORATIONDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.collaboration.ui.InitCollaborationDiagram;
//#endif
//#if defined(DEPLOYMENTDIAGRAM)
//@#$LPS-DEPLOYMENTDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.deployment.ui.InitDeploymentDiagram;
//#endif
//#if defined(SEQUENCEDIAGRAM)
//@#$LPS-SEQUENCEDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.sequence.ui.InitSequenceDiagram;
//#endif
//#if defined(STATEDIAGRAM)
//@#$LPS-STATEDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.state.ui.InitStateDiagram;
//#endif
import org.argouml.uml.diagram.static_structure.ui.InitClassDiagram;
import org.argouml.uml.diagram.ui.InitDiagramAppearanceUI;
//#if defined(USECASEDIAGRAM)
//@#$LPS-USECASEDIAGRAM:GranularityType:Import
import org.argouml.uml.diagram.use_case.ui.InitUseCaseDiagram;
//#endif
import org.argouml.uml.ui.InitUmlUI;
import org.argouml.util.ArgoFrame;
import org.argouml.util.JavaRuntimeUtility;
import org.argouml.util.logging.AwtExceptionHandler;
import org.argouml.util.logging.SimpleTimer;
import org.tigris.gef.util.Util;
/**
* This is the main class for two of the types
* of ArgoUML application invocation:
* non-GUI command line and Swing GUI.<p>
*
* NOTE: Functionality which should be common to all types of application
* invocation (e.g. extension modules to be loaded) should added to some
* common class and <b>not</b> here. Adding things here will cause behavior
* to diverge for other application invocation types (e.g. ArgoEclipse).
*
*/
public class Main {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Field
// initialized in static initializer block below
private static final Logger LOG;
/**
* The location of the default logging configuration (.lcf) file.
*/
public static final String DEFAULT_LOGGING_CONFIGURATION =
"org/argouml/resource/default.lcf";
//#endif
/**
* The default implementation to start.
*/
private static final String DEFAULT_MODEL_IMPLEMENTATION =
"org.argouml.model.mdr.MDRModelImplementation";
private static List<Runnable> postLoadActions = new ArrayList<Runnable>();
private static boolean doSplash = true;
private static boolean reloadRecent = false;
private static boolean batch = false;
private static List<String> commands;
private static String projectName = null;
private static String theTheme;
/**
* The main entry point of ArgoUML.
* @param args command line parameters
*/
public static void main(String[] args) {
try {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:StartMethod
LOG.info("ArgoUML Started.");
//#endif
SimpleTimer st = new SimpleTimer();
st.mark("begin");
initPreinitialize();
st.mark("arguments");
parseCommandLine(args);
// Register our last chance exception handler
AwtExceptionHandler.registerExceptionHandler();
// Get the splash screen up as early as possible
st.mark("create splash");
SplashScreen splash = null;
if (!batch) {
// We have to do this to set the LAF for the splash screen
st.mark("initialize laf");
LookAndFeelMgr.getInstance().initializeLookAndFeel();
if (theTheme != null) {
LookAndFeelMgr.getInstance().setCurrentTheme(theTheme);
}
if (doSplash) {
splash = initializeSplash();
}
}
// main initialization happens here
ProjectBrowser pb = initializeSubsystems(st, splash);
// Needs to happen after initialization is done & modules loaded
st.mark("perform commands");
if (batch) {
// TODO: Add an "open most recent project" command so that
// command state can be decoupled from user settings?
performCommandsInternal(commands);
commands = null;
System.out.println("Exiting because we are running in batch.");
new ActionExit().doCommand(null);
return;
}
if (reloadRecent && projectName == null) {
projectName = getMostRecentProject();
}
URL urlToOpen = null;
if (projectName != null) {
projectName =
PersistenceManager.getInstance().fixExtension(projectName);
urlToOpen = projectUrl(projectName, urlToOpen);
}
openProject(st, splash, pb, urlToOpen);
st.mark("perspectives");
if (splash != null) {
splash.getStatusBar().showProgress(75);
}
st.mark("open window");
updateProgress(splash, 95, "statusmsg.bar.open-project-browser");
ArgoFrame.getInstance().setVisible(true);
st.mark("close splash");
if (splash != null) {
splash.setVisible(false);
splash.dispose();
splash = null;
}
performCommands(commands);
commands = null;
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
st.mark("start critics");
Runnable startCritics = new StartCritics();
Main.addPostLoadAction(startCritics);
//#endif
st.mark("start loading modules");
Runnable moduleLoader = new LoadModules();
Main.addPostLoadAction(moduleLoader);
PostLoad pl = new PostLoad(postLoadActions);
Thread postLoadThead = new Thread(pl);
postLoadThead.start();
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
LOG.info("");
LOG.info("profile of load time ############");
for (Enumeration i = st.result(); i.hasMoreElements();) {
LOG.info(i.nextElement());
}
LOG.info("#################################");
LOG.info("");
//#endif
st = null;
ArgoFrame.getInstance().setCursor(
Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
//ToolTipManager.sharedInstance().setInitialDelay(500);
ToolTipManager.sharedInstance().setDismissDelay(50000000);
} catch (Throwable t) {
//#if defined(LOGGING)
try {
//@#$LPS-LOGGING:GranularityType:Statement
LOG.fatal("Fatal error on startup. ArgoUML failed to start",
t);
} finally {
//#endif
System.out.println("Fatal error on startup. "
+ "ArgoUML failed to start.");
t.printStackTrace();
System.exit(1);
//#if defined(LOGGING)
}
//#endif
}
}
private static void initPreinitialize() {
checkJVMVersion();
checkHostsFile();
// Force the configuration to load
Configuration.load();
// Synchronize the startup directory
String directory = Argo.getDirectory();
org.tigris.gef.base.Globals.setLastDirectory(directory);
initVersion();
initTranslator();
// then, print out some version info for debuggers...
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
org.argouml.util.Tools.logVersionInfo();
//#endif
setSystemProperties();
}
private static void initTranslator() {
// Set the i18n locale
Translator.init(Configuration.getString(Argo.KEY_LOCALE));
// create an anonymous class as a kind of adaptor for the cognitive
// System to provide proper translation/i18n.
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
//@#$LPS-COGNITIVE:Localization:EndMethod
org.argouml.cognitive.Translator.setTranslator(
new AbstractCognitiveTranslator() {
public String i18nlocalize(String key) {
return Translator.localize(key);
}
public String i18nmessageFormat(String key,
Object[] iArgs) {
return Translator.messageFormat(key, iArgs);
}
});
//#endif
}
private static void setSystemProperties() {
/* set properties for application behaviour */
System.setProperty("gef.imageLocation", "/org/argouml/Images");
System.setProperty("apple.laf.useScreenMenuBar", "true");
/* FIX: set the application name for Mac OS X */
System.setProperty(
"com.apple.mrj.application.apple.menu.about.name",
"ArgoUML");
}
/**
* Parse command line args. The assumption is that all options precede the
* name of a project file to load. Sets static fields that can be referenced
* later.
*
* @param args command line args
*/
private static void parseCommandLine(String[] args) {
doSplash = Configuration.getBoolean(Argo.KEY_SPLASH, true);
reloadRecent = Configuration.getBoolean(
Argo.KEY_RELOAD_RECENT_PROJECT, false);
commands = new ArrayList<String>();
theTheme = null;
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
String themeName = LookAndFeelMgr.getInstance()
.getThemeClassNameFromArg(args[i]);
if (themeName != null) {
theTheme = themeName;
} else if (
args[i].equalsIgnoreCase("-help")
|| args[i].equalsIgnoreCase("-h")
|| args[i].equalsIgnoreCase("--help")
|| args[i].equalsIgnoreCase("/?")) {
printUsage();
System.exit(0);
} else if (args[i].equalsIgnoreCase("-nosplash")) {
doSplash = false;
} else if (args[i].equalsIgnoreCase("-norecentfile")) {
reloadRecent = false;
} else if (args[i].equalsIgnoreCase("-command")
&& i + 1 < args.length) {
commands.add(args[i + 1]);
i++;
} else if (args[i].equalsIgnoreCase("-locale")
&& i + 1 < args.length) {
Translator.setLocale(args[i + 1]);
i++;
} else if (args[i].equalsIgnoreCase("-batch")) {
batch = true;
} else if (args[i].equalsIgnoreCase("-open")
&& i + 1 < args.length) {
projectName = args[++i];
} else if (args[i].equalsIgnoreCase("-print")
&& i + 1 < args.length) {
// TODO: Huge side effect. Hoist out of parse - tfm
// let's load the project
String projectToBePrinted =
PersistenceManager.getInstance().fixExtension(
args[++i]);
URL urlToBePrinted = projectUrl(projectToBePrinted,
null);
ProjectBrowser.getInstance().loadProject(
new File(urlToBePrinted.getFile()), true, null);
// now, let's print it
PrintManager.getInstance().print();
// nothing else to do (?)
System.exit(0);
} else {
System.err
.println("Ignoring unknown/incomplete option '"
+ args[i] + "'");
}
} else {
if (projectName == null) {
System.out.println(
"Setting projectName to '" + args[i] + "'");
projectName = args[i];
}
}
}
}
private static ProjectBrowser initializeSubsystems(SimpleTimer st,
SplashScreen splash) {
ProjectBrowser pb = null;
st.mark("initialize model subsystem");
initModel();
updateProgress(splash, 5, "statusmsg.bar.model-subsystem");
st.mark("initialize the profile subsystem");
new InitProfileSubsystem().init();
// The reason the gui is initialized before the commands are run
// is that some of the commands will use the projectbrowser.
st.mark("initialize gui");
pb = initializeGUI(splash);
st.mark("initialize subsystems");
SubsystemUtility.initSubsystem(new InitUiCmdSubsystem());
SubsystemUtility.initSubsystem(new InitNotationUI());
SubsystemUtility.initSubsystem(new InitNotation());
SubsystemUtility.initSubsystem(new InitNotationUml());
SubsystemUtility.initSubsystem(new InitNotationJava());
SubsystemUtility.initSubsystem(new InitDiagramAppearanceUI());
//#if defined(ACTIVITYDIAGRAM)
//@#$LPS-ACTIVITYDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitActivityDiagram());
//#endif
//#if defined(COLLABORATIONDIAGRAM)
//@#$LPS-COLLABORATIONDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitCollaborationDiagram());
//#endif
//#if defined(DEPLOYMENTDIAGRAM)
//@#$LPS-DEPLOYMENTDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitDeploymentDiagram());
//#endif
//#if defined(SEQUENCEDIAGRAM)
//@#$LPS-SEQUENCEDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitSequenceDiagram());
//#endif
//#if defined(STATEDIAGRAM)
//@#$LPS-STATEDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitStateDiagram());
//#endif
SubsystemUtility.initSubsystem(new InitClassDiagram());
//#if defined(USECASEDIAGRAM)
//@#$LPS-USECASEDIAGRAM:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitUseCaseDiagram());
//#endif
SubsystemUtility.initSubsystem(new InitUmlUI());
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
SubsystemUtility.initSubsystem(new InitCheckListUI());
SubsystemUtility.initSubsystem(new InitCognitiveUI());
//#endif
/*
* Initialize the module loader. At least the plug-ins that provide
* profiles need to be initialized before the project is loaded,
* because some of these profile may have been set as default
* profiles and need to be applied to the project as soon as it has
* been created or loaded. The first instance of a Project is needed
* during the GUI initialization.
*/
st.mark("initialize modules");
SubsystemUtility.initSubsystem(new InitModuleLoader());
return pb;
}
/**
* Initialize the UML model repository.
*/
private static void initModel() {
String className = System.getProperty(
"argouml.model.implementation",
DEFAULT_MODEL_IMPLEMENTATION);
Throwable ret = Model.initialise(className);
if (ret != null) {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:NestedStatement
LOG.fatal("Model component not correctly initialized.", ret);
//#endif
System.err.println(className
+ " is not a working Model implementation.");
System.exit(1);
}
}
private static void openProject(SimpleTimer st, SplashScreen splash,
ProjectBrowser pb, URL urlToOpen) {
if (splash != null) {
splash.getStatusBar().showProgress(40);
}
st.mark("open project");
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
Designer.disableCritiquing();
Designer.clearCritiquing();
//#endif
boolean projectLoaded = false;
if (urlToOpen != null) {
if (splash != null) {
Object[] msgArgs = {projectName};
splash.getStatusBar().showStatus(
Translator.messageFormat(
"statusmsg.bar.readingproject",
msgArgs));
}
String filename = urlToOpen.getFile();
File file = new File(filename);
System.err.println("The url of the file to open is "
+ urlToOpen);
System.err.println("The filename is " + filename);
System.err.println("The file is " + file);
System.err.println("File.exists = " + file.exists());
projectLoaded = pb.loadProject(file, true, null);
} else {
if (splash != null) {
splash.getStatusBar().showStatus(
Translator.localize(
"statusmsg.bar.defaultproject"));
}
}
if (!projectLoaded) {
// Although this looks redundant, it's needed to get all
// the initialization state set correctly.
// Too many side effects as part of initialization!
ProjectManager.getManager().setCurrentProject(
ProjectManager.getManager().getCurrentProject());
ProjectManager.getManager().setSaveEnabled(false);
}
st.mark("set project");
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
//@#$LPS-COGNITIVE:Localization:EndMethod
Designer.enableCritiquing();
//#endif
}
private static String getMostRecentProject() {
// If no project was entered on the command line,
// try to reload the most recent project if that option is true
String s = Configuration.getString(
Argo.KEY_MOST_RECENT_PROJECT_FILE, "");
if (!("".equals(s))) {
File file = new File(s);
if (file.exists()) {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:BeforeReturn
//@#$LPS-LOGGING:Localization:NestedStatement
LOG.info("Re-opening project " + s);
//#endif
return s;
}
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:NestedStatement
else {
LOG.warn("Cannot re-open " + s
+ " because it does not exist");
}
//#endif
}
return null;
}
/**
* Helper to update progress if we have a splash screen displayed.
*
* @param splash <code>true</code> if the splash is to be shown
* @param percent the new percentage for progress bar
* @param message the message to be shown in the splash
*/
private static void updateProgress(SplashScreen splash, int percent,
String message) {
if (splash != null) {
splash.getStatusBar().showStatus(Translator.localize(message));
splash.getStatusBar().showProgress(percent);
}
}
/**
* Calculates the {@link URL} for the given project name.
* If the file does not exist or cannot be converted the default
* {@link URL} is returned.
*
* @param theProjectName is the file name of the project
* @param urlToOpen is the default {@link URL}
* @return the new URL.
*/
private static URL projectUrl(final String theProjectName, URL urlToOpen) {
File projectFile = new File(theProjectName);
if (!projectFile.exists()) {
System.err.println("Project file '" + projectFile
+ "' does not exist.");
/* this will cause an empty project to be created */
} else {
try {
urlToOpen = Util.fileToURL(projectFile);
} catch (Exception e) {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
LOG.error("Exception opening project in main()", e);
//#endif
}
}
return urlToOpen;
}
/**
* Prints the usage message.
*/
private static void printUsage() {
System.err.println("Usage: [options] [project-file]");
System.err.println("Options include: ");
System.err.println(" -help display this information");
LookAndFeelMgr.getInstance().printThemeArgs();
System.err.println(" -nosplash don't display logo at startup");
System.err.println(" -norecentfile don't reload last saved file");
System.err.println(" -command <arg> command to perform on startup");
System.err.println(" -batch don't start GUI");
System.err.println(" -locale <arg> set the locale (e.g. 'en_GB')");
/* TODO: The Quickguide also mentions:
* -open <arg> open given file on startup
* -print <arg> print given file on startup (and exit)
* Why are these gone? */
System.err.println("");
System.err.println("You can also set java settings which influence "
+ "the behaviour of ArgoUML:");
System.err.println(" -Xms250M -Xmx500M [makes ArgoUML reserve "
+ "more memory for large projects]");
System.err.println("\n\n");
}
/**
* Check tha JVM Version.
* <p>
* If it is a unsupported JVM version we exit immediately.
* <p>
* NOTE: In most cases the JVM classloader will complain about an
* UnsupportedClassVersionError long before we get anywhere near this point
* in the initialization.
*/
private static void checkJVMVersion() {
// check if we are using a supported java version
if (!JavaRuntimeUtility.isJreSupported()) {
System.err.println("You are using Java "
+ JavaRuntimeUtility.getJreVersion()
+ ", Please use Java 5 (aka 1.5) or later"
+ " with ArgoUML");
System.exit(0);
}
}
/**
* Check that we can get the InetAddress for localhost.
* This can fail on Unix if /etc/hosts is not correctly set up.
*/
private static void checkHostsFile() {
try {
InetAddress.getLocalHost();
} catch (UnknownHostException e) {
System.err.println("ERROR: unable to get localhost information.");
e.printStackTrace(System.err);
System.err.println("On Unix systems this usually indicates that"
+ "your /etc/hosts file is incorrectly setup.");
System.err.println("Stopping execution of ArgoUML.");
System.exit(0);
}
}
/**
* Add an element to the PostLoadActions list,
* which contains actions that are run after ArgoUML has started.
*
* @param r a "Runnable" action
*/
public static void addPostLoadAction(Runnable r) {
postLoadActions.add(r);
}
/**
* Perform a list of commands that were given on the command line.
*
* This first implementation just has a list of commands that
* is possible to give.
*
* @param list The commands, a list of strings.
*/
public static void performCommands(List<String> list) {
// initPreinitialize();
// initializeSubsystems(new SimpleTimer(), null);
// ArgoFrame.getInstance().setVisible(true);
performCommandsInternal(list);
}
/**
* Perform a list of commands that were given on the command line.
*
* This first implementation just has a list of commands that
* is possible to give.
*
* @param list The commands, a list of strings.
*/
private static void performCommandsInternal(List<String> list) {
for (String commandString : list) {
int pos = commandString.indexOf('=');
String commandName;
String commandArgument;
if (pos == -1) {
commandName = commandString;
commandArgument = null;
} else {
commandName = commandString.substring(0, pos);
commandArgument = commandString.substring(pos + 1);
}
// Perform one command.
Class c;
try {
c = Class.forName(commandName);
} catch (ClassNotFoundException e) {
System.out.println("Cannot find the command: " + commandName);
continue;
}
// Now create a new object.
Object o = null;
try {
o = c.newInstance();
} catch (InstantiationException e) {
System.out.println(commandName
+ " could not be instantiated - skipping"
+ " (InstantiationException)");
continue;
} catch (IllegalAccessException e) {
System.out.println(commandName
+ " could not be instantiated - skipping"
+ " (IllegalAccessException)");
continue;
}
if (o == null || !(o instanceof CommandLineInterface)) {
System.out.println(commandName
+ " is not a command - skipping.");
continue;
}
CommandLineInterface clio = (CommandLineInterface) o;
System.out.println("Performing command "
+ commandName + "( "
+ (commandArgument == null
? "" : commandArgument) + " )");
boolean result = clio.doCommand(commandArgument);
if (!result) {
System.out.println("There was an error executing "
+ "the command "
+ commandName + "( "
+ (commandArgument == null
? "" : commandArgument) + " )");
System.out.println("Aborting the rest of the commands.");
return;
}
}
}
/**
* Create the .argouml directory if it doesn't exist.
* This is done here because it must be done before
* setting the log configuration.
*/
static {
File argoDir = new File(System.getProperty("user.home")
+ File.separator + ".argouml");
if (!argoDir.exists()) {
argoDir.mkdir();
}
}
/**
* Install our security handlers,
* and do basic initialization of log4j.
*
* Log4j initialization must be done as
* part of the main class initializer, so that
* the log4j initialization is complete
* before any other static initializers.
*
* Also installs a trap to "eat" certain SecurityExceptions.
* Refer to {@link java.awt.EventDispatchThread} for details.
*/
static {
/*
* Install the trap to "eat" SecurityExceptions.
*
* NOTE: This is temporary and will go away in a "future" release
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4714232
*/
System.setProperty(
"sun.awt.exception.handler",
ArgoAwtExceptionHandler.class.getName());
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:EndStaticBlock
/*
* The string <code>log4j.configuration</code> is the
* same string found in
* {@link org.apache.log4j.Configuration.DEFAULT_CONFIGURATION_FILE}
* but if we use the reference, then log4j configures itself
* and clears the system property and we never know if it was
* set.
*
* If it is set, then we let the static initializer in
* {@link Argo} perform the initialization.
*/
// JavaWebStart properties for logs are :
// deployment.user.logdir & deployment.user.tmp
if (System.getProperty("log4j.configuration") == null) {
Properties props = new Properties();
InputStream stream = null;
try {
stream =
Thread.currentThread().getContextClassLoader()
.getResourceAsStream(
DEFAULT_LOGGING_CONFIGURATION);
if (stream != null) {
props.load(stream);
}
} catch (IOException io) {
io.printStackTrace();
System.exit(-1);
}
PropertyConfigurator.configure(props);
if (stream == null) {
BasicConfigurator.configure();
Logger.getRootLogger().getLoggerRepository().setThreshold(
Level.ERROR); // default level is DEBUG
Logger.getRootLogger().error(
"Failed to find valid log4j properties"
+ "in log4j.configuration"
+ "using default logging configuration");
}
}
// initLogging();
LOG = Logger.getLogger(Main.class);
//#endif
}
/**
* Create and display a splash screen.
* @return the splash screen
*/
private static SplashScreen initializeSplash() {
SplashScreen splash = new SplashScreen();
splash.setVisible(true);
// On uniprocessors wait until we're sure the splash screen
// has been painted so that we aren't competing for resources
if (!EventQueue.isDispatchThread()
&& Runtime.getRuntime().availableProcessors() == 1) {
synchronized (splash) {
while (!splash.isPaintCalled()) {
try {
splash.wait();
} catch (InterruptedException e) {
}
}
}
}
return splash;
}
/**
* Do a part of the initialization that is very much GUI-stuff.
*
* @param splash the splash screeen
*/
private static ProjectBrowser initializeGUI(SplashScreen splash) {
// make the projectbrowser
JPanel todoPanel;
//#if defined(COGNITIVE)
//@#$LPS-COGNITIVE:GranularityType:Statement
todoPanel = new ToDoPane(splash);
//#else
// todoPanel = new JPanel();
//#endif
ProjectBrowser pb = ProjectBrowser.makeInstance(splash, true,todoPanel);
JOptionPane.setRootFrame(pb);
pb.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
// Set the screen layout to what the user left it before, or
// to reasonable defaults.
Rectangle scrSize = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getMaximumWindowBounds();
int configFrameWidth =
Configuration.getInteger(Argo.KEY_SCREEN_WIDTH, scrSize.width);
int w = Math.min(configFrameWidth, scrSize.width);
if (w == 0) {
w = 600;
}
int configFrameHeight =
Configuration.getInteger(Argo.KEY_SCREEN_HEIGHT, scrSize.height);
int h = Math.min(configFrameHeight, scrSize.height);
if (h == 0) {
h = 400;
}
int x = Configuration.getInteger(Argo.KEY_SCREEN_LEFT_X, 0);
int y = Configuration.getInteger(Argo.KEY_SCREEN_TOP_Y, 0);
pb.setLocation(x, y);
pb.setSize(w, h);
pb.setExtendedState(Configuration.getBoolean(
Argo.KEY_SCREEN_MAXIMIZED, false)
? Frame.MAXIMIZED_BOTH : Frame.NORMAL);
UIManager.put("Button.focusInputMap", new UIDefaults.LazyInputMap(
new Object[] {
"ENTER", "pressed",
"released ENTER", "released",
"SPACE", "pressed",
"released SPACE", "released"
})
);
return pb;
}
/**
* Publish the version of the ArgoUML application. <p>
*
* This function is intentionally public,
* since applications built on ArgoUML,
* that do not make use of Main.main(),
* can call this function and then access ArgoUML's version
* from the ApplicationVersion class.
*/
public static void initVersion() {
ArgoVersion.init();
}
} /* end Class Main */
/**
* Class to hold a list of actions to be perform and to perform them
* after the initializations is done.
*/
class PostLoad implements Runnable {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Field
/**
* Logger.
*/
private static final Logger LOG = Logger.getLogger(PostLoad.class);
//#endif
/**
* The list of actions to perform.
*/
private List<Runnable> postLoadActions;
/**
* Constructor.
*
* @param actions The actions to perform.
*/
public PostLoad(List<Runnable> actions) {
postLoadActions = actions;
}
/*
* @see java.lang.Runnable#run()
*/
public void run() {
try {
Thread.sleep(1000);
} catch (Exception ex) {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
LOG.error("post load no sleep", ex);
//#endif
}
for (Runnable r : postLoadActions) {
r.run();
try {
Thread.sleep(100);
} catch (Exception ex) {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
LOG.error("post load no sleep2", ex);
//#endif
}
}
}
} /* end class PostLoad */
/**
* Class to load modules.
*/
class LoadModules implements Runnable {
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Field
/**
* Logger.
*/
private static final Logger LOG = Logger.getLogger(LoadModules.class);
//#endif
private static final String[] OPTIONAL_INTERNAL_MODULES = {
"org.argouml.dev.DeveloperModule",
};
/**
* Load internal modules which should be found on the standard
* classpath.
*/
private void huntForInternalModules() {
for (String module : OPTIONAL_INTERNAL_MODULES) {
try {
ModuleLoader2.addClass(module);
} catch (ClassNotFoundException e) {
/* We don't care if optional modules aren't found. */
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
LOG.debug("Module " + module + " not found");
//#endif
}
}
}
/*
* @see java.lang.Runnable#run()
*/
public void run() {
huntForInternalModules();
//#if defined(LOGGING)
//@#$LPS-LOGGING:GranularityType:Statement
//@#$LPS-LOGGING:Localization:EndMethod
LOG.info("Module loading done");
//#endif
}
} /* end class LoadModules */