KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > VerifyUpdateCenter


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.nbbuild;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.StringReader JavaDoc;
25 import java.net.URI JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.SortedMap JavaDoc;
31 import java.util.SortedSet JavaDoc;
32 import java.util.TreeSet JavaDoc;
33 import java.util.jar.Manifest JavaDoc;
34 import org.apache.tools.ant.AntClassLoader;
35 import org.apache.tools.ant.BuildException;
36 import org.apache.tools.ant.Project;
37 import org.apache.tools.ant.Task;
38 import org.apache.tools.ant.types.Path;
39 import org.w3c.dom.Attr JavaDoc;
40 import org.w3c.dom.Document JavaDoc;
41 import org.w3c.dom.Element JavaDoc;
42 import org.w3c.dom.NamedNodeMap JavaDoc;
43 import org.w3c.dom.NodeList JavaDoc;
44 import org.xml.sax.EntityResolver JavaDoc;
45 import org.xml.sax.InputSource JavaDoc;
46 import org.xml.sax.SAXException JavaDoc;
47
48 /**
49  * Task which checks content of an update center to make sure module dependencies
50  * are internally consistent. Can optionally also check against a previous update
51  * center snapshot to make sure that updates of modules marked as newer (i.e. with
52  * newer specification versions) would result in a consistent snapshot as well.
53  * If there are any modules which cannot be loaded, the build fails with a description.
54  * <p>
55  * Actual NBMs are not downloaded. Everything necessary is present just in
56  * the update center XML descriptor.
57  * <p>
58  * You must specify a classpath to load the NB module system from.
59  * It should suffice to include those JARs in the NB platform cluster's <code>lib</code> folder.
60  * @author Jesse Glick
61  */

62 public final class VerifyUpdateCenter extends Task {
63
64     public VerifyUpdateCenter() {}
65
66     private URI JavaDoc updates;
67     public void setUpdates(File JavaDoc f) {
68         updates = f.toURI();
69     }
70     public void setUpdatesURL(URI JavaDoc u) {
71         updates = u;
72     }
73
74     private URI JavaDoc oldUpdates;
75     public void setOldUpdates(File JavaDoc f) {
76         if (f.isFile()) {
77             oldUpdates = f.toURI();
78         } else {
79             log("No such file: " + f, Project.MSG_WARN);
80         }
81     }
82     public void setOldUpdatesURL(URI JavaDoc u) {
83         if (u.toString().length() > 0) {
84             oldUpdates = u;
85         }
86     }
87
88     private Path classpath = new Path(getProject());
89     public void addConfiguredClasspath(Path p) {
90         classpath.append(p);
91     }
92
93     @Override JavaDoc
94     public void execute() throws BuildException {
95         if (updates == null) {
96             throw new BuildException("you must specify updates");
97         }
98         ClassLoader JavaDoc loader = new AntClassLoader(getProject(), classpath);
99         Set JavaDoc<Manifest JavaDoc> manifests = loadManifests(updates);
100         checkForProblems(findInconsistencies(manifests, loader), "Inconsistency(ies) in " + updates);
101         log(updates + " is internally consistent", Project.MSG_INFO);
102         if (oldUpdates != null) {
103             Map JavaDoc<String JavaDoc,Manifest JavaDoc> updated = new HashMap JavaDoc<String JavaDoc,Manifest JavaDoc>();
104             for (Manifest JavaDoc m : loadManifests(oldUpdates)) {
105                 updated.put(findCNB(m), m);
106             }
107             if (!findInconsistencies(new HashSet JavaDoc<Manifest JavaDoc>(updated.values()), loader).isEmpty()) {
108                 log(oldUpdates + " is already inconsistent, skipping update check", Project.MSG_WARN);
109                 return;
110             }
111             SortedSet JavaDoc<String JavaDoc> updatedCNBs = new TreeSet JavaDoc<String JavaDoc>();
112             for (Manifest JavaDoc m : manifests) {
113                 String JavaDoc cnb = findCNB(m);
114                 boolean doUpdate = true;
115                 Manifest JavaDoc old = updated.get(cnb);
116                 if (old != null) {
117                     String JavaDoc oldspec = old.getMainAttributes().getValue("OpenIDE-Module-Specification-Version");
118                     String JavaDoc newspec = m.getMainAttributes().getValue("OpenIDE-Module-Specification-Version");
119                     doUpdate = specGreaterThan(newspec, oldspec);
120                 }
121                 if (doUpdate) {
122                     updated.put(cnb, m);
123                     updatedCNBs.add(cnb);
124                 }
125             }
126             SortedMap JavaDoc<String JavaDoc,SortedSet JavaDoc<String JavaDoc>> updateProblems = findInconsistencies(new HashSet JavaDoc<Manifest JavaDoc>(updated.values()), loader);
127             checkForProblems(updateProblems, "Inconsistency(ies) in " + updates + " relative to " + oldUpdates);
128             log(oldUpdates + " after updating " + updatedCNBs + " from " + updates + " remains consistent");
129         }
130     }
131
132     @SuppressWarnings JavaDoc("unchecked")
133     private SortedMap JavaDoc<String JavaDoc,SortedSet JavaDoc<String JavaDoc>> findInconsistencies(Set JavaDoc<Manifest JavaDoc> manifests, ClassLoader JavaDoc loader) throws BuildException {
134         try {
135             return (SortedMap JavaDoc) loader.loadClass("org.netbeans.ConsistencyVerifier").
136                     getMethod("findInconsistencies", Set JavaDoc.class).invoke(null, manifests);
137         } catch (Exception JavaDoc x) {
138             throw new BuildException(x, getLocation());
139         }
140     }
141
142     private Set JavaDoc<Manifest JavaDoc> loadManifests(URI JavaDoc u) throws BuildException {
143         try {
144             Document JavaDoc doc = XMLUtil.parse(new InputSource JavaDoc(u.toString()), false, false, null, new EntityResolver JavaDoc() {
145                 public InputSource JavaDoc resolveEntity(String JavaDoc pub, String JavaDoc sys) throws SAXException JavaDoc, IOException JavaDoc {
146                     if (pub.contains("DTD Autoupdate Catalog")) {
147                         return new InputSource JavaDoc(new StringReader JavaDoc(""));
148                     } else {
149                         return null;
150                     }
151                 }
152             });
153             Set JavaDoc<Manifest JavaDoc> manifests = new HashSet JavaDoc<Manifest JavaDoc>();
154             NodeList JavaDoc nl = doc.getElementsByTagName("manifest");
155             for (int i = 0; i < nl.getLength(); i++) {
156                 Element JavaDoc m = (Element JavaDoc) nl.item(i);
157                 Manifest JavaDoc mani = new Manifest JavaDoc();
158                 NamedNodeMap JavaDoc map = m.getAttributes();
159                 for (int j = 0; j < map.getLength(); j++) {
160                     Attr JavaDoc a = (Attr JavaDoc) map.item(j);
161                     mani.getMainAttributes().putValue(a.getName(), a.getValue());
162                 }
163                 manifests.add(mani);
164             }
165             return manifests;
166         } catch (Exception JavaDoc x) {
167             throw new BuildException("Could not load " + u, x, getLocation());
168         }
169     }
170
171     private static String JavaDoc findCNB(Manifest JavaDoc m) {
172         String JavaDoc name = m.getMainAttributes().getValue("OpenIDE-Module");
173         if (name == null) {
174             throw new IllegalArgumentException JavaDoc();
175         }
176         return name.replaceFirst("/\\d+$", "");
177     }
178
179     private static boolean specGreaterThan(String JavaDoc newspec, String JavaDoc oldspec) {
180         if (newspec == null) {
181             return false;
182         }
183         if (oldspec == null) {
184             return true;
185         }
186         String JavaDoc[] olddigits = oldspec.split("\\.");
187         String JavaDoc[] newdigits = newspec.split("\\.");
188         int oldlen = olddigits.length;
189         int newlen = newdigits.length;
190         int max = Math.max(oldlen, newlen);
191         for (int i = 0; i < max; i++) {
192             int oldd = (i < oldlen) ? Integer.parseInt(olddigits[i]) : 0;
193             int newd = (i < newlen) ? Integer.parseInt(newdigits[i]) : 0;
194             if (oldd != newd) {
195                 return newd > oldd;
196             }
197         }
198         return false;
199     }
200     
201     private void checkForProblems(SortedMap JavaDoc<String JavaDoc,SortedSet JavaDoc<String JavaDoc>> problems, String JavaDoc msg) throws BuildException {
202         if (!problems.isEmpty()) {
203             for (Map.Entry JavaDoc<String JavaDoc,SortedSet JavaDoc<String JavaDoc>> entry : problems.entrySet()) {
204                 log("Problems found for module " + entry.getKey() + ": " + entry.getValue(), Project.MSG_ERR);
205             }
206             throw new BuildException(msg, getLocation());
207         }
208     }
209
210 }
211
Popular Tags