Java tutorial
/** Copyright (C) 2016 Nicola Justus <nicola.justus@mni.thm.de> * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package omc.corba; import omc.Global; import omc.corba.parser.ListLexer; import omc.corba.parser.ListParser; import omc.corba.parser.ListParser.ListElementContext; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** Helper for creating commands/expressions for the corba-interface. * This class contains convenient converters to generate Modelica-code. */ public final class ScriptingHelper { //regex voodoo; thumbs up for escaping the escape characters ;) private static String bckslash = "\\\\"; //matches: [{}] AND [{bla, "blup", hans}] private static Pattern extractArrayPattern = Pattern.compile("^\\{+((?:.|\\n)*?)\\}+$"); private static String arraySplitRegex = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; private static Pattern pathPattern = Pattern.compile("((?:\\w:)?(((?:\\/|\\\\)[\\w\\-\\.\\s]+)+))"); private static final String withinRegex = "within\\s+([\\w\\._]+);"; private static final String modelRegex = "(?:(?:model)|(?:class)|(?:package)|(?:function)|(?:connector))\\s+([\\w\\d_]+)"; private static final Pattern withinPattern = Pattern.compile(withinRegex); public static final Pattern modelPattern = Pattern.compile(modelRegex); private ScriptingHelper() { } /** Turns the given object into a modelica string. */ public static String asString(Object str) { return "\"" + str.toString() + "\""; } /** Turns the given collection into an modelica array. */ public static String asArray(Collection<?> c) { return "{" + asParameterList(c) + "}"; } /** Turns the given collection into a modelica parameterlist. */ public static String asParameterList(Collection<?> c) { if (c.isEmpty()) return ""; else { StringBuilder sb = new StringBuilder(); c.forEach(x -> sb.append(x.toString() + ", ")); return sb.substring(0, sb.length() - 2); } } /** Turns the given collection into an modelica array of strings. */ public static String asStringArray(Collection<?> c) { List<?> xs = c.stream().map(ScriptingHelper::asString).collect(Collectors.toList()); return asArray(xs); } /** Turns the given collection into a modelica parameterlist of * strings using Object#toString(). */ public static String asStringParameterList(Collection<?> c) { List<?> xs = c.stream().map(ScriptingHelper::asString).collect(Collectors.toList()); return asParameterList(xs); } /** Removes trailing and leading quotes (") from `s`. */ public static String killTrailingQuotes(String s) { if (s.equals("\"\"")) return ""; else return s.trim().replaceAll("^\"|\"$", ""); } /** Turns the given modelica expression - which should be an array - * into a List of Strings. */ public static List<String> fromArray(String modelicaExpr) { Matcher matcher = extractArrayPattern.matcher(modelicaExpr); matcher.find(); String extractedArray = matcher.group(1); String[] subs = extractedArray.split(arraySplitRegex); return (subs.length == 0 || extractedArray.isEmpty()) ? Collections.emptyList() : Arrays.stream(subs).map(String::trim).collect(Collectors.toList()); } /** Turns the given modelica expression - which should be an array - * into a flat List of Strings. */ public static List<String> fromNestedArray(String modelicaExpr) { List<String> list = new ArrayList<>(); try { ListParser p = new ListParser(new CommonTokenStream( new ListLexer(new ANTLRInputStream(new ByteArrayInputStream(modelicaExpr.getBytes()))))); ListParser.ListContext listContext = p.list(); if (listContext != null) return fromNestedArray(listContext.listElement()); } catch (IOException e) { e.printStackTrace(); } return list; } private static List<String> fromNestedArray(List<ListElementContext> list) { List<String> l = new ArrayList<>(); for (ListElementContext lec : list) { if (lec.list() != null) l.addAll(fromNestedArray(lec.list().listElement())); else if (lec.bool() != null) l.add(lec.bool().getText()); else if (lec.number() != null) l.add(lec.number().getText()); else if (lec.string() != null) l.add(lec.string().getText()); else if (lec.path() != null) l.add(lec.path().getText()); } return l; } /** Turns the given modelica expression - which should be an array - * into a flat List of Strings. */ public static List<Object> fromNestedArrayToNestedList(String modelicaExpr) { List<Object> list = new ArrayList<>(); try { ListParser p = new ListParser(new CommonTokenStream( new ListLexer(new ANTLRInputStream(new ByteArrayInputStream(modelicaExpr.getBytes()))))); ListParser.ListContext listContext = p.list(); if (listContext != null) return fromNestedArrayToNestedList(listContext.listElement()); } catch (IOException e) { e.printStackTrace(); } return list; } private static List<Object> fromNestedArrayToNestedList(List<ListElementContext> list) { List<Object> l = new ArrayList<>(); for (ListElementContext lec : list) { if (lec.list() != null) l.add(fromNestedArrayToNestedList(lec.list().listElement())); else if (lec.bool() != null) l.add(lec.bool().getText()); else if (lec.number() != null) l.add(lec.number().getText()); else if (lec.string() != null) l.add(lec.string().getText().replaceAll("^\\\"|\\\"$", "")); else if (lec.path() != null) l.add(lec.path().getText()); } return l; } /** Returns the `name` of a model inside of `modelicaCode`. * <P>Note: If there are more than one models the result is the * first model. </P> */ public static Optional<String> getModelName(String modelicaCode) { Matcher withinMatcher = withinPattern.matcher(modelicaCode); Matcher modelMatcher = modelPattern.matcher(modelicaCode); String packageName = ""; if (withinMatcher.find()) { packageName = withinMatcher.group(1) + "."; } if (modelMatcher.find()) { String modelName = modelMatcher.group(1); return Optional.of(packageName + modelName); } else return Optional.empty(); } /** Returns the `name` of a model in the `file`. * @see ScriptingHelper#getModelName(String) */ public static Optional<String> getModelName(Path file) throws IOException { return getModelName(new String(Files.readAllBytes(file), Global.encoding)); } /** Extracts a path from the given string `str`. */ public static Optional<String> extractPath(String str) { Matcher pathMatcher = pathPattern.matcher(str); if (pathMatcher.find()) { String path = pathMatcher.group(1); return Optional.of(path); } else return Optional.empty(); } public static String convertPath(String path) { if (Global.isWindowsOS()) return asString(path.replace("\\", "\\\\")); else return asString(path); } public static String convertPath(Path path) { return convertPath(path.toString()); } }