/* * ****************************************************************************** * 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.commons; import java.nio.file.Path; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.slf4j.Logger; import org.slf4j.Marker; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import de.monticore.ast.ASTNode; import de.monticore.io.paths.IterablePath; import de.monticore.symboltable.Scope; import de.monticore.symboltable.Symbol; import de.monticore.symboltable.references.SymbolReference; import de.se_rwth.commons.SourcePosition; import de.se_rwth.commons.logging.Log; /** * ReportingRepository holds all used formatted ASTNode strings. All string * representations for a ASTNode should be retrieved from this repository * (getASTNodeNameFormatted method). * * @author BM */ public class ReportingRepository { private IASTNodeIdentHelper astNodeIdentHelper; // save objects that have no position private Map<Object, Integer> node2Ident = Maps.newHashMap(); private Map<Object, String> node2Name = Maps.newHashMap(); // save nodes that have a position private Map<String, Integer> name2maxidSourcePos = Maps.newHashMap(); private Map<Object, Integer> nodeWithSource2Ident = Maps.newHashMap(); private Map<Object, String> nodeWithSource2Name = Maps.newHashMap(); // save current maxID for aSTNode string private Map<String, Integer> name2maxid = Maps.newHashMap(); private Set<String> allTemplateNames = Sets.newLinkedHashSet(); private Set<String> allHWJavaNames = Sets.newLinkedHashSet(); private Set<String> allHWTemplateNames = Sets.newLinkedHashSet(); public ReportingRepository(IASTNodeIdentHelper astNodeIdentHelper) { this.astNodeIdentHelper = astNodeIdentHelper; } /** * Populates this repository with all resolved paths from the given iterable * path. * * @param hwcPath * @see IterablePath#getResolvedPaths() * @see IterablePath#from(List, String) */ public void initAllHWJava(IterablePath hwcPath) { Iterator<Path> hwcFiles = hwcPath.getResolvedPaths(); while (hwcFiles.hasNext()) { allHWJavaNames.add(hwcFiles.next().toAbsolutePath().toString()); } } /** * Populates this repository with all resolved paths from the given iterable * path. * * @param hwtPath * @see IterablePath#getResolvedPaths() * @see IterablePath#from(List, String) */ public void initAllHWTemplates(IterablePath hwtPath) { Iterator<Path> hwtFiles = hwtPath.get(); while (hwtFiles.hasNext()) { allHWTemplateNames.add(hwtFiles.next().toFile().toString().replaceAll("\\\\", "/")); } } /** * Scans the current class path for templates and stores them in this * repository. */ public void initAllTemplates() { // it's a kind of magic Reflections.log = new Helper(); Reflections helper = new Reflections(new ConfigurationBuilder() .addClassLoader(ClasspathHelper.contextClassLoader()) .setUrls(ClasspathHelper.forClassLoader()) .setScanners(new ResourcesScanner())); this.allTemplateNames = helper.getResources(Pattern.compile(".*\\.ftl")); } private String getNameFormatted(Object obj, String out, SourcePosition sourcePos) { String pos = Layouter.sourcePos(sourcePos); // node has a source position if (!sourcePos.equals( SourcePosition.getDefaultSourcePosition())) { if (!nodeWithSource2Ident.containsKey(obj)) { // set output name for node nodeWithSource2Name.put(obj, out + pos); // name map has no identifier if (!name2maxidSourcePos.containsKey(out + pos)) { // init map MapUtil.incMapValue(name2maxidSourcePos, out + pos); // value is 1 } nodeWithSource2Ident.put(obj, name2maxidSourcePos.get(out + pos)); MapUtil.incMapValue(name2maxidSourcePos, out + pos); // increase current // value } // do not print <...>!1! if (nodeWithSource2Ident.get(obj) != 1) { return nodeWithSource2Name.get(obj).replace(Layouter.END_TAG, "!" + nodeWithSource2Ident.get(obj) + Layouter.END_TAG); } // instead <<...>> if identifier is '1' else { return nodeWithSource2Name.get(obj); } } // first time this node if (!node2Ident.containsKey(obj)) { // set output name for node node2Name.put(obj, out); // name map has no identifier if (!name2maxid.containsKey(out)) { // init map MapUtil.incMapValue(name2maxid, out); } node2Ident.put(obj, name2maxid.get(out)); MapUtil.incMapValue(name2maxid, out); } // do not print <<...>>!1! if (node2Ident.get(obj) != 1) { return node2Name.get(obj) + Layouter.START_TAG + "!" + node2Ident.get(obj) + Layouter.END_TAG; } // instead <<...>> if identifier is '1' else { return node2Name.get(obj); } } /** * Method that converts the ASTNode into a formatted string with a source * position if this is possible. The structure of the string is * @nodeName!nodeType(x,y) or @nodeName!nodeType(!ID). * * @param ASTNode that should be converted into unique String * @return representation of the ASTNode that contains either the position or * a unique identification number for the object */ public String getASTNodeNameFormatted(ASTNode a) { String out = astNodeIdentHelper.getIdent(a); return getNameFormatted(a, out, a.get_SourcePositionStart()); } /** * Method that converts the Symbol into a formatted string with a source * position if this is possible. The structure of the string is * @symbolName!symbolType(x,y) or @symbolName!symbolType(!ID). * * @param symbol The symbol that should be converted into unique String * @return representation of the ASTNode that contains either the position or * a unique identification number for the object */ public String getSymbolNameFormatted(Symbol symbol) { String name = astNodeIdentHelper.getIdent(symbol); return getNameFormatted(symbol, name, symbol.getSourcePosition()); } /** * Method that converts the SymbolReference into a formatted string with a source * position if this is possible. The structure of the string is * @symbolName!symbolType(x,y) or @symbolName!symbolType(!ID). * * @param symbol The symbol that should be converted into unique String * @return representation of the ASTNode that contains either the position or * a unique identification number for the object */ public String getSymbolNameFormatted(SymbolReference<?> symbolReference) { String name = astNodeIdentHelper.getIdent(symbolReference); return getNameFormatted(symbolReference, name, SourcePosition.getDefaultSourcePosition()); } /** * Method that converts the Symbol into a formatted string with a source * position if this is possible. The structure of the string is * @symbolName!symbolType(x,y) or @symbolName!symbolType(!ID). * * @param symbol The symbol that should be converted into unique String * @return representation of the ASTNode that contains either the position or * a unique identification number for the object */ public String getScopeNameFormatted(Scope scope) { String name = astNodeIdentHelper.getIdent(scope); return getNameFormatted(scope, name, SourcePosition.getDefaultSourcePosition()); } public Set<String> getAllTemplateNames() { return allTemplateNames; } public Set<String> getAllHWJavaNames() { return allHWJavaNames; } public Set<String> getAllHWTemplateNames() { return allHWTemplateNames; } /* This is the magic. Don't touch it ;-) */ private class Helper implements Logger { @Override public boolean isTraceEnabled() { return Log.isTraceEnabled(ReportingRepository.class.getName()); } @Override public void trace(String msg) { Log.trace(msg, ReportingRepository.class.getName()); } @Override public void trace(String format, Object arg) { this.trace(String.format(format, new Object[] { arg })); } @Override public void trace(String format, Object arg1, Object arg2) { this.trace(String.format(format, new Object[] { arg1, arg2 })); } @Override public void trace(String format, Object... arguments) { this.trace(String.format(format, arguments)); } @Override public void trace(String msg, Throwable t) { Log.trace(msg, t, ReportingRepository.class.getName()); } @Override public boolean isDebugEnabled() { return Log.isDebugEnabled(ReportingRepository.class.getName()); } @Override public void debug(String msg) { Log.debug(msg, ReportingRepository.class.getName()); } @Override public void debug(String format, Object arg) { this.debug(String.format(format, new Object[] { arg })); } @Override public void debug(String format, Object arg1, Object arg2) { this.debug(String.format(format, new Object[] { arg1, arg2 })); } @Override public void debug(String format, Object... arguments) { this.debug(String.format(format, arguments)); } @Override public void debug(String msg, Throwable t) { Log.debug(msg, t, ReportingRepository.class.getName()); } @Override public boolean isInfoEnabled() { return this.isDebugEnabled(); } @Override public void info(String msg) { this.debug(msg); } @Override public void info(String format, Object arg) { this.debug(format, arg); } @Override public void info(String format, Object arg1, Object arg2) { this.debug(format, arg1, arg2); } @Override public void info(String format, Object... arguments) { this.debug(format, arguments); } @Override public void info(String msg, Throwable t) { this.debug(msg, t); } @Override public boolean isWarnEnabled() { return true; } @Override public void warn(String msg) { Log.warn(msg); } @Override public void warn(String format, Object arg) { this.warn(String.format(format, new Object[] { arg })); } @Override public void warn(String format, Object... arguments) { this.warn(String.format(format, arguments)); } @Override public void warn(String format, Object arg1, Object arg2) { this.warn(String.format(format, new Object[] { arg1, arg2 })); } @Override public void warn(String msg, Throwable t) { Log.warn(msg, t); } @Override public boolean isErrorEnabled() { return true; } @Override public void error(String msg) { Log.error(msg); } @Override public void error(String format, Object arg) { this.error(String.format(format, new Object[] { arg })); } @Override public void error(String format, Object arg1, Object arg2) { this.error(String.format(format, new Object[] { arg1, arg2 })); } @Override public void error(String format, Object... arguments) { this.error(String.format(format, arguments)); } @Override public void error(String msg, Throwable t) { Log.error(msg, t); } @Override public String getName() { return ReportingRepository.class.getName(); } @Override public boolean isTraceEnabled(Marker marker) { return this.isTraceEnabled(); } @Override public void trace(Marker marker, String msg) { this.trace(msg); } @Override public void trace(Marker marker, String format, Object arg) { this.trace(format, arg); } @Override public void trace(Marker marker, String format, Object arg1, Object arg2) { this.trace(format, arg1, arg2); } @Override public void trace(Marker marker, String format, Object... argArray) { this.trace(format, argArray); } @Override public void trace(Marker marker, String msg, Throwable t) { this.trace(msg, t); } @Override public boolean isDebugEnabled(Marker marker) { return this.isDebugEnabled(); } @Override public void debug(Marker marker, String msg) { this.debug(msg); } @Override public void debug(Marker marker, String format, Object arg) { this.debug(format, arg); } @Override public void debug(Marker marker, String format, Object arg1, Object arg2) { this.debug(format, arg1, arg2); } @Override public void debug(Marker marker, String format, Object... arguments) { this.debug(format, arguments); } @Override public void debug(Marker marker, String msg, Throwable t) { this.debug(msg, t); } @Override public boolean isInfoEnabled(Marker marker) { return this.isInfoEnabled(); } @Override public void info(Marker marker, String msg) { this.info(msg); } @Override public void info(Marker marker, String format, Object arg) { this.info(format, arg); } @Override public void info(Marker marker, String format, Object arg1, Object arg2) { this.info(format, arg1, arg2); } @Override public void info(Marker marker, String format, Object... arguments) { this.info(format, arguments); } @Override public void info(Marker marker, String msg, Throwable t) { this.info(msg, t); } @Override public boolean isWarnEnabled(Marker marker) { return this.isWarnEnabled(); } @Override public void warn(Marker marker, String msg) { this.warn(msg); } @Override public void warn(Marker marker, String format, Object arg) { this.warn(format, arg); } @Override public void warn(Marker marker, String format, Object arg1, Object arg2) { this.warn(format, arg1, arg2); } @Override public void warn(Marker marker, String format, Object... arguments) { this.warn(format, arguments); } @Override public void warn(Marker marker, String msg, Throwable t) { this.warn(msg, t); } @Override public boolean isErrorEnabled(Marker marker) { return this.isErrorEnabled(); } @Override public void error(Marker marker, String msg) { this.error(msg); } @Override public void error(Marker marker, String format, Object arg) { this.error(format, arg); } @Override public void error(Marker marker, String format, Object arg1, Object arg2) { this.error(format, arg1, arg2); } @Override public void error(Marker marker, String format, Object... arguments) { this.error(format, arguments); } @Override public void error(Marker marker, String msg, Throwable t) { this.error(msg, t); } } }