Author: tchemit Date: 2008-04-18 17:15:23 +0000 (Fri, 18 Apr 2008) New Revision: 547 Added: trunk/jaxx/src/main/java/org/ trunk/jaxx/src/main/java/org/codelutin/ trunk/jaxx/src/main/java/org/codelutin/ui/ trunk/jaxx/src/main/java/org/codelutin/ui/DialogUI.java trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIDef.java trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIHandler.java trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIModel.java trunk/jaxx/src/main/java/org/codelutin/ui/UIFactory.java trunk/jaxx/src/main/java/org/codelutin/ui/UIProvider.java Removed: trunk/jaxx/src/main/java/jaxx/DialogUI.java trunk/jaxx/src/main/java/jaxx/DialogUIDef.java trunk/jaxx/src/main/java/jaxx/DialogUIHandler.java trunk/jaxx/src/main/java/jaxx/DialogUIModel.java trunk/jaxx/src/main/java/jaxx/UIFactory.java trunk/jaxx/src/main/java/jaxx/UIProvider.java Log: generic UIPRovider, UIFactory and introduce DialogUIDef, outside jaxx namespace Deleted: trunk/jaxx/src/main/java/jaxx/DialogUI.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/DialogUI.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/DialogUI.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,79 +0,0 @@ -/** - * ##% Copyright (C) 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 jaxx; - -import jaxx.runtime.UIHelper; - -import javax.swing.AbstractAction; -import javax.swing.AbstractButton; -import javax.swing.ImageIcon; -import javax.swing.JDialog; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; - -/** - * A abstract dialog contract to be realised by a dialogUI (WindowEvent adapter) - * <p/> - * TODO : make jaxx authorized implementing interface for root tag :) - * - * @author chemit - */ -public abstract class DialogUI<H extends DialogUIHandler> extends JDialog implements WindowListener { - - private H handler; - - public abstract AbstractButton getHelp(); - - //TODO will be handled by jaxx with javax.help... - protected abstract AbstractAction createHelpAction(); - - protected DialogUI() { - UIHelper.setQuitAction(this); - addWindowListener(this); - } - - public H getHandler() { - return handler; - } - - public void setHandler(H handler) { - this.handler = handler; - } - - protected ImageIcon createActionIcon(String name) { - return UIHelper.createActionIcon(name); - } - - public void windowOpened(WindowEvent e) { - } - - public void windowClosed(WindowEvent e) { - } - - public void windowClosing(WindowEvent e) { - } - - public void windowIconified(WindowEvent e) { - } - - public void windowDeiconified(WindowEvent e) { - } - - public void windowActivated(WindowEvent e) { - } - - public void windowDeactivated(WindowEvent e) { - } -} \ No newline at end of file Deleted: trunk/jaxx/src/main/java/jaxx/DialogUIDef.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/DialogUIDef.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/DialogUIDef.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,57 +0,0 @@ -/** - * ##% Copyright (C) 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 jaxx; - -/** @author chemit */ -public class DialogUIDef<M extends DialogUIModel, U extends DialogUI<?>, H extends DialogUIHandler<M, U>> { - - private final Class<U> uiClass; - private final Class<M> modelClass; - private final Class<H> handlerClass; - - public DialogUIDef(Class<H> handlerClass, Class<U> uiClass, Class<M> modelClass) { - this.handlerClass = handlerClass; - this.uiClass = uiClass; - this.modelClass = modelClass; - } - - public Class<U> getUiClass() { - return uiClass; - } - - public Class<H> getHandlerClass() { - return handlerClass; - } - - public Class<M> getModelClass() { - return modelClass; - } - - @Override - public boolean equals(Object o) { - return this == o || o instanceof DialogUIDef && uiClass.equals(((DialogUIDef) o).uiClass); - - } - - @Override - public int hashCode() { - return uiClass.hashCode(); - } - - @Override - public String toString() { - return super.toString() + "<model:" + modelClass + ", ui:" + uiClass + ", handler:" + handlerClass + '>'; - } -} Deleted: trunk/jaxx/src/main/java/jaxx/DialogUIHandler.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/DialogUIHandler.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/DialogUIHandler.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,60 +0,0 @@ -/** - * ##% Copyright (C) 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 jaxx; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.beans.PropertyChangeListener; - -/** - * DialogUI handler - * - * @author chemit - */ -public abstract class DialogUIHandler<M extends DialogUIModel, U extends DialogUI<? extends DialogUIHandler>> implements PropertyChangeListener { - - protected static Log log = LogFactory.getLog(DialogUIHandler.class); - - /** ui handled */ - private U ui; - - /** model handled */ - private M model; - - protected DialogUIHandler(U ui, M model) { - this.ui = ui; - this.model = model; - } - - public U getUi() { - return ui; - } - - public M getModel() { - return model; - } - - public void init() { - if (model == null) { - throw new IllegalStateException("no model was defined for " + this); - } - model.addPropertyChangeListener(this); - } - - public void dispose() { - model.removePropertyChangeListener(this); - } -} \ No newline at end of file Deleted: trunk/jaxx/src/main/java/jaxx/DialogUIModel.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/DialogUIModel.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/DialogUIModel.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,85 +0,0 @@ -/** - * ##% Copyright (C) 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 jaxx; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - -/** - * Abstract ui model, with property change support. - * - * @author chemit - */ -public abstract class DialogUIModel { - - static protected final Log log = LogFactory.getLog(DialogUIModel.class); - - /** support for change properties support */ - protected PropertyChangeSupport changeSupport; - - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (listener == null) { - return; - } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); - } - changeSupport.addPropertyChangeListener(propertyName, listener); - } - - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (listener == null) { - return; - } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); - } - changeSupport.addPropertyChangeListener(listener); - } - - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - if (listener == null || changeSupport == null) { - return; - } - changeSupport.removePropertyChangeListener(listener); - } - - public synchronized void removePropertyChangeListeners() { - if (changeSupport == null) { - return; - } - for (PropertyChangeListener listener : getPropertyChangeListeners()) { - changeSupport.removePropertyChangeListener(listener); - } - } - - public synchronized PropertyChangeListener[] getPropertyChangeListeners() { - if (changeSupport == null) { - return new PropertyChangeListener[0]; - } - return changeSupport.getPropertyChangeListeners(); - } - - public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - if (changeSupport == null || (oldValue == null && newValue == null) || - (oldValue != null && oldValue.equals(newValue))) { - return; - } - changeSupport.firePropertyChange(propertyName, oldValue, newValue); - } -} \ No newline at end of file Deleted: trunk/jaxx/src/main/java/jaxx/UIFactory.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/UIFactory.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/UIFactory.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,218 +0,0 @@ -/** - * ##% Copyright (C) 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 jaxx; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.codelutin.util.ListenerSet; -import org.codelutin.util.StringUtil; - -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; -import java.util.ServiceLoader; - -/** - * Factory if VCS UI, using a cache. - * - * @author chemit - */ -public class UIFactory { - - static protected final Log log = LogFactory.getLog(UIFactory.class); - - protected static UIFactory instance; - - protected Map<DialogUIDef, DialogUI> cache; - - protected ServiceLoader<UIProvider> loader; - - protected String applicationName; - - protected ListenerSet<FactoryWindowListener> listeners; - - public static void initFactory(String applicationName, FactoryWindowListener... listeners) { - UIFactory factory = getInstance(); - synchronized (factory) { - factory.applicationName = applicationName; - for (FactoryWindowListener listener : listeners) { - listener.setFactory(factory); - factory.addFactoryWindowListener(listener); - } - } - } - - public void addFactoryWindowListener(FactoryWindowListener l) { - listeners.add(l); - } - - public void removeFactoryWindowListener(FactoryWindowListener l) { - listeners.remove(l); - } - - public void close() { - if (cache != null) { - cache.clear(); - cache = null; - } - if (loader != null) { - loader.reload(); - loader = null; - } - while (listeners.size() > 0) { - removeFactoryWindowListener(listeners.iterator().next()); - } - - } - - protected static UIFactory getInstance() { - if (instance == null) { - instance = new UIFactory(); - } - return instance; - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - close(); - } - - protected synchronized Map<DialogUIDef, DialogUI> getCache() { - if (cache == null) { - cache = new HashMap<DialogUIDef, DialogUI>(); - } - return cache; - } - - protected synchronized ServiceLoader<UIProvider> getProviders() { - checkInit(); - if (loader == null) { - long t0 = System.nanoTime(); - - loader = ServiceLoader.load(UIProvider.class); - int nb = 0; - for (UIProvider provider : loader) { - log.info(provider.getName() + " [" + provider + ']'); - nb++; - } - log.info("found " + nb + " ui provider(s) in " + StringUtil.convertTime(t0, System.nanoTime())); - } - return loader; - } - - protected DialogUI newUI(DialogUIDef uiType) { - - DialogUI result = getInstance().getCache().get(uiType); - if (result == null) { - try { - getCache().put(uiType, result = newUI0(uiType)); - for (FactoryWindowListener listener : listeners) { - result.addWindowListener(listener); - } - } catch (Exception e) { - throw new IllegalStateException("could not instanciate ui handler " + uiType + " for reason : " + e.getMessage()); - } - } - return result; - } - - protected DialogUI newUI0(DialogUIDef uiType, Object... params) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { - for (UIProvider provider : getProviders()) { - DialogUI ui = provider.newUI(uiType); - if (ui != null) { - Class<?>[] prototype = getHandlerPrototype(ui.getClass(), params); - Object[] parameters = getHandlerParameters(ui, params); - uiType.getHandlerClass().getConstructor(prototype).newInstance(ui, parameters); - ui.getHandler().init(); - return ui; - } - } - throw new IllegalStateException("could not find ui " + uiType); - } - - protected UIFactory() { - listeners = new ListenerSet<FactoryWindowListener>(); - } - - protected Class<?>[] getHandlerPrototype(Class<? extends DialogUI> aClass, Object[] params) { - Class<?>[] classes = new Class<?>[1 + params.length]; - classes[0] = aClass.getSuperclass(); - for (int i = 0; i < params.length; i++) { - classes[i + 1] = params[i].getClass(); - } - return classes; - } - - protected Object[] getHandlerParameters(DialogUI ui, Object[] params) { - Object[] classes = new Object[1 + params.length]; - classes[0] = ui; - System.arraycopy(params, 0, classes, 1, params.length); - return classes; - } - - private void checkInit() throws IllegalStateException { - if (applicationName == null) { - throw new IllegalStateException("factory " + this + " was not init "); - } - } - - public static abstract class FactoryWindowListener extends WindowAdapter { - - protected abstract void allWindowsClosed(); - - private UIFactory factory; - - private boolean wasClosed; - - public UIFactory getFactory() { - return factory; - } - - public void setFactory(UIFactory factory) { - this.factory = factory; - } - - @Override - public void windowClosed(WindowEvent e) { - if (log.isDebugEnabled()) { - log.debug(e.getSource()); - } - if (e.getWindow().isVisible()) { - // only deal with real closed and none visible windows... - return; - } - for (DialogUI vcsui : factory.getCache().values()) { - if (vcsui.isVisible()) { - // at least one ui visible, do not kill connexions - return; - } - } - if (wasClosed) { - // make sure to process once - return; - } - synchronized (this) { - try { - allWindowsClosed(); - } finally { - wasClosed = true; - } - } - } - } -} \ No newline at end of file Deleted: trunk/jaxx/src/main/java/jaxx/UIProvider.java =================================================================== --- trunk/jaxx/src/main/java/jaxx/UIProvider.java 2008-04-18 17:11:28 UTC (rev 546) +++ trunk/jaxx/src/main/java/jaxx/UIProvider.java 2008-04-18 17:15:23 UTC (rev 547) @@ -1,68 +0,0 @@ -/** - * # #% Copyright (C) 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 jaxx; - -/** @author chemit */ -public abstract class UIProvider { - - /** the name of application using this provider */ - protected String applicationName; - - /** the name of ui implementation used by this provider */ - protected String name; - - /** array of ui implementations */ - protected Class<?>[] implementations; - - protected UIProvider(String applicationName, String name, Class<?>... implementations) { - this.applicationName = applicationName; - this.name = name; - this.implementations = implementations; - } - - /** @return the identifier of the ui provider (eg jaxx, swing, ...) */ - public String getName() { - return name; - } - - public String getApplicationName() { - return applicationName; - } - - public Class<?>[] getImplementations() { - return implementations; - } - - public <U extends DialogUI<?>, D extends DialogUIDef<?, U, ?>> U newUI(D def) throws InstantiationException, IllegalAccessException { - Class<U> uiImpl = finImpl(def.getUiClass()); - return uiImpl != null ? uiImpl.newInstance() : null; - } - - @Override - public String toString() { - return super.toString() + " application:" + applicationName + ", provider:" + name + ", uis:" + (java.util.Arrays.toString(implementations)); - } - - @SuppressWarnings({"unchecked"}) - private <X extends DialogUI> Class<X> finImpl(Class<X> uiType) { - for (Class<?> klass : implementations) { - if (uiType.isAssignableFrom(klass)) { - return (Class<X>) klass; - } - } - return null; - } - -} \ No newline at end of file Copied: trunk/jaxx/src/main/java/org/codelutin/ui/DialogUI.java (from rev 540, trunk/jaxx/src/main/java/jaxx/DialogUI.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/DialogUI.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/DialogUI.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,79 @@ +/** + * ##% Copyright (C) 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.ui; + +import jaxx.runtime.UIHelper; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.ImageIcon; +import javax.swing.JDialog; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +/** + * A abstract dialog contract to be realised by a dialogUI (WindowEvent adapter) + * <p/> + * TODO : make jaxx authorized implementing interface for root tag :) + * + * @author chemit + */ +public abstract class DialogUI<H extends DialogUIHandler> extends JDialog implements WindowListener { + + private H handler; + + public abstract AbstractButton getHelp(); + + //TODO will be handled by jaxx with javax.help... + protected abstract AbstractAction createHelpAction(); + + protected DialogUI() { + UIHelper.setQuitAction(this); + addWindowListener(this); + } + + public H getHandler() { + return handler; + } + + public void setHandler(H handler) { + this.handler = handler; + } + + protected ImageIcon createActionIcon(String name) { + return UIHelper.createActionIcon(name); + } + + public void windowOpened(WindowEvent e) { + } + + public void windowClosed(WindowEvent e) { + } + + public void windowClosing(WindowEvent e) { + } + + public void windowIconified(WindowEvent e) { + } + + public void windowDeiconified(WindowEvent e) { + } + + public void windowActivated(WindowEvent e) { + } + + public void windowDeactivated(WindowEvent e) { + } +} \ No newline at end of file Copied: trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIDef.java (from rev 546, trunk/jaxx/src/main/java/jaxx/DialogUIDef.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIDef.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIDef.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,57 @@ +/** + * ##% Copyright (C) 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.ui; + +/** @author chemit */ +public class DialogUIDef<M extends DialogUIModel, U extends DialogUI<?>, H extends DialogUIHandler<M, U>> { + + private final Class<U> uiClass; + private final Class<M> modelClass; + private final Class<H> handlerClass; + + public DialogUIDef(Class<H> handlerClass, Class<U> uiClass, Class<M> modelClass) { + this.handlerClass = handlerClass; + this.uiClass = uiClass; + this.modelClass = modelClass; + } + + public Class<U> getUiClass() { + return uiClass; + } + + public Class<H> getHandlerClass() { + return handlerClass; + } + + public Class<M> getModelClass() { + return modelClass; + } + + @Override + public boolean equals(Object o) { + return this == o || o instanceof DialogUIDef && uiClass.equals(((DialogUIDef) o).uiClass); + + } + + @Override + public int hashCode() { + return uiClass.hashCode(); + } + + @Override + public String toString() { + return super.toString() + "<model:" + modelClass + ", ui:" + uiClass + ", handler:" + handlerClass + '>'; + } +} Copied: trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIHandler.java (from rev 540, trunk/jaxx/src/main/java/jaxx/DialogUIHandler.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIHandler.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIHandler.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,60 @@ +/** + * ##% Copyright (C) 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.ui; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.PropertyChangeListener; + +/** + * DialogUI handler + * + * @author chemit + */ +public abstract class DialogUIHandler<M extends DialogUIModel, U extends DialogUI<? extends DialogUIHandler>> implements PropertyChangeListener { + + protected static Log log = LogFactory.getLog(DialogUIHandler.class); + + /** ui handled */ + private U ui; + + /** model handled */ + private M model; + + protected DialogUIHandler(U ui, M model) { + this.ui = ui; + this.model = model; + } + + public U getUi() { + return ui; + } + + public M getModel() { + return model; + } + + public void init() { + if (model == null) { + throw new IllegalStateException("no model was defined for " + this); + } + model.addPropertyChangeListener(this); + } + + public void dispose() { + model.removePropertyChangeListener(this); + } +} \ No newline at end of file Copied: trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIModel.java (from rev 540, trunk/jaxx/src/main/java/jaxx/DialogUIModel.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIModel.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/DialogUIModel.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,85 @@ +/** + * ##% Copyright (C) 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.ui; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * Abstract ui model, with property change support. + * + * @author chemit + */ +public abstract class DialogUIModel { + + static protected final Log log = LogFactory.getLog(DialogUIModel.class); + + /** support for change properties support */ + protected PropertyChangeSupport changeSupport; + + public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(propertyName, listener); + } + + public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(listener); + } + + public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(listener); + } + + public synchronized void removePropertyChangeListeners() { + if (changeSupport == null) { + return; + } + for (PropertyChangeListener listener : getPropertyChangeListeners()) { + changeSupport.removePropertyChangeListener(listener); + } + } + + public synchronized PropertyChangeListener[] getPropertyChangeListeners() { + if (changeSupport == null) { + return new PropertyChangeListener[0]; + } + return changeSupport.getPropertyChangeListeners(); + } + + public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if (changeSupport == null || (oldValue == null && newValue == null) || + (oldValue != null && oldValue.equals(newValue))) { + return; + } + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } +} \ No newline at end of file Copied: trunk/jaxx/src/main/java/org/codelutin/ui/UIFactory.java (from rev 546, trunk/jaxx/src/main/java/jaxx/UIFactory.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/UIFactory.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/UIFactory.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,218 @@ +/** + * ##% Copyright (C) 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.ui; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.util.ListenerSet; +import org.codelutin.util.StringUtil; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * Factory if VCS UI, using a cache. + * + * @author chemit + */ +public class UIFactory { + + static protected final Log log = LogFactory.getLog(UIFactory.class); + + protected static UIFactory instance; + + protected Map<DialogUIDef, DialogUI> cache; + + protected ServiceLoader<UIProvider> loader; + + protected String applicationName; + + protected ListenerSet<FactoryWindowListener> listeners; + + public static void initFactory(String applicationName, FactoryWindowListener... listeners) { + UIFactory factory = getInstance(); + synchronized (factory) { + factory.applicationName = applicationName; + for (FactoryWindowListener listener : listeners) { + listener.setFactory(factory); + factory.addFactoryWindowListener(listener); + } + } + } + + public void addFactoryWindowListener(FactoryWindowListener l) { + listeners.add(l); + } + + public void removeFactoryWindowListener(FactoryWindowListener l) { + listeners.remove(l); + } + + public void close() { + if (cache != null) { + cache.clear(); + cache = null; + } + if (loader != null) { + loader.reload(); + loader = null; + } + while (listeners.size() > 0) { + removeFactoryWindowListener(listeners.iterator().next()); + } + + } + + protected static UIFactory getInstance() { + if (instance == null) { + instance = new UIFactory(); + } + return instance; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + close(); + } + + protected synchronized Map<DialogUIDef, DialogUI> getCache() { + if (cache == null) { + cache = new HashMap<DialogUIDef, DialogUI>(); + } + return cache; + } + + protected synchronized ServiceLoader<UIProvider> getProviders() { + checkInit(); + if (loader == null) { + long t0 = System.nanoTime(); + + loader = ServiceLoader.load(UIProvider.class); + int nb = 0; + for (UIProvider provider : loader) { + log.info(provider.getName() + " [" + provider + ']'); + nb++; + } + log.info("found " + nb + " ui provider(s) in " + StringUtil.convertTime(t0, System.nanoTime())); + } + return loader; + } + + protected DialogUI newUI(DialogUIDef uiType) { + + DialogUI result = getInstance().getCache().get(uiType); + if (result == null) { + try { + getCache().put(uiType, result = newUI0(uiType)); + for (FactoryWindowListener listener : listeners) { + result.addWindowListener(listener); + } + } catch (Exception e) { + throw new IllegalStateException("could not instanciate ui handler " + uiType + " for reason : " + e.getMessage()); + } + } + return result; + } + + protected DialogUI newUI0(DialogUIDef uiType, Object... params) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + for (UIProvider provider : getProviders()) { + DialogUI ui = provider.newUI(uiType); + if (ui != null) { + Class<?>[] prototype = getHandlerPrototype(ui.getClass(), params); + Object[] parameters = getHandlerParameters(ui, params); + uiType.getHandlerClass().getConstructor(prototype).newInstance(ui, parameters); + ui.getHandler().init(); + return ui; + } + } + throw new IllegalStateException("could not find ui " + uiType); + } + + protected UIFactory() { + listeners = new ListenerSet<FactoryWindowListener>(); + } + + protected Class<?>[] getHandlerPrototype(Class<? extends DialogUI> aClass, Object[] params) { + Class<?>[] classes = new Class<?>[1 + params.length]; + classes[0] = aClass.getSuperclass(); + for (int i = 0; i < params.length; i++) { + classes[i + 1] = params[i].getClass(); + } + return classes; + } + + protected Object[] getHandlerParameters(DialogUI ui, Object[] params) { + Object[] classes = new Object[1 + params.length]; + classes[0] = ui; + System.arraycopy(params, 0, classes, 1, params.length); + return classes; + } + + private void checkInit() throws IllegalStateException { + if (applicationName == null) { + throw new IllegalStateException("factory " + this + " was not init "); + } + } + + public static abstract class FactoryWindowListener extends WindowAdapter { + + protected abstract void allWindowsClosed(); + + private UIFactory factory; + + private boolean wasClosed; + + public UIFactory getFactory() { + return factory; + } + + public void setFactory(UIFactory factory) { + this.factory = factory; + } + + @Override + public void windowClosed(WindowEvent e) { + if (log.isDebugEnabled()) { + log.debug(e.getSource()); + } + if (e.getWindow().isVisible()) { + // only deal with real closed and none visible windows... + return; + } + for (DialogUI vcsui : factory.getCache().values()) { + if (vcsui.isVisible()) { + // at least one ui visible, do not kill connexions + return; + } + } + if (wasClosed) { + // make sure to process once + return; + } + synchronized (this) { + try { + allWindowsClosed(); + } finally { + wasClosed = true; + } + } + } + } +} \ No newline at end of file Copied: trunk/jaxx/src/main/java/org/codelutin/ui/UIProvider.java (from rev 546, trunk/jaxx/src/main/java/jaxx/UIProvider.java) =================================================================== --- trunk/jaxx/src/main/java/org/codelutin/ui/UIProvider.java (rev 0) +++ trunk/jaxx/src/main/java/org/codelutin/ui/UIProvider.java 2008-04-18 17:15:23 UTC (rev 547) @@ -0,0 +1,68 @@ +/** + * # #% Copyright (C) 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.ui; + +/** @author chemit */ +public abstract class UIProvider { + + /** the name of application using this provider */ + protected String applicationName; + + /** the name of ui implementation used by this provider */ + protected String name; + + /** array of ui implementations */ + protected Class<?>[] implementations; + + protected UIProvider(String applicationName, String name, Class<?>... implementations) { + this.applicationName = applicationName; + this.name = name; + this.implementations = implementations; + } + + /** @return the identifier of the ui provider (eg jaxx, swing, ...) */ + public String getName() { + return name; + } + + public String getApplicationName() { + return applicationName; + } + + public Class<?>[] getImplementations() { + return implementations; + } + + public <U extends DialogUI<?>, D extends DialogUIDef<?, U, ?>> U newUI(D def) throws InstantiationException, IllegalAccessException { + Class<U> uiImpl = finImpl(def.getUiClass()); + return uiImpl != null ? uiImpl.newInstance() : null; + } + + @Override + public String toString() { + return super.toString() + " application:" + applicationName + ", provider:" + name + ", uis:" + (java.util.Arrays.toString(implementations)); + } + + @SuppressWarnings({"unchecked"}) + private <X extends DialogUI> Class<X> finImpl(Class<X> uiType) { + for (Class<?> klass : implementations) { + if (uiType.isAssignableFrom(klass)) { + return (Class<X>) klass; + } + } + return null; + } + +} \ No newline at end of file