/** * Copyright 2010-2017 Evgeny Gryaznov * * 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 org.textmapper.idea.compiler; import org.jetbrains.annotations.Nullable; import org.textmapper.lapg.api.ProcessingStatus; import org.textmapper.lapg.common.FileUtil; import org.textmapper.templates.storage.FileBasedResourceLoader; import org.textmapper.templates.storage.IResourceLoader; import org.textmapper.tool.common.GeneratedFile; import org.textmapper.tool.gen.TMGenerator; import org.textmapper.tool.gen.TMOptions; import org.textmapper.tool.gen.ProcessingStrategy; import org.textmapper.tool.parser.TMTree.TextSource; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Gryaznov Evgeny, 3/13/11 */ public class TMSyntaxBuilder implements ProcessingStrategy { private static final Pattern FILENAME = Pattern.compile("([\\w-]+/)*[\\w-]+(\\.\\w+)?"); private final File file; private final String fileContent; private TMOptions options; private final ProcessingStatus status; private Map<String, String> myGeneratedContent; public TMSyntaxBuilder(File file, @Nullable String fileContent, TMOptions options, ProcessingStatus status) { this.file = file; this.fileContent = fileContent; this.options = options; this.status = status; } public Map<String, String> getGeneratedContent() { return myGeneratedContent; } private String getContents() { String contents = fileContent; if (contents != null) { return contents; } try { contents = FileUtil.getFileContents(new FileInputStream(file), FileUtil.DEFAULT_ENCODING); } catch (FileNotFoundException ex) { status.report(ProcessingStatus.KIND_ERROR, "file not found " + file.getName()); return null; } if (contents == null) { status.report(ProcessingStatus.KIND_ERROR, "cannot read " + file.getName()); return null; } return contents; } public boolean generate() { String contents = getContents(); if (contents == null) { return false; } myGeneratedContent = new HashMap<>(); TextSource input = new TextSource(file.getPath(), contents, 1); return new TMGenerator(options, status, this).compileGrammar(input, false); } public void createFile(String name, String contents, Map<String, Object> options, ProcessingStatus status) { try { new GeneratedFile(null, name, contents, options) { @Override public void create() throws IOException { checkName(name); String data = getData(); myGeneratedContent.put(name, data); } @Override protected void checkName(String name) throws IOException { // FIXME Matcher m = FILENAME.matcher(name); if (!m.matches()) { throw new IOException("bad file name: " + name); } } }.create(); } catch (IOException e) { /* cannot happen */ } } public IResourceLoader createResourceLoader(String path) { File folder = new File(path); if (folder.isDirectory()) { // FIXME charset return new FileBasedResourceLoader(new File[]{folder}, FileUtil.DEFAULT_ENCODING); } return null; } /** * returns false if content is unchanged */ static boolean writeFile(File file, String content) throws IOException { File pf = file.getParentFile(); if (file.exists()) { try { String diskContent = readFile(file); if (diskContent != null && diskContent.equals(content)) { return false; } } catch (IOException e) { /* ignore */ } } else if (!pf.exists() && !pf.mkdirs()) { throw new IOException("cannot create folders for `" + pf.getPath() + "'"); } PrintWriter writer = null; try { writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), FileUtil.DEFAULT_ENCODING)); writer.print(content); writer.flush(); } finally { if (writer != null) { writer.close(); } } return true; } static String readFile(File file) throws IOException { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), FileUtil.DEFAULT_ENCODING)); StringBuilder result = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { result.append(line).append("\n"); } return result.toString(); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { /* ignore */ } } } }