001    /******************************************************************************
002     * Copyright (C) MActor Developers. All rights reserved.                        *
003     * ---------------------------------------------------------------------------*
004     * This file is part of MActor.                                               *
005     *                                                                            *
006     * MActor is free software; you can redistribute it and/or modify             *
007     * it under the terms of the GNU General Public License as published by       *
008     * the Free Software Foundation; either version 2 of the License, or          *
009     * (at your option) any later version.                                        *
010     *                                                                            *
011     * MActor is distributed in the hope that it will be useful,                  *
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
014     * GNU General Public License for more details.                               *
015     *                                                                            *
016     * You should have received a copy of the GNU General Public License          *
017     * along with MActor; if not, write to the Free Software                      *
018     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *
019     ******************************************************************************/
020    package org.mactor.ui.gui;
021    
022    import java.awt.event.ActionEvent;
023    import java.net.URL;
024    import java.util.HashMap;
025    import java.util.Iterator;
026    import java.util.LinkedList;
027    import java.util.List;
028    import java.util.Map;
029    
030    import javax.swing.AbstractAction;
031    import javax.swing.Action;
032    import javax.swing.JOptionPane;
033    import javax.swing.event.TreeSelectionEvent;
034    import javax.swing.event.TreeSelectionListener;
035    import javax.swing.tree.TreePath;
036    
037    import org.dom4j.Document;
038    import org.dom4j.Element;
039    import org.dom4j.io.SAXReader;
040    import org.mactor.framework.MactorException;
041    import org.mactor.ui.gui.project.GuiAction;
042    import org.mactor.ui.gui.project.ProjectController;
043    import org.mactor.ui.gui.project.ProjectTree;
044    import org.mactor.ui.gui.project.ProjectTreeNode;
045    
046    public class ActionsManager {
047            private ProjectTreeNode selectedNode;
048            private ProjectTree tree;
049            private ProjectController projectController;
050            private Map<String, ProjectActionInvoker> actions = new HashMap<String, ProjectActionInvoker>();
051            public ActionsManager(ProjectController projectController, ProjectTree tree) throws MactorException {
052                    this.tree = tree;
053                    this.projectController = projectController;
054                    try {
055                            loadActionsDefs("project_actions.xml");
056                    } catch (Exception e) {
057                            throw new MactorException(e);
058                    }
059                    try {
060                            loadActionsDefs("project_actions_ex.xml");
061                            System.out.println("project_actions_ex.xml was loaded");
062                    } catch (Exception e) {
063                            System.out.println("project_actions_ex.xml was not loaded. Reason:" + e.getMessage());
064                    }
065            }
066            private void loadActionsDefs(String resource) throws Exception {
067                    URL u = Thread.currentThread().getContextClassLoader().getResource(resource);
068                    if (u == null)
069                            throw new RuntimeException("Resource '" + resource + "' was not found");
070                    Document doc = null;
071                    doc = new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(resource));
072                    Iterator it = doc.getRootElement().elementIterator("action");
073                    while (it.hasNext()) {
074                            Element e = (Element) it.next();
075                            ProjectActionInvoker invoker = createAction(e.attributeValue("name"), e.attributeValue("class"), Boolean.parseBoolean(e.attributeValue("confirm")), getParams(e));
076                            actions.put(invoker.getName(), invoker);
077                    }
078            }
079            public Action getAction(String action) {
080                    Action a = actions.get(action);
081                    if (a == null)
082                            System.out.println("action '" + action + "' not found");
083                    return a;
084            }
085            private String[] getParams(Element e) {
086                    List<String> tmp = new LinkedList<String>();
087                    Iterator it = e.elementIterator("param");
088                    while (it.hasNext())
089                            tmp.add(((Element) it.next()).getText());
090                    return (String[]) tmp.toArray(new String[tmp.size()]);
091            }
092            private ProjectActionInvoker createAction(String name, String actionClass, boolean confirm, String[] params) throws MactorException {
093                    try {
094                            GuiAction action = (GuiAction) Class.forName(actionClass).newInstance();
095                            ProjectActionInvoker pa = new ProjectActionInvoker(name, confirm, action, params);
096                            return pa;
097                    } catch (Exception e) {
098                            e.printStackTrace();
099                            throw new MactorException("Unable to create instance of specifed action '" + actionClass + "'", e);
100                    }
101            }
102            private class ProjectActionInvoker extends AbstractAction {
103                    final private GuiAction action;
104                    final private String[] parameters;
105                    final private boolean confirm;
106                    final private String name;
107                    public ProjectActionInvoker(String name, boolean confirm, GuiAction action, String[] params) {
108                            super(name);
109                            this.action = action;
110                            this.parameters = params;
111                            this.name = name;
112                            this.confirm = confirm;
113                            tree.addTreeSelectionListener(new TreeSelectionListener() {
114                                    public void valueChanged(TreeSelectionEvent e) {
115                                            TreePath treePath = e.getNewLeadSelectionPath();
116                                            if (treePath == null || treePath.getPathCount() == 0)
117                                                    selectedNode = null;
118                                            else
119                                                    selectedNode = (ProjectTreeNode) treePath.getLastPathComponent();
120                                            boolean p = ProjectActionInvoker.this.action.isPermitted(selectedNode, projectController, parameters);
121                                            setEnabled(p);
122                                    }
123                            });
124                            setEnabled(action.isPermitted(selectedNode, projectController, parameters));
125                    }
126                    public String getName() {
127                            return name;
128                    }
129                    public void actionPerformed(ActionEvent event) {
130                            if (confirm) {
131                                    if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(tree.getParent(), "Are you sure you want to perfom '" + getName() + "' on the selected node?"))
132                                            return;
133                            }
134                            try {
135                                    action.perform(getSelectedTreeNode(), projectController, parameters);
136                            } catch (MactorException me) {
137                                    GuiUtil.showGuiError(projectController.getControllerFrame(), me);
138                            }
139                    }
140                    private ProjectTreeNode getSelectedTreeNode() {
141                            TreePath p = tree.getSelectionPath();
142                            if (p == null || p.getPathCount() == 0)
143                                    return null;
144                            return (ProjectTreeNode) p.getLastPathComponent();
145                    }
146            }
147    }