blob: 830a98f5967e4b8e9bf53274f1ad88f6c22f2160 [file] [log] [blame]
/* --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]);
}
}
}