/* * (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.foundation.wkf; import java.util.Hashtable; import java.util.logging.Logger; import org.openflexo.antar.AlgorithmicUnit; import org.openflexo.kvc.KVCObject; import org.openflexo.localization.FlexoLocalization; import org.openflexo.toolbox.ProgrammingLanguage; /** * This interface is implemented by objects for which a control graph is available in the context of workflow execution * * @author sylvain * */ public interface ExecutableWorkflowElement { public String getExecutableElementName(); public void setProgrammingLanguageForControlGraphComputation(ProgrammingLanguage language); public void setInterproceduralForControlGraphComputation(boolean interprocedural); public static abstract class ControlGraphFactory<E extends ExecutableWorkflowElement> { public static final ProgrammingLanguage DEFAULT_LANGUAGE = ProgrammingLanguage.JAVA; public static final boolean DEFAULT_INTERPROCEDURAL = true; private String unlocalizedInfoLabel; private Hashtable<E, WorkflowControlGraph<E>> storedControlGraphs; public ControlGraphFactory(String unlocalizedInfoLabel) { this.unlocalizedInfoLabel = unlocalizedInfoLabel; storedControlGraphs = new Hashtable<E, WorkflowControlGraph<E>>(); } public WorkflowControlGraph<E> getControlGraph(E object) { if (storedControlGraphs.get(object) == null) { storedControlGraphs.put(object, makeWorkflowControlGraph(object)); } return storedControlGraphs.get(object); } public WorkflowControlGraph<E> makeWorkflowControlGraph(E object) { return new WorkflowControlGraph<E>(object, this); } public abstract AlgorithmicUnit computeAlgorithmicUnit(E object, boolean interprocedural); public String getInfoLabel() { return FlexoLocalization.localizedForKey(unlocalizedInfoLabel); } public abstract String prettyPrintedCode(AlgorithmicUnit algorithmicUnit, ProgrammingLanguage language); } public static class WorkflowControlGraph<E extends ExecutableWorkflowElement> extends KVCObject { private static final Logger logger = Logger.getLogger(ExecutableWorkflowElement.WorkflowControlGraph.class.getPackage().getName()); private E object; private ControlGraphFactory<E> factory; protected AlgorithmicUnit algorithmicUnit; private String code; private ProgrammingLanguage language = ControlGraphFactory.DEFAULT_LANGUAGE; protected boolean interprocedural = ControlGraphFactory.DEFAULT_INTERPROCEDURAL; public WorkflowControlGraph(E object, ControlGraphFactory<E> factory) { this.object = object; this.factory = factory; refresh(); } public void refresh() { refreshAlgorithmicUnit(); } protected void refreshAlgorithmicUnit() { logger.info("Recomputing control flow graph for " + object + " interprocedural=" + interprocedural); algorithmicUnit = factory.computeAlgorithmicUnit(object, interprocedural); refreshPrettyPrintedCode(); } protected void refreshPrettyPrintedCode() { logger.info("Pretty-printing code for " + object + " language=" + language); code = factory.prettyPrintedCode(algorithmicUnit, language); // logger.info("Obtaining: "+code); } public String getInfoLabel() { return factory.getInfoLabel(); } public String getFormattedCode() { return code; } public E getObject() { return object; } public ControlGraphFactory<E> getFactory() { return factory; } public boolean isInterprocedural() { return interprocedural; } public void setInterprocedural(boolean interprocedural) { if (interprocedural != this.interprocedural) { this.interprocedural = interprocedural; refreshAlgorithmicUnit(); } } public ProgrammingLanguage getProgrammingLanguage() { return language; } public void setProgrammingLanguage(ProgrammingLanguage language) { if (language != this.language) { this.language = language; refreshPrettyPrintedCode(); } } public AlgorithmicUnit getAlgorithmicUnit() { return algorithmicUnit; } } }