| package org.eclipse.wtp.releng.tools; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.Writer; |
| import java.text.DateFormat; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.Properties; |
| import java.util.Set; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.Task; |
| |
| public class WritePropertiesAsPHP extends Task { |
| |
| private String buildlabel; |
| private String propFileName; |
| private String outPHPFileName; |
| private static final String EOL = System.getProperty("line.separator"); |
| |
| // simplified view of pattern of property value with nexted property: |
| // (any text)${propertyName}{anyText) |
| private static String START_GROUP = "("; |
| private static String END_GROUP = ")"; |
| private static String PROPSTART = "\\$\\{"; |
| private static String PROPEND = "}"; |
| private static String ANY = ".*"; |
| // private static String ZERO_OR_ONE = "?"; |
| private static Pattern nestPropertypattern = Pattern.compile(START_GROUP + ANY + END_GROUP + // can start with any text |
| START_GROUP + PROPSTART + ANY + PROPEND + END_GROUP + // ant property expression and ant property name is one groups |
| START_GROUP + ANY + END_GROUP); // can end with any text |
| |
| private static Pattern antPropertyExpression = Pattern.compile(PROPSTART + START_GROUP + ANY + END_GROUP + PROPEND); |
| |
| private DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); |
| |
| public static void main(String[] args) { |
| |
| // boolean m = Pattern.matches(PROPSTART + START_GROUP + ANY + END_GROUP + PROPEND, "${teststring}"); |
| // System.out.println(m); |
| WritePropertiesAsPHP testcase = new WritePropertiesAsPHP(); |
| testcase.propFileName = "C:\\builds\\workspaces\\workspaceWTPHead\\releng\\helios\\dependencies.properties"; |
| testcase.outPHPFileName = "C:\\builds\\workspaces\\workspaceWTPHead\\releng\\helios\\dependencies.properties.php"; |
| testcase.execute(); |
| } |
| |
| @Override |
| public void execute() throws BuildException { |
| try { |
| convertPropertiesToVariables(); |
| } |
| catch (FileNotFoundException e) { |
| throw new BuildException(e); |
| } |
| catch (IOException e) { |
| throw new BuildException(e); |
| } |
| } |
| |
| private void convertPropertiesToVariables() throws FileNotFoundException, IOException { |
| File propFile = new File(getPropFileName()); |
| Properties allProps = new Properties(); |
| allProps.load(new FileInputStream(propFile)); |
| File phpFile = new File(getOutPHPFileName()); |
| Writer writer = new FileWriter(phpFile); |
| |
| Set<Object> allPropsKeys = allProps.keySet(); |
| ArrayList<String> sortableKeysList = new ArrayList(allPropsKeys); |
| Collections.sort(sortableKeysList); |
| try { |
| writer.write("<?php" + EOL); |
| writer.write("// This file was created on " + dateFormat.format(new Date()) + EOL); |
| writer.write("// Build Label: " + getBuildlabel() + EOL); |
| writer.write("// Based on input from: " + getPropFileName() + EOL); |
| for (Object key : sortableKeysList) { |
| String keyString = (String) key; |
| String keyValue = allProps.getProperty(keyString); |
| keyValue = expandVariableValues(keyValue, allProps); |
| keyString = toValidPHPVariable(keyString); |
| writer.write("$" + keyString + "=\"" + keyValue + "\";" + EOL); |
| } |
| writer.write("?>" + EOL); |
| } |
| finally { |
| if (writer != null) { |
| writer.close(); |
| } |
| } |
| } |
| |
| private String toValidPHPVariable(String keyString) { |
| // TODO: could also see if starts with digit, and if so, prefix |
| String result = keyString.replace('.', '_'); |
| result = result.replace('-', '_'); |
| return result; |
| } |
| |
| private String expandVariableValues(String keyValue, Properties allProps) { |
| String result = null; |
| Matcher matcher = nestPropertypattern.matcher(keyValue); |
| if (matcher.matches()) { |
| StringBuffer sb = new StringBuffer(); |
| |
| int nGroups = matcher.groupCount(); |
| // we avoid '0', since that's just "everything" |
| for (int i = 1; i <= nGroups; i++) { |
| String part = matcher.group(i); |
| //debug |
| //System.out.println(part); |
| if (part != null) { |
| |
| if (part.startsWith("${")) { |
| // expanedValue can be called recursively to handle cases such as where |
| // ${A} and A=${B}, so expandedValue should be "B", not "${B} |
| String nestedPropValue = expandValue(part, allProps); |
| matcher.appendReplacement(sb, nestedPropValue); |
| } |
| else { |
| // call ourselves recursively to handle properties embedded in |
| // other surrounding text. |
| Matcher nestedmatcher = nestPropertypattern.matcher(part); |
| if (nestedmatcher.matches()) { |
| return expandVariableValues(part, allProps); |
| } |
| else { |
| sb.append(part); |
| } |
| } |
| |
| } |
| } |
| result = sb.toString(); |
| } |
| else { |
| // no nested property. |
| result = keyValue; |
| } |
| |
| |
| return result; |
| } |
| |
| private String expandValue(String part, Properties allProps) { |
| // if part starts with '$', strip it off, get value call recursively |
| if (part.startsWith("${")) { |
| String propName = stripBrackets(part); |
| String value = allProps.getProperty(propName); |
| // if no property for presumed name, just return the part, even though still bracketed. Let caller decide what to do. |
| if (value == null) { |
| return part; |
| } |
| else { |
| return expandVariableValues(value, allProps); |
| } |
| } |
| // if does not start with '$', we are at end of recursion, and can assume previous call arrived at some |
| // terminal value. |
| // debug |
| //System.out.println("Terminal: " + part); |
| return part; |
| } |
| |
| private String stripBrackets(String part) { |
| String result = null; |
| // check input if of form '${anytext}' and if not, just return string |
| Matcher matcher = antPropertyExpression.matcher(part); |
| if (matcher.matches()) { |
| result = matcher.group(1); |
| } |
| else { |
| result = part; |
| } |
| return result; |
| } |
| |
| public String getPropFileName() { |
| return propFileName; |
| } |
| |
| public String getOutPHPFileName() { |
| return outPHPFileName; |
| } |
| |
| public String getBuildlabel() { |
| return buildlabel; |
| } |
| |
| public void setBuildlabel(String buildlabel) { |
| this.buildlabel = buildlabel; |
| } |
| |
| public void setPropFileName(String propFileName) { |
| this.propFileName = propFileName; |
| } |
| |
| public void setOutPHPFileName(String outPHPFileName) { |
| this.outPHPFileName = outPHPFileName; |
| } |
| |
| } |