Source Code Cross Referenced for ADAG.java in  » Workflow-Engines » pegasus-2.1.0 » org » griphyn » vdl » dax » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » pegasus 2.1.0 » org.griphyn.vdl.dax 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:
016:        package org.griphyn.vdl.dax;
017:
018:        import org.griphyn.common.util.Currently;
019:        import org.griphyn.vdl.dax.*;
020:        import org.griphyn.vdl.classes.LFN;
021:        import org.griphyn.vdl.classes.Derivation;
022:        import java.util.*;
023:        import java.io.Writer;
024:        import java.io.IOException;
025:
026:        /**
027:         * This class is the container for an abstract DAG description. It consists
028:         * of three parts.<p>
029:         *
030:         * <ol>
031:         * <li> {@link Filename} deals with the filenames that are used in the
032:         * picture of the DAG - does a file go into the DAG, come out of the
033:         * DAG, or is it an intermediary file. There are multiple instances
034:         * stored in a DAX.
035:         *
036:         * <li> {@link Job} deals with the description of all jobs in a DAG.
037:         * Each job has a logical transformation, commandline argument, possible
038:         * stdio redirection, and a potential set of <code>Profile</code>
039:         * settings. There are multiple instance stored in a DAX.
040:         *
041:         * <li> {@link Child} deals with the dependency in a two-level fashion.
042:         * It contains a list of child to parent(s) relationships. The children
043:         * and parents refer to jobs from the previous section. There are
044:         * multiple instances stored in a DAX.
045:         * </ol>
046:         *
047:         * @author Jens-S. Vöckler
048:         * @author Yong Zhao
049:         * @version $Revision: 366 $
050:         */
051:        public class ADAG extends DAX implements  Cloneable {
052:            /**
053:             * The "official" namespace URI of the DAX schema.
054:             */
055:            public static final String SCHEMA_NAMESPACE = "http://pegasus.isi.edu/schema/DAX";
056:
057:            /**
058:             * The "not-so-official" location URL of the DAX schema definition.
059:             */
060:            public static final String SCHEMA_LOCATION = "http://pegasus.isi.edu/schema/dax-2.1.xsd";
061:
062:            /**
063:             * The version to report.
064:             */
065:            public static final String SCHEMA_VERSION = "2.1";
066:
067:            /**
068:             * list of all filenames in terms of Filename
069:             * @see Filename
070:             */
071:            private TreeMap m_fileMap;
072:
073:            /**
074:             * list of all jobs
075:             * @see Job
076:             */
077:            private TreeMap m_jobMap;
078:
079:            /**
080:             * list of all child nodes to construct DAG.
081:             * @see Child
082:             */
083:            private TreeMap m_childMap;
084:
085:            /**
086:             * list of replacements for node collapsion from compounds.
087:             */
088:            private TreeMap m_replace;
089:            private boolean m_dirty;
090:
091:            /**
092:             * optional name of this document.
093:             */
094:            private String m_name = null;
095:
096:            /**
097:             * When generating alternatives, this is the total number of alternatives.
098:             */
099:            private int m_size;
100:
101:            /**
102:             * When generating alternatives, this is the zero-based count.
103:             */
104:            private int m_index;
105:
106:            /**
107:             * The version to report back, or alternatively to the version that
108:             * the DAX file had when reading.
109:             */
110:            private String m_version = SCHEMA_VERSION;
111:
112:            /**
113:             * Creates and returns a copy of this object.
114:             * @return a new instance, deep copy of elements
115:             */
116:            public Object clone() {
117:                ADAG result = new ADAG(this .m_size, this .m_index, this .m_name);
118:
119:                // maybe unsafe?
120:                result.setVersion(this .m_version);
121:
122:                for (Iterator i = this .m_fileMap.values().iterator(); i
123:                        .hasNext();) {
124:                    result
125:                            .addFilename((Filename) ((Filename) i.next())
126:                                    .clone());
127:                }
128:                for (Iterator i = this .m_jobMap.values().iterator(); i
129:                        .hasNext();) {
130:                    result.addJob((Job) ((Job) i.next()).clone());
131:                }
132:                for (Iterator i = this .m_childMap.values().iterator(); i
133:                        .hasNext();) {
134:                    result.addChild((Child) ((Child) i.next()).clone());
135:                }
136:                for (Iterator i = this .m_replace.keySet().iterator(); i
137:                        .hasNext();) {
138:                    String key = (String) i.next();
139:                    result.replaceParent(key, (String) this .m_replace.get(key));
140:                }
141:
142:                return result;
143:            }
144:
145:            /**
146:             * Default ctor: construct a hollow shell to add data later.
147:             */
148:            public ADAG() {
149:                m_size = 1;
150:                m_index = 0;
151:                m_jobMap = new TreeMap();
152:                m_fileMap = new TreeMap();
153:                m_childMap = new TreeMap();
154:                m_replace = new TreeMap();
155:            }
156:
157:            /**
158:             * Ctor: Construct a hollow shell with the required arguments.
159:             *
160:             * @param size is the total number of DAXes that will be constructed.
161:             * @param index is the zero-based number in the total number of DAXes.
162:             */
163:            public ADAG(int size, int index) {
164:                m_size = size;
165:                m_index = index;
166:                m_jobMap = new TreeMap();
167:                m_fileMap = new TreeMap();
168:                m_childMap = new TreeMap();
169:                m_replace = new TreeMap();
170:            }
171:
172:            /**
173:             * Ctor: Construct a hollow shell with all element attributes
174:             *
175:             * @param size is the total number of DAXes that will be constructed.
176:             * @param index is the zero-based number in the total number of DAXes.
177:             * @param name is an optional name to use for the DAX. In later versions
178:             * this might be useful, if several DAXes are interleaved on the same
179:             * connection.
180:             */
181:            public ADAG(int size, int index, String name) {
182:                m_name = name;
183:                m_size = size;
184:                m_index = index;
185:                m_jobMap = new TreeMap();
186:                m_fileMap = new TreeMap();
187:                m_childMap = new TreeMap();
188:                m_replace = new TreeMap();
189:            }
190:
191:            /**
192:             * Adds a logical filename string with input or output notion to the
193:             * list of maintained filenames. If the filename does not exist
194:             * previously, a new entry is added. If the filename does exist, the
195:             * io state will be checked. A filename that was previously an input,
196:             * and is now an output, will become inout. If a filename was ever
197:             * declared not-transfer or not-register, it will maintain these
198:             * attributes. Each filename is only added once.
199:             *
200:             * @param lfn is the logical filename string
201:             * @param isInput is a predicate with true to signal an input filename.
202:             * @param temporary is a temp file hint, currently unused.
203:             * @param dontRegister a true value will be propagated (mono-flop)
204:             * @param dontTransfer any non-mandatory value will be propagated
205:             */
206:            public void addFilename(String lfn, boolean isInput,
207:                    String temporary, boolean dontRegister, int dontTransfer) {
208:                Filename f = (Filename) this .m_fileMap.get(lfn);
209:                if (f != null) {
210:                    // found! check link status
211:                    if ((f.getLink() == LFN.INPUT && !isInput)
212:                            || (f.getLink() == LFN.OUTPUT && isInput)) {
213:                        // need to change linkage
214:                        f.setLink(LFN.INOUT);
215:                    }
216:                    // set file hint
217:                    if (temporary != null)
218:                        f.setTemporary(temporary);
219:                    if (dontRegister)
220:                        f.setRegister(!dontRegister);
221:                    if (dontTransfer != LFN.XFER_MANDATORY)
222:                        f.setTransfer(dontTransfer);
223:                } else {
224:                    // file is not in list, add it
225:                    // PS: and it is most likely not a stdio filename?
226:                    this .m_fileMap.put(lfn, new Filename(lfn,
227:                            isInput ? LFN.INPUT : LFN.OUTPUT, temporary,
228:                            dontRegister, dontTransfer, null));
229:                }
230:            }
231:
232:            /**
233:             * Adds a completely constructed {@link Filename} structure to the
234:             * map of filenames. The structure must be assembled outside. This
235:             * method is primarily a convenience for the {@link #clone()} method.
236:             *
237:             * @param lfn is the Filename instance.
238:             * @return true, if the bag did not contain an identical Filename already.
239:             */
240:            protected boolean addFilename(Filename lfn) {
241:                String id = lfn.getFilename();
242:                boolean result = !this .m_fileMap.containsKey(id);
243:                this .m_fileMap.put(id, lfn);
244:                return result;
245:            }
246:
247:            /**
248:             * Adds a completely constructed {@link Job} structure to the
249:             * map of jobs. The structure must be assembled outside, using
250:             * the related classes. The job ID will be taken as unique key.
251:             * If a job with this ID already exists in the DAX, it will be
252:             * replaced with the new job.
253:             *
254:             * @param job is the new job to add
255:             * @return true, if the bag did not contain this job already.
256:             */
257:            public boolean addJob(Job job) {
258:                String id = job.getID();
259:                boolean result = !this .m_jobMap.containsKey(id);
260:                this .m_jobMap.put(id, job);
261:                return result;
262:            }
263:
264:            /**
265:             * Adds a child node which was constructed elsewhere to the list of
266:             * known children. If the child already exists, nothing is done.
267:             *
268:             * @param child is the new {@link Child} instance to put into the bag.
269:             * @return true if the bag did not already contain the specified element.
270:             */
271:            public boolean addChild(Child child) {
272:                if (this .m_childMap.containsKey(child.getChild())) {
273:                    return false;
274:                } else {
275:                    this .m_childMap.put(child.getChild(), child);
276:                    return true;
277:                }
278:            }
279:
280:            /**
281:             * Adds a child node without any parent relationship to the list of
282:             * known children. If the child already exists, nothing is done.
283:             *
284:             * @param child_id is the new child to put into the bag.
285:             * @return true if the bag did not already contain the specified element.
286:             */
287:            public boolean addChild(String child_id) {
288:                if (this .m_childMap.containsKey(child_id)) {
289:                    return false;
290:                } else {
291:                    this .m_childMap.put(child_id, new Child(child_id));
292:                    return true;
293:                }
294:            }
295:
296:            /**
297:             * Adds a child node with a parent relationship to the list of known
298:             * children. If the child already exists, but the parent relationship
299:             * is not known, it will be added to the child's list of parents. If
300:             * the child already exists and the parent relationship is known,
301:             * nothing is done.
302:             *
303:             * @param child_id is the id of the child for which to modify a parent
304:             * @param parent_id is the new parent to add to the specified child.
305:             * @return true if the bag did not already contain the relationship. */
306:            public boolean addChild(String child_id, String parent_id) {
307:                Child current = (Child) this .m_childMap.get(child_id);
308:                if (current == null) {
309:                    // unknown child, add to bag
310:                    this .m_childMap.put(child_id,
311:                            new Child(child_id, parent_id));
312:                    return true;
313:                } else {
314:                    // child is know, check the parent
315:                    if (!current.getParent(parent_id)) {
316:                        // parent is unknown, add to child
317:                        current.addParent(parent_id);
318:                        return true;
319:                    } else {
320:                        // parent is already known
321:                        return false;
322:                    }
323:                }
324:            }
325:
326:            /**
327:             * Registers a job node collapsion as a replacement.
328:             */
329:            public String replaceParent(String oldid, String newid) {
330:                String old = (String) this .m_replace.put(oldid, newid);
331:                this .m_dirty = true;
332:                return old;
333:            }
334:
335:            /**
336:             * Accessor: Provides an iterator for the bag of filenames.
337:             * @return the iterator for <code>Filename</code> elements.
338:             * @see Filename
339:             * @deprecated Use the new Collection based interfaces
340:             */
341:            public Enumeration enumerateFilename() {
342:                return Collections.enumeration(this .m_fileMap.values());
343:            }
344:
345:            /**
346:             * Accessor: Provides an iterator for the bag of jobs.
347:             * @return the iterator for <code>Job</code> elements.
348:             * @see Job
349:             * @deprecated Use the new Collection based interfaces
350:             */
351:            public Enumeration enumerateJob() {
352:                return Collections.enumeration(this .m_jobMap.values());
353:            }
354:
355:            /**
356:             * Accessor: Provides an iterator for the bag of relationships.
357:             * @return the iterator for <code>Child</code> elements.
358:             * @see Child
359:             * @deprecated Use the new Collection based interfaces
360:             */
361:            public Enumeration enumerateChild() {
362:                if (this .m_dirty)
363:                    updateChildren();
364:                return Collections.enumeration(this .m_childMap.values());
365:            }
366:
367:            /**
368:             * Accessor: Obtains a <code>Filename</code> from its string.
369:             *
370:             * @param lfn is the logical filename string to look it up with.
371:             * @return the filename instance at the specified place.
372:             * @see #addFilename( Filename )
373:             * @see #setFilename( Filename )
374:             */
375:            public Filename getFilename(String lfn) {
376:                return (Filename) this .m_fileMap.get(lfn);
377:            }
378:
379:            /**
380:             * Accessor: Obtains the index of filename instances.
381:             *
382:             * @return the number of arguments in the filename list.
383:             * @see Filename
384:             */
385:            public int getFilenameCount() {
386:                return this .m_fileMap.size();
387:            }
388:
389:            /**
390:             * Accessor: Counts the number of jobs in the abstract DAG.
391:             *
392:             * @return the number of jobs.
393:             */
394:            public int getJobCount() {
395:                return this .m_jobMap.size();
396:            }
397:
398:            /**
399:             * Access: Counts the number of dependencies in the DAG.
400:             *
401:             * @return dependency count, which may be zilch.
402:             */
403:            public int getChildCount() {
404:                if (this .m_dirty)
405:                    updateChildren();
406:                return this .m_childMap.size();
407:            }
408:
409:            /**
410:             * Accessor: Obtains the zero-based index.
411:             *
412:             * @return a number in the interval [0,size-1].
413:             * @see #setIndex( int )
414:             */
415:            public int getIndex() {
416:                return this .m_index;
417:            }
418:
419:            /**
420:             * Accessor: Obtains a job by its id from the job list.
421:             *
422:             * @return a job or null, if not found.
423:             * @see #addJob( Job )
424:             */
425:            public Job getJob(String jobID) {
426:                return (Job) this .m_jobMap.get(jobID);
427:            }
428:
429:            /**
430:             * Accessor: Obtains the name of the DAX.
431:             *
432:             * @return the name of this DAX, or <code>null</code>, if no name
433:             * was specified.
434:             * @see #setName( String )
435:             */
436:            public String getName() {
437:                return this .m_name;
438:            }
439:
440:            /**
441:             * Accessor: Obtains the total number of alternatives. This is the
442:             * number of DAXes generatable from alternatives.
443:             * @return a positive natural integer.
444:             * @see #setSize( int )
445:             */
446:            public int getSize() {
447:                return this .m_size;
448:            }
449:
450:            /**
451:             * Accessor: Obtains the version that will be reported in the DAX.
452:             * @return the version as a string.
453:             * @see #setVersion( String )
454:             * @since 1.7
455:             */
456:            public String getVersion() {
457:                return this .m_version;
458:            }
459:
460:            /**
461:             * Accessor: Provides an iterator for the bag of filenames.
462:             * @return the iterator for <code>Filename</code> elements.
463:             * @see Filename
464:             */
465:            public Iterator iterateFilename() {
466:                return this .m_fileMap.values().iterator();
467:            }
468:
469:            /**
470:             * Accessor: Provides an iterator for the bag of jobs.
471:             * @return the iterator for <code>Job</code> elements.
472:             * @see Job
473:             */
474:            public Iterator iterateJob() {
475:                return this .m_jobMap.values().iterator();
476:            }
477:
478:            /**
479:             * Accessor: Provides an iterator for the bag of relationships.
480:             * @return the iterator for <code>Child</code> elements.
481:             * @see Child
482:             */
483:            public Iterator iterateChild() {
484:                if (this .m_dirty)
485:                    updateChildren();
486:                return this .m_childMap.values().iterator();
487:            }
488:
489:            /**
490:             * Accessor: Removes all filename instances.
491:             * @see Filename
492:             */
493:            public void removeAllFilename() {
494:                this .m_fileMap.clear();
495:            }
496:
497:            /**
498:             * Accessor: Removes a specific logical filename instance from the bag.
499:             *
500:             * @param lfn is the logical filename string to refer to a filename.
501:             * @return the {@link Filename} instance to which this lfn had been mapped
502:             * in this hashtable, or <code>null</code> if the lfn did not have a mapping.
503:             */
504:            public Filename removeFilename(String lfn) {
505:                return (Filename) this .m_fileMap.remove(lfn);
506:            }
507:
508:            /**
509:             * Accessor: Overwrites an filename instance with a new one.
510:             *
511:             * @param vFilename is the new filename instance, which contains all
512:             * necessary information.
513:             */
514:            public void setFilename(Filename vFilename) {
515:                this .m_fileMap.put(vFilename.getFilename(), vFilename);
516:            }
517:
518:            /**
519:             * Accessor: Replace this filename instance list with a new list.
520:             *
521:             * @param fileArray is the new list of Filename instances
522:             * @see Filename
523:             * @deprecated Use the new Collection based interfaces
524:             */
525:            public void setFilename(Filename[] fileArray) {
526:                this .m_fileMap.clear();
527:                for (int i = 0; i < fileArray.length; i++) {
528:                    this .m_fileMap
529:                            .put(fileArray[i].getFilename(), fileArray[i]);
530:                }
531:            }
532:
533:            /**
534:             * Accessor: Replace this filename instance list with a new list.
535:             *
536:             * @param files is the new collection of Filename instances
537:             * @see Filename
538:             */
539:            public void setFilename(java.util.Collection files) {
540:                this .m_fileMap.clear();
541:                for (Iterator i = files.iterator(); i.hasNext();) {
542:                    Filename lfn = (Filename) i.next();
543:                    this .m_fileMap.put(lfn.getFilename(), lfn);
544:                }
545:            }
546:
547:            /**
548:             * Accessor: Replace this filename instance list with a map.
549:             *
550:             * @param files is the new map of Filename instances
551:             * @see Filename
552:             */
553:            public void setFilename(java.util.Map files) {
554:                this .m_fileMap.clear();
555:                this .m_fileMap.putAll(files);
556:            }
557:
558:            /**
559:             * Acessor: Sets a new zero-based index for this document. The index
560:             * is used in conjunction with the total number of documents count.
561:             *
562:             * @param index is the new zero-based index of this element.
563:             * @see #getIndex()
564:             */
565:            public void setIndex(int index) {
566:                this .m_index = index;
567:            }
568:
569:            /**
570:             * Acessor: Sets a new optional name for this document.
571:             *
572:             * @param name is the new name.
573:             * @see #getName()
574:             */
575:            public void setName(String name) {
576:                this .m_name = name;
577:            }
578:
579:            /**
580:             * Acessor: Sets a new total document count in this document. The count
581:             * is used in conjunction with the zero-based document index.
582:             *
583:             * @param size is the new total document count.
584:             * @see #getSize()
585:             */
586:            public void setSize(int size) {
587:                this .m_size = size;
588:            }
589:
590:            /**
591:             * Acessor: Sets a new version number for this document. The version
592:             * number is taken by the abstract planner to support a range of valid
593:             * DAX documents.
594:             *
595:             * @param version is the new version number as string composed of two
596:             * integers separted by a period.
597:             * @see #getVersion()
598:             * @since 1.7
599:             */
600:            public void setVersion(String version) {
601:                this .m_version = version;
602:            }
603:
604:            private void updateChildren() {
605:                // find all child nodes in need of replacement
606:                TreeMap temp = new TreeMap();
607:                for (Iterator i = this .m_childMap.values().iterator(); i
608:                        .hasNext();) {
609:                    Child newchild = ((Child) i.next())
610:                            .updateChild(this .m_replace);
611:                    if (temp.containsKey(newchild.getChild())) {
612:                        // need to merge two definitions
613:                        Child oldchild = (Child) temp.get(newchild.getChild());
614:                        for (Iterator j = oldchild.iterateParent(); j.hasNext();) {
615:                            newchild.addParent((String) j.next());
616:                        }
617:                    }
618:                    // plain insertion
619:                    temp.put(newchild.getChild(), newchild);
620:                }
621:                this .m_childMap = temp;
622:                this .m_dirty = false;
623:            }
624:
625:            /**
626:             * Adjusts all job levels along the search path. Given a starting point,
627:             * this method will re-iterate the search-tree, and adjust the level of
628:             * each known job by the specified distance.
629:             *
630:             * @param id is the job id to start
631:             * @param distance is the increment (or decrement for negative).
632:             * @return number of jobs adjusted?
633:             */
634:            public int adjustLevels(String id, int distance) {
635:                int result = 0;
636:
637:                if (m_jobMap.containsKey(id)) {
638:                    Job job = (Job) m_jobMap.get(id);
639:                    job.setLevel(job.getLevel() + distance);
640:                    result++;
641:
642:                    // also recursively adjust all known parents of this job
643:                    if (m_childMap.containsKey(id)) {
644:                        Child c = (Child) m_childMap.get(id);
645:                        for (Iterator i = c.iterateParent(); i.hasNext();) {
646:                            result += adjustLevels((String) i.next(), distance);
647:                        }
648:                    }
649:                }
650:
651:                // done
652:                return result;
653:            }
654:
655:            /**
656:             * Converts the active state into something meant for human consumption.
657:             * The method will be called when recursively traversing the instance
658:             * tree.
659:             *
660:             * @param stream is a stream opened and ready for writing. This can also
661:             * be a string stream for efficient output.
662:             */
663:            public void toString(Writer stream) throws IOException {
664:                String newline = System.getProperty("line.separator", "\r\n");
665:
666:                // FIXME: default name of a DAX w/o name is "test"
667:                String daxname = this .m_name != null ? this .m_name : "test";
668:                stream.write("adag ");
669:                stream.write(escape(daxname));
670:                stream.write(" {");
671:                stream.write(newline);
672:
673:                stream.write("  count=");
674:                stream.write((new Integer(this .m_size)).toString());
675:                stream.write(';');
676:                stream.write(newline);
677:
678:                stream.write("  index=");
679:                stream.write((new Integer(this .m_index)).toString());
680:                stream.write(';');
681:                stream.write(newline);
682:
683:                // part 1: filelist
684:                stream.write("  files {");
685:                stream.write(newline);
686:                for (Iterator i = this .m_fileMap.values().iterator(); i
687:                        .hasNext();) {
688:                    stream.write("    ");
689:                    ((Filename) i.next()).toString(stream);
690:                    stream.write(newline);
691:                }
692:                stream.write("  }");
693:                stream.write(newline);
694:
695:                // part 2: job list
696:                stream.write("  jobs {");
697:                stream.write(newline);
698:                for (Iterator i = this .m_jobMap.values().iterator(); i
699:                        .hasNext();) {
700:                    ((Job) i.next()).toString(stream);
701:                }
702:                stream.write("  }");
703:                stream.write(newline);
704:
705:                // part 3: dependencies
706:                stream.write("  dependencies {");
707:                stream.write(newline);
708:                if (this .m_dirty)
709:                    updateChildren();
710:                for (Iterator i = this .m_childMap.values().iterator(); i
711:                        .hasNext();) {
712:                    ((Child) i.next()).toString(stream);
713:                }
714:                stream.write("  }");
715:                stream.write(newline);
716:
717:                stream.write('}');
718:                stream.write(newline);
719:                stream.flush();
720:            }
721:
722:            /**
723:             * Writes the header of the XML output. The output contains the special
724:             * strings to start an XML document, some comments, and the root element.
725:             * The latter points to the XML schema via XML Instances.
726:             *
727:             * @param stream is a stream opened and ready for writing. This can also
728:             * be a string stream for efficient output.
729:             * @param indent is a <code>String</code> of spaces used for pretty
730:             * printing. The initial amount of spaces should be an empty string.
731:             * The parameter is used internally for the recursive traversal.
732:             * @param namespace is the XML schema namespace prefix. If neither
733:             * empty nor null, each element will be prefixed with this prefix,
734:             * and the root element will map the XML namespace.
735:             * @exception IOException if something fishy happens to the stream.
736:             */
737:            public void writeXMLHeader(Writer stream, String indent,
738:                    String namespace) throws IOException {
739:                String newline = System.getProperty("line.separator", "\r\n");
740:
741:                // FIXME: default name of a DAX w/o name is "test"
742:                String daxname = this .m_name != null ? this .m_name : "test";
743:
744:                // intro
745:                if (indent != null && indent.length() > 0)
746:                    stream.write(indent);
747:                stream.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
748:                stream.write(newline);
749:
750:                // when was this document generated
751:                if (indent != null && indent.length() > 0)
752:                    stream.write(indent);
753:                stream.write("<!-- generated: ");
754:                stream.write(Currently.iso8601(false));
755:                stream.write(" -->");
756:                stream.write(newline);
757:
758:                // who generated this document
759:                if (indent != null && indent.length() > 0)
760:                    stream.write(indent);
761:                stream.write("<!-- generated by: ");
762:                stream.write(System.getProperties().getProperty("user.name",
763:                        "unknown"));
764:                stream.write(" [");
765:                stream.write(System.getProperties().getProperty("user.region",
766:                        "??"));
767:                stream.write("] -->");
768:                stream.write(newline);
769:
770:                // root element with elementary attributes
771:                if (indent != null && indent.length() > 0)
772:                    stream.write(indent);
773:                stream.write('<');
774:                if (namespace != null && namespace.length() > 0) {
775:                    stream.write(namespace);
776:                    stream.write(':');
777:                }
778:                stream.write("adag xmlns");
779:                if (namespace != null && namespace.length() > 0) {
780:                    stream.write(':');
781:                    stream.write(namespace);
782:                }
783:                stream.write("=\"");
784:                stream.write(SCHEMA_NAMESPACE);
785:                stream
786:                        .write("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"");
787:                stream.write(SCHEMA_NAMESPACE);
788:                stream.write(' ');
789:                stream.write(SCHEMA_LOCATION);
790:                stream.write('"');
791:                writeAttribute(stream, " version=\"", SCHEMA_VERSION);
792:
793:                writeAttribute(stream, " count=\"", Integer
794:                        .toString(this .m_size));
795:                writeAttribute(stream, " index=\"", Integer
796:                        .toString(this .m_index));
797:                writeAttribute(stream, " name=\"", daxname);
798:
799:                // added with dax-1.9
800:                writeAttribute(stream, " jobCount=\"", Integer
801:                        .toString(this .m_jobMap.size()));
802:                writeAttribute(stream, " fileCount=\"", Integer
803:                        .toString(this .m_fileMap.size()));
804:                writeAttribute(stream, " childCount=\"", Integer
805:                        .toString(this .m_childMap.size()));
806:
807:                stream.write('>');
808:                if (indent != null)
809:                    stream.write(newline);
810:            }
811:
812:            /**
813:             * Dump the state of the current element as XML output. This function
814:             * traverses all sibling classes as necessary, and converts the data
815:             * into pretty-printed XML output. The stream interface should be able
816:             * to handle large output efficiently.
817:             *
818:             * @param stream is a stream opened and ready for writing. This can also
819:             * be a string stream for efficient output.
820:             * @param indent is a <code>String</code> of spaces used for pretty
821:             * printing. The initial amount of spaces should be an empty string.
822:             * The parameter is used internally for the recursive traversal.
823:             * @param namespace is the XML schema namespace prefix. If neither
824:             * empty nor null, each element will be prefixed with this prefix,
825:             * and the root element will map the XML namespace.
826:             * @exception IOException if something fishy happens to the stream.
827:             */
828:            public void toXML(Writer stream, String indent, String namespace)
829:                    throws IOException {
830:                String newline = System.getProperty("line.separator", "\r\n");
831:                String newindent = indent == null ? null : indent + "  ";
832:
833:                // write prefix
834:                writeXMLHeader(stream, indent, namespace);
835:
836:                // part 1: filelist
837:                stream
838:                        .write("<!-- part 1: list of all referenced files (may be empty) -->");
839:                if (indent != null)
840:                    stream.write(newline);
841:
842:                for (Iterator i = this .m_fileMap.values().iterator(); i
843:                        .hasNext();) {
844:                    if (indent != null)
845:                        stream.write(newindent);
846:                    ((Filename) i.next()).shortXML(stream, newindent,
847:                            namespace, 0x03);
848:                    if (indent != null)
849:                        stream.write(newline);
850:                }
851:
852:                // part 2: job list
853:                stream
854:                        .write("<!-- part 2: definition of all jobs (at least one) -->");
855:                if (indent != null)
856:                    stream.write(newline);
857:                for (Iterator i = this .m_jobMap.values().iterator(); i
858:                        .hasNext();) {
859:                    ((Job) i.next()).toXML(stream, newindent, namespace);
860:                }
861:
862:                // part 3: dependencies
863:                if (this .m_dirty)
864:                    updateChildren();
865:                stream
866:                        .write("<!-- part 3: list of control-flow dependencies (may be empty) -->");
867:                if (indent != null)
868:                    stream.write(newline);
869:                for (Iterator i = this .m_childMap.values().iterator(); i
870:                        .hasNext();) {
871:                    ((Child) i.next()).toXML(stream, newindent, namespace);
872:                }
873:
874:                // close tag
875:                if (indent != null && indent.length() > 0)
876:                    stream.write(indent);
877:                stream.write("</");
878:                if (namespace != null && namespace.length() > 0) {
879:                    stream.write(namespace);
880:                    stream.write(':');
881:                }
882:                stream.write("adag>");
883:                stream.write(newline);
884:                stream.flush();
885:            }
886:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.