001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.bootstrap;
028:
029: import java.io.BufferedReader;
030: import java.io.InputStream;
031: import java.io.InputStreamReader;
032: import java.net.URL;
033: import java.util.HashMap;
034: import java.util.Iterator;
035: import java.util.List;
036: import java.util.Map;
037: import java.util.regex.Matcher;
038: import java.util.regex.Pattern;
039: import java.util.zip.ZipEntry;
040: import java.util.zip.ZipInputStream;
041:
042: /**
043: * A Bootstrapper which performs a variety of tests on the
044: * resources found in the hopes of catching problems
045: *
046: * @property org.cougaar.bootstrap.class=org.cougaar.bootstrap.CheckingBootstrapper Enables
047: * the CheckingBootstrapper to check jarfile versions at startup time for mismatches.
048: **/
049:
050: public class CheckingBootstrapper extends Bootstrapper {
051: private static Pattern modPattern = Pattern
052: .compile(".*/([^/]*)\\.\\w*$");
053: private static Pattern manPattern = Pattern
054: .compile("^Manifest/(.*)\\.version$");
055: private static Pattern kvPattern = Pattern
056: .compile("^(\\w*)\\s*=\\s*(.*)$");
057:
058: protected List filterURLs(List l) {
059: List o = super .filterURLs(l);
060: scanAll();
061: return o;
062: }
063:
064: protected boolean checkURL(URL url) {
065: boolean ok = super .checkURL(url);
066: if (ok) {
067: scanURL(url);
068: }
069: return ok;
070: }
071:
072: private Map checkedJars = new HashMap(29);
073:
074: /** parse out the module name from the url if possible **/
075: private String getModName(URL url) {
076: String s = url.getFile(); // e.g. /tmp/foo/lib/core.jar
077: Matcher m = modPattern.matcher(s);
078: if (m.matches()) {
079: String mod = m.group(1);
080: return mod;
081: } else {
082: return null;
083: }
084: }
085:
086: // look for "/Manifest/<something>.version"
087: private String getManName(String path) {
088: Matcher m = manPattern.matcher(path);
089: if (m.matches()) {
090: String man = m.group(1);
091: return man;
092: } else {
093: return null;
094: }
095: }
096:
097: private void scanURL(URL url) {
098: String mod = getModName(url);
099: try {
100: InputStream is = url.openStream();
101:
102: ZipInputStream zis = new ZipInputStream(is);
103:
104: ZipEntry ze;
105: while ((ze = zis.getNextEntry()) != null) {
106: String path = ze.getName();
107: String man = getManName(path);
108: if (man != null) {
109: if (!(man.equals(mod))) {
110: System.err.println("Warning: Classpath entry "
111: + url + " should be module " + mod
112: + " but appears to be " + man);
113: }
114: BufferedReader br = new BufferedReader(
115: new InputStreamReader(zis));
116: String l;
117: HashMap map = new HashMap(11);
118: while ((l = br.readLine()) != null) {
119: Matcher m = kvPattern.matcher(l);
120: if (m.matches()) {
121: String key = m.group(1);
122: String value = m.group(2);
123: map.put(key, value);
124: }
125: }
126: map.put("URL", url.toString());
127: map.put("Manifest", path);
128:
129: String k = (String) map.get("NAME");
130: if (k == null)
131: k = man;
132: if (checkedJars.get(k) != null) {
133: Map ack = (Map) checkedJars.get(k);
134: System.err.println("Warning: Module " + k
135: + " found in two locations:");
136: System.err.println("\t" + ack.get("URL"));
137: System.err.println("\t" + map.get("URL")
138: + " (ignored)");
139: } else {
140: checkedJars.put(k, map);
141: }
142: }
143: zis.closeEntry();
144: }
145: zis.close();
146: } catch (Exception e) {
147: e.printStackTrace();
148: }
149: }
150:
151: public void scanAll() {
152: String iname = null; // index module name... should really be core or somesuch
153: String rtime = null;
154: String rtag = null;
155: String url = null;
156:
157: for (Iterator kit = checkedJars.keySet().iterator(); kit
158: .hasNext();) {
159: String key = (String) kit.next();
160: Map map = (Map) checkedJars.get(key);
161:
162: String mname = (String) map.get("NAME");
163: String mrtime = (String) map.get("REPOSITORY_TIME");
164: String mrtag = (String) map.get("REPOSITORY_TAG");
165: // String mcomment = (String) map.get("COMMENT");
166: String murl = (String) map.get("URL");
167:
168: if (mname == null || mrtime == null || mrtag == null
169: || murl == null) {
170: System.err.println("Warning: Jarfile \"" + key
171: + "\" has incomplete manifest.");
172: continue;
173: }
174:
175: if (iname == null) {
176: iname = mname;
177: rtime = mrtime;
178: rtag = mrtag;
179: url = murl;
180: continue;
181: }
182:
183: if (!mrtag.equals(rtag)) {
184: System.err
185: .println("Warning: Jarfile Repository tag mismatch:");
186: System.err.println("\t" + iname + "(" + url + ") = "
187: + rtag);
188: System.err.println("\t" + mname + "(" + murl + ") = "
189: + mrtag);
190: }
191:
192: if (!mrtime.equals(rtime)) {
193: System.err
194: .println("Warning: Jarfile Repository time mismatch:");
195: System.err.println("\t" + iname + "(" + url + ") = "
196: + rtime);
197: System.err.println("\t" + mname + "(" + murl + ") = "
198: + mrtime);
199: }
200: }
201: }
202:
203: }
|