/** * Copyright (c) 2006-2007 IBM Corporation 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: * IBM - Initial API and implementation */ package org.eclipse.emf.codegen.merge.properties; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This implements the method {@link #run}, * which is called just like main during headless workbench invocation. */ public class PropertyMerger { protected String sourceProperties; protected String targetProperties; protected Map<String, String> sourceToTargetMap = new LinkedHashMap<String, String>(); protected Map<String, String> targetToSourceMap = new LinkedHashMap<String, String>(); /** * This creates an empty instances, when used as a runnable. */ public PropertyMerger() { super(); } public String getSourceProperties() { return sourceProperties; } public void setSourceProperties(String sourceProperties) { this.sourceProperties = sourceProperties; } public String getTargetProperties() { return targetProperties; } public void setTargetProperties(String targetProperties) { this.targetProperties = targetProperties; } public Map<String, String> getSourceToTargetMap() { return sourceToTargetMap; } /** * Create a JDOM from a URI. */ public String createPropertiesForURI(String uri) { try { URL url = null; try { url = new URL(uri); } catch (MalformedURLException exception) { url = new URL("file:" + uri); } BufferedInputStream bufferedInputStream = new BufferedInputStream(url.openStream()); byte [] input = new byte [bufferedInputStream.available()]; bufferedInputStream.read(input); bufferedInputStream.close(); return new String(input, "ISO-8859-1"); } catch (IOException exception) { // Ignore } return null; } public String createPropertiesForInputStream(InputStream inputStream) { try { BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); byte [] input = new byte [bufferedInputStream.available()]; bufferedInputStream.read(input); bufferedInputStream.close(); return new String(input, "ISO-8859-1"); } catch (IOException exception) { // Ignore } return null; } protected static Pattern nlPattern = Pattern.compile("([\\n][\\r]?|[\\r][\\n]?)", Pattern.MULTILINE); public void merge() { Matcher matcher = nlPattern.matcher(targetProperties); String nl = null; if (matcher.find()) { nl = matcher.group(1); matcher = nlPattern.matcher(sourceProperties); if (matcher.find()) { String sourceNL = matcher.group(1); if (!sourceNL.equals(nl)) { sourceProperties = sourceProperties.replaceAll(sourceNL, nl); } } } else { matcher = nlPattern.matcher(sourceProperties); if (matcher.find()) { nl = matcher.group(1); } } if (nl != null) { if (!targetProperties.endsWith(nl)) { targetProperties += nl; } if (!sourceProperties.endsWith(nl)) { sourceProperties += nl; } } Map<String, String> sourcePropertyFragments = parse(sourceProperties); Map<String, String> targetPropertyFragments = parse(targetProperties); StringBuffer result = new StringBuffer(targetProperties); for (Map.Entry<String, String> entry : sourcePropertyFragments.entrySet()) { if (!targetPropertyFragments.containsKey(entry.getKey())) { result.append(entry.getValue()); } } targetProperties = result.toString(); } protected static Pattern propertyLine = Pattern.compile("\\s*(\\S+)\\s*=.*", Pattern.MULTILINE); public Map<String, String> parse(String properties) { Map<String, String> result = new LinkedHashMap<String, String>(); int i = 0; while (i < properties.length()) { int eol; for (int start = i;;) { eol = properties.indexOf("\n", start); if (eol != -1) { if (eol + 1 < properties.length() && properties.charAt(eol + 1) == '\r') { if (eol > start && properties.charAt(eol - 1) == '\\') { start = eol + 2; } else { ++eol; break; } } else if (eol > start && properties.charAt(eol - 1) == '\\' || eol - 1 > start && properties.charAt(eol - 1) == '\r' && properties.charAt(eol - 2) == '\\') { start = eol + 1; } else { break; } } else { eol = properties.indexOf("\r", start); if (eol == -1) { eol = properties.length() - 1; break; } else if (eol > start && properties.charAt(eol - 1) == '\\') { start = eol + 1; } else { break; } } } String property = properties.substring(i, eol + 1); Matcher matcher = propertyLine.matcher(property); if (matcher.find() && matcher.groupCount() >= 1) { int begin = matcher.start(1); int end = matcher.end(1); String propertyName = property.substring(begin, end); if (propertyName.indexOf("#") == -1) { result.put(propertyName, property); } else if (propertyName.startsWith("#")) { result.put(propertyName.substring(1), property); } } i = eol + 1; } return result; } /** * This is called with the command line arguments of a headless workbench invocation. */ public Object run(Object object) { try { // Three arguments are expected: the .xml jControlModel URI, the source java URI, and the target java URI. // String[] arguments = (String[])object; // Create the source and target JDOMs. // sourceProperties = createPropertiesForURI(arguments[0]); targetProperties = createPropertiesForURI(arguments[1]); merge(); System.out.println("**********************************************"); System.out.println(targetProperties); return 0; } catch (Exception exception) { return 1; } } ///////////////////////////////// HEADLESS INVOCATION ///////////////////////////////////// @Deprecated public static class PlatformRunnable extends PropertyMerger implements org.eclipse.core.runtime.IPlatformRunnable { // Empty } }