/* * ****************************************************************************** * MontiCore Language Workbench * Copyright (c) 2015, MontiCore, All rights reserved. * * This project 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.0 of the License, or (at your option) any later version. * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. * ****************************************************************************** */ package de.monticore.generating.templateengine.reporting.artifacts; import java.util.ArrayList; import java.util.List; import java.util.Stack; import de.monticore.ast.ASTNode; import de.monticore.generating.templateengine.reporting.artifacts.formatter.AFormatter; import de.monticore.generating.templateengine.reporting.artifacts.model.Element; import de.monticore.generating.templateengine.reporting.artifacts.model.ElementFactory; import de.monticore.generating.templateengine.reporting.artifacts.model.ElementType; import de.monticore.generating.templateengine.reporting.artifacts.model.RootPkg; import de.monticore.generating.templateengine.reporting.commons.AReporter; /** * Creates a dependency Graph based on a generator run. Dependency Graph can be printed via various * printers. * * @author (last commit) $Author$ * @version $Revision$, $Date$ */ public class ArtifactReporter extends AReporter { ElementFactory factory = new ElementFactory(); Stack<Element> elementStack = new Stack<Element>(); /** * Base of the generated dependency graph */ protected RootPkg rootPkg = new RootPkg(); // Nam of the dotgraph file private AFormatter formatter; // Filters to use private List<ElementType> filters = new ArrayList<ElementType>(); final static String SIMPLE_FILE_NAME = "Artifacts"; public ArtifactReporter(String path, String qualifiedFileName, String fileextension, AFormatter formatter, ElementType... filters) { super(path, qualifiedFileName, fileextension); this.formatter = formatter; this.addFilters(filters); } /** * Allow elements of type filter to be displayed. First invocation disables all other types */ public void addFilter(ElementType filter) { this.filters.add(filter); } /** * Add multiple filters at once * * @see addFilter */ public void addFilters(ElementType... filters) { for (ElementType filter : filters) { this.addFilter(filter); } } /* * (non-Javadoc) * @see mc.codegen.logging.GenLoggerDefaultClient#logModelStart(java.lang.String, * java.lang.String) */ @Override public void reportModelStart(ASTNode ast, String modelName, String fileName) { if (this.filters.isEmpty() || this.filters.contains(ElementType.MODEL)) { String extension = ReportingNameHelper.getSimpleName(fileName); Element e = rootPkg.resolve(ReportingNameHelper.getPath(modelName), ReportingNameHelper.getSimpleName(modelName), extension); if (e == null) { e = factory.createModel(rootPkg, modelName, extension); } count(e); elementStack.push(e); } } /* * (non-Javadoc) * @see mc.codegen.logging.GenLoggerDefaultClient#logTemplateStart(java.lang.String , * de.monticore.ast.ASTNode) */ @Override public void reportTemplateEnd(String templatename, ASTNode ast) { if (this.filters.isEmpty() || this.filters.contains(ElementType.TEMPLATE)) { elementStack.pop(); } } /* * (non-Javadoc) * @see mc.codegen.logging.GenLoggerDefaultClient#logTemplateStart(java.lang.String , * de.monticore.ast.ASTNode) */ @Override public void reportTemplateStart(String templatename, ASTNode ast) { if (this.filters.isEmpty() || this.filters.contains(ElementType.TEMPLATE)) { Element e = handleTemplate(templatename); count(e); elementStack.push(e); } } /* * (non-Javadoc) * @see mc.codegen.logging.GenLoggerDefaultClient#logFileCreation(java.lang.String, * java.lang.String, java.lang.String, de.monticore.ast.ASTNode) */ @Override public void reportFileCreation(String templatename, String qualifiedfilename, String fileextension, ASTNode ast) { if (this.filters.isEmpty() || this.filters.contains(ElementType.FILE)) { /* this method is called when the parent template of the template with name templatename is on * top of the stack. Therefore the template with name templatename has to be handled first */ Element template = handleTemplate(templatename); elementStack.push(template); Element e = rootPkg.resolve(ReportingNameHelper.getPath(qualifiedfilename), ReportingNameHelper.getSimpleName(qualifiedfilename), fileextension); if (e == null) { e = factory.createFile(rootPkg, qualifiedfilename, fileextension); } createElementLink(e); count(e); elementStack.pop(); } } /** * @param templatename * @return */ private Element handleTemplate(String templatename) { String extension = "ftl"; Element e = rootPkg.resolve(ReportingNameHelper.getPath(templatename), ReportingNameHelper.getSimpleName(templatename), extension); if (e == null) { e = factory.createTemplate(rootPkg, templatename, extension); } createElementLink(e); return e; } /** * @see mc.codegen.logging.GenLoggerDefaultClient#logInstantiateStart(java.lang.String, * java.util.List) */ @Override public void reportInstantiate(String className, List<Object> params) { if (this.filters.isEmpty() || this.filters.contains(ElementType.HELPER)) { String extension = "java"; Element e = rootPkg.resolve(ReportingNameHelper.getPath(className), ReportingNameHelper.getSimpleName(className), extension); if (e == null) { e = factory.createHelper(rootPkg, className, extension); } createElementLink(e); count(e); } } /* * (non-Javadoc) * @see mc.codegen.logging.GenLoggerDefaultClient#finish() */ @Override public void flush(ASTNode node) { writeContent(); resetVariables(); super.flush(node); } private void resetVariables() { rootPkg = new RootPkg(); elementStack.clear(); } private void writeContent() { List<String> lines = formatter.getContent(rootPkg); for (String l : lines) { writeLine(l); } } /** * Creates a link from the top element of the stack to the given element. This only works if the * stack is not empty. * * @param element */ private void createElementLink(Element element) { if (!elementStack.isEmpty()) { elementStack.peek().addlink(element); } } public void count(Element element) { element.incCalls(); if (!elementStack.isEmpty()) { Element source = elementStack.peek(); source.incLinkCalls(element); } } /** * @see mc.codegen.reporting.commons.AReporter#writeHeader() */ @Override protected void writeHeader() { // Write empty header } }