From 5808bc275c42b3d12f23f9b04b7549417ea4c6dc Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Fri, 27 Apr 2007 21:30:01 +0000
Subject: [PATCH] implements code to access and parse the newly published upgrade build availability information published at http://www.opends.org/upgrade-builds
---
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java | 135 +++++++++++++++++++---
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java | 10 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java | 22 ++
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java | 175 +++++++++++++++++++----------
4 files changed, 254 insertions(+), 88 deletions(-)
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java
index 9cd4b12..13493a2 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java
@@ -28,23 +28,81 @@
package org.opends.quicksetup.upgrader;
import java.net.URL;
+import java.util.EnumSet;
/**
* Representation of an OpenDS build package.
*/
public class Build implements Comparable<Build> {
- private URL url;
- private String id;
+ /**
+ * Describes build types.
+ */
+ enum Category {
+
+ /**
+ * Daily build descriptor.
+ */
+ DAILY("Daily Build"),
+
+ /**
+ * Weekly build descriptor.
+ */
+ WEEKLY("Weekly Build"),
+
+ /**
+ * Release build descriptor.
+ */
+ RELEASE("Release Build");
+
+ /**
+ * Creates a Category from its 'key' String value.
+ * @param s String representing a key
+ * @return the Category corresponding to the input <code>key</code>; null
+ * if the input string is not a category key
+ */
+ public static Category fromString(String s) {
+ Category category = null;
+ for (Category c : EnumSet.allOf(Category.class)) {
+ if (c.key.equals(s)) {
+ category = c;
+ break;
+ }
+ }
+ return category;
+ }
+
+ String key;
+
+ private Category(String key) {
+ this.key = key;
+ }
+
+ /**
+ * Gets the string that represents this category in
+ * the build information page.
+ * @return String key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ }
+
+ private URL downloadUrl;
+ private String displayName;
+ private Category category;
/**
* Creates an instance.
- * @param url where the build package can be accessed
- * @param id of the new build
+ * @param displayName where the build package can be accessed
+ * @param downloadUrl of the new build
+ * @param category build category
*/
- Build(URL url, String id) {
- this.url = url;
- this.id = id;
+ Build(String displayName, URL downloadUrl, Category category) {
+ this.displayName = displayName;
+ this.downloadUrl = downloadUrl;
+ this.category = category;
}
/**
@@ -52,16 +110,7 @@
* @return URL representing access to the build package
*/
public URL getUrl() {
- return url;
- }
-
- /**
- * Gets the builds ID number, a 14 digit number representing the time
- * the build was created.
- * @return String represenging the build
- */
- public String getId() {
- return id;
+ return this.downloadUrl;
}
/**
@@ -69,7 +118,15 @@
* @return String representing this build
*/
public String getDisplayName() {
- return getId();
+ return this.displayName;
+ }
+
+ /**
+ * Gets the category of this build.
+ * @return Category indicating the type of this build.
+ */
+ public Category getCategory() {
+ return this.category;
}
/**
@@ -83,7 +140,47 @@
* {@inheritDoc}
*/
public int compareTo(Build o) {
- return getDisplayName().compareTo(o.getDisplayName());
+ if (o == null) throw new NullPointerException();
+ int c = getCategory().compareTo(o.getCategory());
+ if (c == 0) {
+ c = getDisplayName().compareTo(o.getDisplayName());
+ }
+ return c;
}
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ int hc = 11;
+ Category cat = getCategory();
+ if (cat != null) {
+ hc = 31 * hc + cat.hashCode();
+ }
+ String disp = getDisplayName();
+ if (disp != null) {
+ hc = 31 * hc + disp.hashCode();
+ }
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ boolean eq = false;
+ if (obj != null && obj instanceof Build) {
+ Category thisCat = getCategory();
+ Category thatCat = ((Build)obj).getCategory();
+ if ((thisCat != null && thisCat.equals(thatCat)) ||
+ (thisCat == null && thatCat == null)) {
+ String thisDisp = getDisplayName();
+ String thatDisp = ((Build)obj).getDisplayName();
+ eq = ((thisDisp != null && thisDisp.equals(thatDisp)) ||
+ (thisDisp == null && thatDisp == null));
+ }
+ }
+ return eq;
+ }
}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
index b9967c9..5d4eff3 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
@@ -34,11 +34,11 @@
import java.net.URL;
import java.net.Proxy;
import java.net.URLConnection;
+import java.net.MalformedURLException;
import java.util.*;
import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
import java.util.logging.Logger;
+import java.util.logging.Level;
import java.io.*;
import java.awt.*;
@@ -50,26 +50,13 @@
static private final Logger LOG =
Logger.getLogger(RemoteBuildManager.class.getName());
- /**
- * Describes build types.
- */
- enum BuildType {
-
- /**
- * Nightly build descriptor.
- */
- NIGHTLY,
-
- /**
- * Weekly build descriptor.
- */
- WEEKLY
-
- }
-
private Application app;
- private URL url;
+ /**
+ * This URL is expected to point at a list of the builds parsable by
+ * the <code>RemoteBuildsPageParser</code>.
+ */
+ private URL buildListUrl;
private Proxy proxy;
@@ -80,11 +67,11 @@
/**
* Creates an instance.
* @param app using this tool
- * @param url base context for an OpenDS build repository
+ * @param url base context for an OpenDS build list
*/
public RemoteBuildManager(Application app, URL url) {
this.app = app;
- this.url = url;
+ this.buildListUrl = url;
}
/**
@@ -92,7 +79,7 @@
* @return URL representing base context of the build repo
*/
public URL getBaseContext() {
- return this.url;
+ return this.buildListUrl;
}
/**
@@ -105,38 +92,9 @@
* from the build repository
*/
public List<Build> listBuilds(InputStream in) throws IOException {
- List<Build> buildList = new ArrayList<Build>();
String dailyBuildsPage = downloadDailyBuildsPage(in);
- Pattern p = Pattern.compile("\\d{14}");
- Matcher m = p.matcher(dailyBuildsPage);
- Set<String> buildIds = new HashSet<String>();
- while (m.find()) {
- buildIds.add(dailyBuildsPage.substring(m.start(), m.end()));
- }
-
-// for (String buildId : buildIds) {
-// // TODO: this needs to be changed
-// URL buildUrl =
-// new URL(url, "daily-builds/" +
-// buildId +
-// "/OpenDS/build/package/OpenDS-0.1.zip");
-// buildList.add(new Build(url, buildId));
-// }
-
- // This is encoded in build.xml. We might need a more dynamic
- // way of getting this information.
- StringBuilder latestContextSb = new StringBuilder()
- .append("daily-builds/latest/OpenDS/build/package/OpenDS-")
- .append(org.opends.server.util.DynamicConstants.MAJOR_VERSION)
- .append(".")
- .append(org.opends.server.util.DynamicConstants.MINOR_VERSION)
- .append(org.opends.server.util.DynamicConstants.VERSION_QUALIFIER)
- .append(".zip");
- Build latest = new Build(new URL(url, latestContextSb.toString()),
- "Latest");
- buildList.add(latest);
- Collections.sort(buildList);
- return buildList;
+ return Collections.unmodifiableList(
+ RemoteBuildsPageParser.parseBuildList(dailyBuildsPage));
}
/**
@@ -150,12 +108,11 @@
final Object o)
throws IOException
{
- URL dailyBuildsUrl = new URL(url, "daily-builds");
URLConnection conn;
if (proxy == null) {
- conn = dailyBuildsUrl.openConnection();
+ conn = buildListUrl.openConnection();
} else {
- conn = dailyBuildsUrl.openConnection(proxy);
+ conn = buildListUrl.openConnection(proxy);
}
String proxyAuthString = createProxyAuthString();
if (proxyAuthString != null) {
@@ -184,7 +141,7 @@
StringBuilder builder = new StringBuilder();
String line;
while (null != (line = reader.readLine())) {
- builder.append(line);
+ builder.append(line).append('\n');
}
return builder.toString();
}
@@ -322,6 +279,104 @@
}
/**
+ * Parser for the web page that lists available builds. This pag is expected
+ * to be a tab-delimited text document where each line represents a build with
+ * the following fields:
+ * 1. A build display name (e.g. OpenDS 0.1 Build 036)
+ * 2. A URL where the build's .zip file can be downloaded
+ * 3. A category string for the build (e.g. Weekly Build, Daily Build)
+ */
+ static private class RemoteBuildsPageParser {
+
+ /**
+ * Parses a string representing the build information list into a list
+ * of builds sorted by usefulness meaning that release builds are first,
+ * followed by weekly builds and finally daily builds.
+ * @param page String representing the build info page
+ * @return List of Builds
+ */
+ static public List<Build> parseBuildList(String page) {
+ List<Build> builds = new ArrayList<Build>();
+ if (page != null) {
+ BufferedReader reader = new BufferedReader(new StringReader(page));
+ String line;
+ try {
+ while (null != (line = reader.readLine())) {
+ try {
+ Build build = parseBuildLine(line);
+ builds.add(build);
+ } catch (IllegalArgumentException iae) {
+ StringBuffer msg = new StringBuffer()
+ .append("Error parsing line '")
+ .append(line)
+ .append("': ")
+ .append(iae.getMessage());
+ LOG.log(Level.INFO, msg.toString());
+ }
+ }
+ } catch (IOException e) {
+ LOG.log(Level.INFO, "error", e);
+ }
+ } else {
+ LOG.log(Level.WARNING, "build list page is null");
+ }
+ return builds;
+ }
+
+ static private Build parseBuildLine(String line)
+ throws IllegalArgumentException {
+ String displayName = null;
+ String downloadUrlString = null;
+ String categoryString = null;
+ URL downloadUrl;
+ Build.Category category;
+ StringTokenizer st = new StringTokenizer(line, "\t");
+ if (st.hasMoreTokens()) {
+ displayName = st.nextToken();
+ }
+ if (st.hasMoreTokens()) {
+ downloadUrlString = st.nextToken();
+ }
+ if (st.hasMoreTokens()) {
+ categoryString = st.nextToken();
+ }
+ if (displayName == null ||
+ downloadUrlString == null ||
+ categoryString == null) {
+ StringBuffer msg = new StringBuffer()
+ .append("Line '")
+ .append(line)
+ .append("' is incomplete or is not correctly delimited")
+ .append("with tab characters");
+ throw new IllegalArgumentException(msg.toString());
+ } else {
+
+ try {
+ downloadUrl = new URL(downloadUrlString);
+ } catch (MalformedURLException e) {
+ StringBuffer msg = new StringBuffer()
+ .append("URL '")
+ .append(downloadUrlString)
+ .append("' is invalid");
+ throw new IllegalArgumentException(msg.toString());
+ }
+ category = Build.Category.fromString(categoryString);
+ if (category == null) {
+ StringBuffer msg = new StringBuffer()
+ .append("Category '")
+ .append(categoryString)
+ .append("' is invalid; must be one of ");
+ for (Build.Category c : EnumSet.allOf(Build.Category.class)) {
+ msg.append("'").append(c.getKey()).append("' ");
+ }
+ throw new IllegalArgumentException(msg.toString());
+ }
+ }
+ return new Build(displayName, downloadUrl, category);
+ }
+ }
+
+ /**
* For testing only.
* @param args command line arguments
*/
@@ -335,8 +390,8 @@
//
// System.setProperties(systemSettings);
//
-// URL url = new URL("http://builds.opends.org");
-// RemoteBuildManager rbm = new RemoteBuildManager(null, url);
+// URL buildListUrl = new URL("http://builds.opends.org");
+// RemoteBuildManager rbm = new RemoteBuildManager(null, buildListUrl);
// //List<Build> builds = rbm.listBuilds();
// //for (Build build : builds) {
// // System.out.println("build " + build);
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
index 305e7f1..4c7956f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -240,10 +240,12 @@
public RemoteBuildManager getRemoteBuildManager() {
if (remoteBuildManager == null) {
try {
- // TODO: make this configurable.
- // The slash at the end of the URL was/is important in getting the
- // correct redirection from the web server
- URL buildRepo = new URL("http://builds.opends.org/");
+ String listUrlString =
+ System.getProperty("org.opends.quicksetup.upgrader.BuildList");
+ if (listUrlString == null) {
+ listUrlString = "http://www.opends.org/upgrade-builds";
+ }
+ URL buildRepo = new URL(listUrlString);
remoteBuildManager = new RemoteBuildManager(this, buildRepo);
} catch (MalformedURLException e) {
LOG.log(Level.INFO, "error", e);
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
index 63324ad..bdb8aa9 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -71,8 +71,15 @@
*/
public void beginDisplay(UserData data) {
tcServerLocation.setText(getServerToUpgrade());
- tcOldBuild.setText(getOldBuildId());
- tcNewBuild.setText(getNewBuildId());
+
+ // Unfortunately these string are different. The
+ // old build string is the build ID (14 digit number)
+ // and the new build is the build display name that
+ // appears in the available builds information page.
+ // It is currently not feasible to correlate these.
+ tcOldBuild.setText(getOldBuildString());
+ tcNewBuild.setText(getNewBuildString());
+
}
/**
@@ -175,7 +182,7 @@
return getUserData().getServerLocation();
}
- private String getOldBuildId() {
+ private String getOldBuildString() {
String oldVersion;
try {
oldVersion = getApplication().getInstallation().getBuildId();
@@ -186,12 +193,17 @@
return oldVersion;
}
- private String getNewBuildId() {
+ /**
+ * Gets the string by which the new build is known in the
+ * available builds page.
+ * @return String indicating the new build
+ */
+ private String getNewBuildString() {
String newVersion;
UpgradeUserData uud = (UpgradeUserData)getUserData();
Build build = uud.getInstallPackageToDownload();
if (build != null) {
- newVersion = build.getId();
+ newVersion = build.getDisplayName();
} else {
// TODO: figure out the build from the zip somehow
newVersion = getMsg("upgrade-build-id-unknown");
--
Gitblit v1.10.0