/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo 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 3 of the License, or * (at your option) any later version. * * OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.generator.action; import java.util.Vector; import java.util.logging.Logger; import org.openflexo.foundation.FlexoEditor; import org.openflexo.foundation.FlexoException; import org.openflexo.foundation.action.ActionGroup; import org.openflexo.foundation.action.ActionMenu; import org.openflexo.foundation.action.FlexoActionType; import org.openflexo.foundation.cg.CGObject; import org.openflexo.foundation.cg.GeneratedOutput; import org.openflexo.foundation.cg.GenerationRepository; import org.openflexo.foundation.cg.version.AbstractCGFileVersion; import org.openflexo.generator.AbstractProjectGenerator; import org.openflexo.generator.file.AbstractCGFile; import org.openflexo.logging.FlexoLogger; /** * Abstract class for actions applying on a set of CGFile * * @author sylvain * */ public abstract class MultipleFileGCAction<A extends MultipleFileGCAction<A>> extends GCAction<A, CGObject> { @SuppressWarnings("unused") private static final Logger logger = FlexoLogger.getLogger(MultipleFileGCAction.class.getPackage().getName()); public static abstract class MultipleFileGCActionType<A extends MultipleFileGCAction<A>> extends FlexoActionType<A, CGObject, CGObject> { protected MultipleFileGCActionType(String actionName, ActionMenu actionMenu, ActionGroup actionGroup, int actionCategory) { super(actionName, actionMenu, actionGroup, actionCategory); } protected MultipleFileGCActionType(String actionName, ActionGroup actionGroup, int actionCategory) { super(actionName, actionGroup, actionCategory); } @Override public boolean isVisibleForSelection(CGObject focusedObject, Vector<CGObject> globalSelection) { if (focusedObject instanceof AbstractCGFileVersion) { return false; } Vector<CGObject> topLevelObjects = getSelectedTopLevelObjects(focusedObject, globalSelection); for (CGObject obj : topLevelObjects) { if (obj instanceof GeneratedOutput) { return false; } } return true; } @Override public boolean isEnabledForSelection(CGObject focusedObject, Vector<CGObject> globalSelection) { GenerationRepository repository = getRepository(focusedObject, globalSelection); if (repository == null) { return false; } AbstractProjectGenerator<? extends GenerationRepository> pg = getProjectGenerator(repository); if (pg == null || !pg.hasBeenInitialized()) { return false; } Vector<AbstractCGFile> selectedFiles = getSelectedCGFilesOnWhyCurrentActionShouldApply(focusedObject, globalSelection); return selectedFiles.size() > 0; } protected Vector<AbstractCGFile> getSelectedCGFilesOnWhyCurrentActionShouldApply(CGObject focusedObject, Vector<CGObject> globalSelection) { Vector<AbstractCGFile> selectedFiles = getSelectedCGFiles(focusedObject, globalSelection); Vector<AbstractCGFile> returned = new Vector<AbstractCGFile>(); for (AbstractCGFile file : selectedFiles) { if (!file.getMarkedAsDoNotGenerate() && accept(file)) { returned.add(file); } } return returned; } protected abstract boolean accept(AbstractCGFile aFile); } @Override public final boolean isLongRunningAction() { return true; } /* public void actionStarted(CGFileRunnable runnable) { if (getFlexoProgress()!=null) getFlexoProgress().setProgress(runnable.getLocalizedName()); } public void actionEnded(CGFileRunnable runnable) { } public void actionFailed(CGFileRunnable runnable, Exception e, String message) { } public abstract class CGFileRunnable implements Runnable { protected AbstractCGFile file; public CGFileRunnable(AbstractCGFile file) { this.file = file; } public void notifyActionStarted() { actionStarted(this); } public void notifyActionEnded() { actionEnded(this); } public void notifyActionFailed(Exception e, String message) { actionFailed(this, e, message); } public abstract String getLocalizedName(); } private ThreadPoolExecutor threadPool; public abstract boolean requiresThreadPool(); public boolean allJobsAreDone() { return threadPool.isTerminated(); } */ protected MultipleFileGCAction(final MultipleFileGCActionType<A> actionType, CGObject focusedObject, Vector<CGObject> globalSelection, FlexoEditor editor) { super(actionType, focusedObject, globalSelection, editor); /*if (requiresThreadPool()) threadPool = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() { public Thread newThread(Runnable r) { return new Thread(r); } }) { @Override protected void beforeExecute(Thread t, Runnable r) { if (r instanceof MultipleFileGCAction<?>.CGFileRunnable) actionStarted((CGFileRunnable) r); if (r instanceof MultipleFileGCAction<?>.CGFileRunnable) t.setName(actionType.getLocalizedName() + " on " + ((MultipleFileGCAction<?>.CGFileRunnable) r).file.getFileName()); super.beforeExecute(t, r); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (r instanceof MultipleFileGCAction<?>.CGFileRunnable) actionEnded((CGFileRunnable) r); } };*/ } private Vector<AbstractCGFile> files; @Override public MultipleFileGCActionType<A> getActionType() { return (MultipleFileGCActionType<A>) super.getActionType(); } protected Vector<AbstractCGFile> getSelectedCGFilesOnWhyCurrentActionShouldApply() { if (files == null) { files = getActionType().getSelectedCGFilesOnWhyCurrentActionShouldApply(getFocusedObject(), getGlobalSelection()); } return files; } @Override protected final void doAction(Object context) throws FlexoException { GenerationRepository repository = getRepository(); repository.notifyLongOperationStarted(); try { doImpl(context); } finally { repository.notifyLongOperationStopped(); } } protected abstract void doImpl(Object context) throws FlexoException; // public abstract void performActionOnFile(AbstractCGFile file); /* public void addJob(MultipleFileGCAction<?>.CGFileRunnable job) { threadPool.execute(job); } public void waitForAllJobsToComplete() { /* * The next line does not stop everything. It simply prevents new job from being added to the pool and allows the method * isTerminated() to return true once all jobs are completed */ /* threadPool.shutdown(); while (!threadPool.isTerminated()) { synchronized (this) { try { wait(300); getEditor().performPendingActions(); } catch (InterruptedException e) { } } } } */ }