View Javadoc

1   package net.sf.tomp.xml.type;
2   
3   import net.sf.tomp.xtcl.filter.XTFilterFactory;
4   import net.sf.tomp.xtcl.result.HasResult;
5   
6   import org.apache.commons.logging.Log;
7   import org.apache.commons.logging.LogFactory;
8   import org.xml.sax.Attributes;
9   import org.xml.sax.SAXException;
10  import org.xml.sax.XMLFilter;
11  import org.xml.sax.helpers.DefaultHandler;
12  
13  import javax.xml.transform.Result;
14  import javax.xml.transform.TransformerConfigurationException;
15  import javax.xml.transform.sax.SAXResult;
16  
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.SortedSet;
23  import java.util.TreeSet;
24  
25  /***
26   * DOCUMENT ME!
27   * 
28   * @author $author$
29   * @version $Revision$
30   */
31  public class TypeDatabaseImpl extends DefaultHandler /* XTFilterImpl */
32  implements TypeDatabase, TypeTransformationFactory, HasResult {
33      //protected Set allTypes = new HashSet();
34      private Log log = LogFactory.getLog(TypeDatabaseImpl.class);
35  
36      /*** DOCUMENT ME! */
37      protected XTFilterFactory xff;
38  
39      /***
40       * parent type database. If it is set, then all queries not answered here
41       * are forwarded to parent TD
42       */
43      protected TypeDatabase parentDatabase;
44  
45      /*** DOCUMENT ME! */
46      protected Type currentType;
47  
48      /*** DOCUMENT ME! */
49      protected Type currentSrcType;
50  
51      /*** DOCUMENT ME! */
52      protected Type currentTargetType;
53  
54      /*** DOCUMENT ME! */
55      protected String currentSource;
56  
57      /*** DOCUMENT ME! */
58      protected String currentTarget;
59  
60      /*** DOCUMENT ME! */
61      protected TypeTransformation currentTransformation;
62  
63      /*** DOCUMENT ME! */
64      protected MultiFilterTypeTransformation currentMultiTransformation;
65  
66      /*** DOCUMENT ME! */
67      protected Variant currentVariant;
68  
69      /*** DOCUMENT ME! */
70      protected Map identification2type = new HashMap();
71  
72      /*** DOCUMENT ME! */
73      protected Map root2type = new HashMap();
74  
75      /*** DOCUMENT ME! */
76      protected Map doctype2type = new HashMap();
77  
78      // array of all types in the TypeDB
79      //protected Type[] allTypes;
80      //protected Map srcTransformations = new HashMap();
81      //protected Map transformations = new HashMap();
82  
83      /*** DOCUMENT ME! */
84      protected Transformations transformations = new Transformations();
85  
86      /***
87       * DOCUMENT ME!
88       * 
89       * @param x DOCUMENT ME!
90       */
91      public void setXTFilterFactory(XTFilterFactory x) {
92          xff = x;
93      }
94  
95      /***
96       * DOCUMENT ME!
97       * 
98       * @return DOCUMENT ME!
99       */
100     public TypeDatabase getParent() {
101         return parentDatabase;
102     }
103 
104     /***
105      * DOCUMENT ME!
106      * 
107      * @param td DOCUMENT ME!
108      */
109     public void setParent(TypeDatabase td) {
110         parentDatabase = td;
111     }
112 
113     /***
114      * DOCUMENT ME!
115      * 
116      * @return DOCUMENT ME!
117      */
118     public Result getResult() {
119         return new SAXResult(this);
120     }
121 
122     /***
123      * DOCUMENT ME!
124      * 
125      * @return DOCUMENT ME!
126      */
127     public int getTypesCount() {
128         return identification2type.entrySet().size();
129     }
130 
131     /***
132      * DOCUMENT ME!
133      * 
134      * @return DOCUMENT ME!
135      */
136     public Transformations getTransformations() {
137         return transformations;
138     }
139 
140     /***
141      * implementation of transformation info storage
142      * 
143      * @param source DOCUMENT ME!
144      * @param target DOCUMENT ME!
145      * @param variant DOCUMENT ME!
146      * @param tt DOCUMENT ME!
147      */
148 
149     /*
150      * public void addTransformation(Type source, Type target,
151      * TypeTransformation tt) { addTransformation(new TransformationKey(source,
152      * target), tt); }
153      */
154     public void addTransformation(Type source, Type target, Variant variant,
155             TypeTransformation tt) {
156         /*
157          * Map transformations = (Map)srcTransformations.get(source);
158          * if(transformations == null) { transformations = new HashMap();
159          * srcTransformations.put(source, transformations); }
160          * transformations.put(target, tt);
161          */
162         TransformationsFromType tft = transformations
163                 .getTransformationsFrom(source);
164 
165         if (tft == null) {
166             tft = new TransformationsFromType(source);
167             transformations.putTransformationsFrom(tft);
168         }
169 
170         tft.putTransformationTo(target, variant, tt);
171     }
172 
173     /***
174      * DOCUMENT ME!
175      * 
176      * @param source DOCUMENT ME!
177      * @param target DOCUMENT ME!
178      * @param variant DOCUMENT ME!
179      * @return DOCUMENT ME!
180      */
181     public TypeTransformation getTransformation(Type source, Type target,
182             Variant variant) {
183         if (source == target) {
184             return null;
185         }
186 
187         /*
188          * Map transformations = (Map)srcTransformations.get(source);
189          * if(transformations != null) { Object o = transformations.get(target);
190          * if(o == null && parentDatabase != null) return
191          * parentDatabase.getTransformation(source, target, variant); else
192          * return (TypeTransformation)o; } else if(parentDatabase != null) {
193          * return parentDatabase.getTransformation(source, target, variant); }
194          * return null;
195          */
196         TransformationsFromType tft = transformations
197                 .getTransformationsFrom(source);
198 
199         if (tft == null) {
200             if (parentDatabase == null) {
201                 return null;
202             } else {
203                 return parentDatabase
204                         .getTransformation(source, target, variant);
205             }
206         }
207 
208         TypeTransformation tt = tft.getTransformationTo(target, variant);
209 
210         if (tt == null) {
211             log.debug("+++ SEARCHING transformationSequence to=" + target
212                     + " variant=" + variant);
213 
214             List transformationSequence = getTransformationSequence(source,
215                     target, variant);
216 
217             log.debug("+++ FOUND transformationSequence="
218                     + transformationSequence);
219 
220             if ((transformationSequence == null)
221                     || (transformationSequence.size() == 0)) {
222                 return null;
223             }
224 
225             TypeTransformation mt = new MultiFilterTypeTransformation(
226                     transformationSequence);
227 
228             // caching!
229             tft.putTransformationTo(target, variant, mt);
230 
231             return mt;
232         }
233 
234         return tft.getTransformationTo(target, variant);
235     }
236 
237     /*
238      * protected void addTransformation(TransformationKey k, TypeTransformation
239      * tt) { transformations.put(k, tt); } public TypeTransformation
240      * getTransformation(Type source, Type target) { return
241      * getTransformation(new TransformationKey(source, target)); } public
242      * TypeTransformation getTransformation(Type source, Type target, Variant
243      * variant) { return getTransformation(new TransformationKey(source, target,
244      * variant)); }
245      */
246     /*
247      * public TypeTransformation getTransformation(TransformationKey k) {
248      * TypeTransformation tt = (TypeTransformation)transformations.get(k); if
249      * (tt == null && parentDatabase != null && k != null) return
250      * parentDatabase.getTransformation(k.source, k.target, k.variant); return
251      * tt; }
252      */
253 
254     /***
255      * implementation of type info storage
256      * 
257      * @param ns DOCUMENT ME!
258      * @param localName DOCUMENT ME!
259      * @return DOCUMENT ME!
260      */
261     public Type getTypeForRootElement(String ns, String localName) {
262         Object t = root2type.get("{" + ns + "}" + localName);
263 
264         if (t == null) {
265             t = root2type.get("{" + ns + "}*");
266         }
267 
268         if (t == null) {
269             t = root2type.get("{*}" + localName);
270         }
271 
272         return (Type) t;
273     }
274 
275     /***
276      * DOCUMENT ME!
277      * 
278      * @param name DOCUMENT ME!
279      * @param dtPublic DOCUMENT ME!
280      * @param dtSystem DOCUMENT ME!
281      * @return DOCUMENT ME!
282      */
283     public Type getTypeForDoctype(String name, String dtPublic, String dtSystem) {
284         return (Type) doctype2type.get(dtPublic);
285     }
286 
287     /***
288      * DOCUMENT ME!
289      * 
290      * @param id DOCUMENT ME!
291      * @return DOCUMENT ME!
292      */
293     public Type getType(String id) {
294         return (Type) identification2type.get(id);
295     }
296 
297     /***
298      * DOCUMENT ME!
299      * 
300      * @param fn DOCUMENT ME!
301      * @return DOCUMENT ME!
302      * @throws ClassNotFoundException DOCUMENT ME!
303      * @throws InstantiationException DOCUMENT ME!
304      * @throws IllegalAccessException DOCUMENT ME!
305      */
306     public TypeTransformation newTransformationForFilterClassName(String fn)
307             throws ClassNotFoundException, InstantiationException,
308             IllegalAccessException {
309         return new FilterTypeTransformation(fn);
310     }
311 
312     /***
313      * DOCUMENT ME!
314      * 
315      * @param ssi DOCUMENT ME!
316      * @return DOCUMENT ME!
317      * @throws TransformerConfigurationException DOCUMENT ME!
318      */
319     public TypeTransformation newTransformationForStyleSystemId(String ssi)
320             throws TransformerConfigurationException {
321         //System.out.println("&&&&&&&&& returning transformation for
322         // stylehref="+ssi);
323         return new StyleTypeTransformation(xff, ssi);
324     }
325 
326     /***
327      * DOCUMENT ME!
328      * 
329      * @param ssi DOCUMENT ME!
330      * @return DOCUMENT ME!
331      * @throws TransformerConfigurationException DOCUMENT ME!
332      */
333     public TypeTransformation newTransformationForSTXStyleSystemId(String ssi)
334             throws TransformerConfigurationException {
335         //System.out.println("&&&&&&&&& returning transformation for
336         // stylehref="+ssi);
337         return new StyleTypeTransformation(xff, ssi);
338     }
339 
340     // end of TypeTransformationFactory implementation
341 
342     /***
343      * Filter a start document event.
344      * 
345      * @param uri DOCUMENT ME!
346      * @param localName DOCUMENT ME!
347      * @param qName DOCUMENT ME!
348      * @param atts DOCUMENT ME!
349      * @exception SAXException The client may throw an exception during
350      *                processing.
351      */
352 
353     /*
354      * public void startDocument () throws SAXException {
355      * //System.out.println(""+this+".startDocument"); super.startDocument(); }
356      */
357 
358     /***
359      * Filter an end document event.
360      * 
361      * @param uri DOCUMENT ME!
362      * @param localName DOCUMENT ME!
363      * @param qName DOCUMENT ME!
364      * @param atts DOCUMENT ME!
365      * @exception SAXException The client may throw an exception during
366      *                processing.
367      */
368 
369     /*
370      * public void endDocument () throws SAXException {
371      * //System.out.println(""+this+".endDocument"); Type source =
372      * getTypeForPublicDoctype("Type1"); Type target =
373      * getTypeForPublicDoctype("Type4");
374      * System.out.println("transformationSequence from "+source+" to "+target+"
375      * is " +getTransformationSequence(source, target, Variant.NO_VARIANT));
376      * super.endDocument(); }
377      */
378 
379     /***
380      * Filter a start element event.
381      * 
382      * @param uri The element's Namespace URI, or the empty string.
383      * @param localName The element's local name, or the empty string.
384      * @param qName The element's qualified (prefixed) name, or the empty
385      *            string.
386      * @param atts The element's attributes.
387      * @exception SAXException The client may throw an exception during
388      *                processing.
389      */
390     public void startElement(String uri, String localName, String qName,
391             Attributes atts) throws SAXException {
392         XMLFilter filter = null;
393 
394         if ("type".equals(qName)) {
395             for (int i = 0; i < atts.getLength(); i++) {
396                 String aName = atts.getQName(i);
397 
398                 if (aName.startsWith("by-")) {
399                     String typeType = aName.substring("by-".length());
400                     String identification = atts.getValue(i);
401 
402                     currentType = new TypeImpl(typeType, identification);
403                     identification2type.put(typeType + ":" + identification,
404                             currentType);
405 
406                     break;
407                 }
408             }
409         } else if ("subtype-of".equals(qName) || "parent-is".equals(qName)) {
410             String typeIdentification = null;
411 
412             for (int i = 0; i < atts.getLength(); i++) {
413                 String aName = atts.getQName(i);
414 
415                 if (aName.startsWith("by-")) {
416                     String typeType = aName.substring("by-".length());
417                     String identification = atts.getValue(i);
418 
419                     typeIdentification = typeType + ":" + identification;
420 
421                     break;
422                 }
423             }
424 
425             if (typeIdentification != null) {
426                 Type parentType = getType(typeIdentification);
427 
428                 if ((currentType != null) && (parentType != null)
429                         && (currentType != parentType)) {
430                     currentVariant = new VariantImpl(atts.getValue("variant"));
431 
432                     currentType.addParent(parentType);
433                     log.debug(">>> add IDENTITY from  currentType="
434                             + currentType + " to " + parentType);
435 
436                     addTransformation(currentType, parentType, currentVariant,
437                             TypeTransformation.IDENTITY);
438                 } else {
439                     System.err.println("Parent type '" + typeIdentification
440                             + "' does not exists yet or is same as current: "
441                             + currentType);
442                 }
443             }
444         } else if ("part-of".equals(qName)) {
445             String typeIdentification = null;
446 
447             for (int i = 0; i < atts.getLength(); i++) {
448                 String aName = atts.getQName(i);
449 
450                 if (aName.startsWith("by-")) {
451                     String typeType = aName.substring("by-".length());
452                     String identification = atts.getValue(i);
453 
454                     typeIdentification = typeType + ":" + identification;
455 
456                     break;
457                 }
458             }
459 
460             String contextIdentification = atts.getValue("context");
461 
462             if ((typeIdentification != null) && (contextIdentification != null)) {
463                 TypeContextImpl context = new TypeContextImpl(
464                         contextIdentification);
465                 Type parentType = getType(typeIdentification);
466 
467                 if ((currentType != null) && (parentType != null)
468                         && (context != null) && (currentType != parentType)) {
469                     log.debug(">>> parentType= " + parentType
470                             + " storing context=" + context + " currentType="
471                             + currentType);
472                     parentType.addTypeForContext(context, currentType);
473                 } else {
474                     System.err.println("Whole-doc type '" + typeIdentification
475                             + "' does not exists yet or is same as current: "
476                             + currentType + "for context " + context);
477                 }
478             }
479         } else if ("root".equals(qName)) {
480             String name = atts.getValue("name");
481 
482             if (name == null) {
483                 name = "*";
484             }
485 
486             String ns = atts.getValue("ns");
487 
488             if (ns == null) {
489                 ns = "*";
490             }
491 
492             if (currentType != null) {
493                 root2type.put("{" + ns + "}" + name, currentType);
494             }
495         } else if ("doctype".equals(qName)) {
496             String name = atts.getValue("name");
497 
498             if (name == null) {
499                 name = "";
500             }
501 
502             String pub = atts.getValue("public");
503 
504             if (pub == null) {
505                 pub = "";
506             }
507 
508             String syst = atts.getValue("system");
509 
510             if (syst == null) {
511                 syst = "";
512             }
513 
514             if (currentType != null) {
515                 // FIXME - works for PUBLIC DOCTYPE only!
516                 doctype2type.put(pub, currentType);
517             }
518         } else if ("transformation".equals(qName)) {
519             for (int i = 0; i < atts.getLength(); i++) {
520                 String aName = atts.getQName(i);
521 
522                 if (aName.startsWith("source-")) {
523                     String typeType = aName.substring("source-".length());
524                     String identification = atts.getValue(i);
525                     String typeIdentification = typeType + ":" + identification;
526 
527                     currentSrcType = getType(typeIdentification);
528                 } else if (aName.startsWith("target-")) {
529                     String typeType = aName.substring("target-".length());
530                     String identification = atts.getValue(i);
531                     String typeIdentification = typeType + ":" + identification;
532 
533                     currentTargetType = getType(typeIdentification);
534                 }
535             }
536 
537             currentVariant = new VariantImpl(atts.getValue("variant"));
538 
539             currentTransformation = null;
540             currentMultiTransformation = null;
541         } else if ("filter".equals(qName)) {
542             String className = atts.getValue("class");
543 
544             //System.out.println("making transformation for filter class
545             // "+className);
546             try {
547                 if (currentTransformation != null) {
548                     // already was a transformation (i.e. it is multiple)
549                     if (currentMultiTransformation == null) {
550                         // this is the second
551                         currentMultiTransformation = new MultiFilterTypeTransformation();
552                     }
553 
554                     // adding last to multiple
555                     currentMultiTransformation
556                             .addTransformation(currentTransformation);
557                 }
558 
559                 currentTransformation = newTransformationForFilterClassName(className);
560             } catch (Exception cnfe) {
561                 cnfe.printStackTrace();
562             }
563         } else if ("style".equals(qName)) {
564             // FIXME - to be completed
565             String styleHref = atts.getValue("href");
566             String styleType = atts.getValue("type");
567 
568             try {
569                 if (currentTransformation != null) {
570                     // already was a transformation (i.e. it is multiple)
571                     if (currentMultiTransformation == null) {
572                         // this is the second
573                         currentMultiTransformation = new MultiFilterTypeTransformation();
574                     }
575 
576                     // adding last to multiple
577                     currentMultiTransformation
578                             .addTransformation(currentTransformation);
579                 }
580 
581                 if ((styleType == null) || styleType.startsWith("xsl")) {
582                     currentTransformation = newTransformationForStyleSystemId(styleHref);
583                 } else if (styleType.startsWith("stx")
584                         || styleType.startsWith("joost")) {
585                     currentTransformation = newTransformationForSTXStyleSystemId(styleHref);
586                 }
587 
588                 //throw new IllegalArgumentException("STX styles are not
589                 // supported yet.");
590             } catch (TransformerConfigurationException tce) {
591                 // FIXME - produces identity filter
592                 tce.printStackTrace();
593 
594                 //throw new
595                 // IllegalArgumentException("TransformerConfigurationException:
596                 // currentTransformation = null");
597             }
598         } else if ("param".equals(qName)) {
599             if (currentTransformation != null) {
600                 String pName = atts.getValue("name");
601 
602                 // FIXME: value can be specified as attribute only
603                 String pValue = atts.getValue("value");
604 
605                 currentTransformation.setParameter(pName, pValue);
606             }
607         }
608 
609         super.startElement(uri, localName, qName, atts);
610     }
611 
612     /***
613      * Filter an end element event.
614      * 
615      * @param uri The element's Namespace URI, or the empty string.
616      * @param localName The element's local name, or the empty string.
617      * @param qName The element's qualified (prefixed) name, or the empty
618      *            string.
619      * @exception SAXException The client may throw an exception during
620      *                processing.
621      */
622     public void endElement(String uri, String localName, String qName)
623             throws SAXException {
624         if ("type".equals(qName)) {
625             currentType = null;
626         } else if ("transformation".equals(qName)) {
627             if (currentMultiTransformation == null) {
628                 addTransformation(currentSrcType, currentTargetType,
629                         currentVariant, currentTransformation);
630             } else {
631                 currentMultiTransformation
632                         .addTransformation(currentTransformation);
633                 addTransformation(currentSrcType, currentTargetType,
634                         currentVariant, currentMultiTransformation);
635             }
636         } else if ("filter".equals(qName)) {
637         } else if ("style".equals(qName)) {
638         } else if ("param".equals(qName)) {
639         }
640 
641         super.endElement(uri, localName, qName);
642     }
643 
644     /***
645      * Filter a character data event.
646      * 
647      * @param ch An array of characters.
648      * @param start The starting position in the array.
649      * @param length The number of characters to use from the array.
650      * @exception SAXException The client may throw an exception during
651      *                processing.
652      */
653     public void characters(char[] ch, int start, int length)
654             throws SAXException {
655         super.characters(ch, start, length);
656     }
657 
658     /***
659      * DOCUMENT ME!
660      * 
661      * @param source DOCUMENT ME!
662      * @param target DOCUMENT ME!
663      * @param variant DOCUMENT ME!
664      * @return DOCUMENT ME!
665      */
666     public List getTransformationSequence(final Type source, final Type target,
667             Variant variant) {
668         // FIXME: no variant
669         List sequence = new ArrayList();
670 
671         //DynamicMultiFilterImpl dmf = new DynamicMultiFilterImpl();
672         //Set pivots = new HashSet();
673         SortedSet typeNodes = new TreeSet();
674         Map types2TypeNodes = new HashMap();
675 
676         // init pivot
677         TypeNode pivot = new TypeNode(source);
678 
679         pivot.costsFromSource = 0;
680         pivot.wasPivot = true;
681         types2TypeNodes.put(source, pivot);
682 
683         do {
684             // add new pivot
685             //System.out.println("&&& new pivot is "+pivot);
686             //pivots.add(pivot);
687             // get all transf. from pivot type
688             TransformationsFromType transFromPivot = transformations
689                     .getTransformationsFrom(pivot.typ);
690 
691             //System.out.println("SEEKING trans from "+source+" to "+target);
692             log.info("\n\nEXAMINING transf from pivot=" + pivot.typ
693                     + " costs to pivot=" + pivot.costsFromSource
694                     + " ... transFromPivot=" + transFromPivot);
695 
696             // FIXME: if transFromPivot == null???
697             if (transFromPivot == null) {
698                 ;
699             }
700 
701             //System.out.println(" NO TRANSF ");
702             else {
703                 for (Iterator i = transFromPivot.typesIterator(); i.hasNext();) {
704                     // target type
705                     Type tg = (Type) i.next();
706 
707                     // transformation to target type
708                     TypeNode tnOrig = (TypeNode) types2TypeNodes.get(tg);
709 
710                     TypeTransformation ts = transFromPivot.getTransformationTo(
711                             tg, variant);
712 
713                     // if no transformation, i.e. not THE variant... skip to
714                     // next
715                     if (ts == null) {
716                         continue;
717                     }
718 
719                     TypeNode tn = (tnOrig == null) ? new TypeNode(tg) : tnOrig;
720 
721                     log.info("   TRANSF TO " + tg + " is " + ts);
722 
723                     // doing only those that haven't been pivots
724                     if (!tn.wasPivot) {
725                         if (tnOrig != null) {
726                             // already was in typeNodes, remove
727                             typeNodes.remove(tnOrig);
728                         }
729 
730                         if ((pivot.costsFromSource + ts.getCosts()) < tn.costsFromSource) {
731                             // should update costs - are now lower or were not
732                             // set yet
733                             tn.costsFromSource = pivot.costsFromSource
734                                     + ts.getCosts();
735                             tn.previous = pivot;
736                             tn.transFromPrevious = ts;
737 
738                             //System.out.println(" ... updating
739                             // costs="+tn.costsFromSource);//+"
740                             // transFromPrevious="+tn.transFromPrevious+"
741                             // previous="+tn.previous);
742                         }
743 
744                         //System.out.print(" tn="+tn+" ts="+ts);
745                         typeNodes.add(tn);
746                         types2TypeNodes.put(tg, tn);
747                     }
748 
749                     //System.out.println();
750                 }
751             }
752 
753             //System.out.println("... examined, typeNodes# "+typeNodes.size());
754             if (typeNodes.isEmpty()) {
755                 return sequence;
756             }
757 
758             // pivot has the lowest costs, thus is first in the SortedSet typs
759             pivot = (TypeNode) typeNodes.first();
760             pivot.wasPivot = true;
761 
762             typeNodes.remove(pivot);
763 
764             //types2TypeNodes.remove(pivot.typ);
765             //System.out.println("&&&&& at while end pivot.typ="+pivot.typ+"
766             // target="+target);
767         } while (!pivot.typ.equals(target));
768 
769         if (pivot.typ.equals(target)) {
770             // FIXME
771             //System.out.println("\n&&& found transf to type "+target+"
772             // costs="+pivot.costsFromSource+"...");
773             TypeNode p = pivot;
774 
775             while ((p != null) && (p.previous != null)) {
776                 sequence.add(0, p.transFromPrevious);
777 
778                 //System.out.print(p.typ);
779                 p = p.previous;
780 
781                 /*
782                  * if(p == null) System.out.println("\n"); else
783                  * System.out.print(" <- ");
784                  */
785             }
786         }
787 
788         return sequence;
789     }
790 }
791 
792 class TypeNode implements Comparable {
793     /*** DOCUMENT ME! */
794     protected TypeNode previous;
795 
796     /*** DOCUMENT ME! */
797     protected Type typ;
798 
799     /*** DOCUMENT ME! */
800     protected TypeTransformation transFromPrevious;
801 
802     /*** DOCUMENT ME! */
803     protected double costsFromSource;
804 
805     /*** DOCUMENT ME! */
806     protected boolean wasPivot;
807 
808     /***
809      * Creates a new TypeNode object.
810      * 
811      * @param t DOCUMENT ME!
812      */
813     public TypeNode(Type t) {
814         typ = t;
815         transFromPrevious = null;
816         costsFromSource = java.lang.Double.POSITIVE_INFINITY;
817         previous = null;
818         wasPivot = false;
819     }
820 
821     /***
822      * Creates a new TypeNode object.
823      * 
824      * @param t DOCUMENT ME!
825      * @param ts DOCUMENT ME!
826      */
827     public TypeNode(Type t, TypeTransformation ts) {
828         this(t);
829         transFromPrevious = ts;
830     }
831 
832     /***
833      * DOCUMENT ME!
834      * 
835      * @param o DOCUMENT ME!
836      * @return DOCUMENT ME!
837      */
838     public boolean equals(Object o) {
839         TypeNode tn = (TypeNode) o;
840 
841         return typ.equals(tn.typ);
842     }
843 
844     /***
845      * DOCUMENT ME!
846      * 
847      * @return DOCUMENT ME!
848      */
849     public int hashCode() {
850         return typ.hashCode();
851     }
852 
853     /***
854      * DOCUMENT ME!
855      * 
856      * @param o DOCUMENT ME!
857      * @return DOCUMENT ME!
858      */
859     public int compareTo(Object o) {
860         TypeNode te = (TypeNode) o;
861 
862         return ((int) (costsFromSource - te.costsFromSource) * 10)
863                 + (equals(o) ? 0 : 1);
864     }
865 
866     /***
867      * DOCUMENT ME!
868      * 
869      * @return DOCUMENT ME!
870      */
871     public String toString() {
872         return "TypeNode[typ=" + typ + " previousTyp="
873                 + ((previous == null) ? null : previous.typ)
874                 + " transFromPrevious=" + transFromPrevious
875                 + " costsFromSource=" + costsFromSource;
876     }
877 }
878 
879 /*
880  * The contents of this file are subject to the Mozilla Public License Version
881  * 1.1 (the "License"); you may not use this file except in compliance with the
882  * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
883  * Software distributed under the License is distributed on an "AS IS" basis,
884  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
885  * the specific language governing rights and limitations under the License. The
886  * Original Code is: all this file. The Initial Developer of the Original Code
887  * is: Tomas Pitner, Masaryk University in Brno, Czech Republic. Contributor(s):
888  */