/*FreeMind - A Program for creating and viewing Mindmaps *Copyright (C) 2000-2004 Joerg Mueller, Daniel Polansky, Christian Foltin and others. * *See COPYING for Details * *This program 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 2 *of the License, or (at your option) any later version. * *This program 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 this program; if not, write to the Free Software *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Created on 24.04.2004 */ package freemind.modes.mindmapmode.actions.xml; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; import freemind.controller.Controller; import freemind.controller.actions.generated.instance.XmlAction; import freemind.modes.mindmapmode.actions.xml.ActionFilter.FinalActionFilter; import freemind.modes.mindmapmode.actions.xml.ActionFilter.FirstActionFilter; /** * @author foltin * */ public class ActionFactory { private Controller controller; /** * This Vector denotes all handler of the action to be called for each * action. */ private Vector registeredHandler; /** This set denotes all filters for XmlActions. */ private Vector registeredFilters; /** HashMap of Action class -> actor instance. */ private HashMap registeredActors; private UndoActionHandler undoActionHandler; private static java.util.logging.Logger logger = null; /** * */ public ActionFactory(Controller c) { super(); this.controller = c; if (logger == null) { logger = freemind.main.Resources.getInstance().getLogger( this.getClass().getName()); } registeredHandler = new Vector(); registeredFilters = new Vector(); registeredActors = new HashMap(); } /** * The handler is put in front. Thus it is called before others are called. */ public void registerHandler(ActionHandler newHandler) { // if it is present, put it in front: if (!registeredHandler.contains(newHandler)) { registeredHandler.remove(newHandler); } registeredHandler.add(0, newHandler); } public void deregisterHandler(ActionHandler newHandler) { registeredHandler.remove(newHandler); } public void registerFilter(ActionFilter newFilter) { if (!registeredFilters.contains(newFilter)) { if (newFilter instanceof FinalActionFilter) { /* Insert as the last one here. */ registeredFilters.insertElementAt(newFilter, registeredFilters.size()); } else if (newFilter instanceof FirstActionFilter) { /* Insert as the first one here. */ registeredFilters.insertElementAt(newFilter, 0); } else { /* Insert before FinalActionFilters */ int index = 0; for (Iterator it = registeredFilters.iterator(); it.hasNext();) { ActionFilter filter = (ActionFilter) it.next(); if (filter instanceof FinalActionFilter) { break; } index++; } registeredFilters.insertElementAt(newFilter, index); } } // int count = 0; // for (Iterator it = registeredFilters.iterator(); it.hasNext();) { // ActionFilter filter = (ActionFilter) it.next(); // logger.info("Filter " + count + ": " + filter.getClass().getName()); // count++; // } } public void deregisterFilter(ActionFilter newFilter) { registeredFilters.remove(newFilter); } private void startTransaction(String name) { for (Iterator i = registeredHandler.iterator(); i.hasNext();) { ActionHandler handler = (ActionHandler) i.next(); handler.startTransaction(name); } } private void endTransaction(String name) { for (Iterator i = registeredHandler.iterator(); i.hasNext();) { ActionHandler handler = (ActionHandler) i.next(); handler.endTransaction(name); } } /** * @return see {@link #executeAction(ActionPair)} */ public boolean doTransaction(String pName, ActionPair pPair) { this.startTransaction(pName); boolean result = this.executeAction(pPair); this.endTransaction(pName); return result; } /** * @return the success of the action. If an exception arises, the method * returns false. */ private boolean executeAction(ActionPair pair) { if (pair == null) return false; boolean returnValue = true; // register for undo first, as the filter things are repeated when the // undo is executed as well! if (undoActionHandler != null) { try { undoActionHandler.executeAction(pair); } catch (Exception e) { freemind.main.Resources.getInstance().logException(e); returnValue = false; } } ActionPair filteredPair = pair; // first filter: for (Iterator i = registeredFilters.iterator(); i.hasNext();) { ActionFilter filter = (ActionFilter) i.next(); filteredPair = filter.filterAction(filteredPair); } Object[] aArray = registeredHandler.toArray(); for (int i = 0; i < aArray.length; i++) { ActionHandler handler = (ActionHandler) aArray[i]; try { handler.executeAction(filteredPair.getDoAction()); } catch (Exception e) { freemind.main.Resources.getInstance().logException(e); returnValue = false; // to break or not to break. this is the question here... } } return returnValue; } /** */ public Controller getController() { return controller; } /** */ public void registerActor(ActorXml actor, Class action) { registeredActors.put(action, actor); } /** */ public void deregisterActor(Class action) { registeredActors.remove(action); } public ActorXml getActor(XmlAction action) { for (Iterator i = registeredActors.keySet().iterator(); i.hasNext();) { Class actorClass = (Class) i.next(); if (actorClass.isInstance(action)) { return (ActorXml) registeredActors.get(actorClass); } } // Class actionClass = action.getClass(); // if(registeredActors.containsKey(actionClass)) { // return (ActorXml) registeredActors.get(actionClass); // } throw new IllegalArgumentException("No actor present for xmlaction" + action.getClass()); } public void registerUndoHandler(UndoActionHandler undoActionHandler) { this.undoActionHandler = undoActionHandler; } }