001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file ../GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015: package org.griphyn.vdl.directive;
016:
017: import java.io.*;
018: import java.sql.SQLException;
019: import java.util.Enumeration;
020: import java.util.ArrayList;
021: import java.util.StringTokenizer;
022: import java.util.Iterator;
023: import java.util.Collection;
024: import java.util.MissingResourceException;
025: import org.griphyn.common.util.Separator;
026: import org.griphyn.vdl.parser.VDLxParser;
027: import org.griphyn.vdl.classes.*;
028: import org.griphyn.vdl.router.*;
029: import org.griphyn.vdl.dbschema.*;
030: import org.griphyn.vdl.dax.ADAG;
031:
032: /**
033: * This class generates the DAX per the request for LFNs or DVs
034: *
035: * @author Jens-S. Vöckler
036: * @author Yong Zhao
037: * @version $Revision: 50 $
038: *
039: * @see org.griphyn.vdl.router.Route
040: * @see org.griphyn.vdl.router.BookKeeper
041: * @see org.griphyn.vdl.dbschema.VDC
042: */
043: public class Explain extends Directive {
044: /**
045: * Maintains the link to the VDC.
046: */
047: private DatabaseSchema m_dbschema = null;
048:
049: /**
050: * Provides a routing object to traverse dependencies in the VDC.
051: */
052: private Route m_route = null;
053:
054: /**
055: * Helpful object for routing requests.
056: */
057: private BookKeeper m_state = null;
058:
059: /**
060: * Constructor
061: */
062: public Explain() throws IOException, MissingResourceException {
063: super ();
064: }
065:
066: /**
067: * Constructor: Sets the database schema instance, and
068: * initializes the internal <code>Route</code> accordingly.
069: *
070: * @param dbs the database schema instance
071: * @see org.griphyn.vdl.router.Route
072: * @see org.griphyn.vdl.router.BookKeeper
073: */
074: public Explain(DatabaseSchema dbs) throws IOException,
075: MissingResourceException {
076: m_dbschema = dbs;
077: m_route = new Route(m_dbschema);
078: m_state = new BookKeeper();
079: }
080:
081: /**
082: * Sets database schema, and initialzes the internal
083: * <code>Route</code> accordingly.
084: *
085: * @param dbs the database schema instance
086: * @see org.griphyn.vdl.router.Route
087: * @see org.griphyn.vdl.router.BookKeeper
088: */
089: public void setDatabaseSchema(DatabaseSchema dbs) {
090: m_dbschema = dbs;
091: m_route = new Route(m_dbschema);
092: m_state = new BookKeeper();
093: }
094:
095: /**
096: * Allows to limit the maximum depth that the router is willing to go.
097: *
098: * @param depth is the maximum depth. Use Integer.MAX_VALUE for
099: * (virtually) unlimited depth.
100: */
101: public void setMaximumDepth(int depth) {
102: m_route.setMaximumDepth(depth);
103: }
104:
105: /**
106: * Requests a data product logical filename. As a result, the complete
107: * build-style DAG for producing the requested filename will be
108: * constructed.
109: *
110: * @param filename is the name of the requested LFN.
111: * @return true if the request is successful
112: *
113: * @see #requestLFN( java.util.Collection )
114: * @see org.griphyn.vdl.router.BookKeeper
115: */
116: public boolean requestLFN(String filename)
117: throws java.sql.SQLException {
118: ArrayList al = new ArrayList(1);
119: al.add(filename);
120: return requestLFN(al);
121: }
122:
123: /**
124: * Requests a set of logical filenames. As a result, the complete
125: * build-style DAG for producing the requested LFNs will be
126: * constructed.
127: *
128: * @param filenames is the list or set of logical filenames requested.
129: * @return true if the request is successful
130: *
131: * @see org.griphyn.vdl.router.Route#requestLfn( Collection, BookKeeper )
132: * @see org.griphyn.vdl.router.BookKeeper
133: */
134: public boolean requestLFN(java.util.Collection filenames)
135: throws java.sql.SQLException {
136: // FIXME: What about previous results?
137: m_route.requestLfn(filenames, m_state);
138: return (m_state != null && !m_state.isEmpty());
139: }
140:
141: /**
142: * Requests for a specific derivation. As a result, a build-style DAG
143: * will be produced and maintained in the book-keeping structure.
144: *
145: * @param namespace is the namespace of the derivation.
146: * @param name is the name of the derivation.
147: * @param version is the version of the derivation.
148: * @return true if the request is successful
149: *
150: * @see org.griphyn.vdl.router.Route#requestDerivation( String, String, String, BookKeeper )
151: * @see org.griphyn.vdl.router.BookKeeper
152: */
153: public boolean requestDerivation(String namespace, String name,
154: String version) {
155: return m_route.requestDerivation(namespace, name, version,
156: m_state);
157: }
158:
159: /**
160: * Requests for a specific derivation. As a result, a build-style DAG
161: * will be produced and maintained in the book-keeping structure.
162: *
163: * @param fqdn is the fully qualified name of the derivation.
164: * @return true if the request is successful
165: *
166: * @see org.griphyn.common.util.Separator#splitFQDI( String )
167: * @see org.griphyn.vdl.router.Route#requestDerivation( String, String, String, BookKeeper )
168: * @see org.griphyn.vdl.router.BookKeeper
169: */
170: public boolean requestDerivation(String fqdn)
171: throws IllegalArgumentException {
172: String[] name = Separator.splitFQDI(fqdn);
173: return m_route.requestDerivation(name[0], name[1], name[2],
174: m_state);
175: }
176:
177: /**
178: * Requests a set of specific derivations. As a result, a build-style
179: * DAG will be produced and maintained in the book-keeping structure.
180: *
181: * @param symbolicList is a collecting of symbolic FQDN derivation triples.
182: * @return true if the request is successful
183: *
184: * @see org.griphyn.common.util.Separator#splitFQDI( String )
185: * @see org.griphyn.vdl.router.Route#requestDerivation( Collection, BookKeeper )
186: * @see org.griphyn.vdl.router.BookKeeper
187: */
188: public boolean requestDerivation(java.util.Collection symbolicList)
189: throws IllegalArgumentException {
190: return m_route.requestDerivation(symbolicList, m_state);
191: }
192:
193: /**
194: * Writes the abstract DAX from the accumulated results.
195: *
196: * @param writer the output writer
197: * @param label the label of the dax
198: *
199: * @see org.griphyn.vdl.router.BookKeeper#getDAX
200: */
201: public void writeDAX(Writer writer, String label)
202: throws IOException {
203: this .writeDAX(writer, label, null);
204: }
205:
206: /**
207: * Writes the abstract DAX with a namespace prefix.
208: *
209: * @param writer the output writer
210: * @param label the label of the dax
211: * @param xmlns the xml namespace prefix
212: *
213: * @see org.griphyn.vdl.router.BookKeeper#getDAX
214: */
215: public void writeDAX(Writer writer, String label, String xmlns)
216: throws IOException {
217: if (m_state == null || m_state.isEmpty()) {
218: // whatever we did, there are no results for us
219: m_logger.log("explain", 0,
220: "WARNING: The requested DAX is empty!\n");
221: } else {
222: ADAG dax = m_state.getDAX(label == null ? "test" : label);
223: m_logger.log("explain", 2, "DAX has "
224: + dax.getFilenameCount() + " LFNs, "
225: + dax.getJobCount() + " jobs, "
226: + dax.getChildCount() + " deps.");
227: dax.toXML(writer, "", xmlns);
228: }
229: }
230:
231: /**
232: * Checks if the result is empty or not.
233: *
234: * @return true, if the result is undefined or empty, false otherwise.
235: */
236: public boolean isEmpty() {
237: return (m_state == null || m_state.isEmpty());
238: }
239: }
|