/* * Copyright (c) 2012, 2013, 2015, 2016 Eike Stepper (Berlin, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.releng; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Eike Stepper */ public class GenerateExampleBuilders { private static final String TOKEN_EXAMPLE_PROJECT = "#EXAMPLE_PROJECT#"; private static final String TOKEN_INSTALLER_PROJECT = "#INSTALLER_PROJECT#"; private static final String TOKEN_RELEVANT_RESOURCES = "#RELEVANT_RESOURCES#"; private static final String TOKEN_REFRESH_RESOURCES = "#REFRESH_RESOURCES#"; private static final String NL = System.getProperty("line.separator"); public static void main(String[] args) throws Exception { File installerPoject = new File(args[0]).getCanonicalFile(); File pluginXML = new File(installerPoject, "plugin.xml"); System.out.println("Analyzing " + pluginXML); SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); XMLHandler handler = new XMLHandler(installerPoject); InputStream in = new FileInputStream(pluginXML); try { parser.parse(in, handler); } finally { in.close(); } } private static void processProjectDescriptor(File exampleProject, File installerPoject, String targetFolder) throws Exception { String exampleProjectName = exampleProject.getName(); String targetPath = installerPoject.getName() + "/" + targetFolder; StringBuilder relevantResources = new StringBuilder(); relevantResources.append(getItemPath(targetPath, 2)); for (File file : exampleProject.listFiles()) { String name = file.getName(); int type = file.isDirectory() ? 2 : 1; if (!"bin".equals(name)) { String path = exampleProjectName + "/" + name; relevantResources.append(getItemPath(path, type)); } } Map<String, String> substitutes = new HashMap<String, String>(); addSubtitute(substitutes, TOKEN_EXAMPLE_PROJECT, exampleProject.getName()); addSubtitute(substitutes, TOKEN_INSTALLER_PROJECT, installerPoject.getName()); addSubtitute(substitutes, TOKEN_RELEVANT_RESOURCES, relevantResources.toString()); addSubtitute(substitutes, TOKEN_REFRESH_RESOURCES, getItemPath(new File(targetPath).getParent(), 2)); copy(exampleProject, substitutes, "copyExample.ant", ".externalToolBuilders/copyExample.ant"); copy(exampleProject, substitutes, "template.launch", ".externalToolBuilders/" + exampleProjectName + ".launch"); updateProjectDescription(exampleProject, substitutes); } private static void copy(File targetProject, Map<String, String> substitutes, String template, String targetPath) throws IOException { File source = getTemplate(targetProject.getParentFile(), template); String content = substitute(readFile(source), substitutes); File target = new File(targetProject, targetPath); System.out.println(" Generating " + target.getCanonicalPath()); writeFile(target, content); } private static void updateProjectDescription(File targetProject, Map<String, String> substitutes) throws IOException { File snippetTemplate = getTemplate(targetProject.getParentFile(), "template.project"); String snippet = substitute(readFile(snippetTemplate), substitutes); File descriptionFile = new File(targetProject, ".project"); String description = readFile(descriptionFile); System.out.println(" Updating " + descriptionFile.getCanonicalPath()); if (description.indexOf(snippet) != -1) { // Nothing to update return; } String newDescription = description; Pattern pattern = Pattern.compile("(\\s*<buildCommand>.*?</buildCommand>)*(\\s*<buildCommand>.*?<value><project>/\\.externalToolBuilders/" + targetProject.getName().replace(".", "\\.") + "\\.launch</value>.*?</buildCommand>)", Pattern.DOTALL); Matcher matcher = pattern.matcher(description); if (matcher.find()) { String remove = matcher.group(2); newDescription = newDescription.replace(remove, ""); } newDescription = newDescription.replaceFirst("[ \\t]*</buildSpec>", snippet + "\t</buildSpec>"); if (!newDescription.equals(description)) { writeFile(descriptionFile, newDescription); } } private static String readFile(File file) throws IOException { StringBuilder result = new StringBuilder(); FileReader in = null; try { in = new FileReader(file); BufferedReader reader = new BufferedReader(in); String line; while ((line = reader.readLine()) != null) { result.append(line); result.append(NL); } return result.toString(); } finally { if (in != null) { in.close(); } } } private static void writeFile(File file, String content) throws IOException { FileWriter out = null; try { out = new FileWriter(file); @SuppressWarnings("resource") BufferedWriter writer = new BufferedWriter(out); writer.write(content); writer.flush(); } finally { if (out != null) { out.close(); } } } private static String getItemPath(String resource, int type) { return "<item path="/" + resource.replace('\\', '/') + "" type="" + type + ""/> "; } private static File getTemplate(File root, String template) { return new File(root, "org.eclipse.emf.cdo.releng/exampleBuilderTemplates/" + template); } private static void addSubtitute(Map<String, String> substitutes, String token, String substitute) { System.out.println(" " + token + " = " + substitute); substitutes.put(token, substitute); } private static String substitute(String content, Map<String, String> substitutes) { for (Entry<String, String> entry : substitutes.entrySet()) { content = content.replace(entry.getKey(), entry.getValue()); } return content; } /** * @author Eike Stepper */ private static class XMLHandler extends DefaultHandler { private File installerPoject; public XMLHandler(File installerPoject) { this.installerPoject = installerPoject; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("projectDescriptor".equalsIgnoreCase(qName)) { try { String name = attributes.getValue("name"); String contentURI = attributes.getValue("contentURI"); File exampleProject = new File(installerPoject, "../" + name).getCanonicalFile(); System.out.println(" Processing " + name + " --> " + contentURI); processProjectDescriptor(exampleProject, installerPoject, contentURI); } catch (Exception ex) { ex.printStackTrace(); } } } } }