source: axis/ParseTopdl.java @ a3b31ed

compt_changes
Last change on this file since a3b31ed was a3b31ed, checked in by Ted Faber <faber@…>, 12 years ago

More robust parsing of topdl (force kinds to lower case) fixes #47

  • Property mode set to 100644
File size: 20.7 KB
Line 
1// WSDL generated classes
2import edu.isi.www.fedd_types.*;
3import edu.isi.www.topdl.*;
4
5import java.io.*;
6
7import java.util.*;
8
9import javax.xml.parsers.*;
10
11import org.xml.sax.*;
12import org.xml.sax.helpers.*;
13
14public class ParseTopdl {
15    /** Parser instance */
16    protected XMLReader xr;
17    /** Handler that parses topdl file */
18    protected TopdlHandler h;
19
20    /**
21     * This class encapsulates the state of an XML parse of a topdl file.  It
22     * contains abunch of parsing state and is called from the standard SAX
23     * parser at 3 places: when an XML element starts (&lt;element&gt;) when
24     * one ends (&lt;element/&gt;) and whenever characters inside an element
25     * are encountered.  It mostly initializes fields as elements are exited,
26     * collecting other parsed fields into objects that are finally attached to
27     * the topology itself.
28     */
29    protected class TopdlHandler extends DefaultHandler {
30        /** The name of the outermost element, "experiment" by default */
31        protected String topName;
32
33        // Topology parameters
34        /** The current topology being built */
35        protected TopologyType topo;
36        /** The current element being built */
37        protected ElementType element;
38        /** The current computer being built */
39        protected ComputerType comp;
40        /** The current testbed being built */
41        protected TestbedType tb;
42        /** The current segment being built */
43        protected SegmentType seg;
44        /** The current other element being built */
45        protected OtherType other;
46
47        // Many elements have a name
48        /** the most recent name element parsed */
49        protected String name;
50        // Many statuses as well
51        protected StatusType status;
52
53        // CPU parameters
54        /** current cpu type */
55        protected String type;
56        /** current number of cpus */
57        protected int ncpus;
58
59        // Operatingsystem parameters
60        /** Current OS version */
61        protected String version;
62        /** Current OS distro */
63        protected String distribution;
64        /** Current OS distro version */
65        protected String distributionversion;
66        /** Local names of this node */
67        protected Vector<String> localnames;
68
69        /** True if in a Computer testbed or substrate that has local names */
70        protected boolean collectLocalnames;
71
72
73        // Software parameters
74        /** Current software installation point */
75        protected String install;
76        /** Current software location */
77        protected String location;
78
79        // Service Parameters
80        protected Vector<String> importers;
81        protected Vector<ServiceParamType> serviceParams;
82        protected String description;
83
84        //ServiceParam parameters
85        protected String serviceParamName;
86        protected ServiceParamTypeType serviceParamType;
87
88        // Storage parameters
89        /** Current storage amount */
90        protected double amount;
91        /** Current storage persistence */
92        protected PersistenceType persistence;
93
94        // Interface Parameters
95        /** Vector of substrate names the current interface is attached to */
96        protected Vector<String> ifsubs;
97        /** Current interface capacity */
98        protected edu.isi.www.topdl.CapacityType cap;
99        /** Current interface latency */
100        protected LatencyType lat;
101
102        // Capacity parameters
103        /** Current capacity rate (bandwidth) */
104        protected double rate;
105        /** Current capacity kind (max, peak)*/
106        protected edu.isi.www.topdl.KindType kind;
107
108        // Latency parameters (shares kind)
109        /** Current latency time */
110        protected double time;
111
112        // Testbed parameters (shares interfaces, type)
113        /** Current URI */
114        protected String uri;
115
116        // Segment parameters (shares interfaces, type, uri)
117        /** Current segment ID */
118        protected IDType id;
119        // IDType parameters
120        /** Current ID uuid (if any) */
121        protected byte[] uuid;
122        /** Current ID fedid (if any) */
123        protected byte[] fedid;
124        /** Current ID uri (if any) */
125        protected String id_uri;
126        /** Current ID localname (if any) */
127        protected String localname;
128        /** Current ID kerberosUsername (if any) */
129        protected String kerberosUsername;
130        /** True when we are parsing an ID (so URIs are stored in id_uri) */
131        protected boolean inID;
132
133        // Attribute parameters
134        /** Current attribute name */
135        protected String aname;
136        /** Current attribute value */
137        protected String aval;
138
139        /** Elements seen so far */
140        protected Vector<ElementType> elements;
141        /** Substrates seen so far */
142        protected Vector<SubstrateType> subs;
143        /** Attributes seen so far */
144        protected Vector<AttributeType> attrs;
145        /** CPUs seen so far */
146        protected Vector<CpuType> cpus;
147        /** Operating Systems seen so far */
148        protected Vector<OperatingsystemType> oses;
149        /** Software seen so far */
150        protected Vector<SoftwareType> software;
151        /** Storage seen so far */
152        protected Vector<StorageType> storage;
153        /** Interfaces seen so far */
154        protected Vector<InterfaceType> interfaces;
155        /** Services seen so far */
156        protected Vector<ServiceType> services;
157        /** Operations seen so far */
158        protected Vector<String> operations;
159
160        /**
161         * Attributes appear in many elements, some of which can appear inside
162         * the definition of others.  We keep a stack of live attributes so
163         * that a sub-element does not overwrite a super-element's attributes.
164         * attrElements is a set of element names that should start a new set
165         * of recorded attributes, and attrStack keeps the contexts stacked.
166         */
167        protected Set<String> attrElements;
168        /**
169         * The stack of attribute contexts.
170         */
171        protected Stack<Vector<AttributeType>> attrStack;
172        /**
173         * Analogous to attrElements for names.
174         */
175        protected Set<String> nameElements;
176        /**
177         * Analogous to attrStack for names.
178         */
179        protected Stack<String> nameStack;
180        /**
181         * Analogous to attrStack for status
182         */
183        protected Stack<StatusType> statusStack;
184        /**
185         * Analogous to attrElements for names.
186         */
187        protected Set<String> statusElements;
188        /**
189         * These elements collect localnames
190         */
191        protected Set<String> localnameElements;
192        /**
193         * The current buffer of characters collected.
194         */
195        protected char[] c;
196
197        /**
198         * Print parsing info if true
199         */
200        protected boolean debug;
201
202        /**
203         * Initialize the internal data structures.  Top is the outer element
204         * name.  If d is true, debugging info is printed.
205         * @param top a String containing the outer element name
206         * @param d a boolean, if true pring debugging info
207         */
208        TopdlHandler(String top, boolean d) {
209            debug = d;
210            topName = top;
211            topo = null;
212            element = null;
213            comp = null;
214            tb = null;
215            seg = null;
216            other = null;
217
218            localnames = new Vector<String>();
219            collectLocalnames = false;
220
221            type = null;
222            name = null;
223            ncpus = 1;
224
225            version = distribution = distributionversion = null;
226            description = null;
227
228            install = location = null;
229
230            amount = 0.0;
231            persistence = null;
232
233            ifsubs = new Vector<String>();
234            cap = null;
235            lat = null;
236
237            rate = 0.0;
238            kind = null;
239
240            time = 0.0;
241
242            uri = null;
243
244            id = null;
245
246            uuid = fedid = null;
247            id_uri = localname = kerberosUsername = null;
248            inID = false;
249
250            aname = aval = null;
251            importers = new Vector<String>();;
252            serviceParams = new Vector<ServiceParamType>();
253
254            elements = new Vector<ElementType>();
255            cpus = new Vector<CpuType>();
256            subs = new Vector<SubstrateType>();
257            oses = new Vector<OperatingsystemType>();
258            software = new Vector<SoftwareType>();
259            storage = new Vector<StorageType>();
260            interfaces = new Vector<InterfaceType>();
261            services = new Vector<ServiceType>();
262            serviceParams = new Vector<ServiceParamType>();
263            attrs = new Vector<AttributeType>();
264            operations = new Vector<String>();
265
266            attrElements = new TreeSet<String>();
267            for (String e : new String[] {
268                topName, "computer", "cpu", "os", "software", "storage",
269                "interface", "segment", "testbed", "other", "substrates" 
270            }) attrElements.add(e);
271
272            attrStack = new Stack<Vector<AttributeType>>();
273
274            nameElements = new TreeSet<String>();
275            for (String e : new String[] {
276                "computer", "os", "interface", "substrates", "service",
277                "param"
278            }) nameElements.add(e);
279            nameStack = new Stack<String>();
280
281            statusElements = new TreeSet<String>();
282            for (String e : new String[] {
283                "computer", "testbed", "substrates", "service",
284            }) statusElements.add(e);
285            statusStack = new Stack<StatusType>();
286
287            localnameElements = new TreeSet<String>();
288            for (String e : new String[] {
289                "computer", "testbed", "substrates",
290            }) localnameElements.add(e);
291            c = new char[0];
292        }
293
294        /**
295         * Called when an element begins.  qn is the element and a has
296         * attributes assigned in the element.  This starts new name or
297         * attribute contexts, if necessary as well as noting the start of an
298         * id (which is a lightweight uri context).  The parameter definitions
299         * below are from org.xml.sax.helpers.DefaultHandler
300         * @param u - The Namespace URI, or the empty string if the element has
301         * no Namespace URI or if Namespace processing is not being performed.
302         * @param l - The local name (without prefix), or the empty string if
303         * Namespace processing is not being performed.
304         * @param qn - The qualified name (with prefix), or the empty string if
305         * qualified names are not available.
306         * @param a - The attributes attached to the element. If there are no
307         * attributes, it shall be an empty Attributes object.
308         */
309        public void startElement(String u, String l, String qn, Attributes a) 
310                throws SAXException {
311
312            if (debug) System.err.println("<" + qn + ">");
313            c = new char[0];
314            if ( attrElements.contains(qn) ) {
315                attrStack.push(attrs);
316                attrs = new Vector<AttributeType>();
317            }
318            if ( nameElements.contains(qn) ) {
319                nameStack.push(name);
320                name = null;
321            }
322            if ( statusElements.contains(qn) ) {
323                statusStack.push(status);
324                status = null;
325            }
326            if ( localnameElements.contains(qn) ) {
327                collectLocalnames = true;
328            }
329            if (qn.equals("id")) inID = true;
330            if (qn.equals("cpu")) {
331                String n = a.getValue("count");
332                if ( n != null) ncpus = Integer.valueOf(n);
333                else ncpus = 1;
334            }
335        }
336
337        /**
338         * Collect the data from each element and stash it where any containing
339         * elent can find it when it is time to construct that thing.  Clear
340         * any fields used.  This is long but straightforward parsing.
341         * @param u - The Namespace URI, or the empty string if the element has
342         * no Namespace URI or if Namespace processing is not being performed.
343         * @param l - The local name (without prefix), or the empty string if
344         * Namespace processing is not being performed.
345         * @param qn - The qualified name (with prefix), or the empty string if
346         * qualified names are not available.
347         */
348        public void endElement(String u, String l, String qn) 
349                throws SAXException {
350
351            if (debug) System.err.println("<" + qn + "/>");
352
353            // Each branch parses the data from the given element, e.g,
354            // "computer" parses the fields collected for </computer>.  In that
355            // case the data stashed by trips through here for
356            // <operatingsystem>, <name>, etc.
357            //
358            // The vector.toArray(new Type[vector.size()], idiom just returns
359            // the contents of the vector as a java array of the vector's type.
360            if (qn.equals(topName)) {
361                topo = new TopologyType("1.0",
362                        subs.toArray(new SubstrateType[subs.size()]), 
363                        elements.toArray(new ElementType[elements.size()]), 
364                        attrs.toArray(new AttributeType[attrs.size()]));
365                elements = new Vector<ElementType>();
366                subs = new Vector<SubstrateType>();
367                attrs = attrStack.pop();
368            }
369            else if (qn.equals("elements")) {
370                elements.add(new ElementType(comp, tb, seg, other));
371                comp = null;
372                tb = null;
373                seg = null;
374                other = null;
375            }
376            else if (qn.equals("computer")) {
377                comp = new ComputerType(name, 
378                        cpus.toArray(new CpuType[cpus.size()]), 
379                        oses.toArray(new OperatingsystemType[oses.size()]), 
380                        software.toArray(new SoftwareType[software.size()]), 
381                        storage.toArray(new StorageType[storage.size()]), 
382                        interfaces.toArray(
383                            new InterfaceType[interfaces.size()]),
384                        attrs.toArray(new AttributeType[attrs.size()]),
385                        localnames.toArray(new String[localnames.size()]),
386                        status,
387                        services.toArray(new ServiceType[services.size()]),
388                        operations.toArray(new String[operations.size()])
389                        );
390                name = nameStack.pop();
391                cpus = new Vector<CpuType>();
392                oses = new Vector<OperatingsystemType>();
393                software = new Vector<SoftwareType>();
394                storage = new Vector<StorageType>();
395                interfaces = new Vector<InterfaceType>();
396                attrs = attrStack.pop();
397                localnames = new Vector<String>();
398                status = statusStack.pop();
399                services = new Vector<ServiceType>();
400                operations = new Vector<String>();
401                collectLocalnames = false;
402            }
403            else if (qn.equals("cpu")) {
404                cpus.add(new CpuType(type, 
405                        attrs.toArray(new AttributeType[attrs.size()]), ncpus));
406                type = null;
407                attrs = attrStack.pop();
408                ncpus = 1;
409            }
410            else if (qn.equals("type")) { type = new String(c).trim(); }
411            else if (qn.equals("os")) {
412                oses.add(new OperatingsystemType(name, version, 
413                        distribution, distributionversion, 
414                        attrs.toArray(new AttributeType[attrs.size()])));
415                name = nameStack.pop();
416                version = distribution = distributionversion = null;
417                attrs = attrStack.pop();
418            }
419            else if ( qn.equals("version")) { version = new String(c).trim(); }
420            else if ( qn.equals("distribution")) {
421                distribution = new String(c).trim();
422            }
423            else if ( qn.equals("distributionversion")) {
424                distributionversion = new String(c).trim();
425            }
426            else if (qn.equals("software")) {
427                software.add(new SoftwareType(location, install, 
428                            attrs.toArray(new AttributeType[attrs.size()])));
429                location = install = null;
430                attrs = attrStack.pop();
431            }
432            else if ( qn.equals("location")) { 
433                location = new String(c).trim();
434            }
435            else if ( qn.equals("install")) { install = new String(c).trim(); }
436            else if (qn.equals("storage")) {
437                storage.add(new StorageType(amount, persistence, 
438                            attrs.toArray(new AttributeType[attrs.size()])));
439                amount = 0.0;
440                persistence = null;
441                attrs = attrStack.pop();
442            }
443            else if ( qn.equals("amount")) { 
444                amount = Double.valueOf(new String(c));
445            }
446            else if ( qn.equals("persistence")) { 
447                persistence = PersistenceType.fromValue(new String(c));
448            }
449            else if (qn.equals("interface")) {
450                interfaces.add(new InterfaceType(
451                            ifsubs.toArray(new String[ifsubs.size()]),
452                            name,
453                            cap, lat,
454                            attrs.toArray(new AttributeType[attrs.size()])));
455                ifsubs = new Vector<String>();
456                name = nameStack.pop();
457                cap = null;
458                lat = null;
459                attrs = attrStack.pop();
460            }
461            else if (qn.equals("substrate")) {
462                ifsubs.add(new String(c).trim());
463            }
464            else if (qn.equals("capacity")) {
465                cap = new edu.isi.www.topdl.CapacityType(rate, kind);
466                rate = 0.0;
467                kind = null;
468            }
469            else if ( qn.equals("rate")) { 
470                rate = Double.valueOf(new String(c));
471            }
472            else if ( qn.equals("kind")) { 
473                kind = edu.isi.www.topdl.KindType.fromValue(
474                        new String(c).toLowerCase());
475            }
476            else if (qn.equals("latency")) {
477                lat = new LatencyType(time, kind);
478                time = 0.0;
479                kind = null;
480            }
481            else if ( qn.equals("time")) { 
482                time = Double.valueOf(new String(c));
483            }
484            else if (qn.equals("testbed")) {
485                tb = new TestbedType(uri, type, 
486                        interfaces.toArray(
487                            new InterfaceType[interfaces.size()]),
488                        attrs.toArray(new AttributeType[attrs.size()]),
489                        localnames.toArray(new String[localnames.size()]),
490                        status,
491                        services.toArray(new ServiceType[services.size()]),
492                        operations.toArray(new String[operations.size()]));
493                uri = type = null;
494                interfaces = new Vector<InterfaceType>();
495                attrs = attrStack.pop();
496                localnames = new Vector<String>();
497                status = statusStack.pop();
498                services = new Vector<ServiceType>();
499                operations = new Vector<String>();
500                collectLocalnames = false;
501            }
502            else if (qn.equals("uri")) { 
503                if (inID) id_uri = new String(c).trim();
504                else uri = new String(c).trim();
505            }
506            else if (qn.equals("segment")) {
507                seg = new SegmentType(id, type, uri,
508                        interfaces.toArray(
509                            new InterfaceType[interfaces.size()]),
510                        attrs.toArray(new AttributeType[attrs.size()]));
511                id = null;
512                type = uri = null;
513                interfaces = new Vector<InterfaceType>();
514                attrs = attrStack.pop();
515            }
516            else if (qn.equals("id")) { 
517                id = new IDType(uuid, fedid, id_uri, localname, 
518                        kerberosUsername);
519                uuid = null;
520                fedid = null;
521                id_uri = null;
522                localname = null;
523                kerberosUsername = null;
524                inID = false;
525            }
526            else if (qn.equals("uuid")) {
527                uuid = new String(c).trim().getBytes();
528            }
529            else if (qn.equals("fedid")) {
530                fedid = new String(c).trim().getBytes();
531            }
532            else if (qn.equals("localname")) {
533                if (collectLocalnames) localnames.add(new String(c).trim());
534                else localname = new String(c).trim();
535            }
536            else if (qn.equals("kerberosUsername")) { 
537                kerberosUsername = new String(c).trim();
538            }
539            else if (qn.equals("description")) { 
540                description = new String(c).trim();
541            }
542            else if (qn.equals("other")) { 
543                other = new OtherType(
544                        interfaces.toArray(
545                            new InterfaceType[interfaces.size()]),
546                        attrs.toArray(new AttributeType[attrs.size()]));
547                interfaces = new Vector<InterfaceType>();
548                attrs = attrStack.pop();
549            }
550            else if (qn.equals("substrates")) {
551                subs.add(new SubstrateType(name, cap, lat, 
552                        attrs.toArray(new AttributeType[attrs.size()]),
553                        localnames.toArray(new String[localnames.size()]),
554                        status,
555                        services.toArray(new ServiceType[services.size()]),
556                        operations.toArray(new String[operations.size()])
557                        ));
558                name = nameStack.pop();
559                cap = null;
560                lat = null;
561                attrs = attrStack.pop();
562                localnames = new Vector<String>();
563                status = statusStack.pop();
564                services = new Vector<ServiceType>();
565                operations = new Vector<String>();
566                collectLocalnames = false;
567            }
568            else if (qn.equals("attribute")) {
569                if ( aname != null && aval != null ) {
570                    attrs.add(new AttributeType(aname, aval));
571                    aname = aval = null;
572                }
573                else { aname = new String(c).trim(); }
574            }
575            else if ( qn.equals("value")) { aval = new String(c).trim(); }
576            else if ( qn.equals("name")) { name = new String(c).trim(); }
577            else if ( qn.equals("param") ) {
578                serviceParams.add(new ServiceParamType(name, 
579                            ServiceParamTypeType.fromString(type)));
580                name = nameStack.pop();
581                type = null;
582            }
583            else if (qn.equals("service")) {
584                services.add(new ServiceType(
585                        name, importers.toArray(new String[importers.size()]),
586                        serviceParams.toArray(
587                            new ServiceParamType[serviceParams.size()]),
588                        description, status));
589                name = nameStack.pop();
590                importers = new Vector<String>();
591                serviceParams = new Vector<ServiceParamType>();
592                description = null;
593                status = statusStack.pop();
594            }
595
596            // Always clear any accumulated characters
597            c = new char[0];
598        }
599
600        /**
601         * Collect text.
602         */
603        public void characters(char[] ch, int s, int l) {
604            char[] nc = new char[c.length + l];
605            System.arraycopy(c, 0, nc, 0, c.length);
606            System.arraycopy(ch, s, nc, c.length, l);
607            c = nc;
608        }
609        /**
610         * Return the parsed topology
611         * @return the parsed topology
612         */
613        public TopologyType getTopology() { return topo; }
614    }
615
616    /**
617     * Main constructor.  Parse the given stream assuming that the outermost
618     * element is in topName (defaults to "experiment" if topName is null).  If
619     * debug is true, print extra debugging information to the standard error
620     * stream.
621     * @param s the InputStream to parse
622     * @param topName a String with the outer element name
623     * @param debug a boolean, true for extra debugging output
624     * @throws IOException if the stream cannot be read
625     * @throws SAXException if the parsing fails
626     * @throws ParserConfigurationException if the parser creation fails
627     */
628    public ParseTopdl(InputStream s, String topName, boolean debug) 
629        throws IOException, SAXException, ParserConfigurationException {
630        h = new TopdlHandler(topName != null ? topName: "experiment", debug);
631
632        xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
633        xr.setContentHandler(h);
634        xr.parse(new InputSource(s));
635    }
636
637    /**
638     * Equivalent to ParseTopdl(s, topName, false)
639     * @param s the InputStream to parse
640     * @param topName a String with the outer element name
641     * @throws IOException if the stream cannot be read
642     * @throws SAXException if the parsing fails
643     * @throws ParserConfigurationException if the parser creation fails
644     */
645    public ParseTopdl(InputStream s, String topName)
646        throws IOException, SAXException, ParserConfigurationException {
647        this(s, topName, false);
648    }
649
650    /**
651     * Return the parsed topology
652     * @return the parsed topology
653     */
654    public TopologyType getTopology() { return h.getTopology(); }
655
656    /**
657     * Test code.  Shouldn't really be called.
658     */
659    static public void main(String args[]) {
660        ParseTopdl p = null;
661
662        System.out.println("Checking file: " + args[0]);
663        try {
664            p = new ParseTopdl(new FileInputStream(new File(args[0])),
665                    "experiment", false);
666            System.out.println("Parse OK");
667        }
668        catch (ParserConfigurationException e) {
669            System.err.println("Parse failed: " + e);
670        }
671        catch (SAXException e) {
672            System.err.println("Parse failed: " + e);
673        }
674        catch (IOException e) {
675            System.err.println("Parse failed: " + e);
676        }
677    }
678}
Note: See TracBrowser for help on using the repository browser.