001: /*
002: * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
003: * NETSCAPE COMMUNICATIONS CORPORATION
004: *
005: * Copyright (c) 1996 Netscape Communications Corporation.
006: * All Rights Reserved.
007: * Use of this Source Code is subject to the terms of the applicable
008: * license agreement from Netscape Communications Corporation.
009: */
010:
011: package soif;
012:
013: import communications.ReadConnection;
014: import util.ReportError;
015: import util.StopWatch;
016: import java.io.*;
017:
018: import java.net.URL;
019:
020: /**
021: * Thread that gets SOIF.
022: * <p>
023: * A status flag needs to be correctly maintained by subclasses.
024: * Calling the constructor of this class will set the status
025: * to PREPARED. Constructors of subclasses that do not call
026: * this constructor should mark the status as PREPARED.
027: * Subclasses that override the run() method should mark the
028: * status as PROCESSING as early as possible in the subclass's
029: * run() method. When the subclass's run() method completes,
030: * the status should be marked COMPLETE for successful completion
031: * or ABEND for completion with errors. If the subclass calls
032: * this class's getSOIF() method and the status gets set to
033: * ABEND by this class's getSOIF() method, that status should
034: * not be changed to COMPLETE by the subclass. Once the status
035: * is set to ABEND, it cannot be changed to COMPLETE. The status
036: * is maintained by a setStatus() method which enforces the
037: * ABEND/COMPLETE restriction and cannot be overridden.
038: * An "empty" getter instance is sometimes useful; this
039: * is created using the argumentless constructor, has a status
040: * of UNINITIALIZED and cannot be exectuted.
041: * <p>
042: * <b><font color="#FF0050">Note:</font></b>
043: * The RDMHeader class is not currently used to formulate requests.
044: * <b>This may change.</b>
045: * Both <i>SchemaGetter</i> and <i>TaxonomyGetter</i> initialize
046: * their RDM header strings with a correct RDM request.
047: * Because there are other schema and taxonomy requests that can be
048: * made which are currently not well (or not at all) documented
049: * the standard request can be changed using <i>setRDMHeader()</i>
050: * which allows you to put in anything but prevents you from changing
051: * the request during processing (the scope of the processing
052: * phase far exceeds the requirement for safe operation).
053: * The <i>setRDMHeader()</i> method should be used with the
054: * understanding that the interface will very likely change.
055: * It is also possible that the constructors will change,
056: * but the most likely scenario is that RDMHeader savvy
057: * constructors will be added.
058: */
059: public class SOIFGetter extends Thread {
060: /**
061: * Processing status.
062: */
063: private int status;
064:
065: /**
066: * Debug flag.
067: */
068: public boolean debug;
069:
070: /**
071: * Processing status: completed successfully.
072: */
073: public final static int COMPLETE = 0;
074: /**
075: * Processing status: prepared to run.
076: */
077: public final static int PREPARED = 1;
078: /**
079: * Processing status: running.
080: */
081: public final static int PROCESSING = 2;
082: /**
083: * Processing status: completed unsucessfully.
084: */
085: public final static int ABEND = 3;
086: /**
087: * Processing status: never prepared/initialized/started.
088: */
089: public final static int UNINITIALIZED = 4;
090:
091: /**
092: * Source of SOIF to which a ReadConnection will be
093: * established.
094: */
095: private String provider;
096:
097: /**
098: * Target Compass Server ID.
099: */
100: protected CSID csid;
101:
102: /**
103: * RDM Header used in request.
104: */
105: protected String rdmhead;
106:
107: /**
108: * The RDM header, if present.
109: */
110: private SOIF rdmh;
111:
112: /**
113: * SOIF.
114: * This is a list of SOIF nodes not includng any RDM header.
115: * (XXX when using csadmingw, there is no RDM header)
116: */
117: protected SOIF sl;
118:
119: /**
120: * SOIF parser.
121: */
122: protected SOIFParser slp;
123:
124: /**
125: * Constructor.
126: */
127: public SOIFGetter() {
128: status = UNINITIALIZED;
129: }
130:
131: /**
132: * Constructor.
133: * @param CGILocation location of the CGI target of the rdm request
134: * @param exe CGI executable which will fill rdm request
135: * @param csid compass server id
136: */
137: public SOIFGetter(String CGILocation, String exe, CSID csid) {
138: this .debug = debug;
139: provider = CGILocation + exe;
140: this .csid = csid;
141: rdmhead = "";
142: sl = null;
143: status = PREPARED;
144: }
145:
146: /**
147: * <b><font color="#FF0050">Not Supported.</font></b> Set the RDM header.
148: * See note in class definition.
149: * @param s rdm header
150: */
151: public void setRDMHead(String s) {
152: if (status == PROCESSING)
153: ReportError.reportError(ReportError.INTERNAL, "SOIFGetter",
154: "setRDMHead", Messages.RDMHEADERFROZEN);
155: else
156: rdmhead = s;
157: }
158:
159: /**
160: * Set processing status. If the current status is ABEND, it
161: * will not be changed.
162: */
163: protected final void setStatus(int i) {
164: if (status != ABEND)
165: status = i;
166: }
167:
168: /**
169: * Return processing status.
170: */
171: public final int getStatus() {
172: return status;
173: }
174:
175: /**
176: * Return whether or not processing is complete.
177: */
178: public final boolean finished() {
179: return ((status == COMPLETE) || (status == ABEND));
180: }
181:
182: /**
183: * Return the SOIF that the SOIFGetter got.
184: */
185: public SOIF getSOIFList() {
186: if (!finished()) {
187: return null;
188: }
189: return sl;
190: }
191:
192: /**
193: * Return the RDM header SOIF that the SOIFGetter got.
194: */
195: public SOIF getRDMHeader() {
196: if (!finished()) {
197: return null;
198: }
199: return rdmh;
200: }
201:
202: /**
203: * Wait for the getter to finish.
204: */
205: public void waitFor() {
206: while (!finished()) {
207: try {
208: Thread.sleep(100);
209: } catch (InterruptedException e) {
210: break;
211: }
212: }
213: }
214:
215: /**
216: * Wait for the getter to finish.
217: * @param max don't wait longer than max (increments are 100)
218: */
219: public void waitFor(int max) {
220: int counter = 0;
221: while ((!finished()) && (max > counter)) {
222: counter += 100;
223: try {
224: Thread.sleep(100);
225: } catch (InterruptedException e) {
226: break;
227: }
228: }
229: }
230:
231: /**
232: * Get some of that SOIF.
233: */
234: protected void getSOIF() {
235: URL url;
236: ReadConnection rc = null;
237: String s;
238: StringBuffer sb = new StringBuffer();
239: boolean errors = false;
240:
241: try {
242: if (rdmhead.length() == 0) {
243: ReportError.reportError(ReportError.INTERNAL,
244: "SOIFGetter", "getSOIF",
245: Messages.RDMHEADERNOTSET);
246: errors = true;
247: return;
248: }
249:
250: if (debug)
251: System.out.println(provider + "?" + rdmhead);
252: rc = new ReadConnection(provider + "?" + rdmhead);
253:
254: if (rc.openIn() == false)
255: return;
256:
257: //StopWatch sw;
258: //sw = new StopWatch();
259: //sw.start();
260:
261: try {
262: s = rc.doRead();
263: } catch (Exception e) {
264: ReportError.reportError(util.ReportError.INTERNAL,
265: "SOIFGetter", "getSOIF",
266: Messages.DATAINPUTSTREAMREADFAIL);
267: errors = true;
268: return;
269: }
270:
271: //sw.stop();
272: //System.out.println("SOIFGetter time = " + sw.lapTime() + "ms");
273:
274: if (debug) {
275: System.out.println("getSOIF() beg");
276: System.out.println("s[" + s + "]");
277: System.out.println("getSOIF() end");
278: }
279:
280: if (rc.closeIn() == false) {
281: errors = true;
282: return;
283: }
284:
285: if (s.indexOf("@") != -1) {
286: slp = new SOIFParser(s.substring(s.indexOf("@")));
287: if (slp.isValid())
288: sl = slp.getSOIF();
289: else {
290: sl = null;
291: errors = true;
292: return;
293: }
294: }
295: } finally {
296: if (errors) {
297: status = ABEND;
298: return;
299: }
300: }
301:
302: if (sl == null) {
303: ReportError.reportError(ReportError.INTERNAL, "SOIFGetter",
304: "getSOIF", Messages.NOSOIF);
305: status = ABEND;
306: return;
307: }
308:
309: if (debug)
310: System.out.println(sl.toStringList());
311:
312: /* sl at this point should have a list of
313: ** two or more SOIF nodes. the first is the RDM
314: ** header (if present) and the RDM header is checked
315: ** for the error strings.
316: */
317:
318: if ("RDMHEADER".equals(sl.getSchemaName())) {
319: rdmh = sl;
320: sl = sl.next;
321: rdmh.next = null;
322: }
323:
324: }
325:
326: /**
327: * Run the thread, get the SOIF.
328: */
329: public void run() {
330: if (status != PREPARED) {
331: ReportError.reportError(ReportError.INTERNAL, "SOIFGetter",
332: "run", Messages.UNINITIALIZED);
333: System.out.println(Messages.COMPLETESOIFTHREAD);
334: return;
335: }
336:
337: status = PROCESSING;
338:
339: getSOIF();
340:
341: if (status != ABEND)
342: status = COMPLETE;
343:
344: System.out.println(Messages.COMPLETESOIFTHREAD);
345: }
346:
347: }
|