package org.jwall.app;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import org.jwall.app.ui.ApplicationWindow;
import org.jwall.app.ui.MenuBar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
* This is a basic application class. It provides a basic framework for building
* abstract applications. This class is thus the basic building-block for
* applications such as the AuditViewer, the WebApplicationProfiler client or
* the ProfileEditor.
* </p>
* <p>
* The intention of the application class is to provide a modularized pluggable
* framework to easily create applications by implementing modules which hook
* themselves up within the an implementation of this class.
* </p>
*
* @author Christian Bockermann <chris@jwall.org>
*
*/
public abstract class Application implements ActionListener {
/** A unique logger for this class */
private static Logger log = LoggerFactory.getLogger(Application.class);
/** The version of this component (package org.jwall.app) */
public final static String VERSION = "0.2";
/*
* We populate the version to the system properties, allowing others to
* check for it.
*/
static {
System.setProperty("org.jwall.app.version", VERSION);
}
/** A global constant for separating paths */
public final static String SLASH = System.getProperty("file.separator");
/** This application's properties */
protected Properties properties = new Properties();
/** A list of actions provided by this application */
protected SortedSet<Action> actions = new TreeSet<Action>();
/** The applications name */
protected String name = "";
/** A reference to the main application window */
protected static ApplicationWindow win;
/** A list of exception handlers */
protected static ExceptionHandler exceptionHandler = new BugReporter();
/**
* A list of resources pointing to UI-resources such as messages, icons,
* etc.
*/
protected static Resources resources = new Resources();
/**
* Create a new application by initializing the basic data structures. The
* applications name is given by <code>appName</code>.
*
* @param appName
* The applications name.
*/
public Application(String appName) {
name = appName;
if (System.getProperty("org.jwall.app.laf") == null)
setLookAndFeel();
win = new ApplicationWindow(this);
try {
loadResources();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setLookAndFeel() {
try {
/*
* Class<?> clazz =
* Class.forName("com.jgoodies.looks.plastic.PlasticLookAndFeel");
* Method method = clazz.getMethod("setTabStyle", String.class);
* method.invoke( null, new Object[]{ "Metal" } );
*
* Class<?> themeClazz =
* Class.forName("com.jgoodies.looks.plastic.PlasticTheme");
*
* Class<?> skyBluerClazz =
* Class.forName("com.jgoodies.looks.plastic.theme.SkyBluer");
* Object theme = skyBluerClazz.newInstance(); method =
* clazz.getMethod("setPlasticTheme", themeClazz ); method.invoke(
* null, new Object[]{ theme } );
*
* Class<?> lafClazz =
* Class.forName("com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
* Object lafInstance = lafClazz.newInstance();
*
* UIManager.setLookAndFeel((LookAndFeel) lafInstance);
*/
String osName = System.getProperty("os.name");
if (osName != null && !osName.toLowerCase().contains("Windows")) {
throw new Exception("");
}
} catch (Exception e) {
log.debug("Setting native look-and-feel...");
try {
for (Object k : System.getProperties().keySet())
log.debug(k + " => " + System.getProperty(k.toString()));
String osName = System.getProperty("os.name");
if (osName != null && !osName.toLowerCase().contains("windows")) {
String lafName = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
lafName = "javax.swing.plaf.metal.MetalLookAndFeel";
UIManager.setLookAndFeel(lafName);
} else {
log.info("Setting windows-LaF ");
String lafName = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
UIManager.setLookAndFeel(lafName);
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
public String getName() {
return name;
}
public MenuBar getMenuBar() {
return win.getMenu();
}
public void registerAction(Action act) {
if (actions.contains(act)) {
log.debug("Action already registered: " + act);
return;
}
Resource res = resources.getActionById(act.getCommand());
if (res != null) {
if (res.getTooltip() != null && !"".equals(res.getTooltip()))
act.putValue(Action.SHORT_DESCRIPTION, res.getTooltip());
}
act.addActionListener(this);
actions.add(act);
if (act.getMenu() != null) {
JMenuItem mi = win.getMenu().add(act);
if (act.getKeyStroke() != null)
mi.setAccelerator(act.getKeyStroke());
// mi.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S,
// ActionEvent.CTRL_MASK ) );
/*
* if( act.getCommand().equals( Action.LOAD_FILE ) &&
* System.getProperty( FileSelectionPanel.PROPERTY_LAST_FILE_NAMES )
* != null ){
*
* String[] lastFiles = System.getProperty(
* FileSelectionPanel.PROPERTY_LAST_FILE_NAMES ).split(":"); for(
* String f : lastFiles ){ if( ! f.equals("") ){ JMenuItem fi = new
* JMenuItem( f ); fi.addActionListener( act ); fi.setActionCommand(
* Action.LOAD_FILE + "-" + f ); mi.add( fi ); } } }
*/
}
for (org.jwall.app.Action a : actions)
if (a.showInToolbar())
win.getToolBar().add(a);
win.getMenu().revalidate();
}
public void unregisterAction(Action act) {
actions.remove(act);
}
public Action getAction(String cmd) {
for (Action a : actions)
if (cmd.equals(a.getCommand()))
return a;
return null;
}
public boolean setActionEnabled(String cmd, boolean b) {
for (Action a : actions)
if (cmd.equals(a.getCommand())) {
a.setEnabled(b);
return true;
}
return false;
}
public static ApplicationWindow getWindow() {
return win;
}
/**
* The absolute path to the directory that is used to store appliation
* preferences
*/
public String getPreferenceDirectory() {
return System.getProperty("user.home") + "/" + ".jwall";
}
/** The name of the preference-file within the preference-directory */
public abstract String getPreferenceFileName();
public String getUpdateURL() {
return null;
}
public abstract String getVersion();
public abstract void actionPerformed(ActionEvent evt);
/**
* This methods loads the preferences from the file specified by
* <code>getPreferenceDirectory()</code> and
* <code>getPreferenceFileName()</code>.
*
* @throws IOException
*/
public void loadProperties() throws IOException {
Properties p = new Properties();
File dir = new File(getPreferenceDirectory());
if (!dir.isDirectory())
if (!dir.mkdirs())
log.info("Unable to create preference directory ("
+ getPreferenceDirectory() + ")!");
File f = new File(getPreferenceDirectory() + SLASH
+ getPreferenceFileName());
if (f.exists()) {
if (getPreferenceFileName().endsWith(".xml"))
p.loadFromXML(new FileInputStream(f));
else
p.load(new FileInputStream(f));
Set<Object> keys = p.keySet();
for (Object k : keys)
if (k.toString().startsWith("jwall")
|| k.toString().startsWith("org.jwall")) {
System.setProperty(k.toString(),
p.getProperty(k.toString()));
// System.out.println("\t"+k.toString()+" = "+System.getProperty(
// k.toString() ) );
}
} else
log.debug("PreferenceFile " + f + " does not exist!");
}
/**
* This methods saves the preferences to the file specified by
* <code>getPreferenceDirectory()</code> and
* <code>getPreferenceFileName()</code>.
*
* @throws IOException
*/
public void saveProperties() throws IOException {
Properties p = new Properties();
File dir = new File(getPreferenceDirectory());
if (!dir.isDirectory())
dir.mkdirs();
File f = new File(getPreferenceDirectory() + SLASH
+ getPreferenceFileName());
if (!f.exists())
f.createNewFile();
// System.out.println("Saving properties to "+f.getAbsolutePath());
Set<Object> keys = System.getProperties().keySet();
for (Object o : keys)
if (o.toString().startsWith("jwall")
|| o.toString().startsWith("org.jwall"))
p.put(o.toString(), System.getProperty(o.toString()));
if (getPreferenceFileName().endsWith(".xml"))
p.storeToXML(new FileOutputStream(f), "");
else
p.store(new FileOutputStream(f), "");
}
public String getLatestVersion() {
try {
URL url = new URL(getUpdateURL());
BufferedReader r = new BufferedReader(new InputStreamReader(
url.openStream()));
String lv = r.readLine();
r.close();
// System.out.println("Latest version is: "+lv);
return lv;
} catch (Exception e) {
return getVersion();
}
}
public static ImageIcon getIcon(Action act) {
return resources.getIcon(act);
}
public static ImageIcon getIcon(Object o) {
String s = o.getClass().getCanonicalName();
return getIcon(s);
}
public static ImageIcon getIcon(String icon) {
return resources.getIcon(icon);
}
public static ImageIcon getLargeIcon(String icon) {
return resources.getLargeIcon(icon);
}
public static String getMessage(String s) {
Resource r = resources.getActionById(s);
if (r != null)
return r.getLabel();
return s;
}
public static URL getResource(String name) {
Resource r = resources.getActionById(name);
if (r != null)
return Application.class.getResource(r.getIcon());
return Application.class.getResource(name);
}
public List<String> getResourceFiles() {
LinkedList<String> res = new LinkedList<String>();
res.add(new String("/org/jwall/app/resources.xml"));
return res;
}
public void loadResources() throws Exception {
for (String resourceFile : getResourceFiles()) {
log.debug("Loading resources from " + resourceFile);
InputStream in = Application.class
.getResourceAsStream(resourceFile);
if (in != null)
resources.load(resourceFile);
else
log.warn("Unable to locate \"" + resourceFile + "\" !");
}
}
public void registerExceptionHandler(ExceptionHandler handler) {
exceptionHandler = handler;
}
public static void handleException(Exception e) {
if (exceptionHandler == null)
exceptionHandler = new BugReporter();
exceptionHandler.handleException(e);
}
}