Author: tchemit Date: 2010-06-07 12:44:18 +0200 (Mon, 07 Jun 2010) New Revision: 1951 Url: http://nuiton.org/repositories/revision/jaxx/1951 Log: introduce wizard ext package and remove old too complex wizard operation framework Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStep.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStepModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUI.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUtil.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardState.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/package.html Removed: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardState.java Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -45,7 +45,7 @@ * @see WizardStep * @since 1.3 */ -public class WizardModel<E extends WizardStep> { +public abstract class WizardModel<E extends WizardStep> { public static final String STEPS_PROPERTY_NAME = "steps"; @@ -259,7 +259,9 @@ firePropertyChange(VALID_STEP_PROPERTY_NAME, null, validStep); } - protected Class<E> getStepClass() { + public abstract void updateUniverse(); + + public Class<E> getStepClass() { return stepClass; } @@ -279,15 +281,12 @@ pcs.firePropertyChange(propertyName, oldValue, newValue); } + protected void firePropertyChange(String propertyName, Object newValue) { + pcs.firePropertyChange(propertyName, null, newValue); + } + protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) { pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue); } - - protected E[] updateStepUniverse() { - return null; - } - - protected void updateUniverse() { - } } Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,169 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -import jaxx.runtime.JAXXContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.SwingWorker; - -/** - * La classe de base a implanter pour definir l'action d'une operation dans un - * wizard. - * - * @author tchemit <chemit@codelutin.com> - * @param <E> le type d'étapes - * @param <M> le type de modèle - * @since 1.3 - */ -public abstract class WizardOperationAction<E extends WizardOperationStep, M extends WizardOperationModel<E>, O extends WizardOperationActionModel<E>> extends SwingWorker<WizardState, String> { - - /** Logger */ - private static final Log log = LogFactory.getLog(WizardOperationAction.class); - - protected O operationModel; - - public WizardOperationAction(O operationModel) { - this.operationModel = operationModel; - } - - public E getOperation() { - return operationModel.getOperation(); - } - - public O getOperationModel() { - return operationModel; - } - - public WizardState getOperationState() { - return getModel().getOperationState(); - } - - public Exception getError() { - return operationModel.getError(); - } - - /** - * @param e the error to set - * @deprecated since 2.1 prefer use the {@link WizardOperationActionModel#setError(Exception)} - */ - @Deprecated - public void setError(Exception e) { - operationModel.setError(e); - } - - public void sendMessage(String msg) { - firePropertyChange("message", null, msg); - } - - /** - * Recopie les états d'une action vers une nouvelle action. - * <p/> - * Cette méthode est appellé quand une action se déroule en plusieurs - * étapes. Du fait que les {@link SwingWorker} ne sont utilisable qu'une - * seule fois, on recopie les états de l'action courante vers la nouvelle - * action à exécuter. - * - * @param newAction la nouvelle action - */ - public void copyTo(WizardOperationAction<?, ?, ?> newAction) { - ((WizardOperationAction<?, ?, O>)newAction).operationModel = operationModel; - } - - public abstract void start(JAXXContext context); - - public abstract void beforeAction(JAXXContext context, M model) throws Exception; - - public abstract WizardState doAction(M model) throws Exception; - - public abstract WizardState onError(M model, Exception e); - - public abstract WizardState onCancel(M model, Exception e); - - protected abstract M getModel(); - - protected abstract JAXXContext getContext(); - - @Override - public String toString() { - return super.toString() + " < operation: " + getOperation() + ", state: " + - getState() + " >"; - } - - @Override - protected WizardState doInBackground() throws Exception { - log.trace(this); - WizardState result; - M model = getModel(); - try { - beforeAction(getContext(), model); - result = doAction(model); - } catch (Exception e) { - operationModel.setError(e); - result = onError(model, e); - } - return result; - } - - @Override - protected void done() { - log.trace(this); - WizardState result = null; - try { - if (isCancelled()) { - - result = onCancel(getModel(), operationModel.getError()); - } else { - result = get(); - } - } catch (Exception e) { - result = WizardState.FAILED; - operationModel.setError(e); - // ne devrait jamais arrivé ? - log.error(e.getMessage(), e); - } finally { - // on enregistre le resultat de l'opération - getModel().setOperationState(result); - getModel().setBusy(false); - } - } - - public void destroy() { - if (operationModel != null) { - operationModel.destroy(); - operationModel = null; - } - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - if (log.isDebugEnabled()) { - log.debug("Will destroy " + this); - } - destroy(); - } -} Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionModel.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionModel.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,122 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -import jaxx.runtime.JAXXUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - -/** - * Abstract model of {@link WizardOperationAction}. - * - * @author tchemit <chemit@codelutin.com> - * @see WizardOperationAction - * @since 2.1 - */ -public abstract class WizardOperationActionModel<E extends WizardOperationStep> { - - /** Logger */ - private static final Log log = - LogFactory.getLog(WizardOperationActionModel.class); - - /** pour propager les changements dans le modèle vers l'ui */ - private final PropertyChangeSupport pcs; - - protected final E operation; - -// protected WizardState operationState; - - protected Exception error; - - protected WizardOperationActionModel(E operation) { - this.operation = operation; - pcs = new PropertyChangeSupport(this); - } - - public final E getOperation() { - return operation; - } - -// public final WizardState getOperationState() { -// return operationState; -// } - - public final Exception getError() { - return error; - } - - public void setError(Exception error) { - this.error = error; - } - -// public void setOperationState(WizardState operationState) { -// this.operationState = operationState; -// } - - public final void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - - public final void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.addPropertyChangeListener(propertyName, listener); - } - - - public final void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - - public final void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.removePropertyChangeListener(propertyName, listener); - } - - public void destroy() { - if (log.isDebugEnabled()) { - log.debug("will destroy " + this); - } - - // remove all listeners - JAXXUtil.destroy(pcs); - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - destroy(); - } - - protected final void firePropertyChange(String propertyName, - Object oldValue, - Object newValue) { - pcs.firePropertyChange(propertyName, oldValue, newValue); - } - - protected final void firePropertyChange(String propertyName, Object newValue) { - pcs.firePropertyChange(propertyName, null, newValue); - } -} Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,228 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -import jaxx.runtime.JAXXContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.SwingWorker.StateValue; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.Date; - -/** - * Thread qui réalise les opérations. - * <p/> - * Pour exécuter une nouvelle opération, on utilise la méthode {@link - * #launchOperation(WizardOperationStep)}. - * <p/> - * Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link - * #setWaiting(boolean)} - * - * @author tchemit <chemit@codelutin.com> - * @param <E> le type des etapes - * @param <M> le type de modele - * @param <A> le type d'action d'operation - * @since 1.3 - */ -public abstract class WizardOperationActionThread<E extends WizardOperationStep, M extends WizardOperationModel<E>, A extends WizardOperationAction<E, M,?>> extends Thread implements PropertyChangeListener { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - private static final Log log = LogFactory.getLog(WizardOperationActionThread.class); - - /** l'état du thread si annulé */ - private boolean canceled; - - protected Class<M> modelClass; - - protected A currentAction; - - /** - * un lock pour permettre la suspension et la reprise du thread lors du mode - * interactif. - */ - private final Object LOCK = new Object(); - - protected abstract M getModel(); - - protected abstract JAXXContext getContext(); - - public WizardOperationActionThread(Class<M> modelClass) throws IllegalArgumentException { - super(WizardOperationActionThread.class.getSimpleName() + " " + new Date()); - this.modelClass = modelClass; - } - - public void cancel() { - log.info("cancel " + this); - canceled = true; - - // on annule le modele - getModel().cancel(); - - // on rend la main au thread - setWaiting(false); - } - - @SuppressWarnings("unchecked") - public A launchOperation(E operation) { - - if (currentAction != null && (!currentAction.isDone() || currentAction.getOperationState() == WizardState.RUNNING)) { - // on ne peut traiter qu'une seule opération à la fois - throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done"); - } - currentAction = (A) getModel().getOperationAction(operation); - - // on libere le thread pour qu'il execute l'opération - setWaiting(false); - - return currentAction; - } - - public A getCurrentAction() { - return currentAction; - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">"); - if ("state".equals(evt.getPropertyName())) { - StateValue state = (StateValue) evt.getNewValue(); - if (state == StateValue.DONE) { - // on rend la main au thread pour qu'il attende une prochaine operation - setWaiting(false); - } - } - } - - @Override - public void run() { - try { - - // on vérifie que le context contient bien le modèle - if (getModel() == null) { - throw new NullPointerException("could not find model " + modelClass + " for " + this); - } - - while (!canceled) { - - if (canceled) { - // une annulation a été demandé - // donc même si une opération est demandée, on ne la traite - // pas - break; - } - - // en attente qu'une opération - // le block est bloqué jusqu'à arrivée d'une opération - // ou une demande d'annulation - setWaiting(true); - - // le thread a repris la main, donc plus en attente - log.trace("no more waiting " + this); - - if (!canceled) { - // une opération a été demandée - - // le thread écoute les modifications de l'action - currentAction.addPropertyChangeListener(this); - - // l'opération passe en etant en cours - getModel().setOperationState(WizardState.RUNNING); - - // démarrage de l'opération dans un worker - currentAction.start(getContext()); - // le thread est bloqué jusqu'à la fin de l'opération - // ou une demande d'annulation - setWaiting(true); - - // le thread reprend la main des que l'operation - // est terminée ou a été annulée, on passera alors - // dans la méthode onPropertyChanged - - if (canceled) { - getModel().setOperationState(WizardState.CANCELED); - } else { - getModel().setOperationState(currentAction.getOperationState()); - } - - // le thread n'écoute plus l'action car elle est terminée - // ou annulée - currentAction.removePropertyChangeListener(this); - // suppression de l'action - //currentAction = null; - } - - } - - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - unlockThread(); - log.trace(this + " will close..."); - close(); - } - } - - /** La méthode pour nettoyer le thread, a la fermeture. */ - protected void close() { - // par defaut, on ne fait rien - log.trace(this); - } - - protected void setWaiting(boolean waiting) { - - if (waiting && !canceled) { - // locking thread - try { - lockThread(); - } catch (InterruptedException ex) { - log.error(ex.getMessage(), ex); - canceled = true; - } - } - - if (!waiting) { - // release lock - unlockThread(); - } - } - - protected void lockThread() throws InterruptedException { - synchronized (LOCK) { - log.trace(this); - // lock - LOCK.wait(); - } - } - - protected void unlockThread() { - synchronized (LOCK) { - log.trace(this); - // unlock - LOCK.notify(); - } - } -} Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,382 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.SwingWorker.StateValue; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Un modèle de wizard avec des opérations. - * - * @author tchemit <chemit@codelutin.com> - * @param <E> le type des étapes. - * @since 1.3 - */ -public class WizardOperationModel<E extends WizardOperationStep> extends WizardModel<E> { - - - /** Logger */ - private static final Log log = LogFactory.getLog(WizardOperationModel.class); - - public static final String BUSY_PROPERTY_NAME = "busy"; - - public static final String OPERATIONS_PROPERTY_NAME = "operations"; - - public static final String OPERATION_STATE_PROPERTY_NAME = "operationState"; - - public static final String MODEL_STATE_PROPERTY_NAME = "modelState"; - - public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted"; - - /** La liste des opérations à effectuer */ - protected Set<E> operations; - - /** le dictionnaire des modèles d'opération */ - protected final Map<E, WizardOperationActionModel<E>> models; - - /** Pour conserver les états des opérations */ - protected Map<E, WizardState> operationStates; - - protected Map<E, WizardOperationAction<?, ? extends WizardOperationModel<E>, ? extends WizardOperationActionModel<E>>> operationActions; - - /** L'état générale du modèle */ - protected WizardState modelState; - - /** un drapeau pour savoir siune opération a été lancée */ - protected boolean wasStarted; - - /** un drapeau pour savoir si le modèle est occupé. */ - protected boolean busy; - - @SuppressWarnings("unchecked") - public <T extends Enum<T>> WizardOperationModel(Class<E> stepClass, E... steps) { - super(stepClass, steps); - Class<T> k = (Class<T>) stepClass; - operationStates = new EnumMap(k); - operations = (Set<E>) EnumSet.noneOf(k); - operationActions = new EnumMap(k); - models = (Map<E, WizardOperationActionModel<E>>) new EnumMap(k); - for (T o : EnumSet.allOf(k)) { - E step = (E) o; - if (step.isOperation()) { - - // initialisation du modèle associé à l'opération - WizardOperationActionModel<E> model = (WizardOperationActionModel<E>) step.newModel(); - if (log.isInfoEnabled()) { - log.info("[" + step + "] Add an operation model " + model); - } - models.put(step, model); - } - } - } - - public Set<E> getOperations() { - return operations; - } - - public WizardState getModelState() { - return modelState; - } - - public boolean isWasStarted() { - return wasStarted; - } - - public boolean isBusy() { - return busy; - } - - public void setBusy(boolean busy) { - boolean oldValue = this.busy; - this.busy = busy; - firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy); - } - - public boolean containsOperation(E step) { - return getOperations().contains(step); - } - - @SuppressWarnings("unchecked") - public E getOperation() { - return getStep() != null && getStep().isOperation() ? getStep() : null; - } - - public WizardState getOperationState() { - E operation = getOperation(); - return getOperationState(operation); - } - - public WizardState getOperationState(E operation) { - return operationStates.get(operation); - } - - public WizardOperationAction<?, ?, ?> getOperationAction(E operation) { - if (operation==null || !operation.isOperation()) { - return null; - } - WizardOperationAction<?, ?, ?> action = operationActions.get(operation); - if (action == null) { - try { - WizardOperationActionModel<?> operationModel = getOperationModel(operation); - action = operation.newAction(operationModel); - operationActions.put(operation, (WizardOperationAction<E, ? extends WizardOperationModel<E>, ? extends WizardOperationActionModel<E>>) action); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - return action; - } - - public void setOperationState(WizardState operationState) { - E operation = getOperation(); - setOperationState(operation, operationState); - } - - public void setOperationState(E operation, WizardState operationState) { - WizardState oldValue = getOperationState(operation); - operationStates.put(operation, operationState); - fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getSteps().indexOf(operation), oldValue, operationState); - updateModelState(operation, operationState); - validate(); - } - - public boolean[] getAccessibleSteps() { - if (log.isDebugEnabled()) { - log.debug("compute with steps "+getSteps()); - } - boolean[] result = new boolean[getSteps().size()]; - int index = getSteps().indexOf(getStep()); - if (index != -1) { - - for (int i = 0, j = steps.size(); i < j; i++) { - if (i <= index) { - // tous les onglets inferieur ou egal au courant sont accessibles - result[i] = true; - continue; - } - // les onglets au dela de l'onglet sélectionné sont accessibles - // uniquement si l'onglet precedent est accessible, valide et son etat est a SUCCESSED - E previousStep = steps.get(i - 1); - result[i] = modelState == WizardState.SUCCESSED || - result[i - 1] && - validate(previousStep) && - (!previousStep.isOperation() || getOperationState(previousStep) == WizardState.SUCCESSED); - } - } - if (log.isDebugEnabled()) { - log.debug("accessibles steps -------- " + Arrays.toString(result)); - } - return result; - } - - @Override - public void start() { - super.start(); - - // update universe of steps and actions - updateUniverse(); - - // le modèle n'est pas démarré - setModelState(WizardState.PENDING); - } - - public void cancel() { - - for (E op : operations) { - if (getOperationState(op) == WizardState.PENDING) { - // on annule l'opération à venir - setOperationState(op, WizardState.CANCELED); - } - } - setModelState(WizardState.CANCELED); - if (getStep() != null && getStep().isOperation()) { - WizardOperationAction<?, ?, ?> action = getOperationAction(getStep()); - if (action != null) { - if (!action.isCancelled() && !action.isDone() && action.getState() == StateValue.STARTED) { - // on annule l'action - action.cancel(true); - } - } - } - } - - public WizardOperationModel<E> addOperation(E operation) { - operations.add(operation); - // mis a jour de l'univers des etapes et operations - updateUniverse(); - // validation - validate(); - return this; - } - - public void removeOperation(E operation) { - operations.remove(operation); - - // mis a jour de l'univers des etapes et operations - updateUniverse(); - // validation - validate(); - } - - @Override - public void setSteps(E... steps) { - super.setSteps(steps); - // on force la propagation de la nouvelle liste - firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations); - updateOperationStates(Arrays.asList(steps)); - } - - public WizardOperationActionModel<E> getOperationModel(E operation) { - if (operation==null) { - return null; - } - if (!operation.isOperation()) { - throw new IllegalStateException("step [" + operation + "] is not an operation."); - } - return models.get(operation); - } - - public void updateOperationStates(List<E> steps) { - int index = 0; - for (E e : steps) { - fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e)); - } - firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState); - } - - public WizardOperationAction<?, ?, ?> reloadOperation(E operation) { - operationActions.remove(operation); - WizardOperationAction<?, ?, ?> newOp = getOperationAction(operation); - return newOp; - } - - protected void setModelState(WizardState modelState) { - WizardState oldValue = this.modelState; - this.modelState = modelState; - firePropertyChange(MODEL_STATE_PROPERTY_NAME, oldValue, modelState); - if (!wasStarted) { - if ((oldValue == null || oldValue == WizardState.PENDING) && modelState == WizardState.RUNNING) { - wasStarted = true; - firePropertyChange(WAS_STARTED_PROPERTY_NAME, false, true); - } - } - } - - protected void updateModelState(E operation, WizardState operationState) { - - switch (operationState) { - case RUNNING: - //le modele est occupé - setModelState(WizardState.RUNNING); - break; - case FAILED: - //le modele est en erreur - setModelState(WizardState.FAILED); - break; - case CANCELED: - //le modele devient annulé - setModelState(WizardState.CANCELED); - return; - case PENDING: - //le modele est en attente - setModelState(WizardState.PENDING); - break; - case NEED_FIX: - //le modele est en attente - setModelState(WizardState.PENDING); - break; - case SUCCESSED: - // on regarde si on peut passer le model a l'état success - boolean valid = true; - for (E o : operations) { - if (getOperationState(o) != WizardState.SUCCESSED) { - valid = false; - break; - } - } - if (valid) { - setModelState(WizardState.SUCCESSED); - } else { - setModelState(WizardState.PENDING); - } - break; - } - updateOperationStates(steps); - } - - @Override - protected void updateUniverse() { - E[] newSteps = updateStepUniverse(); - setSteps(newSteps); - } - - @Override - public void destroy() { - super.destroy(); - Set<E> operations = getOperations(); - for (E op : operations) { - WizardOperationAction<?, ?, ?> action = getOperationAction(op); - if (log.isDebugEnabled()) { - log.debug("destroy action " + action); - } - action.destroy(); - } - } - - @Override - protected E[] updateStepUniverse() { - // on met a jour les opérations - for (E op : operations) { - if (!operationStates.containsKey(op)) { - operationStates.put(op, WizardState.PENDING); - } - } - for (E op : operationStates.keySet()) { - if (!operations.contains(op)) { - operationStates.remove(op); - } - } - return null; - } - - protected int getOperationIndex(E operation) { - int index = 0; - for (E o : operations) { - if (o.equals(operation)) { - return index; - } - index++; - } - return -1; - } -} Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,67 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -/** - * Le contrat a implanter pour une etapes dans le modèle de wizard avec - * opérations. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.3 - */ -public interface WizardOperationStep extends WizardStep { - - /** @return le label de l'opération */ - String getOperationLabel(); - - /** @return la description de l'opération */ - String getOperationDescription(); - - /** @return le type du modèle de l'action */ - Class<? extends WizardOperationActionModel<?>> getModelClass(); - - /** - * @return le type de l'action associée à l'étape ou <code>null</code> si - * l'étape n'a pas d'opération associée. - */ - Class<? extends WizardOperationAction<?, ?, ?>> getActionClass(); - - /** @return le type de l'ui de l'opération */ - Class<? extends WizardStepUI<?, ?>> getUiClass(); - - /** - * @return <code>true</code> si l'étape a une opération associée, - * <code>false</code> sinon. - */ - boolean isOperation(); - - boolean isConfig(); - - WizardOperationActionModel<?> newModel(); - - WizardOperationAction<?, ?, ?> newAction(WizardOperationActionModel<?> operationModel); - - WizardStepUI<?,?> newUI(WizardUI<?,?> ui) ; -} Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardState.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardState.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardState.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -1,51 +0,0 @@ -/* - * #%L - * JAXX :: Runtime - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package jaxx.runtime.swing.wizard; - -/** - * Pour caractériser l'état d'une opération. - * - * @author tchemit <chemit@codelutin.com> - */ -public enum WizardState { - - /** quand l'opération n'a pas encore été réalisée */ - PENDING, - - /** quand l'opération est en cours */ - RUNNING, - - /** quand l'opération est annulé en cours d'exécution */ - CANCELED, - - /** quand une erreur s'est produite pendant l'exécution */ - FAILED, - - /** quand l'exécution s'est terminée mais requière des corrections */ - NEED_FIX, - - /** quand l'exécution s'est terminée et ne requière pas de correction */ - SUCCESSED -} Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -24,7 +24,7 @@ */ package jaxx.runtime.swing.wizard; -import javax.swing.*; +import javax.swing.JTabbedPane; /** * Contrat a respecter pour une ui de wizard. @@ -67,9 +67,6 @@ */ JTabbedPane getTabs(); - /** Méthode invoqué lorsque la première opération du modèlé a été démarrée. */ - void onWasStarted(); - /** * Méthode invoquée lorsque l'univers des étapes a été modifié dans le * modèle. @@ -84,20 +81,4 @@ * @param newStep la nouvelle étape courante */ void onStepChanged(E newStep); - - /** - * Méthode invoquée lorsque l'état interne du modèle a changé. - * - * @param newState le nouvelle état du modèle de wizard - */ - void onModelStateChanged(WizardState newState); - - /** - * Méthode invoqué lorsque l'état d'une opération a changé. - * - * @param step l'étape dont l'état a changé - * @param newState le nouvel état pour l'étape donné - */ - void onOperationStateChanged(E step, WizardState newState); - } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java 2010-06-05 07:51:37 UTC (rev 1950) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -29,7 +29,6 @@ import javax.swing.JTabbedPane; import java.awt.Component; -import java.beans.IndexedPropertyChangeEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.Array; @@ -51,24 +50,24 @@ protected WizardUtil() { } - public static boolean acceptStates(WizardState state, WizardState... accepted) { - for (WizardState s : accepted) { - if (s == state) { - return true; - } - } - return false; - } +// public static boolean acceptStates(WizardState state, WizardState... accepted) { +// for (WizardState s : accepted) { +// if (s == state) { +// return true; +// } +// } +// return false; +// } +// +// public static boolean rejectStates(WizardState state, WizardState... rejected) { +// for (WizardState s : rejected) { +// if (s == state) { +// return false; +// } +// } +// return true; +// } - public static boolean rejectStates(WizardState state, WizardState... rejected) { - for (WizardState s : rejected) { - if (s == state) { - return false; - } - } - return true; - } - public static void addDebugLogListener(final Log log, WizardModel<?> model) { if (log.isDebugEnabled()) { model.addPropertyChangeListener(new PropertyChangeListener() { @@ -100,10 +99,10 @@ @SuppressWarnings("unchecked") public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); - if (WizardOperationModel.WAS_STARTED_PROPERTY_NAME.equals(propertyName)) { - ui.onWasStarted(); - return; - } +// if (WizardExtModel.WAS_STARTED_PROPERTY_NAME.equals(propertyName)) { +// ui.onWasStarted(); +// return; +// } if (WizardModel.STEPS_PROPERTY_NAME.equals(propertyName)) { List<E> steps = (List<E>) evt.getNewValue(); ui.onStepsChanged( @@ -114,9 +113,9 @@ } if (WizardModel.STEP_PROPERTY_NAME.equals(propertyName)) { ui.onStepChanged((E) evt.getNewValue()); - return; +// return; } - if (WizardModel.VALID_STEP_PROPERTY_NAME.equals(propertyName)) { + /*if (WizardModel.VALID_STEP_PROPERTY_NAME.equals(propertyName)) { Boolean value = (Boolean) evt.getNewValue(); if (value == null || !value) { ui.onModelStateChanged(WizardState.NEED_FIX); @@ -125,18 +124,18 @@ } return; } - if (WizardOperationModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) { + if (WizardExtModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) { //TODO should be unicast : only for good stepUI ? ui.onModelStateChanged((WizardState) evt.getNewValue()); return; } - if (WizardOperationModel.OPERATION_STATE_PROPERTY_NAME.equals(propertyName)) { + if (WizardExtModel.STEP_STATE_PROPERTY_NAME.equals(propertyName)) { IndexedPropertyChangeEvent e = (IndexedPropertyChangeEvent) evt; int stepIndex = e.getIndex(); E step = ui.getModel().getSteps().get(stepIndex); ui.onOperationStateChanged(step, (WizardState) evt.getNewValue()); return; - } + }*/ } }); } Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtModel.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtModel.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,453 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.wizard.ext; + +import jaxx.runtime.swing.wizard.WizardModel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Un modèle de wizard avec des opérations. + * + * @author tchemit <chemit@codelutin.com> + * @param <E> le type des étapes. + * @since 1.3 + */ +public abstract class WizardExtModel<E extends WizardExtStep> extends WizardModel<E> { + + /** Logger */ + private static final Log log = LogFactory.getLog(WizardExtModel.class); + + public static final String BUSY_PROPERTY_NAME = "busy"; + + public static final String OPERATIONS_PROPERTY_NAME = "operations"; + + public static final String STEP_STATE_PROPERTY_NAME = "stepState"; + + public static final String MODEL_STATE_PROPERTY_NAME = "modelState"; + + public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted"; + + /** La liste des opérations à effectuer */ + protected Set<E> operations; + + /** le dictionnaire des modèles d'opération */ + protected final Map<E, WizardExtStepModel<E>> models; + + /** Pour conserver les états des opérations */ + protected Map<E, WizardState> stepStates; + + /** L'état générale du modèle */ + protected WizardState modelState; + + /** un drapeau pour savoir siune opération a été lancée */ + protected boolean wasStarted; + + /** un drapeau pour savoir si le modèle est occupé. */ + protected boolean busy; + + @SuppressWarnings("unchecked") + public <T extends Enum<T>> WizardExtModel(Class<E> stepClass, E... steps) { + super(stepClass, steps); + Class<T> k = (Class<T>) stepClass; + stepStates = new EnumMap(k); + operations = (Set<E>) EnumSet.noneOf(k); + models = (Map<E, WizardExtStepModel<E>>) new EnumMap(k); + } + + public Set<E> getOperations() { + return operations; + } + + public WizardState getModelState() { + return modelState; + } + + public boolean isWasStarted() { + return wasStarted; + } + + public boolean isBusy() { + return busy; + } + + public void setBusy(boolean busy) { + boolean oldValue = this.busy; + this.busy = busy; + firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy); + } + + public boolean containsOperation(E step) { + return getOperations().contains(step); + } + + @SuppressWarnings("unchecked") + public E getOperation() { + return getStep() != null && getStep().isOperation() ? getStep() : null; + } + + public WizardState getStepState() { + E operation = getOperation(); + return getStepState(operation); + } + + public WizardState getStepState(E step) { + return stepStates.get(step); + } + + public void setStepState(WizardState newState) { + E operation = getOperation(); + setStepState(operation, newState); + } + + public void setStepState(E step, WizardState newState) { + WizardState oldValue = getStepState(step); + stepStates.put(step, newState); + if (valueAdjusting) { + return; + } + fireIndexedPropertyChange(STEP_STATE_PROPERTY_NAME, getSteps().indexOf(step), oldValue, newState); + updateModelState(step, newState); + validate(); + } + + public boolean[] getAccessibleSteps() { + if (log.isDebugEnabled()) { + log.debug("compute with steps " + getSteps()); + } + boolean[] result = new boolean[getSteps().size()]; + int index = getSteps().indexOf(getStep()); + if (index != -1) { + + for (int i = 0, j = steps.size(); i < j; i++) { + if (i <= index) { + // tous les onglets inferieur ou egal au courant sont accessibles + result[i] = true; + continue; + } + // les onglets au dela de l'onglet sélectionné sont accessibles + // uniquement si l'onglet precedent est accessible, valide et son etat est a SUCCESSED + E previousStep = steps.get(i - 1); + result[i] = modelState == WizardState.SUCCESSED || + result[i - 1] && + validate(previousStep) && + (!previousStep.isOperation() || getStepState(previousStep) == WizardState.SUCCESSED); + } + } + if (log.isDebugEnabled()) { + log.debug("accessibles steps -------- " + Arrays.toString(result)); + } + return result; + } + + @Override + public void start() { +// super.start(); + + if (steps.isEmpty()) { + throw new IllegalStateException("can not start, no step found"); + } + + // update universe of steps and actions + updateUniverse(); + + // set first step + step = null; + E startStep = steps.get(0); + setStep(startStep); + + // model is ready + setModelState(WizardState.PENDING); + + validate(); + } + + public void cancel() { + + for (E op : operations) { + if (getStepState(op) == WizardState.PENDING) { + // on annule l'opération à venir + setStepState(op, WizardState.CANCELED); + } + } + setModelState(WizardState.CANCELED); + } + + public WizardExtModel<E> addOperation(E operation) { + if (operations.contains(operation)) { + + // skip add + return this; + } + + log.info("Add operation " + operation); + operations.add(operation); + // mis a jour de l'univers des etapes et operations + updateUniverse(); + // validation + validate(); + return this; + } + + public void removeOperation(E operation) { + if (!operations.contains(operation)) { + + // skip remove + return; + } + operations.remove(operation); + + // mis a jour de l'univers des etapes et operations + updateUniverse(); + // validation + validate(); + } + + @Override + public void setSteps(E... steps) { + super.setSteps(steps); + if (valueAdjusting) { + return; + } + // on force la propagation de la nouvelle liste + firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations); + } + + public WizardExtStepModel<E> getStepModel(E operation) { + if (operation == null) { + return null; + } + if (!operation.isOperation()) { + throw new IllegalStateException("step [" + operation + "] is not an operation."); + } + return models.get(operation); + } + + public void updateStepStates(List<E> steps) { + int index = 0; + for (E e : steps) { + fireIndexedPropertyChange(STEP_STATE_PROPERTY_NAME, index++, null, getStepState(e)); + } + firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState); + } + + protected void setModelState(WizardState modelState) { + WizardState oldValue = this.modelState; + this.modelState = modelState; + firePropertyChange(MODEL_STATE_PROPERTY_NAME, oldValue, modelState); + if (!wasStarted) { + if ((oldValue == null || oldValue == WizardState.PENDING) && modelState == WizardState.RUNNING) { + wasStarted = true; + firePropertyChange(WAS_STARTED_PROPERTY_NAME, false, true); + } + } + } + + protected void updateModelState(E step, WizardState newState) { + + switch (newState) { + case RUNNING: + //le modele est occupé + setModelState(WizardState.RUNNING); + break; + case FAILED: + //le modele est en erreur + setModelState(WizardState.FAILED); + break; + case CANCELED: + //le modele devient annulé + setModelState(WizardState.CANCELED); + return; + case PENDING: + //le modele est en attente + setModelState(WizardState.PENDING); + break; + case NEED_FIX: + //le modele est en attente + setModelState(WizardState.PENDING); + break; + case SUCCESSED: + // on regarde si on peut passer le model a l'état success + boolean valid = true; + for (E o : operations) { + if (getStepState(o) != WizardState.SUCCESSED) { + valid = false; + break; + } + } + if (valid) { + setModelState(WizardState.SUCCESSED); + } else { + setModelState(WizardState.PENDING); + } + break; + } + updateStepStates(steps); + } + + @Override + public void updateUniverse() { +// setValueAdjusting(true); + + List<E> oldSteps = new ArrayList<E>(getSteps()); + log.info("Start updateUniverse (oldSteps = " + oldSteps + ")"); + E[] newSteps = updateStepUniverse(); + log.info("newSteps = " + Arrays.toString(newSteps)); + + // do nothing if steps has not changed + boolean skip = true; + for (E newStep : newSteps) { + if (!oldSteps.contains(newStep)) { + skip = false; + } + } + + if (skip && oldSteps.size() == newSteps.length) { + + // same steps, so nothing to do + log.info("Steps are same, do not modify anything"); + return; + } + + for (WizardExtStepModel<E> model : models.values()) { + log.info("Destroy previous model : " + model); + model.destroy(); + } + models.clear(); + + List<E> toAdd = new ArrayList<E>(Arrays.asList(newSteps)); + + log.info("Will add models for " + toAdd); + + Iterator<E> itr = toAdd.iterator(); + while (itr.hasNext()) { + + E step = itr.next(); + + if (step.getModelClass() == null) { + + // no model attach to the step + itr.remove(); + continue; + } + + if (step.isOperation()) { + + // step is operation, model must be instanciate + WizardExtStepModel<E> model = (WizardExtStepModel<E>) step.newModel(); + if (log.isInfoEnabled()) { + log.info("[" + step + "] Add primary model " + model); + } + models.put(step, model); + + itr.remove(); + } + + // step has a model + } + + if (!toAdd.isEmpty()) { + + // there is some steps with model to attach + itr = toAdd.iterator(); + while (itr.hasNext()) { + + E step = itr.next(); + Class<? extends WizardExtStepModel<?>> modelClass = step.getModelClass(); + WizardExtStepModel<E> selectedModel = null; + // find out in models a + for (WizardExtStepModel<E> model : models.values()) { + if (modelClass.isAssignableFrom(model.getClass())) { + // find one + selectedModel = model; + break; + } + } + + if (selectedModel == null) { + throw new IllegalStateException("Could not find a primary model " + modelClass + " for step [" + step + "]"); + } + + log.info("[" + step + "] Attach model " + selectedModel); + models.put(step, selectedModel); + itr.remove(); + } + + if (!toAdd.isEmpty()) { + throw new IllegalStateException("There is some step no model : " + toAdd); + } + } + + setSteps(newSteps); + + // on met a jour les états des étapes + stepStates.clear(); + for (E step : newSteps) { + if (!stepStates.containsKey(step)) { + setStepState(step, WizardState.PENDING); + } + } + + // finally set the steps (this will refire a lot) + + log.info("Ending updateUniverse"); + +// setValueAdjusting(false); + } + + protected abstract E[] updateStepUniverse(); + + @Override + public void destroy() { + super.destroy(); + + for (WizardExtStepModel<E> model : models.values()) { + if (log.isDebugEnabled()) { + log.debug("destroy model " + model); + } + model.destroy(); + } + } + + protected int getOperationIndex(E operation) { + int index = 0; + for (E o : operations) { + if (o.equals(operation)) { + return index; + } + index++; + } + return -1; + } +} \ No newline at end of file Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStep.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStep.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStep.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,54 @@ +package jaxx.runtime.swing.wizard.ext; + +import jaxx.runtime.swing.wizard.WizardStep; +import jaxx.runtime.swing.wizard.WizardStepUI; + + +/** + * Extension de {@link WizardStep} avec des états supplémentaires. + * <p/> + * Chaque étape possède un modèle de type {@link #getModelClass()}. + * Ce modèle peut être partagé par plusieurs étapes. + * <p/> + * De plus, on a deux drapeaux {@link #isConfig()} pour savoir si l'étape est une phase de configuration. + * <p/> + * Le drapeau {@link #isOperation()} quand à lui permet de savoir si l'étape est une opération. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.1 + */ +public interface WizardExtStep extends WizardStep { + + /** @return le label de l'opération */ + String getOperationLabel(); + + /** @return la description de l'opération */ + String getOperationDescription(); + + /** @return le type du modèle de l'action */ + Class<? extends WizardExtStepModel<?>> getModelClass(); + + /** @return le type de l'ui de l'opération */ + Class<? extends WizardStepUI<?, ?>> getUiClass(); + + /** @return {@code true} si l'étape a une opération associée, {@code false} sinon. */ + boolean isOperation(); + + /** @return {@code true} si l'étape est une phase de configuration, {@code false} sinon. */ + boolean isConfig(); + + /** + * Instancie le modèle associée à l'étape. + * + * @return le nouveau modèle associé à l'étape + */ + WizardExtStepModel<?> newModel(); + + /** + * Construit l'ui associée à l'étape. + * + * @param ui l'ui principale du wiard + * @return la noveau ui associé à l'étape + */ + WizardStepUI<?, ?> newUI(WizardExtUI<?, ?> ui); +} Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStep.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStepModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStepModel.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStepModel.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,111 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.wizard.ext; + +import jaxx.runtime.JAXXUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * Abstract model of {@link WizardExtStep}. + * + * @author tchemit <chemit@codelutin.com> + * @see WizardExtStep + * @since 2.1 + */ +public abstract class WizardExtStepModel<E extends WizardExtStep> { + + /** Logger */ + private static final Log log = LogFactory.getLog(WizardExtStepModel.class); + + /** for properties change support */ + private final PropertyChangeSupport pcs; + + /** step of the model */ + protected final E step; + + /** to store if an error occurs while running */ + protected Exception error; + + protected WizardExtStepModel(E step) { + this.step = step; + pcs = new PropertyChangeSupport(this); + } + + public final E getStep() { + return step; + } + + public final Exception getError() { + return error; + } + + public void setError(Exception error) { + this.error = error; + } + + public final void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public final void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + + public final void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public final void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + public void destroy() { + if (log.isDebugEnabled()) { + log.debug("will destroy " + this); + } + + // remove all listeners + JAXXUtil.destroy(pcs); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + destroy(); + } + + protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + pcs.firePropertyChange(propertyName, oldValue, newValue); + } + + protected final void firePropertyChange(String propertyName, Object newValue) { + pcs.firePropertyChange(propertyName, null, newValue); + } +} \ No newline at end of file Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtStepModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUI.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUI.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUI.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,60 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.wizard.ext; + +import jaxx.runtime.swing.wizard.WizardUI; + +/** + * Contrat a respecter pour une ui de wizard. + * + * @author tchemit <chemit@codelutin.com> + * @param <E> le type d'etape + * @param <M> le type de model + * @since 1.3 + */ +public interface WizardExtUI<E extends WizardExtStep, M extends WizardExtModel<E>> extends WizardUI<E, M> { + + /** Méthode invoqué lorsque le modèle a été initialisé. */ + void onWasInit(); + + /** Méthode invoqué lorsque la première opération du modèlé a été démarrée. */ + void onWasStarted(); + + /** + * Méthode invoquée lorsque l'état interne du modèle a changé. + * + * @param newState le nouvelle état du modèle de wizard + */ + void onModelStateChanged(WizardState newState); + + /** + * Méthode invoqué lorsque l'état d'une opération a changé. + * + * @param step l'étape dont l'état a changé + * @param newState le nouvel état pour l'étape donné + */ + void onOperationStateChanged(E step, WizardState newState); + +} \ No newline at end of file Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUI.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUtil.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUtil.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUtil.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,124 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.wizard.ext; + +import jaxx.runtime.swing.wizard.WizardModel; +import jaxx.runtime.swing.wizard.WizardUI; +import jaxx.runtime.swing.wizard.WizardUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.IndexedPropertyChangeEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Array; +import java.util.List; + +/** + * Classe de méthodes utiles sur les wizard. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class WizardExtUtil extends WizardUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WizardUI.class); + + protected WizardExtUtil() { + } + + public static boolean acceptStates(WizardState state, WizardState... accepted) { + for (WizardState s : accepted) { + if (s == state) { + return true; + } + } + return false; + } + + public static boolean rejectStates(WizardState state, WizardState... rejected) { + for (WizardState s : rejected) { + if (s == state) { + return false; + } + } + return true; + } + + public static <E extends WizardExtStep, M extends WizardExtModel<E>> void installWizardUIListeners(final WizardExtUI<E, M> ui) { + + + PropertyChangeListener dispatcher = new PropertyChangeListener() { + + @Override + @SuppressWarnings("unchecked") + public void propertyChange(PropertyChangeEvent evt) { + String propertyName = evt.getPropertyName(); + if (WizardExtModel.WAS_STARTED_PROPERTY_NAME.equals(propertyName)) { + ui.onWasStarted(); + return; + } + WizardExtModel<E> model = (WizardExtModel<E>) evt.getSource(); + if (WizardModel.STEPS_PROPERTY_NAME.equals(propertyName)) { + List<E> steps = (List<E>) evt.getNewValue(); + ui.onStepsChanged( + steps.toArray((E[]) Array.newInstance( + model.getStepClass(), steps.size())) + ); + return; + } + if (WizardModel.STEP_PROPERTY_NAME.equals(propertyName)) { + ui.onStepChanged((E) evt.getNewValue()); + return; + } + if (WizardModel.VALID_STEP_PROPERTY_NAME.equals(propertyName)) { + Boolean value = (Boolean) evt.getNewValue(); + if (value == null || !value) { + ui.onModelStateChanged(WizardState.NEED_FIX); + } else { + ui.onModelStateChanged(WizardState.PENDING); + } + return; + } + if (WizardExtModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) { + //TODO should be unicast : only for good stepUI ? + ui.onModelStateChanged((WizardState) evt.getNewValue()); + return; + } + if (WizardExtModel.STEP_STATE_PROPERTY_NAME.equals(propertyName)) { + IndexedPropertyChangeEvent e = (IndexedPropertyChangeEvent) evt; + int stepIndex = e.getIndex(); + E step = model.getSteps().get(stepIndex); + ui.onOperationStateChanged(step, (WizardState) evt.getNewValue()); + } + } + }; + M model = ui.getModel(); + log.info("Adding dispatcher " + dispatcher + " to model " + model); + model.addPropertyChangeListener(dispatcher); + } + +} \ No newline at end of file Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardExtUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Copied: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardState.java (from rev 1950, trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/WizardState.java) =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardState.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardState.java 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,51 @@ +/* + * #%L + * JAXX :: Runtime + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.wizard.ext; + +/** + * Pour caractériser l'état d'une opération. + * + * @author tchemit <chemit@codelutin.com> + */ +public enum WizardState { + + /** quand l'opération n'a pas encore été réalisée */ + PENDING, + + /** quand l'opération est en cours */ + RUNNING, + + /** quand l'opération est annulé en cours d'exécution */ + CANCELED, + + /** quand une erreur s'est produite pendant l'exécution */ + FAILED, + + /** quand l'exécution s'est terminée mais requière des corrections */ + NEED_FIX, + + /** quand l'exécution s'est terminée et ne requière pas de correction */ + SUCCESSED +} Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/WizardState.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo + Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/package.html =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/package.html (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/package.html 2010-06-07 10:44:18 UTC (rev 1951) @@ -0,0 +1,9 @@ +<html> +<body> +<h1>JAXX - Wizard framework</h1> + +This package contains all the classes of the wizard framework ext. + +This is a enriched wizard with operation on some steps. +</body> +</html> Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/wizard/ext/package.html ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL