/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.view.controller;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.naming.InvalidNameException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.xml.rpc.ServiceException;
import org.openflexo.AdvancedPrefs;
import org.openflexo.ApplicationContext;
import org.openflexo.FlexoCst;
import org.openflexo.GeneralPreferences;
import org.openflexo.antar.binding.TypeUtils;
import org.openflexo.components.ProgressWindow;
import org.openflexo.components.validation.ConsistencyCheckDialog;
import org.openflexo.fib.FIBLibrary;
import org.openflexo.fib.controller.FIBController.Status;
import org.openflexo.fib.controller.FIBDialog;
import org.openflexo.foundation.DataModification;
import org.openflexo.foundation.DocType;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.FlexoObservable;
import org.openflexo.foundation.FlexoObserver;
import org.openflexo.foundation.InspectorGroup;
import org.openflexo.foundation.Inspectors;
import org.openflexo.foundation.action.FlexoActionType;
import org.openflexo.foundation.action.SetPropertyAction;
import org.openflexo.foundation.cg.CGFile;
import org.openflexo.foundation.cg.GeneratedCode;
import org.openflexo.foundation.cg.GeneratedDoc;
import org.openflexo.foundation.cg.GenerationRepository;
import org.openflexo.foundation.cg.templates.CGTemplateObject;
import org.openflexo.foundation.dkv.DKVObject;
import org.openflexo.foundation.dm.DMObject;
import org.openflexo.foundation.dm.DuplicateClassNameException;
import org.openflexo.foundation.ie.IEObject;
import org.openflexo.foundation.ie.IEWOComponent;
import org.openflexo.foundation.ie.cl.ComponentDefinition;
import org.openflexo.foundation.ontology.AbstractOntologyObject;
import org.openflexo.foundation.ontology.OntologyFolder;
import org.openflexo.foundation.ontology.OntologyLibrary;
import org.openflexo.foundation.rm.DuplicateResourceException;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.foundation.rm.FlexoProjectReference;
import org.openflexo.foundation.rm.ProjectClosedNotification;
import org.openflexo.foundation.toc.TOCObject;
import org.openflexo.foundation.utils.FlexoProgress;
import org.openflexo.foundation.validation.Validable;
import org.openflexo.foundation.validation.ValidationModel;
import org.openflexo.foundation.validation.ValidationRule;
import org.openflexo.foundation.validation.ValidationRuleSet;
import org.openflexo.foundation.view.AbstractViewObject;
import org.openflexo.foundation.viewpoint.ViewPointLibraryObject;
import org.openflexo.foundation.wkf.FlexoProcess;
import org.openflexo.foundation.wkf.WKFObject;
import org.openflexo.foundation.wkf.WorkflowModelObject;
import org.openflexo.foundation.wkf.node.OperationNode;
import org.openflexo.foundation.wkf.utils.OperationAssociatedWithComponentSuccessfully;
import org.openflexo.icon.CGIconLibrary;
import org.openflexo.icon.DEIconLibrary;
import org.openflexo.icon.DGIconLibrary;
import org.openflexo.icon.DMEIconLibrary;
import org.openflexo.icon.FilesIconLibrary;
import org.openflexo.icon.IconFactory;
import org.openflexo.icon.IconLibrary;
import org.openflexo.icon.IconMarker;
import org.openflexo.icon.OntologyIconLibrary;
import org.openflexo.icon.SEIconLibrary;
import org.openflexo.icon.VEIconLibrary;
import org.openflexo.icon.VPMIconLibrary;
import org.openflexo.icon.WKFIconLibrary;
import org.openflexo.inspector.InspectableObject;
import org.openflexo.inspector.InspectorDelegate;
import org.openflexo.inspector.InspectorExceptionHandler;
import org.openflexo.inspector.InspectorNotFoundHandler;
import org.openflexo.inspector.InspectorSinglePanel;
import org.openflexo.inspector.InspectorWindow;
import org.openflexo.inspector.ModuleInspectorController;
import org.openflexo.inspector.selection.EmptySelection;
import org.openflexo.kvc.KeyValueCoding;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.model.exceptions.ModelDefinitionException;
import org.openflexo.model.factory.ModelFactory;
import org.openflexo.module.FlexoModule;
import org.openflexo.module.ModuleLoader;
import org.openflexo.module.ProjectLoader;
import org.openflexo.prefs.PreferencesController;
import org.openflexo.prefs.PreferencesHaveChanged;
import org.openflexo.prefs.PreferencesWindow;
import org.openflexo.rm.ResourceManagerWindow;
import org.openflexo.selection.SelectionManager;
import org.openflexo.toolbox.FileResource;
import org.openflexo.toolbox.PropertyChangeListenerRegistrationManager;
import org.openflexo.toolbox.ToolBox;
import org.openflexo.utils.CancelException;
import org.openflexo.utils.TooManyFailedAttemptException;
import org.openflexo.view.FlexoDialog;
import org.openflexo.view.FlexoFrame;
import org.openflexo.view.FlexoMainPane;
import org.openflexo.view.FlexoRelativeWindow;
import org.openflexo.view.ModuleView;
import org.openflexo.view.controller.WebServiceURLDialog.PPMWSClientParameter;
import org.openflexo.view.controller.model.ControllerModel;
import org.openflexo.view.controller.model.FlexoPerspective;
import org.openflexo.view.controller.model.Location;
import org.openflexo.view.menu.FlexoMenuBar;
import org.openflexo.ws.client.PPMWebService.PPMWebServiceAuthentificationException;
import org.openflexo.ws.client.PPMWebService.PPMWebServiceClient;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Collections2;
import com.google.common.collect.Multimap;
/**
* Abstract controller defined for an application module
*
* @author benoit, sylvain
*/
public abstract class FlexoController implements FlexoObserver, InspectorNotFoundHandler, InspectorExceptionHandler, PropertyChangeListener {
static final Logger logger = Logger.getLogger(FlexoController.class.getPackage().getName());
public static final String DISPOSED = "disposed";
public static boolean USE_NEW_INSPECTOR_SCHEME = false;
public static boolean USE_OLD_INSPECTOR_SCHEME = true;
public boolean useNewInspectorScheme() {
return USE_NEW_INSPECTOR_SCHEME;
}
public boolean useOldInspectorScheme() {
return USE_OLD_INSPECTOR_SCHEME;
}
private PropertyChangeSupport propertyChangeSupport;
private boolean disposed = false;
private final Map<Location, ModuleView<?>> viewsForLocation;
private final Multimap<ModuleView<?>, Location> locationsForView;
private ConsistencyCheckDialog consistencyCheckWindow;
protected FlexoModule module;
protected FlexoMenuBar menuBar;
protected SelectionManager selectionManager;
private ControllerActionInitializer controllerActionInitializer;
protected FlexoFrame flexoFrame;
private FlexoMainPane mainPane;
private ResourceManagerWindow rmWindow;
private ControllerModel controllerModel;
private final List<FlexoMenuBar> registeredMenuBar = new ArrayList<FlexoMenuBar>();
private FlexoDocInspectorController docInspectorController = null;
private FlexoSharedInspectorController inspectorController;
private ModuleInspectorController mainInspectorController;
protected PropertyChangeListenerRegistrationManager manager = new PropertyChangeListenerRegistrationManager();
/**
* Constructor
*/
protected FlexoController(FlexoModule module) {
super();
ProgressWindow.setProgressInstance(FlexoLocalization.localizedForKey("init_module_controller"));
this.module = module;
locationsForView = ArrayListMultimap.create();
viewsForLocation = new HashMap<Location, ModuleView<?>>();
controllerModel = new ControllerModel(module.getApplicationContext(), module);
propertyChangeSupport = new PropertyChangeSupport(this);
manager.new PropertyChangeListenerRegistration(this, controllerModel);
flexoFrame = createFrame();
controllerActionInitializer = createControllerActionInitializer();
registerShortcuts(controllerActionInitializer);
menuBar = createAndRegisterNewMenuBar();
selectionManager = createSelectionManager();
flexoFrame.setJMenuBar(menuBar);
flexoFrame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
flexoFrame.getRootPane().getActionMap().put("escape", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
cancelCurrentAction();
}
});
mainPane = createMainPane();
getFlexoFrame().getContentPane().add(mainPane, BorderLayout.CENTER);
((JComponent) getFlexoFrame().getContentPane()).revalidate();
initInspectors();
initializePerspectives();
if (getModule().getModule().requireProject()) {
if (getModuleLoader().getLastActiveEditor() != null) {
controllerModel.setCurrentEditor(getModuleLoader().getLastActiveEditor());
}
} else {
controllerModel.setCurrentEditor(getApplicationContext().getApplicationEditor());
}
GeneralPreferences.getPreferences().addObserver(this);
}
protected abstract void initializePerspectives();
public final ControllerModel getControllerModel() {
return controllerModel;
}
protected abstract SelectionManager createSelectionManager();
/**
* Creates a new instance of MenuBar for the module this controller refers to
*
* @return
*/
protected abstract FlexoMenuBar createNewMenuBar();
protected FlexoFrame createFrame() {
return new FlexoFrame(this);
}
public final SelectionManager getSelectionManager() {
return selectionManager;
}
public final FlexoMenuBar getMenuBar() {
return menuBar;
}
public final ApplicationContext getApplicationContext() {
return getModule().getApplicationContext();
}
public final ProjectLoader getProjectLoader() {
return getApplicationContext().getProjectLoader();
}
public final ModuleLoader getModuleLoader() {
return getApplicationContext().getModuleLoader();
}
/**
* Creates a new instance of MenuBar for the module this controller refers to
*
* @return
*/
public ControllerActionInitializer createControllerActionInitializer() {
return new ControllerActionInitializer(this);
}
public ControllerActionInitializer getControllerActionInitializer() {
return controllerActionInitializer;
}
/**
* Creates and register a new instance of MenuBar for the module this controller refers to
*
* @return
*/
public final FlexoMenuBar createAndRegisterNewMenuBar() {
FlexoMenuBar returned = createNewMenuBar();
registeredMenuBar.add(returned);
if (getFlexoFrame() != null) {
for (FlexoRelativeWindow next : getFlexoFrame().getRelativeWindows()) {
returned.getWindowMenu().addFlexoRelativeWindowMenu(next);
}
}
return returned;
}
public void notifyNewFlexoRelativeWindow(FlexoRelativeWindow w) {
for (FlexoMenuBar next : registeredMenuBar) {
next.getWindowMenu().addFlexoRelativeWindowMenu(w);
}
}
public void notifyRemoveFlexoRelativeWindow(FlexoRelativeWindow w) {
for (FlexoMenuBar next : registeredMenuBar) {
next.getWindowMenu().removeFlexoRelativeWindowMenu(w);
}
}
public void notifyRenameFlexoRelativeWindow(FlexoRelativeWindow w, String title) {
for (FlexoMenuBar next : registeredMenuBar) {
next.getWindowMenu().renameFlexoRelativeWindowMenu(w, title);
}
}
/**
*
*/
public void initInspectors() {
if (useOldInspectorScheme()) {
if (inspectorController == null) {
inspectorController = new FlexoSharedInspectorController(this);
}
/*
* if (getInspectorWindow() != null) { getInspectorWindow().setAlwaysOnTop(GeneralPreferences.getInspectorAlwaysOnTop()); }
*/
getSelectionManager().addObserver(getSharedInspectorController());
getSharedInspectorController().addInspectorExceptionHandler(this);
loadAllModuleInspectors();
}
if (useNewInspectorScheme()) {
loadInspectorGroup(getModule().getShortName().toUpperCase());
getSelectionManager().addObserver(getModuleInspectorController());
}
docInspectorController = new FlexoDocInspectorController(this);
getSelectionManager().addObserver(docInspectorController);
}
public ModuleInspectorController getModuleInspectorController() {
if (mainInspectorController == null) {
mainInspectorController = new ModuleInspectorController(this);
}
return mainInspectorController;
}
protected void loadInspectorGroup(String inspectorGroup) {
File inspectorsDir = new FileResource("Inspectors/" + inspectorGroup);
getModuleInspectorController().loadDirectory(inspectorsDir);
}
public FlexoDocInspectorController getDocInspectorController() {
return docInspectorController;
}
public InspectorSinglePanel getDocInspectorPanel() {
if (getDocInspectorController() != null) {
return getDocInspectorController().getDocInspectorPanel();
}
return null;
}
/**
* Return doc inspector panel, after having it disconnected from its actual parent
*
* @return
*/
public final JPanel getDisconnectedDocInspectorPanel() {
/*if (getDocInspectorPanel().getParent() != null) {
getDocInspectorPanel().getParent().remove(getDocInspectorPanel());
}*/
return getDocInspectorPanel();
}
public FlexoFrame getFlexoFrame() {
return flexoFrame;
}
public FlexoModule getModule() {
return module;
}
protected final void setEditor(FlexoEditor editor) {
controllerModel.setCurrentEditor(editor);
}
protected void updateEditor(FlexoEditor from, FlexoEditor to) {
if (from instanceof InteractiveFlexoEditor) {
((InteractiveFlexoEditor) from).unregisterControllerActionInitializer(getControllerActionInitializer());
}
if (to instanceof InteractiveFlexoEditor) {
((InteractiveFlexoEditor) to).registerControllerActionInitializer(getControllerActionInitializer());
}
}
public abstract FlexoModelObject getDefaultObjectToSelect(FlexoProject project);
public FlexoProject getProject() {
if (getEditor() != null) {
return getEditor().getProject();
}
return null;
}
public File getProjectDirectory() {
return getProject().getProjectDirectory();
}
public FlexoSharedInspectorController getSharedInspectorController() {
return inspectorController;
}
public InspectorWindow getInspectorWindow() {
if (getSharedInspectorController() != null) {
return getSharedInspectorController().getInspectorWindow();
}
return null;
}
private FlexoMenuBar inspectorMenuBar;
public FlexoMenuBar getInspectorMenuBar() {
if (inspectorMenuBar == null) {
inspectorMenuBar = createAndRegisterNewMenuBar();
}
return inspectorMenuBar;
}
public static void showError(String msg) throws HeadlessException {
showError(FlexoLocalization.localizedForKey("error"), msg);
}
public static void showError(String title, String msg) throws HeadlessException {
showMessageDialog(msg, title, JOptionPane.ERROR_MESSAGE);
}
public static void notify(String msg) throws HeadlessException {
showMessageDialog(msg, FlexoLocalization.localizedForKey("confirmation"), JOptionPane.INFORMATION_MESSAGE);
}
public static boolean notifyWithCheckbox(String title, String msg, String checkboxText, boolean defaultValue) {
JPanel root = new JPanel(new BorderLayout());
Icon msgIcon = UIManager.getDefaults().getIcon("OptionPane.informationIcon");
JLabel notifyIcon = new JLabel(msgIcon);
notifyIcon.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JLabel label = new JLabel(msg);
label.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
label.setHorizontalAlignment(SwingConstants.LEFT);
JCheckBox box = new JCheckBox(checkboxText, defaultValue);
box.setBorder(BorderFactory.createEmptyBorder(1, 20, 10, 10));
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(label, BorderLayout.NORTH);
centerPanel.add(box, BorderLayout.SOUTH);
JButton ok = new JButton("ok"/*FlexoLocalization.localizedForKey("ok")*/);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonPanel.add(ok);
root.add(notifyIcon, BorderLayout.WEST);
root.add(centerPanel, BorderLayout.CENTER);
root.add(buttonPanel, BorderLayout.SOUTH);
final FlexoDialog dialog = new FlexoDialog();
if (title != null) {
dialog.setTitle(title);
}
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.setResizable(false);
dialog.add(root);
dialog.pack();
dialog.setVisible(true);
return box.isSelected();
}
public static int ask(String msg) throws HeadlessException {
return showConfirmDialog(msg, FlexoLocalization.localizedForKey("information"), JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
}
public static boolean confirmWithWarning(String msg) throws HeadlessException {
return showOptionDialog(FlexoFrame.getActiveFrame(), msg, FlexoLocalization.localizedForKey("information"),
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, new Object[] { FlexoLocalization.localizedForKey("yes"),
FlexoLocalization.localizedForKey("no") }, FlexoLocalization.localizedForKey("no")) == JOptionPane.YES_OPTION;
}
public static boolean confirm(String msg) throws HeadlessException {
return ask(msg) == JOptionPane.YES_OPTION;
}
public static int confirmYesNoCancel(String localizedMessage) {
return showOptionDialog(FlexoFrame.getActiveFrame(), localizedMessage, localizedMessage, JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
}
public static String askForString(String msg) throws HeadlessException {
return showInputDialog(msg, FlexoLocalization.localizedForKey("information"), JOptionPane.QUESTION_MESSAGE);
}
public static String askForString(Component parentComponent, String msg) throws HeadlessException {
return showInputDialog(parentComponent, msg, FlexoLocalization.localizedForKey("information"), JOptionPane.OK_CANCEL_OPTION);
}
public static String askForStringMatchingPattern(String msg, Pattern pattern, String localizedPattern) {
String result = askForString(msg);
while (result != null && !pattern.matcher(result).matches()) {
notify(localizedPattern);
result = askForString(msg);
}
return result;
}
public static int selectOption(String msg, String[] options, String initialOption) {
return showOptionDialog(FlexoFrame.getActiveFrame(), msg, FlexoLocalization.localizedForKey("confirmation"),
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, initialOption);
}
public static int selectOption(String msg, String initialOption, String... options) {
return showOptionDialog(FlexoFrame.getActiveFrame(), msg, FlexoLocalization.localizedForKey("confirmation"),
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, initialOption);
}
public void showInspector() {
if (useOldInspectorScheme()) {
/*
* if (!getInspectorWindow().isActive()) { int state = getInspectorWindow().getExtendedState(); state &= ~Frame.ICONIFIED;
* getInspectorWindow().setExtendedState(state); }
*/
getInspectorWindow().setVisible(true);
}
if (useNewInspectorScheme()) {
getModuleInspectorController().getInspectorDialog().setVisible(true);
}
}
public void resetInspector() {
if (useOldInspectorScheme()) {
getInspectorWindow().newSelection(new EmptySelection());
} else {
getModuleInspectorController().resetInspector();
}
}
public PreferencesWindow getPreferencesWindow(boolean create) {
return PreferencesController.instance().getPreferencesWindow(create);
}
public void showPreferences() {
PreferencesController.instance().showPreferences();
}
public void registerShortcuts(ControllerActionInitializer controllerInitializer) {
for (final Entry<FlexoActionType<?, ?, ?>, ActionInitializer<?, ?, ?>> entry : controllerInitializer.getActionInitializers()
.entrySet()) {
KeyStroke accelerator = entry.getValue().getShortcut();
if (accelerator != null) {
registerActionForKeyStroke(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
FlexoModelObject focusedObject = getSelectionManager().getFocusedObject();
Vector<FlexoModelObject> globalSelection = getSelectionManager().getSelection();
FlexoActionType actionType = entry.getKey();
if (TypeUtils.isAssignableTo(focusedObject, actionType.getFocusedObjectType())
&& (globalSelection == null || TypeUtils.isAssignableTo(globalSelection,
actionType.getGlobalSelectionType()))) {
getEditor().performActionType(actionType, focusedObject, globalSelection, e);
}
}
}, accelerator, entry.getKey().getUnlocalizedName());
}
}
}
public void registerActionForKeyStroke(AbstractAction action, KeyStroke accelerator, String actionName) {
String key = actionName;
Object object = getFlexoFrame().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).get(accelerator);
Action action2 = null;
if (object != null) {
action2 = getFlexoFrame().getRootPane().getActionMap().get(object);
}
if (action2 != null) {
class CompoundAction extends AbstractAction {
private List<Action> actions = new ArrayList<Action>();
void addToAction(Action action) {
actions.add(action);
}
@Override
public void actionPerformed(ActionEvent e) {
for (Action action : actions) {
action.actionPerformed(e);
}
}
}
if (action2 instanceof CompoundAction) {
((CompoundAction) action2).addToAction(action);
return;
} else {
CompoundAction compoundAction = new CompoundAction();
compoundAction.addToAction(action2);
compoundAction.addToAction(action);
action = compoundAction;
key = "compound-" + accelerator.toString();
}
}
getFlexoFrame().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(accelerator, key);
getFlexoFrame().getRootPane().getActionMap().put(key, action);
if (accelerator.getKeyCode() == FlexoCst.DELETE_KEY_CODE) {
int keyCode = FlexoCst.BACKSPACE_DELETE_KEY_CODE;
getFlexoFrame().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(keyCode, accelerator.getModifiers()), key);
}
}
protected void loadAllModuleInspectors() {
// Load flexo inspectors
if (getModule().getInspectorGroups() != null) {
ProgressWindow.setProgressInstance(FlexoLocalization.localizedForKey("load_inspectors"));
for (InspectorGroup group : getModule().getInspectorGroups()) {
getSharedInspectorController().loadInspectors(group);
}
getSharedInspectorController().updateSuperInspectors();
}
}
@Override
public void inspectorNotFound(String inspectorName) {
InspectorGroup inspectorGroup = Inspectors.inspectorGroupForInspector(inspectorName);
if (inspectorGroup != null) {
boolean openedWindow = false;
if (!ProgressWindow.hasInstance()) {
ProgressWindow.showProgressWindow(FlexoLocalization.localizedForKey("load_required_inspectors"), 3);
openedWindow = true;
}
ProgressWindow.setProgressInstance(FlexoLocalization.localizedForKey("load_required_inspectors"));
getSharedInspectorController().loadInspectors(inspectorGroup);
ProgressWindow.setProgressInstance(FlexoLocalization.localizedForKey("update_inspector"));
getSharedInspectorController().updateSuperInspectors();
if (openedWindow) {
ProgressWindow.hideProgressWindow();
}
}
}
/**
* Tries to handle an exception raised during object inspection.<br>
*
* @param inspectable
* the object on which exception was raised
* @param propertyName
* the concerned property name
* @param value
* the value that raised an exception
* @param exception
* the exception that was raised
* @return a boolean indicating if this handler has handled this exception, or not
*/
@Override
public boolean handleException(InspectableObject inspectable, String propertyName, Object value, Throwable exception) {
if (inspectable instanceof FlexoProcess && exception instanceof DuplicateResourceException) {
if (propertyName.equals("name")) {
boolean isOK = false;
while (!isOK) {
String newName = askForString(FlexoLocalization
.localizedForKey("invalid_name_process_already_exists_please_choose_an_other_one"));
if (newName != null) {
try {
((FlexoProcess) inspectable).setName(newName);
isOK = true;
} catch (DuplicateResourceException e) {
} catch (InvalidNameException e) {
}
} else {
return true;
}
}
return true;
}
} else if (inspectable instanceof OperationNode && exception instanceof DuplicateResourceException) {
if (propertyName.equals("WOComponentName")) {
boolean isOK = false;
while (!isOK) {
String newName = askForString(FlexoLocalization
.localizedForKey("invalid_name_component_already_exists_please_choose_an_other_one"));
if (newName != null) {
try {
((OperationNode) inspectable).setWOComponentName(newName);
isOK = true;
} catch (DuplicateResourceException e) {
} catch (OperationAssociatedWithComponentSuccessfully e) {
// TODO: FIXME
if (logger.isLoggable(Level.INFO)) {
logger.info("FIXME: handle new component association in FlexoController.class");
}
}
} else {
return true;
}
}
return true;
}
} else if (inspectable instanceof ComponentDefinition && exception instanceof DuplicateResourceException) {
if (propertyName.equals("name")) {
boolean isOK = false;
while (!isOK) {
String newName = askForString(FlexoLocalization
.localizedForKey("invalid_name_component_already_exists_please_choose_an_other_one"));
if (newName != null) {
try {
((ComponentDefinition) inspectable).setName(newName);
isOK = true;
} catch (DuplicateResourceException e) {
} catch (DuplicateClassNameException e) {
notify(e.getLocalizedMessage());
} catch (InvalidNameException e) {
notify(FlexoLocalization.localizedForKey("invalid_component_name"));
}
} else {
return true;
}
}
return true;
}
} else if ((inspectable instanceof IEWOComponent || inspectable instanceof ComponentDefinition)
&& exception instanceof InvalidNameException) {
if (propertyName.equals("name")) {
notify(FlexoLocalization.localizedForKey("invalid_component_name"));
return true;
}
}
return false;
}
public ConsistencyCheckDialog getConsistencyCheckWindow() {
return getConsistencyCheckWindow(true);
}
public ConsistencyCheckDialog getConsistencyCheckWindow(boolean create) {
if (create && getDefaultValidationModel() != null) {
if (consistencyCheckWindow == null || consistencyCheckWindow.isDisposed()) {
consistencyCheckWindow = new ConsistencyCheckDialog(this);
}
}
return consistencyCheckWindow;
}
public void consistencyCheck(Validable objectToValidate) {
if (getDefaultValidationModel() != null) {
initializeValidationModel();
getConsistencyCheckWindow(true).setVisible(true);
getConsistencyCheckWindow(true).consistencyCheck(objectToValidate);
}
}
public void initializeValidationModel() {
ValidationModel validationModel = getDefaultValidationModel();
if (validationModel != null) {
for (int i = 0; i < validationModel.getSize(); i++) {
ValidationRuleSet ruleSet = validationModel.getElementAt(i);
for (ValidationRule<?, ?> rule : ruleSet.getRules()) {
rule.setIsEnabled(GeneralPreferences.isValidationRuleEnabled(rule));
}
}
}
}
/**
* Brings up a dialog with a specified icon, where the initial choice is determined by the <code>initialValue</code> parameter and the
* number of choices is determined by the <code>optionType</code> parameter.
* <p>
* If <code>optionType</code> is <code>YES_NO_OPTION</code>, or <code>YES_NO_CANCEL_OPTION</code> and the <code>options</code> parameter
* is <code>null</code>, then the options are supplied by the look and feel.
* <p>
* The <code>messageType</code> parameter is primarily used to supply a default icon from the look and feel.
*
* @param parentComponent
* determines the <code>Frame</code> in which the dialog is displayed; if <code>null</code>, or if the
* <code>parentComponent</code> has no <code>Frame</code>, a default <code>Frame</code> is used
* @param message
* the <code>Object</code> to display
* @param title
* the title string for the dialog
* @param optionType
* an integer designating the options available on the dialog: <code>YES_NO_OPTION</code>, or
* <code>YES_NO_CANCEL_OPTION</code>
* @param messageType
* an integer designating the kind of message this is, primarily used to determine the icon from the pluggable Look and Feel:
* <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>, <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>,
* or <code>PLAIN_MESSAGE</code>
* @param icon
* the icon to display in the dialog
* @param options
* an array of objects indicating the possible choices the user can make; if the objects are components, they are rendered
* properly; non-<code>String</code> objects are rendered using their <code>toString</code> methods; if this parameter is
* <code>null</code>, the options are determined by the Look and Feel
* @param initialValue
* the object that represents the default selection for the dialog; only meaningful if <code>options</code> is used; can be
* <code>null</code>
* @return an integer indicating the option chosen by the user, or <code>CLOSED_OPTION</code> if the user closed the dialog
* @exception HeadlessException
* if <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
*/
private static synchronized int showOptionDialog(Component parentComponent, Object message, String title, int optionType,
int messageType, Icon icon, Object[] options, Object initialValue) throws HeadlessException {
if (parentComponent == null) {
if (ProgressWindow.hasInstance()) {
parentComponent = ProgressWindow.instance();
}
}
final Component parent = parentComponent;
JOptionPane pane = null;
boolean isLocalized = false;
Object[] availableOptions = null;
if (optionType == JOptionPane.OK_CANCEL_OPTION && options == null) {
availableOptions = new Object[] { FlexoLocalization.localizedForKey("OK"), FlexoLocalization.localizedForKey("cancel") };
pane = new JOptionPane(message, messageType, optionType, icon, availableOptions, availableOptions[0]) {
@Override
public int getMaxCharactersPerLineCount() {
return FlexoController.getMaxCharactersPerLine(parent, this);
}
};
isLocalized = true;
// pane.setInitialSelectionValue();
} else if (optionType == JOptionPane.YES_NO_OPTION && options == null) {
availableOptions = new Object[] { FlexoLocalization.localizedForKey("yes"), FlexoLocalization.localizedForKey("no") };
pane = new JOptionPane(message, messageType, optionType, icon, availableOptions, availableOptions[0]) {
@Override
public int getMaxCharactersPerLineCount() {
return FlexoController.getMaxCharactersPerLine(parent, this);
}
};
isLocalized = true;
// pane.setInitialSelectionValue(availableOptions[1]);
} else if (optionType == JOptionPane.YES_NO_CANCEL_OPTION && options == null) {
availableOptions = new Object[] { FlexoLocalization.localizedForKey("yes"), FlexoLocalization.localizedForKey("no"),
FlexoLocalization.localizedForKey("cancel") };
pane = new JOptionPane(message, messageType, optionType, icon, availableOptions, availableOptions[0]) {
@Override
public int getMaxCharactersPerLineCount() {
return FlexoController.getMaxCharactersPerLine(parent, this);
}
};
isLocalized = true;
// pane.setInitialSelectionValue(availableOptions[1]);
} else {
pane = new JOptionPane(message, messageType, optionType, icon, options, initialValue) {
@Override
public int getMaxCharactersPerLineCount() {
return FlexoController.getMaxCharactersPerLine(parent, this);
}
};
pane.setInitialValue(initialValue);
}
pane.setComponentOrientation((parentComponent == null ? FlexoFrame.getActiveFrame() : parentComponent).getComponentOrientation());
pane.setMessageType(messageType);
final JDialog dialog = pane.createDialog(parentComponent, title);
Container content = dialog.getContentPane();
JScrollPane scroll = new JScrollPane(content, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
dialog.setContentPane(scroll);
dialog.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
dialog.setVisible(false);
}
}
});
dialog.validate();
dialog.pack();
Window window = null;
if (parentComponent instanceof Window) {
window = (Window) parentComponent;
}
if (window == null && parentComponent != null) {
window = SwingUtilities.getWindowAncestor(parentComponent);
}
Dimension maxDim;
if (window != null && window.isVisible()) {
maxDim = new Dimension(Math.min(dialog.getWidth(), window.getGraphicsConfiguration().getDevice().getDefaultConfiguration()
.getBounds().width), Math.min(dialog.getHeight(), window.getGraphicsConfiguration().getDevice()
.getDefaultConfiguration().getBounds().height));
} else {
maxDim = new Dimension(Math.min(dialog.getWidth(), Toolkit.getDefaultToolkit().getScreenSize().width), Math.min(
dialog.getHeight(), Toolkit.getDefaultToolkit().getScreenSize().height));
}
dialog.setSize(maxDim);
dialog.setLocationRelativeTo(window);
dialog.setVisible(true);
// pane.selectInitialValue();
dialog.dispose();
Object selectedValue = pane.getValue();
if (selectedValue == null) {
return JOptionPane.CLOSED_OPTION;
}
if (isLocalized) {
for (int counter = 0, maxCounter = availableOptions.length; counter < maxCounter; counter++) {
if (optionType == JOptionPane.OK_CANCEL_OPTION) {
if (availableOptions[counter].equals(selectedValue)) {
if (counter == 0) {
return JOptionPane.OK_OPTION;
}
if (counter == 1) {
return JOptionPane.CANCEL_OPTION;
}
}
} else if (optionType == JOptionPane.YES_NO_OPTION) {
if (availableOptions[counter].equals(selectedValue)) {
if (counter == 0) {
return JOptionPane.YES_OPTION;
}
if (counter == 1) {
return JOptionPane.NO_OPTION;
}
}
} else if (optionType == JOptionPane.YES_NO_CANCEL_OPTION) {
if (availableOptions[counter].equals(selectedValue)) {
if (counter == 0) {
return JOptionPane.YES_OPTION;
}
if (counter == 1) {
return JOptionPane.NO_OPTION;
}
if (counter == 2) {
return JOptionPane.CANCEL_OPTION;
}
}
}
}
}
if (options == null) {
if (selectedValue instanceof Integer) {
return ((Integer) selectedValue).intValue();
}
return JOptionPane.CLOSED_OPTION;
}
for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++) {
if (options[counter].equals(selectedValue)) {
return counter;
}
}
return JOptionPane.CLOSED_OPTION;
}
protected static int getMaxCharactersPerLine(Component parent, JOptionPane pane) {
if (pane.getMessage() instanceof String && ((String) pane.getMessage()).startsWith("<html>")) {
return Integer.MAX_VALUE;
}
Window w = null;
if (parent != null) {
w = SwingUtilities.getWindowAncestor(parent);
}
int width = 0;
if (w != null) {
width = w.getGraphicsConfiguration().getDevice().getDisplayMode().getWidth();
} else {
width = Toolkit.getDefaultToolkit().getScreenSize().width;
}
int availableWidth = width;
if (pane.getIcon() != null) {
availableWidth -= pane.getIcon().getIconWidth();
} else {
Icon icon = UIManager.getIcon("OptionPane.errorIcon");
availableWidth -= icon != null ? icon.getIconWidth() : 0;
}
return availableWidth / pane.getFontMetrics(UIManager.getFont("Label.font")).charWidth('W');
}
private static void showMessageDialog(Object message, String title, int messageType) throws HeadlessException {
showMessageDialog(message, title, messageType, null);
}
private static void showMessageDialog(Object message, String title, int messageType, Icon icon) throws HeadlessException {
showOptionDialog(FlexoFrame.getActiveFrame(), message, title, JOptionPane.DEFAULT_OPTION, messageType, icon, null, null);
}
private static int showConfirmDialog(Object message, String title, int optionType, int messageType) throws HeadlessException {
return showConfirmDialog(message, title, optionType, messageType, null);
}
private static int showConfirmDialog(Object message, String title, int optionType, int messageType, Icon icon) throws HeadlessException {
return showOptionDialog(FlexoFrame.getActiveFrame(), message, title, optionType, messageType, icon, null, null);
}
private static String showInputDialog(Object message, String title, int messageType) throws HeadlessException {
return (String) showInputDialog(FlexoFrame.getActiveFrame(), message, title, messageType, null, null, null);
}
private static String showInputDialog(Component parentComponent, Object message, String title, int messageType)
throws HeadlessException {
return (String) showInputDialog(parentComponent, message, title, messageType, null, null, null);
}
private static Object showInputDialog(Component parentComponent, Object message, String title, int messageType, Icon icon,
Object[] selectionValues, Object initialSelectionValue) throws HeadlessException {
if (parentComponent == null) {
if (ProgressWindow.hasInstance()) {
parentComponent = ProgressWindow.instance();
}
}
Object[] availableOptions = new Object[] { FlexoLocalization.localizedForKey("OK"), FlexoLocalization.localizedForKey("cancel") };
JOptionPane pane = new JOptionPane(message, messageType, JOptionPane.OK_CANCEL_OPTION, icon, availableOptions, availableOptions[0]);
pane.setWantsInput(true);
pane.setSelectionValues(selectionValues);
pane.setInitialSelectionValue(initialSelectionValue);
pane.setComponentOrientation((parentComponent == null ? FlexoFrame.getActiveFrame() : parentComponent).getComponentOrientation());
pane.setMessageType(messageType);
JDialog dialog = pane.createDialog(parentComponent, title);
pane.selectInitialValue();
dialog.validate();
dialog.pack();
if (parentComponent == null) {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation((dim.width - dialog.getSize().width) / 2, (dim.height - dialog.getSize().height) / 2);
}
dialog.setVisible(true);
dialog.dispose();
Object val = pane.getValue();
for (int counter = 0, maxCounter = availableOptions.length; counter < maxCounter; counter++) {
if (availableOptions[counter].equals(val)) {
if (counter == 1) {
return null;
}
}
}
Object value = pane.getInputValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return null;
}
return value;
}
public void switchToPerspective(FlexoPerspective perspective) {
controllerModel.setCurrentPerspective(perspective);
}
/**
* Return current displayed object, assuming that current displayed view represents returned object (for example the process for WKF
* module)
*
* @return the FlexoModelObject
*/
public FlexoModelObject getCurrentDisplayedObjectAsModuleView() {
// logger.info("getCurrentModuleView()="+getCurrentModuleView());
if (getCurrentModuleView() != null) {
return getCurrentModuleView().getRepresentedObject();
}
return null;
}
public ModuleView<?> moduleViewForLocation(Location location, boolean createViewIfRequired) {
if (location == null) {
return null;
}
if (location.getObject() == null) {
return null;
}
if (location.getPerspective() == null) {
return null;
}
if (location.getEditor() == null) {
return null;
}
ModuleView<?> moduleView = viewsForLocation.get(location);
if (moduleView == null) {
moduleView = lookupViewForLocation(location);
if (createViewIfRequired && location.getPerspective().hasModuleViewForObject(location.getObject())) {
moduleView = createModuleViewForObjectAndPerspective(location.getObject(), location.getPerspective(), location.isEditable());
if (moduleView != null) {
FlexoModelObject representedObject = moduleView.getRepresentedObject();
if (representedObject == null) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Module view: " + moduleView.getClass().getName() + " does not return its represented object");
}
representedObject = location.getObject();
}
manager.new PropertyChangeListenerRegistration(representedObject.getDeletedProperty(), this, representedObject);
if (representedObject.getProject() != null
&& !manager.hasListener(ProjectClosedNotification.CLOSE, this, representedObject.getProject())) {
manager.new PropertyChangeListenerRegistration(ProjectClosedNotification.CLOSE, this,
representedObject.getProject());
}
viewsForLocation.put(location, moduleView);
locationsForView.put(moduleView, location);
}
}
}
return moduleView;
}
private ModuleView<?> lookupViewForLocation(Location location) {
for (Entry<Location, ModuleView<?>> e : viewsForLocation.entrySet()) {
Location l = e.getKey();
if (l.getObject().equals(location.getObject()) && l.getPerspective().equals(location.getPerspective())
&& l.isEditable() == location.isEditable()) {
return e.getValue();
}
}
return null;
}
/**
* Returns an initialized view (build and initialize a new one, or return the stored one) representing supplied object. An additional
* flag indicates if this view must be build if not already existent.
*
* @param object
* @param createViewIfRequired
* @return an initialized ModuleView instance
*/
public ModuleView<?> moduleViewForObject(FlexoModelObject object, boolean createViewIfRequired) {
return moduleViewForLocation(new Location(controllerModel.getCurrentEditor(), object, getCurrentPerspective()),
createViewIfRequired);
}
/**
* Returns an initialized view (build and initialize a new one, or return the stored one) representing supplied object.If not already
* existent, build the view.
*
* @param object
* @return an initialized ModuleView instance
*/
public ModuleView<?> moduleViewForObject(FlexoModelObject object) {
return moduleViewForObject(object, true);
}
/**
* Creates a new view for supplied object, or null if this object is not representable in this module
*
* @param object
* @param perspective
* TODO
* @return a newly created and initialized ModuleView instance
*/
private ModuleView<?> createModuleViewForObjectAndPerspective(FlexoModelObject object, FlexoPerspective perspective, boolean editable) {
if (perspective == null) {
return null;
} else {
if (logger.isLoggable(Level.INFO)) {
logger.info("Creating module view for " + object + " in perspective " + perspective.getName()
+ (editable ? " (editable)" : " (read-only)"));
}
return perspective.createModuleViewForObject(object, this, editable);
}
}
public boolean isEditable(Object object) {
if (isDisposed()) {
return false;
}
return !getModule().getModule().requireProject() || !(object instanceof FlexoModelObject)
|| ((FlexoModelObject) object).getProject() == getProject();
}
/**
* Sets supplied object to be the main object represented as the current view for this module (for example the process for WKF module).
* Does nothing if supplied object is not representable in this module
*
* @param object
* @return an initialized ModuleView instance
*/
@Deprecated
public final void setObjectAsModuleView(Object object) {
// This hack is introduced to support double click in imported workflow tree.
// This should be removed and imported wofklow tree should be updated to support casting
if (object instanceof FlexoModelObject) {
setCurrentEditedObjectAsModuleView((FlexoModelObject) object);
}
}
/**
* Sets supplied object to be the main object represented as the current view for this module (for example the process for WKF module).
* Does nothing if supplied object is not representable in this module
*
* @param object
* @return an initialized ModuleView instance
*/
public void setCurrentEditedObjectAsModuleView(FlexoModelObject object) {
getControllerModel().setCurrentObject(object);
}
/**
* Sets supplied object to be the main object represented as the current view for this module (for example the process for WKF module)
* and supplied perspective. Does nothing if supplied object is not representable in this module
*
* @param object
* @return an initialized ModuleView instance
*/
public void setCurrentEditedObjectAsModuleView(FlexoModelObject object, FlexoPerspective perspective) {
controllerModel.setCurrentPerspective(perspective);
controllerModel.setCurrentObject(object);
}
public void addToPerspectives(FlexoPerspective perspective) {
controllerModel.addToPerspectives(perspective);
}
/**
* Return currently displayed ModuleView
*
* @return
*/
public ModuleView<?> getCurrentModuleView() {
if (mainPane != null) {
return mainPane.getModuleView();
}
return null;
}
/**
* Returns MainPane for this module
*
* @return a FlexoMainPane instance
*/
public FlexoMainPane getMainPane() {
return mainPane;
}
public boolean hasMainPane() {
return mainPane != null;
}
/**
* Creates FlexoMainPane instance for this module.
*
* @return a newly created FlexoMainPane instance
*/
protected abstract FlexoMainPane createMainPane();
/*********
* VIEWS *
*********/
/**
* Handle removing of supplied ModuleView from the control panel
*
* @param aView
* the view to remove
*/
public void removeModuleView(ModuleView<?> aView) {
Collection<Location> locations = locationsForView.get(aView);
if (locations != null) {
for (Location location : locations) {
viewsForLocation.remove(location);
}
}
locationsForView.removeAll(aView);
}
/**
* Returns all the views currently loaded.
*
* @return all the views currently loaded.
*/
protected Collection<ModuleView<?>> getViews() {
return viewsForLocation.values();
}
@SuppressWarnings("unchecked")
protected <T extends ModuleView<?>> Collection<T> getViews(final Class<T> klass) {
return (Collection<T>) Collections2.filter(viewsForLocation.values(), new Predicate<ModuleView<?>>() {
@Override
public boolean apply(ModuleView<?> input) {
return klass.isAssignableFrom(input.getClass());
};
});
}
/**
* Shows control panel
*/
public void showControlPanel() {
if (mainPane != null) {
mainPane.showControlPanel();
}
}
/**
* Hides control panel
*/
public void hideControlPanel() {
if (mainPane != null) {
mainPane.hideControlPanel();
}
}
public void updateRecentProjectMenu() {
if (menuBar != null) {
menuBar.getFileMenu(this).updateRecentProjectMenu();
}
}
/**
* Returns a custom component to be added to control panel in main pane Default implementation returns null, override it when required
*
* @return
*/
public final JComponent getCustomActionPanel() {
return null;
}
public abstract String getWindowTitleforObject(FlexoModelObject object);
public String getWindowTitle() {
String projectTitle = getModule().getModule().requireProject() && getProject() != null ? " - " + getProject().getProjectName()
+ " - " + getProjectDirectory().getAbsolutePath() : "";
if (getCurrentModuleView() != null) {
return getModule().getName() + " : " + getWindowTitleforObject(getCurrentDisplayedObjectAsModuleView()) + projectTitle;
} else {
if (getModule() == null) {
return FlexoCst.BUSINESS_APPLICATION_VERSION_NAME + projectTitle;
} else {
return FlexoCst.BUSINESS_APPLICATION_VERSION_NAME + " - " + getModule().getName() + projectTitle;
}
}
}
public void cancelCurrentAction() {
if (logger.isLoggable(Level.INFO)) {
logger.info("Escape was pressed but the current controller does not do anything about it");
}
}
public class FlexoControllerInspectorDelegate implements InspectorDelegate {
private KeyValueCoding target;
private String key;
private String localizedPropertyName;
/**
* Overrides setObjectValue
*
* @see org.openflexo.inspector.InspectorDelegate#setObjectValue(java.lang.Object)
*/
@Override
public boolean setObjectValue(Object value) {
if (target != null) {
if (target instanceof FlexoModelObject) {
SetPropertyAction action = SetPropertyAction.actionType.makeNewAction((FlexoModelObject) target,
new Vector<FlexoModelObject>(), getEditor());
action.setKey(key);
action.setValue(value);
action.setLocalizedPropertyName(localizedPropertyName);
action.doAction();
return action.hasActionExecutionSucceeded() && action.getThrownException() == null;
} else if (target != null) {
target.setObjectForKey(value, key);
} else {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("Target object is not a FlexoModelObject, I cannot set the value for that object");
}
}
} else if (logger.isLoggable(Level.WARNING)) {
logger.warning("Target object is null for key " + key + ". We should definitely investigate this.");
}
return false;
}
/**
* Overrides handlesObjectOfClass
*
* @see org.openflexo.inspector.InspectorDelegate#handlesObjectOfClass(java.lang.Class)
*/
@Override
public boolean handlesObjectOfClass(Class<?> c) {
return KeyValueCoding.class.isAssignableFrom(c);
}
/**
* Overrides setKey
*
* @see org.openflexo.inspector.InspectorDelegate#setKey(java.lang.String)
*/
@Override
public void setKey(String path) {
this.key = path;
}
/**
* Overrides setObject
*
* @see org.openflexo.inspector.InspectorDelegate#setObject(org.openflexo.inspector.InspectableObject)
*/
@Override
public void setTarget(KeyValueCoding object) {
this.target = object;
}
/**
* Overrides performAction
*
* @see org.openflexo.inspector.InspectorDelegate#performAction(java.lang.String, java.lang.Object)
*/
@Override
public boolean performAction(ActionEvent e, String actionName, Object object) {
if (object instanceof FlexoModelObject) {
FlexoModelObject m = (FlexoModelObject) object;
for (FlexoActionType<?, ?, ?> actionType : m.getActionList()) {
if (actionType.getUnlocalizedName().equals(actionName)) {
return getEditor().performActionType((FlexoActionType<?, FlexoModelObject, FlexoModelObject>) actionType, m,
(Vector<FlexoModelObject>) null, e).hasActionExecutionSucceeded();
}
}
}
return false;
}
/**
* Overrides setLocalizedPropertyName
*
* @see org.openflexo.inspector.InspectorDelegate#setLocalizedPropertyName(java.lang.String)
*/
@Override
public void setLocalizedPropertyName(String name) {
localizedPropertyName = name;
}
}
public boolean isDisposed() {
return disposed;
}
public void dispose() {
if (getSelectionManager() != null) {
if (getSharedInspectorController() != null) {
getSelectionManager().deleteObserver(getSharedInspectorController());
}
if (getDocInspectorController() != null) {
getSelectionManager().deleteObserver(getDocInspectorController());
}
}
manager.delete();
GeneralPreferences.getPreferences().deleteObserver(this);
mainPane.dispose();
if (consistencyCheckWindow != null && !consistencyCheckWindow.isDisposed()) {
consistencyCheckWindow.dispose();
}
if (useOldInspectorScheme()) {
getSharedInspectorController().getInspectorWindow().dispose();
}
if (mainInspectorController != null) {
mainInspectorController.delete();
}
for (ModuleView<?> view : new ArrayList<ModuleView<?>>(getViews())) {
try {
view.deleteModuleView();
} catch (Exception e) {
e.printStackTrace();
}
}
if (rmWindow != null) {
rmWindow.dispose();
rmWindow = null;
}
registeredMenuBar.clear();
if (PreferencesController.hasInstance()) {
PreferencesController.instance().getPreferencesWindow().setVisible(false);
}
if (flexoFrame != null) {
flexoFrame.disposeAll();
}
if (menuBar != null) {
menuBar.dispose();
}
if (getEditor() instanceof InteractiveFlexoEditor) {
((InteractiveFlexoEditor) getEditor()).unregisterControllerActionInitializer(getControllerActionInitializer());
}
controllerModel.delete();
viewsForLocation.clear();
locationsForView.clear();
disposed = true;
if (propertyChangeSupport != null) {
propertyChangeSupport.firePropertyChange(DISPOSED, false, true);
}
setEditor(null);
propertyChangeSupport = null;
inspectorMenuBar = null;
docInspectorController = null;
consistencyCheckWindow = null;
flexoFrame = null;
mainPane = null;
menuBar = null;
module = null;
}
@Override
protected void finalize() throws Throwable {
if (logger.isLoggable(Level.INFO)) {
logger.info("Finalizing controller " + getClass().getSimpleName());
}
super.finalize();
}
public PPMWebServiceClient getWSClient() {
return getWSClient(false);
}
public PPMWebServiceClient getWSClient(boolean forceDialog) {
ModelFactory factory;
try {
factory = new ModelFactory(PPMWSClientParameter.class);
} catch (ModelDefinitionException e) {
e.printStackTrace();
throw new Error("Improperly configured PPMWSClientParameter. ", e);
}
FlexoServerInstance instance = FlexoServerInstanceManager.getInstance().getAddressBook()
.getInstanceWithID(AdvancedPrefs.getWebServiceInstance());
PPMWSClientParameter params = factory.newInstance(PPMWSClientParameter.class);
params.setWSInstance(instance);
params.setWSLogin(AdvancedPrefs.getWebServiceLogin());
params.setWSPassword(AdvancedPrefs.getWebServiceMd5Password());
params.setWSURL(AdvancedPrefs.getWebServiceUrl());
params.setRemember(AdvancedPrefs.getRememberAndDontAskWebServiceParamsAnymore());
if (params.getWSInstance() != null && !params.getWSInstance().getID().equals(FlexoServerInstance.OTHER_ID)) {
params.setWSURL(params.getWSInstance().getWSURL());
}
String oldMD5Password = params.getWSPassword();
if (forceDialog || !params.getRemember() || params.getWSURL() == null || params.getWSLogin() == null
|| params.getWSPassword() == null || !isWSUrlValid(params.getWSURL()) || urlSeemsIncorrect(params.getWSURL())) {
WebServiceURLDialog data = new WebServiceURLDialog();
data.setClientParameter(params);
FIBDialog<WebServiceURLDialog> dialog = FIBDialog.instanciateAndShowDialog(WebServiceURLDialog.FIB_FILE, data, getFlexoFrame(),
true, FlexoLocalization.getMainLocalizer());
if (dialog.getStatus() == Status.VALIDATED) {
if (params.getWSInstance() != null && !params.getWSInstance().getID().equals(FlexoServerInstance.OTHER_ID)) {
params.setWSURL(params.getWSInstance().getWSURL());
}
try {
String password = params.getWSPassword();
if (oldMD5Password == null || !oldMD5Password.equals(password)) {
params.setWSPassword(ToolBox.getMd5Hash(params.getWSPassword()));
}
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
FlexoController.notify(e1.getMessage());
AdvancedPrefs.setRememberAndDontAskWebServiceParamsAnymore(false);
AdvancedPrefs.save();
return null;
}
if (params.getWSInstance() != null) {
AdvancedPrefs.setWebServiceInstance(params.getWSInstance().getID());
}
if (params.getWSURL() != null) {
AdvancedPrefs.setWebServiceUrl(params.getWSURL());
}
if (params.getWSLogin() != null) {
AdvancedPrefs.setWebServiceLogin(params.getWSLogin());
}
if (params.getWSPassword() != null) {
AdvancedPrefs.setWebServiceMd5Password(params.getWSPassword());
}
AdvancedPrefs.setRememberAndDontAskWebServiceParamsAnymore(params.getRemember());
AdvancedPrefs.save();
} else {
return null;
}
}
// now that we have the parameters. We have to invoke the WS
PPMWebServiceClient client = null;
try {
client = new PPMWebServiceClient(params.getWSURL(), params.getWSLogin(), params.getWSPassword());
} catch (ServiceException e1) {
e1.printStackTrace();
FlexoController.notify(e1.getMessage());
AdvancedPrefs.setRememberAndDontAskWebServiceParamsAnymore(false);
AdvancedPrefs.save();
return null;
}
return client;
}
public void handleWSException(RemoteException e) {
if (e.getCause() instanceof TooManyFailedAttemptException) {
throw (TooManyFailedAttemptException) e.getCause();
}
if (e.getCause() instanceof CancelException) {
throw (CancelException) e.getCause();
}
if (logger.isLoggable(Level.SEVERE)) {
logger.log(Level.SEVERE, "An error ocurred " + (e.getMessage() == null ? "no message" : e.getMessage()), e);
}
if (e.getMessage() != null && e.getMessage().startsWith("redirect")) {
String location = null;
if (e.getMessage().indexOf("Location") > -1) {
location = e.getMessage().substring(e.getMessage().indexOf("Location") + 9).trim();
}
FlexoController.notify(FlexoLocalization.localizedForKey("could_not_connect_to_web_sevice") + ": "
+ FlexoLocalization.localizedForKey("the_url_seems_incorrect")
+ (location != null ? "\n" + FlexoLocalization.localizedForKey("try_with_this_one") + " " + location : ""));
return;
}
if (e instanceof PPMWebServiceAuthentificationException) {
handleWSException((PPMWebServiceAuthentificationException) e);
} else if (e.getCause() instanceof ConnectException) {
FlexoController.notify(FlexoLocalization.localizedForKey("connection_error")
+ (e.getCause().getMessage() != null ? " (" + e.getCause().getMessage() + ")" : ""));
} else if (e.getMessage() != null && "(500)Apple WebObjects".equals(e.getMessage())
|| e.getMessage().startsWith("No such operation")) {
FlexoController.notify(FlexoLocalization.localizedForKey("could_not_connect_to_web_sevice") + ": "
+ FlexoLocalization.localizedForKey("the_url_seems_incorrect"));
} else if (e.toString() != null && e.toString().startsWith("javax.net.ssl.SSLHandshakeException")) {
FlexoController.notify(FlexoLocalization.localizedForKey("connection_error") + ": " + e);
} else if (e.detail instanceof SocketTimeoutException) {
FlexoController.notify(FlexoLocalization.localizedForKey("connection_timeout"));
} else if (e.detail instanceof IOException || e.getCause() instanceof IOException) {
IOException ioEx = (IOException) (e.detail instanceof IOException ? e.detail : e.getCause());
FlexoController.notify(FlexoLocalization.localizedForKey("connection_error") + ": "
+ FlexoLocalization.localizedForKey(ioEx.getClass().getSimpleName()) + " " + ioEx.getMessage());
} else {
if (e.getMessage() != null && e.getMessage().indexOf("Content is not allowed in prolog") > -1) {
FlexoController
.notify("Check your connection url in FlexoPreferences > Advanced.\n It seems wrong.\nsee logs for details.");
} else {
FlexoController
.notify(FlexoLocalization.localizedForKey("webservice_remote_error")
+ " \n"
+ (e.getMessage() == null || "java.lang.NullPointerException".equals(e.getMessage()) ? "Check your connection parameters.\nThe service may be temporary unavailable."
: e.getMessage()));
}
}
}
public void handleWSException(ServiceException e) {
FlexoController.notify(FlexoLocalization.localizedForKey("webservice_connection_failed"));
}
public void handleWSException(PPMWebServiceAuthentificationException e) {
FlexoController.notify(FlexoLocalization.localizedForKey("webservice_authentification_failed") + ": "
+ FlexoLocalization.localizedForKey(e.getMessage1()));
}
private boolean isWSUrlValid(final String wsURL) {
return wsURL != null
&& (wsURL.toLowerCase().startsWith("http://") && wsURL.charAt(7) != '/' || wsURL.toLowerCase().startsWith("https://")
&& wsURL.charAt(8) != '/');
}
private boolean urlSeemsIncorrect(String wsURL) {
try {
URL url = new URL(wsURL);
// Bug 1007330 Fix
return url.getAuthority() == null;
} catch (MalformedURLException e) {
return true;
}
}
public void objectWasClicked(FlexoModelObject object) {
logger.info("Object was clicked: " + object);
}
public void objectWasRightClicked(FlexoModelObject object, MouseEvent e) {
logger.info("Object was right-clicked: " + object + "event=" + e);
getSelectionManager().getContextualMenuManager().showPopupMenuForObject(object, (Component) e.getSource(), e.getPoint());
}
public void objectWasDoubleClicked(FlexoModelObject object) {
logger.info("Object was double-clicked: " + object);
if (getCurrentPerspective().hasModuleViewForObject(object)) {
// Try to display object in view
selectAndFocusObject(object);
}
}
public boolean displayInspectorTabForContext(String context) {
// logger.info("Enquiring inspector tab display for context=" + context + "... Answering NO");
return false;
}
public FlexoProgress willLoad(File fibFile) {
if (!FIBLibrary.instance().componentIsLoaded(fibFile)) {
FlexoProgress progress = ProgressWindow.makeProgressWindow(FlexoLocalization.localizedForKey("loading_interface..."), 3);
progress.setProgress("loading_component");
FIBLibrary.instance().retrieveFIBComponent(fibFile);
progress.setProgress("build_interface");
return progress;
}
return null;
}
public FlexoProgress willLoad(String fibResourcePath) {
if (!FIBLibrary.instance().componentIsLoaded(fibResourcePath)) {
FlexoProgress progress = ProgressWindow.makeProgressWindow(FlexoLocalization.localizedForKey("loading_interface..."), 3);
progress.setProgress("loading_component");
FIBLibrary.instance().retrieveFIBComponent(fibResourcePath);
progress.setProgress("build_interface");
return progress;
}
return null;
}
@Override
public void update(FlexoObservable observable, DataModification dataModification) {
if (observable == GeneralPreferences.getPreferences()) {
if (dataModification instanceof PreferencesHaveChanged) {
String key = ((PreferencesHaveChanged) dataModification).propertyName();
if (GeneralPreferences.LANGUAGE_KEY.equals(key)) {
getFlexoFrame().updateTitle();
} else if (GeneralPreferences.LAST_OPENED_PROJECTS_1.equals(key) || GeneralPreferences.LAST_OPENED_PROJECTS_2.equals(key)
|| GeneralPreferences.LAST_OPENED_PROJECTS_3.equals(key) || GeneralPreferences.LAST_OPENED_PROJECTS_4.equals(key)
|| GeneralPreferences.LAST_OPENED_PROJECTS_5.equals(key)) {
updateRecentProjectMenu();
}
}
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getSource() == getControllerModel()) {
if (evt.getPropertyName().equals(ControllerModel.CURRENT_EDITOR)) {
FlexoEditor oldEditor = (FlexoEditor) evt.getOldValue();
FlexoEditor newEditor = (FlexoEditor) evt.getNewValue();
if (oldEditor != null || newEditor != null) {
updateEditor(oldEditor, newEditor);
}
} else if (evt.getPropertyName().equals(ControllerModel.LOCATIONS)) {
if (evt.getOldValue() != null) {
Location location = (Location) evt.getOldValue();
ModuleView<?> moduleViewForLocation = moduleViewForLocation(location, false);
if (moduleViewForLocation != null) {
if (locationsForView.get(moduleViewForLocation).size() < 2) {
moduleViewForLocation.deleteModuleView();
} else {
locationsForView.remove(moduleViewForLocation, location);
}
}
}
} else if (evt.getPropertyName().equals(ControllerModel.CURRENT_OBJECT)) {
getSelectionManager().setSelectedObject(getControllerModel().getCurrentObject());
}
} else if (evt.getSource() instanceof FlexoProject && evt.getPropertyName().equals(ProjectClosedNotification.CLOSE)) {
FlexoProject project = (FlexoProject) evt.getSource();
for (ModuleView<?> view : new ArrayList<ModuleView>(getViews())) {
if (project.equals(view.getRepresentedObject().getProject())) {
view.deleteModuleView();
}
}
manager.removeListener(ProjectClosedNotification.CLOSE, this, project);
}
}
public ResourceManagerWindow getRMWindow(FlexoProject project) {
if (rmWindow != null) {
if (rmWindow.getProject() == project) {
return rmWindow;
}
rmWindow.dispose();
}
return rmWindow = new ResourceManagerWindow(project);
}
public void selectAndFocusObject(FlexoModelObject object) {
if (object instanceof FlexoProject) {
getControllerModel().setCurrentProject((FlexoProject) object);
} else {
setCurrentEditedObjectAsModuleView(object);
}
}
public ValidationModel getDefaultValidationModel() {
return null;
}
public final FlexoPerspective getCurrentPerspective() {
return getControllerModel().getCurrentPerspective();
}
public final FlexoEditor getEditor() {
return getControllerModel().getCurrentEditor();
}
public ImageIcon iconForObject(Object object) {
ImageIcon iconForObject = statelessIconForObject(object);
if (iconForObject != null) {
if (getModule().getModule().requireProject() && object instanceof FlexoModelObject && getProject() != null
&& ((FlexoModelObject) object).getProject() != getProject() && ((FlexoModelObject) object).getProject() != null
&& (!(object instanceof FlexoProject) || !getProjectLoader().getRootProjects().contains(object))) {
iconForObject = IconFactory.getImageIcon(iconForObject, new IconMarker[] { IconLibrary.IMPORT });
} else if (object instanceof FlexoProjectReference) {
iconForObject = IconFactory.getImageIcon(iconForObject, new IconMarker[] { IconLibrary.IMPORT });
} else if (object instanceof WorkflowModelObject && ((WorkflowModelObject) object).getWorkflow().isCache()) {
iconForObject = IconFactory.getImageIcon(iconForObject, new IconMarker[] { IconLibrary.IMPORT });
}
}
return iconForObject;
}
public ImageIcon iconForWorkflow(boolean imported) {
if (imported) {
return WKFIconLibrary.IMPORTED_PROCESS_LIBRARY_ICON;
} else {
return WKFIconLibrary.WORKFLOW_ICON;
}
}
public static ImageIcon statelessIconForObject(Object object) {
if (object instanceof WorkflowModelObject) {
return WKFIconLibrary.iconForObject((WorkflowModelObject) object);
} else if (object instanceof WKFObject) {
return WKFIconLibrary.iconForObject((WKFObject) object);
} else if (object instanceof IEObject) {
return SEIconLibrary.iconForObject((IEObject) object);
} else if (object instanceof DKVObject) {
return SEIconLibrary.iconForObject((DKVObject) object);
} else if (object instanceof DMObject) {
return DMEIconLibrary.iconForObject((DMObject) object);
} else if (object instanceof ViewPointLibraryObject) {
return VPMIconLibrary.iconForObject((ViewPointLibraryObject) object);
} else if (object instanceof AbstractViewObject) {
return VEIconLibrary.iconForObject((AbstractViewObject) object);
} else if (object instanceof OntologyLibrary) {
return OntologyIconLibrary.ONTOLOGY_LIBRARY_ICON;
} else if (object instanceof OntologyFolder) {
return IconLibrary.FOLDER_ICON;
} else if (object instanceof AbstractOntologyObject) {
return OntologyIconLibrary.iconForObject((AbstractOntologyObject) object);
} else if (object instanceof TOCObject) {
return DEIconLibrary.iconForObject((TOCObject) object);
} else if (object instanceof CGFile) {
return FilesIconLibrary.smallIconForFileFormat(((CGFile) object).getFileFormat());
} else if (object instanceof CGTemplateObject) {
return DGIconLibrary.iconForObject((CGTemplateObject) object);
} else if (object instanceof DocType) {
return CGIconLibrary.TARGET_ICON;
} else if (object instanceof FlexoProject) {
return IconLibrary.OPENFLEXO_NOTEXT_16;
} else if (object instanceof FlexoProjectReference) {
return WKFIconLibrary.OPENFLEXO_NOTEXT_16;
} else if (object instanceof GeneratedDoc) {
return DGIconLibrary.GENERATED_DOC_ICON;
} else if (object instanceof GeneratedCode) {
return CGIconLibrary.GENERATED_CODE_ICON;
} else if (object instanceof GenerationRepository) {
return CGIconLibrary.GENERATED_CODE_REPOSITORY_ICON;
}
logger.warning("Sorry, no icon defined for " + object + " " + (object != null ? object.getClass() : ""));
return null;
}
}