Author: tchemit Date: 2008-07-24 18:19:27 +0000 (Thu, 24 Jul 2008) New Revision: 781 Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactory.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactoryFromProvider.java Removed: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java Log: introduce factory package Deleted: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java 2008-07-24 18:16:34 UTC (rev 780) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java 2008-07-24 18:19:27 UTC (rev 781) @@ -1,395 +0,0 @@ -/* -* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin, -* Tony Chemit -* -* 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. -* ##% */ -package org.codelutin.jaxx.action; - -import jaxx.runtime.JAXXObject; -import jaxx.runtime.swing.JAXXToggleButton; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.codelutin.jaxx.action.initializer.AbstractActionInitializer; -import org.codelutin.jaxx.action.initializer.ActionConfigInitializer; -import org.codelutin.jaxx.action.initializer.ActionInitializer; -import org.codelutin.jaxx.action.initializer.SelectActionConfigInitializer; -import org.codelutin.jaxx.action.initializer.ToggleActionConfigInitializer; - -import javax.swing.AbstractAction; -import javax.swing.AbstractButton; -import javax.swing.Action; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import java.awt.event.ActionEvent; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -/** - * Action factory using the ActionConfig annotations to configure the action. - * <p/> - * The factory is abstract, implements method {@link #init()} to fill the - * dictonary of known action implementations. - * <p/> - * Use after the {@link #loadActions(jaxx.runtime.JAXXObject)} to instanciate - * actions in ui with id equals a known action... - * <p/> - * TODO Finish doc - * - * @author chemit - */ -public abstract class ActionFactory<A extends MyAbstractAction> { - - protected static Log log = LogFactory.getLog(ActionFactory.class); - - /** class of encapsuling action */ - protected Class<A> baseImpl; - - /** dictionary of known actions implementations */ - private Map<String, Class<? extends MyAbstractAction>> impls; - - /** dictionary of instanciated actions */ - private Map<String, MyAbstractAction> cache; - - protected final ActionConfigInitializer actionConfigInitializer; - protected final ToggleActionConfigInitializer toggleActionConfigInitializer; - protected final SelectActionConfigInitializer selectActionConfigInitializer; - - /** - * Method to init the dictionary of knwon action implementations. - * - * @return the dictionary of known action implementations - */ - protected abstract Map<String, Class<? extends MyAbstractAction>> init(); - - protected List<AbstractActionInitializer> registredInitializers; - - - protected ActionFactory(Class<A> baseImpl) { - this.baseImpl = baseImpl; - this.impls = init(); - this.cache = new TreeMap<String, MyAbstractAction>(); - this.registredInitializers = new java.util.ArrayList<AbstractActionInitializer>(); - - this.toggleActionConfigInitializer = registerInitializer(ToggleActionConfigInitializer.class); - this.actionConfigInitializer = registerInitializer(ActionConfigInitializer.class); - this.selectActionConfigInitializer = registerInitializer(SelectActionConfigInitializer.class); - } - - public void resetCache() { - cache.clear(); - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - resetCache(); - impls.clear(); - } - - public MyAbstractAction get(String actionKey) { - return cache.get(actionKey); - } - - public MyAbstractAction[] loadActions(JAXXObject ui) { - if (log.isDebugEnabled()) { - log.debug("for ui " + ui.getClass()); - } - List<MyAbstractAction> result = new ArrayList<MyAbstractAction>(); - for (Map.Entry<String, Class<? extends MyAbstractAction>> entry : implsEntrySet()) { - String actionKey = entry.getKey(); - Object comp = ui.getObjectById(actionKey); - if (comp == null || !(comp instanceof AbstractButton || comp instanceof JComboBox)) { - // nothing to do - continue; - } - if (log.isTraceEnabled()) { - log.trace("detect action " + actionKey); - } - if (comp instanceof AbstractButton) { - AbstractButton component = (AbstractButton) comp; - MyAbstractAction action = newAction(actionKey, component); - - component.setAction(action); - - if (component instanceof JAXXToggleButton) { - JAXXToggleButton glueComponent = (JAXXToggleButton) component; - glueComponent.setIcon((Icon) action.getValue(Action.SMALL_ICON)); - Integer integer = (Integer) action.getValue(Action.MNEMONIC_KEY); - if (integer != null) { - glueComponent.setNormalMnemonic(integer); - } - glueComponent.setSelectedIcon((Icon) action.getValue(Action.SMALL_ICON + 2)); - integer = (Integer) action.getValue(Action.MNEMONIC_KEY + 2); - if (integer != null) { - glueComponent.setGlueMnemonic(integer); - } - glueComponent.setGlueText((String) action.getValue(Action.NAME + 2)); - glueComponent.setGlueTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION + 2)); - - glueComponent.setNormalText((String) action.getValue(Action.NAME)); - glueComponent.setNormalTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION)); - } - - Boolean value = (Boolean) action.getValue("hideActionText"); - component.setHideActionText(value != null && value); - action.setEnabled(true); - result.add(action); - continue; - } - // is JComboBox - JComboBox component = (JComboBox) comp; - MyAbstractAction action = newAction(actionKey, component); - - component.setAction(action); - Integer val = (Integer) action.getValue("selectedIndex"); - if (val != null && val != -1 && val < component.getItemCount() && val != component.getSelectedIndex()) { - component.setSelectedIndex(val); - } - result.add(action); - } - return result.toArray(new MyAbstractAction[result.size()]); - } - - public static ImageIcon createImageIcon(String path) { - java.net.URL imgURL = org.codelutin.jaxx.action.ActionFactory.class.getResource("/icons/" + path); - if (imgURL != null) { - return new ImageIcon(imgURL); - } else { - throw new RuntimeException("could not find icon " + path); - } - } - - /** - * @param actionKey le nom de l'action tel que d�finie dans le fichier - * de mapping (sans le prefix action.) - * @param component le button o� rattacher l'action - * @return une nouvelle instance de l'action associ�e � sa clef. - */ - public MyAbstractAction newAction(String actionKey, JComponent component) { - // try first in cache - MyAbstractAction result = getActionFromCache(actionKey); - if (result != null) { - return result; - } - - try { - result = newActionInstance(actionKey); - } catch (Exception e) { - throw new RuntimeException(e); - } - - if (log.isDebugEnabled()) { - log.debug("create <" + actionKey + " : " + result + ">"); - } - - // recherche de l'annotation de configuration - ActionInitializer<?, ?> initializer = findInitializer(result.getClass()); - - if (initializer != null) { - initializer.initAction(component, result); - } - - try { - - if (initializer != null) { - if (AbstractButton.class.isAssignableFrom(initializer.getComponentImpl())) { - finalizeNewAction((AbstractButton) component, result, initializer); - } - - if (JComboBox.class.isAssignableFrom(initializer.getComponentImpl())) { - finalizeNewAction((JComboBox) component, result, initializer); - } - - return result; - } - - if (component == null || component instanceof AbstractButton) { - finalizeNewAction((AbstractButton) component, result, initializer); - return result; - } - - if (component instanceof JComboBox) { - finalizeNewAction((JComboBox) component, result, initializer); - } - } finally { - // save result in cache - cache.put(actionKey, result); - } - - return result; - } - - public String[] getActionNames() { - return impls.keySet().toArray(new String[impls.size()]); - } - - public Set<Map.Entry<String, Class<? extends MyAbstractAction>>> implsEntrySet() { - return impls.entrySet(); - } - - public Set<Map.Entry<String, MyAbstractAction>> cacheEntrySet() { - return cache.entrySet(); - } - - public void fireAction(String actionKey, Object source, JComponent component) { - AbstractAction action = newAction(actionKey, component); - fireAction0(actionKey, source, action); - } - - public void fireAction(String actionKey, Object source) { - fireAction(actionKey, source, null); - } - - /** - * @param actionKey la clef de l'action - * @return l'action deja stockee dans le cache d'action, ou <code>null</code> si non trouv�e. - */ - public MyAbstractAction getActionFromCache(String actionKey) { - // on v�rifie que l'action existe bien - checkRegistredAction(actionKey); - - // try in cache - if (cache.containsKey(actionKey)) { - // use cached action - MyAbstractAction action = cache.get(actionKey); - if (log.isDebugEnabled()) { - log.debug("use cache action " + action); - } - return action; - } - return null; - } - - public void dispose() { - if (log.isInfoEnabled()) { - log.info(this); - } - for (String actionKey : getActionNames()) { - MyAbstractAction action = getActionFromCache(actionKey); - if (action != null) { - action.disposeUI(); - } - } - resetCache(); - } - - /** - * @param component le button o� rattacher l'action - * @param action action - * @param initializer initializer - */ - protected void finalizeNewAction(AbstractButton component, MyAbstractAction action, ActionInitializer<?, ?> initializer) { - - if (initializer == null) { - // no initializer matching, - if (component != null) { - action.putValue(Action.ACTION_COMMAND_KEY, component.getName()); - action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); - action.putValue(Action.SMALL_ICON, component.getIcon()); - action.putValue(Action.NAME, component.getText()); - action.putValue(Action.MNEMONIC_KEY, component.getMnemonic()); - action.putValue("hideActionText", component.getHideActionText()); - if (component instanceof JAXXToggleButton) { - JAXXToggleButton glueComponent = (JAXXToggleButton) component; - action.putValue(Action.SHORT_DESCRIPTION, glueComponent.getNormalTooltipText()); - action.putValue(Action.NAME, glueComponent.getNormalText()); - action.putValue(Action.SMALL_ICON, glueComponent.getIcon()); - action.putValue(Action.MNEMONIC_KEY, glueComponent.getNormalMnemonic()); - action.putValue(Action.SHORT_DESCRIPTION + 2, glueComponent.getGlueTooltipText()); - action.putValue(Action.NAME + 2, glueComponent.getGlueText()); - action.putValue(Action.SMALL_ICON + 2, glueComponent.getSelectedIcon()); - action.putValue(Action.MNEMONIC_KEY + 2, glueComponent.getGlueMnemonic()); - } - } - - } - - String text = (String) action.getValue(Action.NAME); - Integer mnemo = (Integer) action.getValue(Action.MNEMONIC_KEY); - if (mnemo != null && mnemo != '\0') { - int pos = text.indexOf((char) mnemo.intValue()); - if (pos == -1) { - pos = text.indexOf(Character.toLowerCase((char) mnemo.intValue())); - } - action.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, pos); - } - - } - - /** - * @param component le select box o� rattacher l'action - * @param action action - * @param initializer initializer - */ - protected void finalizeNewAction(JComboBox component, MyAbstractAction action, ActionInitializer<?, ?> initializer) { - - if (initializer == null) { - action.putValue(Action.ACTION_COMMAND_KEY, component.getName()); - action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); - //result.putValue("selectedIndex", component.getSelectedIndex()); - } - - } - - protected ActionInitializer findInitializer(Class<? extends AbstractAction> action) { - for (ActionInitializer registredInitializer : registredInitializers) { - if (registredInitializer.getAnnotation(action) != null) { - return registredInitializer; - } - } - return null; - } - - protected <I extends AbstractActionInitializer> I registerInitializer(Class<I> initizalizer) { - try { - I instance = initizalizer.newInstance(); - registredInitializers.add(instance); - return instance; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - protected void fireAction0(String actionKey, Object source, AbstractAction action) { - if (action == null) { - log.warn("could not find action " + actionKey); - return; - } - ActionEvent event = new ActionEvent(source, ActionEvent.ACTION_FIRST, actionKey); - action.actionPerformed(event); - } - - protected void checkRegistredAction(String actionKey) { - if (!impls.containsKey(actionKey)) { - throw new IllegalStateException("can not find a registered action for key " + actionKey); - } - } - - - protected MyAbstractAction newActionInstance(String actionKey) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - Class<? extends MyAbstractAction> klazz = impls.get(actionKey); - MyAbstractAction result; - result = klazz.getConstructor(String.class).newInstance(actionKey); - result.putValue(Action.ACTION_COMMAND_KEY, actionKey); - return result; - } -} \ No newline at end of file Deleted: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java 2008-07-24 18:16:34 UTC (rev 780) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java 2008-07-24 18:19:27 UTC (rev 781) @@ -1,64 +0,0 @@ -/* -* ##% Copyright (C) 2007, 2008 Code Lutin, Tony Chemit -* -* 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. -* ##% */ -package org.codelutin.jaxx.action; - -import org.codelutin.jaxx.action.provider.ActionProvider; - -import java.util.Map; -import java.util.ServiceLoader; -import java.util.TreeMap; - -/** - * A simple implementation of {@link ActionFactory} using a properties file to - * load action mapping. - * <p/> - * An entry is in that form : <code>action.actionName=fqn</code> where - * <p/> - * <code>actionName</code> is the key of action used in factory, and - * <code>fqn</code> is the fully qualified name of the implemented action class. - * - * @author chemit - */ -public class ActionFactoryFromProvider<A extends MyAbstractAction> extends ActionFactory<A> { - - public static <A extends MyAbstractAction> ActionFactoryFromProvider<A> newInstance(Class<A> klazz) { - return new ActionFactoryFromProvider<A>(klazz); - } - - protected ActionFactoryFromProvider(Class<A> baseClass) { - super(baseClass); - } - - protected Map<String, Class<? extends MyAbstractAction>> init() { - if (log.isDebugEnabled()) { - log.debug("start loading " + this); - } - // obtain a ServiceLoader on ActionProvider - ServiceLoader<ActionProvider> loader = ServiceLoader.load(ActionProvider.class); - Map<String, Class<? extends MyAbstractAction>> cache = new TreeMap<String, Class<? extends MyAbstractAction>>(); - - for (ActionProvider<?> actionProvider : loader) { - if (log.isDebugEnabled()) { - log.debug("found " + actionProvider); - } - cache.putAll(actionProvider.getClasses()); - } - return cache; - } - -} \ No newline at end of file Copied: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactory.java (from rev 780, trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java) =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactory.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactory.java 2008-07-24 18:19:27 UTC (rev 781) @@ -0,0 +1,396 @@ +/* +* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin, +* Tony Chemit +* +* 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. +* ##% */ +package org.codelutin.jaxx.action.factory; + +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.JAXXToggleButton; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.jaxx.action.MyAbstractAction; +import org.codelutin.jaxx.action.initializer.AbstractActionInitializer; +import org.codelutin.jaxx.action.initializer.ActionConfigInitializer; +import org.codelutin.jaxx.action.initializer.ActionInitializer; +import org.codelutin.jaxx.action.initializer.SelectActionConfigInitializer; +import org.codelutin.jaxx.action.initializer.ToggleActionConfigInitializer; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import java.awt.event.ActionEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Action factory using the ActionConfig annotations to configure the action. + * <p/> + * The factory is abstract, implements method {@link #init()} to fill the + * dictonary of known action implementations. + * <p/> + * Use after the {@link #loadActions(jaxx.runtime.JAXXObject)} to instanciate + * actions in ui with id equals a known action... + * <p/> + * TODO Finish doc + * + * @author chemit + */ +public abstract class ActionFactory<A extends MyAbstractAction> { + + protected static Log log = LogFactory.getLog(ActionFactory.class); + + /** class of encapsuling action */ + protected Class<A> baseImpl; + + /** dictionary of known actions implementations */ + private Map<String, Class<? extends MyAbstractAction>> impls; + + /** dictionary of instanciated actions */ + private Map<String, MyAbstractAction> cache; + + protected final ActionConfigInitializer actionConfigInitializer; + protected final ToggleActionConfigInitializer toggleActionConfigInitializer; + protected final SelectActionConfigInitializer selectActionConfigInitializer; + + /** + * Method to init the dictionary of knwon action implementations. + * + * @return the dictionary of known action implementations + */ + protected abstract Map<String, Class<? extends MyAbstractAction>> init(); + + protected List<AbstractActionInitializer> registredInitializers; + + + protected ActionFactory(Class<A> baseImpl) { + this.baseImpl = baseImpl; + this.impls = init(); + this.cache = new TreeMap<String, MyAbstractAction>(); + this.registredInitializers = new java.util.ArrayList<AbstractActionInitializer>(); + + this.toggleActionConfigInitializer = registerInitializer(ToggleActionConfigInitializer.class); + this.actionConfigInitializer = registerInitializer(ActionConfigInitializer.class); + this.selectActionConfigInitializer = registerInitializer(SelectActionConfigInitializer.class); + } + + public void resetCache() { + cache.clear(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + resetCache(); + impls.clear(); + } + + public MyAbstractAction get(String actionKey) { + return cache.get(actionKey); + } + + public MyAbstractAction[] loadActions(JAXXObject ui) { + if (log.isDebugEnabled()) { + log.debug("for ui " + ui.getClass()); + } + List<MyAbstractAction> result = new ArrayList<MyAbstractAction>(); + for (Map.Entry<String, Class<? extends MyAbstractAction>> entry : implsEntrySet()) { + String actionKey = entry.getKey(); + Object comp = ui.getObjectById(actionKey); + if (comp == null || !(comp instanceof AbstractButton || comp instanceof JComboBox)) { + // nothing to do + continue; + } + if (log.isTraceEnabled()) { + log.trace("detect action " + actionKey); + } + if (comp instanceof AbstractButton) { + AbstractButton component = (AbstractButton) comp; + MyAbstractAction action = newAction(actionKey, component); + + component.setAction(action); + + if (component instanceof JAXXToggleButton) { + JAXXToggleButton glueComponent = (JAXXToggleButton) component; + glueComponent.setIcon((Icon) action.getValue(Action.SMALL_ICON)); + Integer integer = (Integer) action.getValue(Action.MNEMONIC_KEY); + if (integer != null) { + glueComponent.setNormalMnemonic(integer); + } + glueComponent.setSelectedIcon((Icon) action.getValue(Action.SMALL_ICON + 2)); + integer = (Integer) action.getValue(Action.MNEMONIC_KEY + 2); + if (integer != null) { + glueComponent.setGlueMnemonic(integer); + } + glueComponent.setGlueText((String) action.getValue(Action.NAME + 2)); + glueComponent.setGlueTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION + 2)); + + glueComponent.setNormalText((String) action.getValue(Action.NAME)); + glueComponent.setNormalTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION)); + } + + Boolean value = (Boolean) action.getValue("hideActionText"); + component.setHideActionText(value != null && value); + action.setEnabled(true); + result.add(action); + continue; + } + // is JComboBox + JComboBox component = (JComboBox) comp; + MyAbstractAction action = newAction(actionKey, component); + + component.setAction(action); + Integer val = (Integer) action.getValue("selectedIndex"); + if (val != null && val != -1 && val < component.getItemCount() && val != component.getSelectedIndex()) { + component.setSelectedIndex(val); + } + result.add(action); + } + return result.toArray(new MyAbstractAction[result.size()]); + } + + public static ImageIcon createImageIcon(String path) { + java.net.URL imgURL = ActionFactory.class.getResource("/icons/" + path); + if (imgURL != null) { + return new ImageIcon(imgURL); + } else { + throw new RuntimeException("could not find icon " + path); + } + } + + /** + * @param actionKey le nom de l'action tel que d�finie dans le fichier + * de mapping (sans le prefix action.) + * @param component le button o� rattacher l'action + * @return une nouvelle instance de l'action associ�e � sa clef. + */ + public MyAbstractAction newAction(String actionKey, JComponent component) { + // try first in cache + MyAbstractAction result = getActionFromCache(actionKey); + if (result != null) { + return result; + } + + try { + result = newActionInstance(actionKey); + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (log.isDebugEnabled()) { + log.debug("create <" + actionKey + " : " + result + ">"); + } + + // recherche de l'annotation de configuration + ActionInitializer<?, ?> initializer = findInitializer(result.getClass()); + + if (initializer != null) { + initializer.initAction(component, result); + } + + try { + + if (initializer != null) { + if (AbstractButton.class.isAssignableFrom(initializer.getComponentImpl())) { + finalizeNewAction((AbstractButton) component, result, initializer); + } + + if (JComboBox.class.isAssignableFrom(initializer.getComponentImpl())) { + finalizeNewAction((JComboBox) component, result, initializer); + } + + return result; + } + + if (component == null || component instanceof AbstractButton) { + finalizeNewAction((AbstractButton) component, result, initializer); + return result; + } + + if (component instanceof JComboBox) { + finalizeNewAction((JComboBox) component, result, initializer); + } + } finally { + // save result in cache + cache.put(actionKey, result); + } + + return result; + } + + public String[] getActionNames() { + return impls.keySet().toArray(new String[impls.size()]); + } + + public Set<Map.Entry<String, Class<? extends MyAbstractAction>>> implsEntrySet() { + return impls.entrySet(); + } + + public Set<Map.Entry<String, MyAbstractAction>> cacheEntrySet() { + return cache.entrySet(); + } + + public void fireAction(String actionKey, Object source, JComponent component) { + AbstractAction action = newAction(actionKey, component); + fireAction0(actionKey, source, action); + } + + public void fireAction(String actionKey, Object source) { + fireAction(actionKey, source, null); + } + + /** + * @param actionKey la clef de l'action + * @return l'action deja stockee dans le cache d'action, ou <code>null</code> si non trouv�e. + */ + public MyAbstractAction getActionFromCache(String actionKey) { + // on v�rifie que l'action existe bien + checkRegistredAction(actionKey); + + // try in cache + if (cache.containsKey(actionKey)) { + // use cached action + MyAbstractAction action = cache.get(actionKey); + if (log.isDebugEnabled()) { + log.debug("use cache action " + action); + } + return action; + } + return null; + } + + public void dispose() { + if (log.isInfoEnabled()) { + log.info(this); + } + for (String actionKey : getActionNames()) { + MyAbstractAction action = getActionFromCache(actionKey); + if (action != null) { + action.disposeUI(); + } + } + resetCache(); + } + + /** + * @param component le button o� rattacher l'action + * @param action action + * @param initializer initializer + */ + protected void finalizeNewAction(AbstractButton component, MyAbstractAction action, ActionInitializer<?, ?> initializer) { + + if (initializer == null) { + // no initializer matching, + if (component != null) { + action.putValue(Action.ACTION_COMMAND_KEY, component.getName()); + action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); + action.putValue(Action.SMALL_ICON, component.getIcon()); + action.putValue(Action.NAME, component.getText()); + action.putValue(Action.MNEMONIC_KEY, component.getMnemonic()); + action.putValue("hideActionText", component.getHideActionText()); + if (component instanceof JAXXToggleButton) { + JAXXToggleButton glueComponent = (JAXXToggleButton) component; + action.putValue(Action.SHORT_DESCRIPTION, glueComponent.getNormalTooltipText()); + action.putValue(Action.NAME, glueComponent.getNormalText()); + action.putValue(Action.SMALL_ICON, glueComponent.getIcon()); + action.putValue(Action.MNEMONIC_KEY, glueComponent.getNormalMnemonic()); + action.putValue(Action.SHORT_DESCRIPTION + 2, glueComponent.getGlueTooltipText()); + action.putValue(Action.NAME + 2, glueComponent.getGlueText()); + action.putValue(Action.SMALL_ICON + 2, glueComponent.getSelectedIcon()); + action.putValue(Action.MNEMONIC_KEY + 2, glueComponent.getGlueMnemonic()); + } + } + + } + + String text = (String) action.getValue(Action.NAME); + Integer mnemo = (Integer) action.getValue(Action.MNEMONIC_KEY); + if (mnemo != null && mnemo != '\0') { + int pos = text.indexOf((char) mnemo.intValue()); + if (pos == -1) { + pos = text.indexOf(Character.toLowerCase((char) mnemo.intValue())); + } + action.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, pos); + } + + } + + /** + * @param component le select box o� rattacher l'action + * @param action action + * @param initializer initializer + */ + protected void finalizeNewAction(JComboBox component, MyAbstractAction action, ActionInitializer<?, ?> initializer) { + + if (initializer == null) { + action.putValue(Action.ACTION_COMMAND_KEY, component.getName()); + action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); + //result.putValue("selectedIndex", component.getSelectedIndex()); + } + + } + + protected ActionInitializer findInitializer(Class<? extends AbstractAction> action) { + for (ActionInitializer registredInitializer : registredInitializers) { + if (registredInitializer.getAnnotation(action) != null) { + return registredInitializer; + } + } + return null; + } + + protected <I extends AbstractActionInitializer> I registerInitializer(Class<I> initizalizer) { + try { + I instance = initizalizer.newInstance(); + registredInitializers.add(instance); + return instance; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected void fireAction0(String actionKey, Object source, AbstractAction action) { + if (action == null) { + log.warn("could not find action " + actionKey); + return; + } + ActionEvent event = new ActionEvent(source, ActionEvent.ACTION_FIRST, actionKey); + action.actionPerformed(event); + } + + protected void checkRegistredAction(String actionKey) { + if (!impls.containsKey(actionKey)) { + throw new IllegalStateException("can not find a registered action for key " + actionKey); + } + } + + + protected MyAbstractAction newActionInstance(String actionKey) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + Class<? extends MyAbstractAction> klazz = impls.get(actionKey); + MyAbstractAction result; + result = klazz.getConstructor(String.class).newInstance(actionKey); + result.putValue(Action.ACTION_COMMAND_KEY, actionKey); + return result; + } +} \ No newline at end of file Copied: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactoryFromProvider.java (from rev 777, trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java) =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactoryFromProvider.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/factory/ActionFactoryFromProvider.java 2008-07-24 18:19:27 UTC (rev 781) @@ -0,0 +1,65 @@ +/* +* ##% Copyright (C) 2007, 2008 Code Lutin, Tony Chemit +* +* 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. +* ##% */ +package org.codelutin.jaxx.action.factory; + +import org.codelutin.jaxx.action.MyAbstractAction; +import org.codelutin.jaxx.action.provider.ActionProvider; + +import java.util.Map; +import java.util.ServiceLoader; +import java.util.TreeMap; + +/** + * A simple implementation of {@link ActionFactory} using a properties file to + * load action mapping. + * <p/> + * An entry is in that form : <code>action.actionName=fqn</code> where + * <p/> + * <code>actionName</code> is the key of action used in factory, and + * <code>fqn</code> is the fully qualified name of the implemented action class. + * + * @author chemit + */ +public class ActionFactoryFromProvider<A extends MyAbstractAction> extends ActionFactory<A> { + + public static <A extends MyAbstractAction> ActionFactoryFromProvider<A> newInstance(Class<A> klazz) { + return new ActionFactoryFromProvider<A>(klazz); + } + + protected ActionFactoryFromProvider(Class<A> baseClass) { + super(baseClass); + } + + protected Map<String, Class<? extends MyAbstractAction>> init() { + if (log.isDebugEnabled()) { + log.debug("start loading " + this); + } + // obtain a ServiceLoader on ActionProvider + ServiceLoader<ActionProvider> loader = ServiceLoader.load(ActionProvider.class); + Map<String, Class<? extends MyAbstractAction>> cache = new TreeMap<String, Class<? extends MyAbstractAction>>(); + + for (ActionProvider<?> actionProvider : loader) { + if (log.isDebugEnabled()) { + log.debug("found " + actionProvider); + } + cache.putAll(actionProvider.getClasses()); + } + return cache; + } + +} \ No newline at end of file