0001: /*
0002: * Copyright 2001-2006 C:1 Financial Services GmbH
0003: *
0004: * This software is free software; you can redistribute it and/or
0005: * modify it under the terms of the GNU Lesser General Public
0006: * License Version 2.1, as published by the Free Software Foundation.
0007: *
0008: * This software is distributed in the hope that it will be useful,
0009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0011: * Lesser General Public License for more details.
0012: *
0013: * You should have received a copy of the GNU Lesser General Public
0014: * License along with this library; if not, write to the Free Software
0015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
0016: */
0017:
0018: package de.finix.contelligent.client;
0019:
0020: import java.awt.BorderLayout;
0021: import java.awt.Component;
0022: import java.awt.Dimension;
0023: import java.awt.Font;
0024: import java.awt.Rectangle;
0025: import java.awt.Toolkit;
0026: import java.awt.event.ActionEvent;
0027: import java.io.IOException;
0028: import java.net.MalformedURLException;
0029: import java.net.URL;
0030: import java.security.AccessController;
0031: import java.security.PrivilegedAction;
0032: import java.util.ArrayList;
0033: import java.util.Iterator;
0034: import java.util.List;
0035: import java.util.StringTokenizer;
0036: import java.util.Vector;
0037: import java.util.logging.Level;
0038: import java.util.logging.Logger;
0039: import java.util.prefs.Preferences;
0040:
0041: import javax.jnlp.BasicService;
0042: import javax.jnlp.ServiceManager;
0043: import javax.jnlp.UnavailableServiceException;
0044: import javax.security.auth.Subject;
0045: import javax.swing.AbstractAction;
0046: import javax.swing.Action;
0047: import javax.swing.Icon;
0048: import javax.swing.JFrame;
0049: import javax.swing.JLabel;
0050: import javax.swing.JMenuBar;
0051: import javax.swing.JOptionPane;
0052: import javax.swing.JPanel;
0053: import javax.swing.JTabbedPane;
0054: import javax.swing.JToolBar;
0055: import javax.swing.KeyStroke;
0056: import javax.swing.event.ChangeEvent;
0057: import javax.swing.event.ChangeListener;
0058:
0059: import de.finix.contelligent.client.base.BuildInfo;
0060: import de.finix.contelligent.client.base.ComponentFactory;
0061: import de.finix.contelligent.client.base.Errors;
0062: import de.finix.contelligent.client.base.ModuleManager;
0063: import de.finix.contelligent.client.base.ServerInfo;
0064: import de.finix.contelligent.client.base.Session;
0065: import de.finix.contelligent.client.base.SessionListener;
0066: import de.finix.contelligent.client.event.ContelligentEvent;
0067: import de.finix.contelligent.client.event.ContelligentEventDispatcher;
0068: import de.finix.contelligent.client.event.RawContelligentEventListener;
0069: import de.finix.contelligent.client.event.TaskEventListener;
0070: import de.finix.contelligent.client.event.TaskFinishedEvent;
0071: import de.finix.contelligent.client.event.TaskStartedEvent;
0072: import de.finix.contelligent.client.gui.ContelligentAction;
0073: import de.finix.contelligent.client.i18n.Resources;
0074: import de.finix.contelligent.client.modules.Module;
0075: import de.finix.contelligent.client.modules.ModuleDescription;
0076: import de.finix.contelligent.client.modules.ModuleFrame;
0077: import de.finix.contelligent.client.modules.ModuleInitException;
0078: import de.finix.contelligent.client.modules.ModuleRegistry;
0079: import de.finix.contelligent.client.modules.event.ModuleEvent;
0080: import de.finix.contelligent.client.modules.event.ModuleListener;
0081: import de.finix.contelligent.client.modules.preferences.PreferencesModule;
0082: import de.finix.contelligent.client.remote.ActionResult;
0083: import de.finix.contelligent.client.remote.Actions;
0084: import de.finix.contelligent.client.remote.IncompatibleServerException;
0085: import de.finix.contelligent.client.remote.RemoteActionException;
0086: import de.finix.contelligent.client.remote.ServerConnector;
0087: import de.finix.contelligent.client.security.LoginOptionPane;
0088: import de.finix.contelligent.client.util.ActionBundle;
0089: import de.finix.contelligent.client.util.ChangePasswordDialog;
0090: import de.finix.contelligent.client.util.EventIndicatorPanel;
0091: import de.finix.contelligent.client.util.ExceptionDialog;
0092: import de.finix.contelligent.client.util.ImagePanel;
0093: import de.finix.contelligent.client.util.MemoryUsagePanel;
0094: import de.finix.contelligent.client.util.MenuAndToolbarComposer;
0095: import de.finix.contelligent.client.util.MnemonicAbstractAction;
0096: import de.finix.contelligent.client.util.OptionalPopupMenu;
0097: import de.finix.contelligent.client.util.SwingWorker;
0098: import de.finix.contelligent.client.util.TableLayout;
0099: import de.finix.contelligent.client.util.xml.XMLUtil;
0100:
0101: /**
0102: * The <code>MainPanel</code> is the main application screen of the
0103: * contelligent client. To create an MainPanel a valid sessionHandle is
0104: * required. MainPanel can live as an applet. In this case the sessionHandle
0105: * shoud be given as a requestParameter to the calling applet. If the MainPanel
0106: * is running as an application the calling AdminFrame should do the login.
0107: */
0108: public class MainPanel extends JPanel implements SessionListener,
0109: ModuleListener, RawContelligentEventListener, TaskEventListener {
0110:
0111: private static Logger logger = Logger.getLogger(MainPanel.class
0112: .getName());
0113:
0114: private final static String HELP_PATH = "/contelligent/documentation/docs/core/index.html";
0115:
0116: private static String login, group, password, context;
0117:
0118: private int openTasks;
0119:
0120: private MenuAndToolbarComposer menuAndToolbarComposer;
0121:
0122: private JToolBar toolbar;
0123:
0124: private JMenuBar menuBar = new JMenuBar();
0125:
0126: private JLabel taskLabel;
0127:
0128: private EventIndicatorPanel eventIndicator = new EventIndicatorPanel();
0129:
0130: private JLabel serverVersionLabel, serverBuildLabel;
0131:
0132: private JLabel clientVersionLabel, clientBuildLabel;
0133:
0134: private JPanel contentPanel;
0135:
0136: private MemoryUsagePanel memory = new MemoryUsagePanel();
0137:
0138: private JTabbedPane tabbedPane;
0139:
0140: private Font infoFont;
0141:
0142: private Module selectedModule;
0143:
0144: private List<Object[]> moduleFrames = new Vector<Object[]>();
0145:
0146: private ContelligentClient client;
0147:
0148: private ModuleDescription newPreferencesModule, helpModule;
0149:
0150: private LoginAction loginAction = new LoginAction();
0151:
0152: private ReloadSessionAction reloadSessionAction = new ReloadSessionAction();
0153:
0154: private ExitAction exitAction = new ExitAction();
0155:
0156: private ChangePasswordAction changePasswordAction = new ChangePasswordAction();
0157:
0158: private LaunchModuleAction helpAction;
0159:
0160: private boolean isConnected = false;
0161:
0162: private boolean isIncompatible = false;
0163:
0164: public MainPanel(ContelligentClient frame) {
0165: super (new BorderLayout());
0166: setOpaque(false);
0167:
0168: int offset = PreferencesModule.getPreferences().getInt(
0169: PreferencesModule.FONTSIZE_OFFSET,
0170: PreferencesModule.DEFAULT_FONTSIZE_OFFSET);
0171: infoFont = new Font("Verdana", Font.PLAIN, 10 + offset);
0172: this .setFont(infoFont);
0173:
0174: contentPanel = new JPanel(new BorderLayout());
0175: contentPanel.setOpaque(false);
0176:
0177: // before we let anything else register to event dispatcher first create
0178: // and register component factory
0179: ComponentFactory.getInstance();
0180:
0181: client = frame;
0182: frame.setJMenuBar(menuBar);
0183:
0184: toolbar = new JToolBar();
0185: toolbar.setOpaque(false);
0186: add(toolbar, BorderLayout.NORTH);
0187:
0188: OptionalPopupMenu popupMenu = new OptionalPopupMenu();
0189: popupMenu.addActionGroupName(ContelligentAction.VIEW_ACTION);
0190: popupMenu.addActionBundleName(ActionBundle.TRANSACTION_ACTIONS);
0191:
0192: menuAndToolbarComposer = new MenuAndToolbarComposer(menuBar,
0193: toolbar, popupMenu);
0194: menuAndToolbarComposer.removeAllActionBundles();
0195: menuAndToolbarComposer.showInfo(true);
0196: menuAndToolbarComposer.addOptionalPopupMenu(popupMenu);
0197:
0198: JPanel infoPanel = new JPanel(new TableLayout(new double[][] {
0199: { TableLayout.FILL, 280, 12 },
0200: { TableLayout.PREFERRED } }));
0201: infoPanel.setOpaque(false);
0202: taskLabel = new JLabel(Resources.serverIcon, JLabel.LEFT);
0203: taskLabel.setFont(infoFont);
0204: infoPanel.add(taskLabel, "0,0");
0205: if (showMemoryPanel()) {
0206: infoPanel.add(memory, "1,0");
0207: } else {
0208: infoPanel.add(new JLabel(""), "1,0");
0209: }
0210: contentPanel.add(infoPanel, BorderLayout.SOUTH);
0211: infoPanel.add(eventIndicator, "2,0");
0212:
0213: loginAction.setEnabled(false);
0214: reloadSessionAction.setEnabled(false);
0215: changePasswordAction.setEnabled(false);
0216:
0217: newPreferencesModule = new ModuleDescription(ModuleRegistry
0218: .getInstance().getImpl("NewPreferences"), Resources
0219: .getLocalString("preferences"),
0220: ContelligentAction.TOOLS_ACTION, "preferences", true,
0221: false, false, false, null,
0222: ContelligentClient.defaultClientEnvironment);
0223: helpModule = new ModuleDescription("", "help",
0224: ContelligentAction.HELP_ACTION, "help", true, false,
0225: false, false, HELP_PATH,
0226: ContelligentClient.defaultClientEnvironment);
0227: helpAction = new LaunchModuleAction(helpModule, true);
0228: helpAction.putValue(Action.ACCELERATOR_KEY, KeyStroke
0229: .getKeyStroke("F1"));
0230:
0231: Session.getInstance().addRawContelligentEventListener(this ,
0232: ContelligentEventDispatcher.DOES_USE_SWING);
0233: // actually does use swing, but text setting methods are synchronized
0234: Session.getInstance().addTaskEventListener(this ,
0235: ContelligentEventDispatcher.DOES_NOT_USE_SWING);
0236:
0237: LaunchModuleAction newPrefsAction = new LaunchModuleAction(
0238: newPreferencesModule, false);
0239: newPrefsAction.putValue(ContelligentAction.ACTION_TYPE,
0240: ContelligentAction.TOOLS_ACTION);
0241: newPrefsAction.putValue(ContelligentAction.ACTION_GROUP,
0242: ContelligentAction.TOOLS_SYSTEM_GROUP);
0243: newPrefsAction.putValue(ContelligentAction.ACTION_POS,
0244: ContelligentAction.TOOLS_SYSTEM_NEWPREFS);
0245:
0246: menuAndToolbarComposer.addPermanentActionBundle(new Action[] {
0247: newPrefsAction, loginAction, reloadSessionAction,
0248: exitAction, changePasswordAction, helpAction });
0249:
0250: tabbedPane = createTabbedPane();
0251: contentPanel.add(tabbedPane, BorderLayout.CENTER);
0252: add(contentPanel, BorderLayout.CENTER);
0253: }
0254:
0255: private boolean showMemoryPanel() {
0256: Preferences preferences = PreferencesModule.getPreferences();
0257: return preferences.getBoolean(PreferencesModule.SHOW_MEM_PANEL,
0258: PreferencesModule.DEFAULT_SHOW_MEM_PANEL);
0259: }
0260:
0261: // needed to redraw menubar stuff when language is changed
0262: public void refresh() {
0263: menuAndToolbarComposer.compose();
0264: for (Iterator it = moduleFrames.iterator(); it.hasNext();) {
0265: Object[] pair = (Object[]) it.next();
0266: ModuleFrame moduleFrame = (ModuleFrame) pair[1];
0267: moduleFrame.getMenuAndToolbarComposer().compose();
0268: }
0269: }
0270:
0271: public boolean openModulesExist() {
0272: return (moduleFrames.size() != 0);
0273: }
0274:
0275: public void moduleActivated(ModuleEvent event) {
0276: }
0277:
0278: public void moduleDeactivated(ModuleEvent event) {
0279: }
0280:
0281: public void moduleDestroyed(ModuleEvent event) {
0282: Module eventModul = event.getModule();
0283: for (Iterator it = moduleFrames.iterator(); it.hasNext();) {
0284: Object[] pair = (Object[]) it.next();
0285: Module module = (Module) pair[0];
0286: if (eventModul == module) {
0287: moduleFrames.remove(pair);
0288: break;
0289: }
0290: }
0291: }
0292:
0293: public class ReloadSessionAction extends AbstractAction implements
0294: ContelligentAction {
0295: public ReloadSessionAction() {
0296: super ("reload_session_action", Resources.reloadIcon);
0297: putValue(ROLLOVER_ICON, Resources.reloadIconRollOver);
0298: putValue(TYPE, PUSH_ACTION);
0299: putValue(ACTION_TYPE, FILE_ACTION);
0300: putValue(ACTION_GROUP, FILE_SESSION_GROUP);
0301: putValue(ACTION_POS, FILE_SESSION_RELOAD);
0302: putValue(MENU_TARGET, MENU);
0303: putValue(BUTTON_TARGET, NO_BUTTON);
0304: }
0305:
0306: public void actionPerformed(ActionEvent e) {
0307: reloadSession();
0308: }
0309: }
0310:
0311: public void reloadSession() {
0312: TaskStartedEvent loginStartedEvent = new TaskStartedEvent(this ,
0313: Resources.getLocalString("login"));
0314: Session.getInstance().fireTaskStartEvent(loginStartedEvent);
0315: setTabbedPaneEnabledNoActions(false);
0316:
0317: SwingWorker worker = new SwingWorker("Reload-Thread") {
0318: public Object construct() {
0319: Session session = Session.getInstance();
0320: /*
0321: * if (session.isAlreadyLoggedIn()) { try { session.logout(); }
0322: * catch (InterruptedException e) { } }
0323: */
0324: if (session.isAlreadyLoggedIn()) {
0325: session.clearForConnect();
0326: }
0327: session.addSessionListener(MainPanel.this );
0328:
0329: // ...and try to log in
0330: if (session.login("", "", "")) {
0331: logger.log(Level.FINE,
0332: "Login successful, so switch context");
0333: boolean contextSwitched = ComponentFactory
0334: .getInstance()
0335: .switchCurrentContext(context);
0336: if (contextSwitched) {
0337: session.load();
0338: // System.gc();
0339: return Boolean.valueOf(true);
0340: } else {
0341: logger.log(Level.SEVERE,
0342: "Switching to context failed");
0343: return Boolean.valueOf(true);
0344: }
0345: } else {
0346: logger.log(Level.WARNING, "Login failed, retrying");
0347: return Boolean.valueOf(false);
0348: }
0349: }
0350:
0351: public void finished() {
0352: TaskFinishedEvent loginFinishedEvent = new TaskFinishedEvent(
0353: this );
0354: Session.getInstance().fireTaskFinishEvent(
0355: loginFinishedEvent);
0356: ComponentFactory.getInstance().clearEditedComponents();
0357: if (((Boolean) get()).booleanValue()) {
0358: loginAction.setEnabled(true);
0359: reloadSessionAction.setEnabled(true);
0360: changePasswordAction.setEnabled(true);
0361: } else {
0362: // (Re-)Login failed; visually log out client just in case,
0363: // since
0364: // we also overwrote our stored credentials with the wrong
0365: // ones.
0366:
0367: // Clean the tabs
0368: removeTabbedPaneComponents();
0369: // Clean the menus
0370: menuAndToolbarComposer.removeAllActionBundles();
0371: menuAndToolbarComposer
0372: .addPermanentActionBundle(new Action[] {
0373: new LaunchModuleAction(
0374: newPreferencesModule, false),
0375: exitAction, loginAction,
0376: reloadSessionAction,
0377: changePasswordAction, helpAction });
0378: // Open login dialog again - no don't open a dialog, that's
0379: // bullshit!
0380: // It is done by the session transparently so don't bother
0381: // with this
0382: // stupid hack
0383: // JOptionPane.showConfirmDialog(null,
0384: // Resources.getLocalString("login_failed"),
0385: // Resources.getLocalString("login_failed_title"),
0386: // JOptionPane.CLOSED_OPTION, JOptionPane.ERROR_MESSAGE);
0387: loginAction.setEnabled(true);
0388: // login();
0389: }
0390: setTabbedPaneEnabledNoActions(true);
0391: }
0392: };
0393: worker.start();
0394: }
0395:
0396: public void login() {
0397: if (!ServerInfo.isInitialized()) {
0398: // oops, connection failed, so no login possible, but connect is
0399: // possible
0400: loginAction.setEnabled(false);
0401: reloadSessionAction.setEnabled(false);
0402: changePasswordAction.setEnabled(false);
0403: connect(PreferencesModule.getServerPreferences().get(
0404: PreferencesModule.SERVER,
0405: PreferencesModule.DEFAULT_SERVER),
0406: PreferencesModule.getServerPreferences().get(
0407: PreferencesModule.ANON_SERVER,
0408: PreferencesModule.DEFAULT_ANON_SERVER));
0409:
0410: } else {
0411: boolean oldReload = reloadSessionAction.isEnabled();
0412: boolean oldChangePassword = changePasswordAction
0413: .isEnabled();
0414:
0415: context = ServerInfo.getInstance().getMainContextName();
0416: login("", "", "", context);
0417: }
0418: }
0419:
0420: private void login(final String login, final String group,
0421: final String password, final String context) {
0422: TaskStartedEvent loginStartedEvent = new TaskStartedEvent(this ,
0423: Resources.getLocalString("login"));
0424: Session.getInstance().fireTaskStartEvent(loginStartedEvent);
0425: setTabbedPaneEnabledNoActions(false);
0426:
0427: SwingWorker worker = new SwingWorker("Login-Thread") {
0428: public Object construct() {
0429: Session session = Session.getInstance();
0430: if (session.isAlreadyLoggedIn()) {
0431: try {
0432: session.logout();
0433: } catch (InterruptedException e) {
0434: }
0435: }
0436: session.addSessionListener(MainPanel.this );
0437:
0438: // ...and try to log in
0439: if (session.login(login, group, password)) {
0440: logger.log(Level.FINE,
0441: "Login successful, so switch context");
0442: boolean contextSwitched = ComponentFactory
0443: .getInstance()
0444: .switchCurrentContext(context);
0445: if (contextSwitched) {
0446: session.load();
0447: // System.gc();
0448: return Boolean.valueOf(true);
0449: } else {
0450: logger.log(Level.SEVERE,
0451: "Switching to context failed");
0452: return Boolean.valueOf(true);
0453: }
0454: } else {
0455: logger.log(Level.WARNING, "Login failed, retrying");
0456: return Boolean.valueOf(false);
0457: }
0458: }
0459:
0460: public void finished() {
0461: TaskFinishedEvent loginFinishedEvent = new TaskFinishedEvent(
0462: this );
0463: Session.getInstance().fireTaskFinishEvent(
0464: loginFinishedEvent);
0465: if (((Boolean) get()).booleanValue()) {
0466: loginAction.setEnabled(true);
0467: reloadSessionAction.setEnabled(true);
0468: changePasswordAction.setEnabled(true);
0469: } else {
0470: // (Re-)Login failed; visually log out client just in case,
0471: // since
0472: // we also overwrote our stored credentials with the wrong
0473: // ones.
0474:
0475: // Clean the tabs
0476: removeTabbedPaneComponents();
0477: // Clean the menus
0478: menuAndToolbarComposer.removeAllActionBundles();
0479: menuAndToolbarComposer
0480: .addPermanentActionBundle(new Action[] {
0481: new LaunchModuleAction(
0482: newPreferencesModule, false),
0483: exitAction, loginAction,
0484: reloadSessionAction,
0485: changePasswordAction, helpAction });
0486: // Open login dialog again - no don't open a dialog ...
0487: // that's bullshit!
0488: // It is done by the session transparently so don't bother
0489: // with this
0490: // stupid hack
0491: // JOptionPane.showConfirmDialog(null,
0492: // Resources.getLocalString("login_failed"),
0493: // Resources.getLocalString("login_failed_title"),
0494: // JOptionPane.CLOSED_OPTION, JOptionPane.ERROR_MESSAGE);
0495: ServerConnector.reset();
0496: loginAction.setEnabled(true);
0497: // login();
0498: }
0499: setTabbedPaneEnabledNoActions(true);
0500: }
0501: };
0502: worker.start();
0503: }
0504:
0505: public static void showURL(String urlAsString) {
0506: if (urlAsString != null) {
0507: URL url = null;
0508: try {
0509: if (urlAsString.startsWith("http://")) {
0510: url = new URL(urlAsString);
0511: } else {
0512: url = new URL(ServerInfo.getInstance()
0513: .getAnonServer()
0514: + urlAsString);
0515: }
0516: try {
0517: BasicService bs = ((BasicService) ServiceManager
0518: .lookup("javax.jnlp.BasicService"));
0519: if (bs.isWebBrowserSupported()) {
0520: boolean result = bs.showDocument(url);
0521: if (result) {
0522: return; // All right, we are done
0523: }
0524: }
0525: } catch (UnavailableServiceException e) {
0526: // Seems like we were not started via Web Start
0527: }
0528: // try to launch it manually using info in prefs
0529: try {
0530: Preferences applicationPreferences = PreferencesModule
0531: .getApplicationPreferences();
0532: String htmlEditor = applicationPreferences.get(
0533: PreferencesModule.HTML_RENDERER,
0534: PreferencesModule.DEFAULT_HTML_RENDERER);
0535: // we need tokenizer because of parameters
0536: StringTokenizer tokenizer = new StringTokenizer(
0537: htmlEditor);
0538: List<String> command = new ArrayList<String>();
0539: while (tokenizer.hasMoreTokens()) {
0540: command.add(tokenizer.nextToken());
0541: }
0542: command.add(url.toExternalForm());
0543: Runtime.getRuntime().exec(
0544: (String[]) command.toArray(new String[0]));
0545: } catch (Exception ex) {
0546: // show original exception if this failed
0547: ExceptionDialog.show(ex);
0548: }
0549: } catch (MalformedURLException e) {
0550: logger.log(Level.SEVERE, "No valid url given!", e);
0551: }
0552: }
0553: }
0554:
0555: public LaunchModuleAction buildLaunchModuleAction(
0556: ModuleDescription module) {
0557: return new LaunchModuleAction(module, true);
0558: }
0559:
0560: public class LaunchModuleAction extends AbstractAction implements
0561: ContelligentAction {
0562: private final static String MODULE = "module";
0563:
0564: private boolean tabbed;
0565:
0566: public LaunchModuleAction(ModuleDescription module,
0567: boolean tabbed) {
0568: super (module.getName(), Resources.defaultViewIcon);
0569: this .tabbed = tabbed;
0570: putValue(ROLLOVER_ICON, Resources.defaultViewIconRollOver);
0571: putValue(MODULE, module);
0572: putValue(SHORT_DESCRIPTION, module.getTooltip());
0573: putValue(ACTION_TYPE, module.getCategory());
0574: if (module.createToolbarEntry()) {
0575: putValue(BUTTON_TARGET, TOOLBAR);
0576: } else {
0577: putValue(BUTTON_TARGET, NO_BUTTON);
0578: }
0579: if (module.createMenuEntry()) {
0580: putValue(MENU_TARGET, MENU);
0581: } else {
0582: putValue(MENU_TARGET, NO_MENU);
0583: }
0584: putValue(TYPE, PUSH_ACTION);
0585: }
0586:
0587: public void actionPerformed(final ActionEvent e) {
0588: // switch to the server
0589: final ModuleDescription moduleDescription = (ModuleDescription) getValue(MODULE);
0590:
0591: if (moduleDescription.getMode() == ModuleDescription.LAUNCH_MODULE
0592: || moduleDescription.getMode() == ModuleDescription.LAUNCH_VIEW) {
0593: final Module module = moduleDescription.createModule();
0594:
0595: // this is a java module that shall be embedded
0596: if (module instanceof java.awt.Window) {
0597: ((java.awt.Window) module).setVisible(true);
0598: } else {
0599: // if module is no window, place the component into a new
0600: // created window...
0601: if (module instanceof Module) {
0602: logger
0603: .log(
0604: Level.FINE,
0605: "LaunchModuleAction.actionPerformed(): try to launch contelligent module in ModuleFrame '"
0606: + moduleDescription
0607: .getName()
0608: + "'");
0609: TaskStartedEvent moduleStartedEvent = new TaskStartedEvent(
0610: this ,
0611: Resources
0612: .getLocalString("intializing_module_task"));
0613: Session.getInstance().fireTaskStartEvent(
0614: moduleStartedEvent);
0615:
0616: // a contelligent module is able to deal with a
0617: // MenuAndToolbarComposer...
0618: SwingWorker worker = new SwingWorker(
0619: "Launch-Modul-Action-Thread") {
0620: public Object construct() {
0621: // this is what takes time, so give it a thread
0622: // of its own
0623: try {
0624: ModuleFrame moduleFrame = new ModuleFrame(
0625: moduleDescription.getName(),
0626: module, tabbed);
0627: return moduleFrame;
0628: } catch (ModuleInitException mie) {
0629: return mie;
0630: }
0631: }
0632:
0633: public void finished() {
0634: Object res = get();
0635: if (res instanceof ModuleFrame) {
0636: ModuleFrame moduleFrame = (ModuleFrame) res;
0637: TaskFinishedEvent moduleFinishedEvent = new TaskFinishedEvent(
0638: this );
0639: Session
0640: .getInstance()
0641: .fireTaskFinishEvent(
0642: moduleFinishedEvent);
0643: // the following two statements are not
0644: // thread safe, so put them here instead of
0645: // construct
0646: // we need this to deregister closed frames
0647: module
0648: .addModuleListener(MainPanel.this );
0649: // but first register this module frame:
0650: moduleFrames.add(new Object[] {
0651: module, moduleFrame });
0652: moduleFrame
0653: .setIconImage(Resources.contelligentIcon
0654: .getImage());
0655: moduleFrame.pack();
0656: moduleFrame.setVisible(true);
0657: // If this action was called for an
0658: // automatically launched module (event ==
0659: // null),
0660: // move the main frame to the front after we
0661: // are done.
0662: if (e == null) {
0663: ContelligentClient.getFrame()
0664: .toFront();
0665: }
0666: } else if (res instanceof ModuleInitException) {
0667: ExceptionDialog
0668: .show((ModuleInitException) res);
0669: }
0670: }
0671: };
0672: worker.start();
0673: } else {
0674: // the module can't deal with a
0675: // MenuAndToolbarComposer...
0676: JFrame frame = new JFrame(moduleDescription
0677: .getName());
0678: frame.getContentPane().add(
0679: (java.awt.Component) module);
0680: frame.setIconImage(Resources.contelligentIcon
0681: .getImage());
0682: frame.setVisible(true);
0683: }
0684: }
0685: } else if (moduleDescription.getMode() == ModuleDescription.LAUNCH_EXECUTABLE) {
0686: try {
0687: logger.log(Level.FINE,
0688: "LaunchModuleAction.actionPerformed(): try to start '"
0689: + moduleDescription.getExecutable()
0690: + "'");
0691: Runtime.getRuntime().exec(
0692: new String[] {
0693: moduleDescription.getExecutable(),
0694: moduleDescription
0695: .getConfiguration() });
0696: } catch (IOException ioe) {
0697: logger.log(Level.SEVERE,
0698: "LaunchModuleAction.actionPerformed(): cannot run executable '"
0699: + moduleDescription.getExecutable()
0700: + "' ", ioe);
0701: ExceptionDialog.show(ioe);
0702: }
0703: } else if (moduleDescription.getMode() == ModuleDescription.LAUNCH_BROWSER) {
0704: showURL(moduleDescription.getConfiguration());
0705: }
0706: }
0707: }
0708:
0709: public synchronized void connect(final String server,
0710: final String anonServer) {
0711: final TaskStartedEvent connectStartedEvent = new TaskStartedEvent(
0712: this , Resources.getLocalString("connecting_task"));
0713: Session.getInstance().fireTaskStartEvent(connectStartedEvent);
0714: setTabbedPaneEnabledNoActions(false);
0715:
0716: SwingWorker worker = new SwingWorker("Connection-Thread") {
0717: public Object construct() {
0718: logger.log(Level.FINE,
0719: "ConnectAction.actionPerformed(): connecting to: "
0720: + server);
0721: PreferencesModule.getServerPreferences().put(
0722: PreferencesModule.SERVER, server);
0723: try {
0724: // invalidate all loaded components
0725: ComponentFactory.getInstance().clear();
0726:
0727: // clear session
0728: if (Session.isSessionCreated()) {
0729: Session.getInstance().clearForConnect();
0730: }
0731: ServerInfo.init(new URL(server),
0732: new URL(anonServer));
0733:
0734: return Boolean.valueOf(true);
0735: } catch (MalformedURLException mue) {
0736: logger
0737: .log(
0738: Level.SEVERE,
0739: "ConnectAction.actionPerformed(): invalid server url",
0740: mue);
0741: ExceptionDialog.show(mue);
0742: } catch (RemoteActionException rae) {
0743: logger
0744: .log(
0745: Level.SEVERE,
0746: "ConnectAction.actionPerformed(): exception while getting server info",
0747: rae);
0748:
0749: if (!Errors.LOGIN_ABORTED.equals(rae.getMessage())) {
0750: ExceptionDialog.show(rae);
0751: }
0752: } catch (IncompatibleServerException e) {
0753: isIncompatible = true;
0754: JOptionPane.showMessageDialog(ContelligentClient
0755: .getFrame(), Resources
0756: .getLocalString("incompatible_server"));
0757: }
0758: return Boolean.valueOf(false);
0759: }
0760:
0761: // Runs on the event-dispatching thread.
0762: public void finished() {
0763: TaskFinishedEvent connectFinishedEvent = new TaskFinishedEvent(
0764: this );
0765: Session.getInstance().fireTaskFinishEvent(
0766: connectFinishedEvent);
0767: if (((Boolean) get()).booleanValue()) {
0768: isConnected = true;
0769: updateServerInfo();
0770: loginAction.setEnabled(true);
0771: reloadSessionAction.setEnabled(false);
0772: changePasswordAction.setEnabled(false);
0773: validate();
0774: login();
0775: } else {
0776: loginAction.setEnabled(true);
0777: if (isIncompatible) {
0778: updateServerInfo();
0779: }
0780: }
0781: setTabbedPaneEnabledNoActions(true);
0782: }
0783: };
0784: worker.start(); // required for SwingWorker 3
0785: }
0786:
0787: private JTabbedPane createTabbedPane() {
0788: final JTabbedPane pane = new JTabbedPane();
0789: ImagePanel contelligentPanel = new ImagePanel(
0790: Resources.background.getImage(), new BorderLayout());
0791: JPanel animationPanel = new JPanel(null);
0792: animationPanel.setOpaque(false);
0793:
0794: // server version info
0795: serverVersionLabel = new JLabel();
0796: animationPanel.add(serverVersionLabel);
0797: serverVersionLabel.setFont(infoFont);
0798: serverVersionLabel.setBounds(70, 173 - serverVersionLabel
0799: .getFontMetrics(infoFont).getHeight(), 300, 25);
0800: serverBuildLabel = new JLabel();
0801: serverBuildLabel.setFont(infoFont);
0802: animationPanel.add(serverBuildLabel);
0803: serverBuildLabel.setBounds(70, 198 - serverBuildLabel
0804: .getFontMetrics(infoFont).getHeight(), 300, 25);
0805:
0806: // client version info
0807: clientVersionLabel = new JLabel("Client "
0808: + BuildInfo.getVersion());
0809: animationPanel.add(clientVersionLabel);
0810: clientVersionLabel.setFont(infoFont);
0811: clientVersionLabel.setBounds(70, 237 - clientVersionLabel
0812: .getFontMetrics(infoFont).getHeight(), 300, 25);
0813: clientBuildLabel = new JLabel(BuildInfo.getBuildTime());
0814: clientBuildLabel.setFont(infoFont);
0815: animationPanel.add(clientBuildLabel);
0816: clientBuildLabel.setBounds(70, 262 - clientBuildLabel
0817: .getFontMetrics(infoFont).getHeight(), 300, 25);
0818:
0819: contelligentPanel.add(animationPanel, BorderLayout.CENTER);
0820: pane.addTab(Resources.getLocalString("info"),
0821: Resources.infoModule, contelligentPanel);
0822:
0823: pane.addChangeListener(new ChangeListener() {
0824: public void stateChanged(ChangeEvent e) {
0825: logger.log(Level.FINE, "Tab state changed: " + e);
0826: java.awt.Component module = pane.getSelectedComponent();
0827: if (selectedModule != null) {
0828: // fire module activated event
0829: logger
0830: .log(Level.FINE,
0831: "Module deactivated. Will inform listeners.");
0832: for (Iterator i = selectedModule
0833: .getModuleListeners().iterator(); i
0834: .hasNext();) {
0835: ((ModuleListener) i.next())
0836: .moduleDeactivated(new ModuleEvent(
0837: selectedModule));
0838: }
0839: }
0840: if (module instanceof Module) {
0841: selectedModule = (Module) module;
0842: // fire module activated event
0843: for (Iterator i = ((Module) module)
0844: .getModuleListeners().iterator(); i
0845: .hasNext();) {
0846: ((ModuleListener) i.next())
0847: .moduleActivated(new ModuleEvent(
0848: (Module) module));
0849: }
0850: logger.log(Level.FINE,
0851: "Tab component is module. Module actions: "
0852: + ((Module) module).getActions());
0853: menuAndToolbarComposer.addTemporaryActionBundle(
0854: ActionBundle.MODULE_ACTIONS,
0855: ((Module) module).getActions());
0856: } else {
0857: selectedModule = null;
0858: logger
0859: .log(Level.FINE,
0860: "Tab component is not module. Remove actions.");
0861: menuAndToolbarComposer
0862: .removeActionBundle(ActionBundle.MODULE_ACTIONS);
0863: }
0864: }
0865: });
0866:
0867: return pane;
0868: }
0869:
0870: public void removeTabbedPaneComponents() {
0871: setTabbedPaneEnabled(false);
0872:
0873: // remove all tabs but first (XXX this funny way to do this was chosen,
0874: // because there is no iterator on compoennts)
0875: Component component0 = tabbedPane.getComponentAt(0);
0876: String title0 = tabbedPane.getTitleAt(0);
0877: Icon icon0 = tabbedPane.getIconAt(0);
0878:
0879: tabbedPane.removeAll();
0880: tabbedPane.addTab(title0, icon0, component0);
0881:
0882: menuAndToolbarComposer.removeAllActionBundles();
0883: menuAndToolbarComposer.addPermanentActionBundle(new Action[] {
0884: new LaunchModuleAction(newPreferencesModule, false),
0885: exitAction, loginAction, reloadSessionAction,
0886: helpAction });
0887: menuAndToolbarComposer.compose();
0888: loginAction.setEnabled(true);
0889: }
0890:
0891: private void setTabbedPaneEnabled(boolean enabled) {
0892: reloadSessionAction.setEnabled(enabled);
0893: loginAction.setEnabled(enabled);
0894:
0895: // XXX we switch to tab one and hope this is no component module doing
0896: // reloads on ComponentFactory,
0897: // as reloads of components crash the complete session reload
0898: if (!enabled && tabbedPane.getTabCount() > 0)
0899: tabbedPane.setSelectedIndex(0);
0900: tabbedPane.setEnabled(enabled);
0901: }
0902:
0903: private void setTabbedPaneEnabledNoActions(boolean enabled) {
0904: // XXX we switch to tab one and hope this is no component module doing
0905: // reloads on ComponentFactory,
0906: // as reloads of components crash the complete session reload
0907: if (!enabled && tabbedPane.getTabCount() > 0)
0908: tabbedPane.setSelectedIndex(0);
0909: tabbedPane.setEnabled(enabled);
0910: }
0911:
0912: private void updateServerInfo() {
0913: // ComponentFactory.getInstance().setCurrentContext(ServerInfo.getInstance().getMainContextName());
0914: serverVersionLabel.setText("Server "
0915: + ServerInfo.getInstance().getVersion());
0916: serverBuildLabel.setText(ServerInfo.getInstance()
0917: .getBuildTime());
0918: }
0919:
0920: public void sessionChanged(final Session session) {
0921:
0922: logger.log(Level.FINE, "Session changed - updating modules");
0923:
0924: TaskStartedEvent moduleStartedEvent = new TaskStartedEvent(
0925: this , Resources
0926: .getLocalString("intializing_modules_task"));
0927: Session.getInstance().fireTaskStartEvent(moduleStartedEvent);
0928:
0929: final JTabbedPane oldPane = tabbedPane;
0930:
0931: SwingWorker worker = new SwingWorker("Module creation") {
0932: public Object construct() {
0933: logger.log(Level.FINE, "Creating modules");
0934: tabbedPane = createTabbedPane();
0935: // create modules...
0936: List<Action> modules = new Vector<Action>();
0937: for (Iterator i = ModuleManager.getInstance()
0938: .getModules().iterator(); i.hasNext();) {
0939: ModuleDescription moduleDescription = (ModuleDescription) i
0940: .next();
0941: logger
0942: .log(Level.INFO,
0943: "creating contelligent module '"
0944: + moduleDescription
0945: .getName() + "'");
0946: TaskStartedEvent moduleStartedEvent = new TaskStartedEvent(
0947: this ,
0948: Resources
0949: .getLocalString("intializing_modules_task")
0950: + ": "
0951: + moduleDescription.getName());
0952: Session.getInstance().fireTaskStartEvent(
0953: moduleStartedEvent);
0954: TaskFinishedEvent moduleFinishedEvent = new TaskFinishedEvent(
0955: this );
0956: LaunchModuleAction lma = new LaunchModuleAction(
0957: moduleDescription, true);
0958: if (moduleDescription.createMenuEntry()
0959: || moduleDescription.createToolbarEntry()) {
0960: modules.add(lma);
0961: }
0962: if (moduleDescription.createTab()
0963: && (moduleDescription.getMode() == ModuleDescription.LAUNCH_MODULE || moduleDescription
0964: .getMode() == ModuleDescription.LAUNCH_VIEW)) {
0965: logger.log(Level.FINE,
0966: "Creating module in tab: "
0967: + moduleDescription.getName());
0968: // create module in main tab panel - this only works if
0969: // module is no window
0970: Module module = moduleDescription
0971: .createModule();
0972: if (module != null) {
0973: // a contelligent module is able to deal with a
0974: // MenuAndToolbarComposer...
0975: module
0976: .setMenuAndToolbarComposer(menuAndToolbarComposer);
0977: try {
0978: module.init();
0979: } catch (ModuleInitException mie) {
0980: // if module could not be initialized, it is
0981: // errorneous to use it:
0982: logger.log(Level.SEVERE,
0983: "Creation of module "
0984: + moduleDescription
0985: .getName()
0986: + " failed!");
0987: de.finix.contelligent.client.util.ExceptionDialog
0988: .show(mie);
0989: Session.getInstance()
0990: .fireTaskFinishEvent(
0991: moduleFinishedEvent);
0992: continue;
0993: }
0994: tabbedPane.addTab(moduleDescription
0995: .getName(), module.getIcon(),
0996: (java.awt.Component) module);
0997: if (module instanceof SessionListener) {
0998: ((SessionListener) module)
0999: .sessionChanged(session);
1000: }
1001: logger.log(Level.INFO,
1002: "creation contelligent module '"
1003: + moduleDescription
1004: .getName()
1005: + "' finished");
1006: }
1007: }
1008: // Automatically open modules by faking execution of the
1009: // regular launch action
1010: if (moduleDescription.autoOpenModule()
1011: && (moduleDescription.getMode() == ModuleDescription.LAUNCH_MODULE || moduleDescription
1012: .getMode() == ModuleDescription.LAUNCH_VIEW)) {
1013: logger.log(Level.FINE, "Auto-opening module: "
1014: + moduleDescription.getName());
1015: lma.actionPerformed(null);
1016: }
1017: Session.getInstance().fireTaskFinishEvent(
1018: moduleFinishedEvent);
1019: }
1020: return modules;
1021: }
1022:
1023: public void finished() {
1024: TaskFinishedEvent moduleFinishedEvent = new TaskFinishedEvent(
1025: this );
1026: Session.getInstance().fireTaskFinishEvent(
1027: moduleFinishedEvent);
1028: List<Action> modules = (List<Action>) get();
1029: logger.log(Level.FINE, "Modules created: " + modules);
1030: Action[] moduleActions = (Action[]) modules
1031: .toArray(new Action[0]);
1032: menuAndToolbarComposer.addTemporaryActionBundle(
1033: "modules", moduleActions);
1034: updateServerInfo();
1035: contentPanel.remove(oldPane);
1036: contentPanel.add(tabbedPane, BorderLayout.CENTER);
1037: int index = oldPane.getSelectedIndex();
1038: if (index >= 0 && index < tabbedPane.getTabCount()) {
1039: tabbedPane.setSelectedIndex(index);
1040: }
1041: validate();
1042: repaint();
1043: }
1044: };
1045: worker.start();
1046: }
1047:
1048: public void onEvent(ContelligentEvent event) {
1049: eventIndicator.onEvent();
1050: }
1051:
1052: public void onTaskStarted(TaskStartedEvent e) {
1053: openTasks++;
1054: taskLabel.setText(e.getTaskName());
1055: }
1056:
1057: public void onTaskFinished(TaskFinishedEvent e) {
1058: openTasks--;
1059: if (openTasks == 0) {
1060: taskLabel.setText(!ServerInfo.isInitialized() ? ""
1061: : ServerInfo.getInstance().getServer().toString());
1062: }
1063: }
1064:
1065: public class LoginAction extends AbstractAction implements
1066: ContelligentAction {
1067: final Subject derivedSubject = Subject
1068: .getSubject(AccessController.getContext());
1069:
1070: public LoginAction() {
1071: super ("login_action", Resources.loginIcon);
1072: putValue(ROLLOVER_ICON, Resources.loginIconRollOver);
1073: putValue(TYPE, PUSH_ACTION);
1074: putValue(ACTION_TYPE, FILE_ACTION);
1075: putValue(ACTION_GROUP, FILE_SESSION_GROUP);
1076: putValue(ACTION_POS, FILE_SESSION_LOGIN);
1077: putValue(MENU_TARGET, MENU);
1078: putValue(BUTTON_TARGET, TOOLBAR);
1079: }
1080:
1081: public void actionPerformed(final ActionEvent e) {
1082: Subject.doAs(derivedSubject, new PrivilegedAction() {
1083: public Object run() {
1084: login();
1085: return null;
1086: }
1087: });
1088: }
1089: }
1090:
1091: static class ChangePasswordAction extends MnemonicAbstractAction
1092: implements ContelligentAction {
1093: public ChangePasswordAction() {
1094: super ("change_password_action", Resources.loginIcon);
1095: putValue(Action.SHORT_DESCRIPTION,
1096: "change_password_description");
1097: putValue(TYPE, PUSH_ACTION);
1098: putValue(ACTION_TYPE, TOOLS_ACTION);
1099: putValue(ACTION_GROUP, TOOLS_SYSTEM_GROUP);
1100: putValue(ACTION_POS, TOOLS_SYSTEM_PASSWORD);
1101: putValue(MENU_TARGET, MENU);
1102: putValue(BUTTON_TARGET, NO_BUTTON);
1103: }
1104:
1105: public void actionPerformed(ActionEvent e) {
1106: boolean changedOrCancel = false;
1107: while (!changedOrCancel) {
1108: ChangePasswordDialog changePassword = new ChangePasswordDialog(
1109: Resources.getLocalString("change_password"),
1110: Resources.getLocalString("password"), Resources
1111: .getLocalString("retype_password"),
1112: Resources.getLocalString("old_password"),
1113: ServerInfo.getInstance()
1114: .getUserGroupMinPasswordChars(
1115: Session.getInstance().getUser()
1116: .getGroup()));
1117: changePassword.pack();
1118: Dimension screenDim = Toolkit.getDefaultToolkit()
1119: .getScreenSize();
1120: Rectangle winDim = changePassword.getBounds();
1121: changePassword.setLocation(
1122: (screenDim.width - winDim.width) / 2,
1123: (screenDim.height - winDim.height) / 2);
1124: changePassword.setVisible(true);
1125: if (changePassword.getOption() == JOptionPane.OK_OPTION) {
1126: String oldPassword = changePassword
1127: .getOldPassword();
1128: String newPassword = changePassword.getPassword();
1129: // change password
1130: try {
1131: ActionResult actionResult = Actions
1132: .changePassword(oldPassword,
1133: newPassword);
1134: if (!actionResult.getState().equals("ok")) {
1135: String content = XMLUtil
1136: .getContent(actionResult
1137: .getContent());
1138: actionResult.showErrors();
1139: } else {
1140: JOptionPane
1141: .showMessageDialog(
1142: ContelligentClient
1143: .getActiveFrame(),
1144: Resources
1145: .getLocalString("password_changed"));
1146: changedOrCancel = true;
1147: }
1148: } catch (RemoteActionException rae) {
1149: ExceptionDialog.show(rae);
1150: }
1151: } else {
1152: changedOrCancel = true;
1153: }
1154: }
1155: }
1156: }
1157:
1158: public class ExitAction extends MnemonicAbstractAction implements
1159: ContelligentAction {
1160: public ExitAction() {
1161: super ("exit_action", Resources.cancelIcon);
1162: putValue(ROLLOVER_ICON, Resources.cancelIconRollOver);
1163: putValue(SHORT_DESCRIPTION, "exit_action_description");
1164: putValue(TYPE, PUSH_ACTION);
1165: putValue(ACTION_TYPE, FILE_ACTION);
1166: putValue(ACTION_GROUP, FILE_EXIT_GROUP);
1167: putValue(ACTION_POS, FILE_EXIT_EXIT);
1168: putValue(MENU_TARGET, MENU);
1169: putValue(BUTTON_TARGET, NO_BUTTON);
1170: }
1171:
1172: public void actionPerformed(ActionEvent e) {
1173: client.exit();
1174: }
1175: }
1176: }
|