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 }