| /* --COPYRIGHT--,EPL |
| * Copyright (c) 2008 Texas Instruments 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: |
| * Texas Instruments - initial implementation |
| * |
| * --/COPYRIGHT--*/ |
| /* |
| * ======== Vers.java ======== |
| * This class provides access to RTSC package version support. |
| */ |
| package xdc.services.global; |
| |
| import xdc.services.global.*; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.FactoryConfigurationError; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| |
| import java.io.FileReader; |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.IOException; |
| |
| import java.util.Vector; |
| import java.util.regex.Pattern; |
| import java.util.regex.Matcher; |
| |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DOMException; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.Element; |
| |
| /* |
| * ======== Vers ======== |
| */ |
| public class Vers { |
| |
| public static final class Desc implements Cloneable { |
| public String name = null; |
| public String label = null; |
| public long date = 0; |
| public long buildCount = 0; |
| public String producerId = null; |
| protected Object clone() throws CloneNotSupportedException |
| { |
| return (super.clone()); |
| } |
| }; |
| |
| public static final class RepoDesc implements Cloneable { |
| public String name = null; |
| public String providerId = null; |
| protected Object clone() throws CloneNotSupportedException |
| { |
| return (super.clone()); |
| } |
| }; |
| |
| static final class BuildDesc implements Cloneable { |
| public String name = null; |
| public String producerId = null; |
| protected Object clone() throws CloneNotSupportedException |
| { |
| return (super.clone()); |
| } |
| }; |
| |
| /* |
| * ======== getReferences ======== |
| * Read the specified XML file (that conforms to release.dtd) and |
| * return an array of all referenced packages and their versions. |
| * |
| * Return an array of strings of the form: "<package>{<vers>" |
| * where <package> is a package name and <vers> is the package's |
| * version number. |
| */ |
| public static String[] getReferences(String fileName) |
| { |
| Vector<String> result = new Vector<String>(); |
| |
| Document doc; |
| if ((doc = openDoc(fileName)) == null) { |
| return (new String [0]); |
| } |
| |
| NodeList nl = doc.getElementsByTagName("references"); |
| |
| if (nl != null && nl.getLength() >= 1) { |
| NodeList pkgs = nl.item(0).getChildNodes(); |
| if (pkgs != null) { |
| int len = pkgs.getLength(); |
| for (int i = 0; i < len; i++) { |
| Node node = pkgs.item(i); |
| if (node.getNodeType() == Node.ELEMENT_NODE) { |
| Element pkg = (Element)node; |
| Attr name = pkg.getAttributeNode("name"); |
| Attr vers = pkg.getAttributeNode("version"); |
| if (name != null && vers != null) { |
| result.add(name.getValue() + "{" +vers.getValue()); |
| } |
| } |
| } |
| } |
| } |
| |
| return ((String [])result.toArray(new String [result.size()])); |
| } |
| |
| /* |
| * ======== getOrphans ======== |
| */ |
| public static String[] getOrphans(String fileName) |
| { |
| return (readList(fileName, "orphans", "name")); |
| } |
| |
| /* |
| * ======== getTargetReferences ======== |
| * Read the specified XML file (that conforms to build.dtd) and |
| * return an array of all referenced targets and their versions. |
| * |
| * Return an array of strings of the form: "<package>.<mod>{<vers>" |
| * where <package> is a package name, <mod> is the module name of a |
| * module implementing bld.ITarget, and <vers> is the target's |
| * version number. |
| */ |
| public static String[] getTargetReferences(String fileName) |
| { |
| return (readList(fileName, "targets", "version")); |
| } |
| |
| /*! |
| * ======== getAttrs ======== |
| * Quick and dirty read of release.*.xml file to get release attrs |
| */ |
| public static Vers.Desc getAttrs(String fileName) |
| { |
| return (getAttrs(new File(fileName))); |
| } |
| |
| public static Vers.Desc getAttrs(File file) |
| { |
| Vers.Desc result = new Vers.Desc(); |
| BufferedReader src = null; |
| |
| try { |
| /* open file conforming to release.dtd */ |
| src = new BufferedReader(new FileReader(file)); |
| |
| /* read the input stream */ |
| int state = 0; |
| String sline = src.readLine(); |
| for (; sline != null && state < 3; sline = src.readLine()) { |
| int idx; |
| int start, end; |
| if (state == 0 |
| && (idx = sline.indexOf("release name=\"")) >= 0) { |
| /* 14 = length of the string 'release name="' */ |
| start = idx + 14; |
| end = sline.indexOf('"', start); |
| result.name = sline.substring(start, end); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("label=\"")) >= 0) { |
| /* 7 = length of the string 'label="' */ |
| start = idx + 7; |
| end = sline.indexOf('"', start); |
| result.label = sline.substring(start, end); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("date=\"")) >= 0) { |
| /* 6 = length of the string 'date="' */ |
| start = idx + 6; |
| end = sline.indexOf('"', start); |
| result.date = toLong(sline.substring(start, end)); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("buildCount=\"")) >= 0) { |
| /* 12 = length of the string 'buildCount="' */ |
| start = idx + 12; |
| end = sline.indexOf('"', start); |
| result.buildCount = toLong(sline.substring(start, end)); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("producerId=\"")) >= 0) { |
| /* 13 = length of the string 'producerId="' */ |
| start = idx + 13; |
| end = sline.indexOf('"', start); |
| result.producerId = sline.substring(start, end); |
| state++; |
| } |
| } |
| } |
| catch (Exception e) { |
| ; |
| } |
| finally { |
| if (src != null) { |
| try { |
| src.close(); |
| } |
| catch (java.io.IOException e) { |
| ; |
| } |
| } |
| } |
| |
| return (result); |
| } |
| |
| /*! |
| * ======== getBuildAttrs ======== |
| * Quick and dirty read of build XML file |
| */ |
| public static Vers.BuildDesc getBuildAttrs(String fileName) |
| { |
| return (getBuildAttrs(new File(fileName))); |
| } |
| |
| public static Vers.BuildDesc getBuildAttrs(File file) |
| { |
| Vers.BuildDesc result = new Vers.BuildDesc(); |
| BufferedReader src = null; |
| |
| try { |
| /* open file conforming to build.dtd */ |
| src = new BufferedReader(new FileReader(file)); |
| |
| /* read the input stream */ |
| int state = 0; |
| String sline = src.readLine(); |
| for (; sline != null && state < 3; sline = src.readLine()) { |
| int idx; |
| int start, end; |
| if (state == 0 |
| && (idx = sline.indexOf("package name=\"")) >= 0) { |
| /* 14 = length of the string 'package name="' */ |
| start = idx + 14; |
| end = sline.indexOf('"', start); |
| result.name = sline.substring(start, end); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("producerId=\"")) >= 0) { |
| /* 13 = length of the string 'producerId="' */ |
| start = idx + 13; |
| end = sline.indexOf('"', start); |
| result.producerId = sline.substring(start, end); |
| state++; |
| } |
| } |
| } |
| catch (Exception e) { |
| ; |
| } |
| finally { |
| if (src != null) { |
| try { |
| src.close(); |
| } |
| catch (java.io.IOException e) { |
| ; |
| } |
| } |
| } |
| |
| return (result); |
| } |
| |
| /*! |
| * ======== getRepoAttrs ======== |
| * Quick and dirty read of repository XML file |
| */ |
| public static Vers.RepoDesc getRepoAttrs(String fileName) |
| { |
| return (getRepoAttrs(new File(fileName))); |
| } |
| |
| public static Vers.RepoDesc getRepoAttrs(File file) |
| { |
| Vers.RepoDesc result = new Vers.RepoDesc(); |
| BufferedReader src = null; |
| |
| try { |
| /* open file conforming to release.dtd */ |
| src = new BufferedReader(new FileReader(file)); |
| |
| /* read the input stream */ |
| int state = 0; |
| String sline = src.readLine(); |
| for (; sline != null && state < 3; sline = src.readLine()) { |
| int idx; |
| int start, end; |
| if (state == 0 |
| && (idx = sline.indexOf("repository name=\"")) >= 0) { |
| /* 14 = length of the string 'release name="' */ |
| start = idx + 14; |
| end = sline.indexOf('"', start); |
| result.name = sline.substring(start, end); |
| state++; |
| } |
| if (state >= 1 |
| && (idx = sline.indexOf("providerId=\"")) >= 0) { |
| /* 12 = length of the string 'providerId="' */ |
| start = idx + 12; |
| end = sline.indexOf('"', start); |
| result.providerId = sline.substring(start, end); |
| state++; |
| } |
| } |
| } |
| catch (Exception e) { |
| ; |
| } |
| finally { |
| if (src != null) { |
| try { |
| src.close(); |
| } |
| catch (java.io.IOException e) { |
| ; |
| } |
| } |
| } |
| |
| return (result); |
| } |
| |
| /*! |
| * ======== getProviderId ======== |
| * Compute the providerId of a released package |
| * |
| * Given the base directory of a package, this method looks into the |
| * package's repository for meta-data that describes who created |
| * (i.e., provided) the repository. |
| * |
| * Repositories created via xdc contain a file named ".repo.xml" which |
| * identifies the "provider" of the repository. In this case, the |
| * providerId is just the bundle name; by convention, the bundle name |
| * has the marketing version number in the name and servers as the |
| * "marketing" version number. |
| * |
| * If the package is not released or if the repository was created |
| * "by hand" (and does not contain meta-data), "" is returned. |
| */ |
| public static String getProviderId(String base) |
| { |
| String result = ""; |
| |
| /* get package name from the build XML file */ |
| Vers.BuildDesc attrs = getBuildAttrs(base +"/package/package.bld.xml"); |
| if (attrs.name != null) { |
| /* compute repository from the package's name */ |
| String repo = base |
| + (attrs.name + ".").replaceAll("\\w+\\.", "/..") + "/"; |
| |
| /* get providerId info from repository's XML file */ |
| Vers.RepoDesc rattrs = getRepoAttrs(repo + ".repo.xml"); |
| if (rattrs.providerId != null) { |
| result = rattrs.providerId; |
| |
| /* TODO: validate that this name really is right; try to |
| * catch situations where the user copies/moves repositories |
| * repositories by hand. |
| */ |
| } |
| else { |
| try { |
| result = (new File(repo)).getCanonicalPath(); |
| } |
| catch (IOException ex) { |
| result = (new File(repo)).getAbsolutePath(); |
| } |
| result = result.replaceAll("\\\\", "/"); |
| } |
| } |
| |
| return (result); |
| } |
| |
| /*! |
| * ======== getDate ======== |
| * Returns a number that monotonically increases with each release of |
| * a package |
| */ |
| public static long getDate(String base) |
| { |
| /* get it from the release (if possible) */ |
| File tmp = new File(base + "/package/package.rel.xml"); |
| if (tmp.exists()) { |
| Vers.Desc attrs = getAttrs(tmp); |
| return (attrs.date); |
| } |
| |
| /* if pkg isn't released, approximate it with last mod dates */ |
| long max = 0; |
| tmp = new File(base + "/package/package.ext.xml"); |
| if (tmp.exists()) { |
| long date = tmp.lastModified(); |
| max = max < date ? date : max; |
| } |
| tmp = new File(base + "/.xdcenv.mak"); |
| if (tmp.exists()) { |
| long date = tmp.lastModified(); |
| max = max < date ? date : max; |
| } |
| |
| return (max); |
| } |
| |
| /*! |
| * ======== getBuildCount ======== |
| * Returns a number that monotonically increases with each release of |
| * a package |
| */ |
| public static long getBuildCount(String base) |
| { |
| /* get it from the release (if possible) */ |
| File tmp = new File(base + "/package/package.rel.xml"); |
| if (tmp.exists()) { |
| Vers.Desc attrs = getAttrs(tmp); |
| return (attrs.date); |
| } |
| |
| /* if pkg isn't released, get it from the build .xdcenv.mak file */ |
| tmp = new File(base + "/.xdcenv.mak"); |
| if (tmp.exists()) { |
| String value = readEnvValue(tmp, "_XDCBUILDCOUNT"); |
| if (value != null && value.length() != 0) { |
| return (Long.decode(value)); |
| } |
| } |
| |
| /* otherwise, it must be brand spanking new */ |
| return (0); |
| } |
| |
| /* |
| * ======== readEnvValue ======== |
| * Return the value of the specified token from the file envFile. |
| * |
| * Returns null if no value is specified in envFile. |
| */ |
| private static String readEnvValue(File envFile, String token) |
| { |
| String result = null; |
| BufferedReader file = null; |
| |
| Pattern reg = Pattern.compile( |
| "^[#\\s]*(override\\s+)?" + token + "\\s*=\\s*(.*)$"); |
| try { |
| file = new BufferedReader(new FileReader(envFile)); |
| String nextLine; |
| while ((nextLine = file.readLine()) != null) { |
| Matcher matcher = reg.matcher(nextLine); |
| if (matcher.find() && matcher.groupCount() == 2) { |
| result = matcher.group(2); |
| break; |
| } |
| } |
| } |
| catch (Exception e) { |
| ; |
| } |
| finally { |
| if (file != null) { |
| try { |
| file.close(); |
| } |
| catch (java.io.IOException e) { |
| ; |
| } |
| } |
| } |
| |
| return (result); |
| } |
| |
| /* |
| * ======== readList ======== |
| */ |
| private static String[] readList(String fileName, String listName, String attrName) |
| { |
| Document doc; |
| String [] result = new String [0]; |
| |
| if ((doc = openDoc(fileName)) != null) { |
| result = XML.getList(doc, listName, attrName); |
| } |
| |
| return (result); |
| } |
| |
| /* |
| * ======== openDoc ======== |
| */ |
| private static Document openDoc(String fileName) |
| { |
| Document doc = null; |
| File file = new File(fileName); |
| |
| if (file.exists()) { |
| if ((doc = XML.parse(file)) == null) { |
| System.err.println(fileName + " is not a valid XML document."); |
| } |
| } |
| |
| return (doc); |
| } |
| |
| /* |
| * ======== toLong ======== |
| */ |
| private static long toLong(String num) |
| { |
| long result = 0; |
| try { |
| result = Long.decode(num); |
| } |
| catch (java.lang.NumberFormatException e) { |
| ; |
| } |
| return (result); |
| } |
| |
| /* |
| * ======== getWhatString ======== |
| */ |
| public static String getWhatString(String fileName) |
| throws java.io.IOException |
| { |
| return What.getWhatString(fileName); |
| } |
| |
| public static String getWhatString(File file) |
| throws java.io.IOException |
| { |
| return What.getWhatString(file); |
| } |
| |
| /* |
| * ======== main ======== |
| * Read XML file specified on the command line, display its contents, |
| * and extract and display the "references" (as defined by |
| * release.dtd) defined in the file. |
| */ |
| public static void main(String argv[]) |
| { |
| if (argv.length != 1) { |
| System.err.println("Usage: java xdc.services.global.Vers filename"); |
| System.exit(1); |
| } |
| |
| System.out.println("\n package references:"); |
| String [] releases = getReferences(argv[0]); |
| for (int i = 0; i < releases.length; i++) { |
| System.out.println(" " + releases[i]); |
| } |
| |
| System.out.println("\n target references:"); |
| releases = getTargetReferences(argv[0]); |
| for (int i = 0; i < releases.length; i++) { |
| System.out.println(" " + releases[i]); |
| } |
| } |
| } |