package org.openflexo.builders.utils; import java.util.EventObject; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.openflexo.builders.FlexoExternalMainWithProject; import org.openflexo.components.ProgressWindow; import org.openflexo.dg.ProjectDocGenerator; import org.openflexo.dg.docx.ProjectDocDocxGenerator; import org.openflexo.dg.html.ProjectDocHTMLGenerator; import org.openflexo.foundation.DefaultFlexoEditor; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.action.FlexoAction; import org.openflexo.foundation.action.ValidateProject; import org.openflexo.foundation.cg.CGRepository; import org.openflexo.foundation.cg.DGRepository; import org.openflexo.foundation.cg.GenerationRepository; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.utils.FlexoProgressFactory; import org.openflexo.generator.AbstractProjectGenerator; import org.openflexo.generator.ProjectGenerator; import org.openflexo.generator.action.GCAction.ProjectGeneratorFactory; import org.openflexo.generator.exception.GenerationException; import com.sun.istack.NotNull; /** * This class extends the DefaultFlexoEditor for the Flexo server application. So far the implementation is just a simple extension of the * default editor but it may be used later for additional purposes. * * @author gpolet * */ public class FlexoBuilderEditor extends DefaultFlexoEditor implements ProjectGeneratorFactory { protected static final Logger logger = Logger.getLogger(FlexoBuilderEditor.class.getPackage().getName()); private AbstractProjectGenerator<? extends GenerationRepository> projectGenerator; private ProjectDocGenerator projectDocGenerator; private final FlexoExternalMainWithProject externalMainWithProject; public FlexoBuilderEditor(FlexoExternalMainWithProject externalMainWithProject, FlexoProject project) { super(project); this.externalMainWithProject = externalMainWithProject; } @Override public AbstractProjectGenerator<? extends GenerationRepository> generatorForRepository(GenerationRepository repository) { if (repository instanceof CGRepository) { if (projectGenerator == null) { try { projectGenerator = new ProjectGenerator(this.getProject(), (CGRepository) repository); } catch (GenerationException e) { logger.log(Level.SEVERE, "Error while generating code.", e); } } return projectGenerator; } else if (repository instanceof DGRepository) { if (projectDocGenerator == null) { try { switch (repository.getFormat()) { /*case LATEX: projectDocGenerator = new ProjectDocLatexGenerator(this.getProject(), (DGRepository) repository); break;*/ case HTML: projectDocGenerator = new ProjectDocHTMLGenerator(this.getProject(), (DGRepository) repository); break; case DOCX: projectDocGenerator = new ProjectDocDocxGenerator(this.getProject(), (DGRepository) repository); break; default: logger.severe("Invalid format in repository to generate documentation. Format: " + repository.getFormat()); } } catch (GenerationException e) { logger.log(Level.SEVERE, "Error while generating documentation.", e); } } return projectDocGenerator; } return null; } private FlexoProgressFactory flexoProgressFactory; private volatile List<FlexoAction<?, ?, ?>> todos; private Runnable whenDone; protected Throwable exception; @Override public <A extends FlexoAction<A, T1, T2>, T1 extends FlexoModelObject, T2 extends FlexoModelObject> A performAction(final A action, EventObject event) { if (action.getActionType() == ValidateProject.actionType) { return action; } if (action.isLongRunningAction() && SwingUtilities.isEventDispatchThread()) { ProgressWindow.showProgressWindow(action.getLocalizedName(), 100); SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { @Override protected Void doInBackground() throws Exception { try { action.doActionInContext(); } catch (Throwable e) { e.printStackTrace(); FlexoBuilderEditor.this.exception = e; } return null; } @Override protected void done() { if (!action.isEmbedded()) { doNextTodo(action); } if (FlexoBuilderEditor.this.exception != null) { externalMainWithProject.setExitCodePrintStackTraceCleanUpAndExit(FlexoBuilderEditor.this.exception); } } }; worker.execute(); } else { try { action.doActionInContext(); } catch (Throwable e) { FlexoBuilderEditor.this.exception = e; externalMainWithProject.setExitCodePrintStackTraceCleanUpAndExit(e); } if (!action.isEmbedded()) { doNextTodo(action); } } return action; } public void chainActions(List<FlexoAction<?, ?, ?>> actions, Runnable whenDone) { this.todos = actions; this.whenDone = whenDone; doNextTodo(null); } public <A extends FlexoAction<?, T1, T2>, T1 extends FlexoModelObject, T2 extends FlexoModelObject> void doNextTodo(final A action) { if (action != null && (!action.hasActionExecutionSucceeded() || exception != null)) { externalMainWithProject.handleActionFailed(action); } else { if (todos == null && whenDone == null) { return; } if (todos.isEmpty()) { class RunnableExceptionCatcher implements Runnable { private Runnable toRun; public RunnableExceptionCatcher(@NotNull Runnable toRun) { super(); this.toRun = toRun; } @Override public void run() { try { toRun.run(); } catch (Throwable t) { FlexoBuilderEditor.this.exception = t; externalMainWithProject.setExitCodePrintStackTraceCleanUpAndExit(t); } } } SwingUtilities.invokeLater(new RunnableExceptionCatcher(whenDone)); } else { final FlexoAction<?, ?, ?> todo = todos.remove(0); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { todo.doAction(); } catch (Throwable e) { e.printStackTrace(); externalMainWithProject.handleActionFailed(todo); } } }); } } } @Override public FlexoProgressFactory getFlexoProgressFactory() { return flexoProgressFactory; } public void setFactory(FlexoProgressFactory flexoProgressFactory) { this.flexoProgressFactory = flexoProgressFactory; } @Override public boolean performResourceScanning() { return false; } }