KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > kilim > repository > TemplateDescriptionParser


1 /**
2  * Copyright (C) 2002 Kelua SA
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.kilim.repository;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.util.Stack JavaDoc;
23
24 import javax.xml.parsers.ParserConfigurationException JavaDoc;
25 import javax.xml.parsers.SAXParser JavaDoc;
26 import javax.xml.parsers.SAXParserFactory JavaDoc;
27
28 import org.objectweb.kilim.KilimException;
29 import org.objectweb.kilim.description.Arity;
30 import org.objectweb.kilim.description.ArraySource;
31 import org.objectweb.kilim.description.BasicElement;
32 import org.objectweb.kilim.description.BasicNamedElement;
33 import org.objectweb.kilim.description.BindTrigger;
34 import org.objectweb.kilim.description.Binding;
35 import org.objectweb.kilim.description.ClassSource;
36 import org.objectweb.kilim.description.EventSource;
37 import org.objectweb.kilim.description.Instance;
38 import org.objectweb.kilim.description.KILIM;
39 import org.objectweb.kilim.description.NullElement;
40 import org.objectweb.kilim.description.Parameter;
41 import org.objectweb.kilim.description.Plug;
42 import org.objectweb.kilim.description.Port;
43 import org.objectweb.kilim.description.Property;
44 import org.objectweb.kilim.description.Provider;
45 import org.objectweb.kilim.description.Reference;
46 import org.objectweb.kilim.description.Slot;
47 import org.objectweb.kilim.description.TemplateDescription;
48 import org.objectweb.kilim.description.TemplateElementImpl;
49 import org.objectweb.kilim.description.TpAccessor;
50 import org.objectweb.kilim.description.TpConstructor;
51 import org.objectweb.kilim.description.TpGetter;
52 import org.objectweb.kilim.description.TpMethod;
53 import org.objectweb.kilim.description.TpSetter;
54 import org.objectweb.kilim.description.Transformer;
55 import org.objectweb.kilim.description.Trigger;
56 import org.objectweb.kilim.description.UnBindTrigger;
57
58 import org.xml.sax.Attributes JavaDoc;
59 import org.xml.sax.InputSource JavaDoc;
60 import org.xml.sax.Locator JavaDoc;
61 import org.xml.sax.SAXException JavaDoc;
62 import org.xml.sax.SAXNotRecognizedException JavaDoc;
63 import org.xml.sax.SAXParseException JavaDoc;
64 import org.xml.sax.helpers.DefaultHandler JavaDoc;
65
66 /**
67  * @author dutoo, horn
68  * Kilim xml format parser. Uses a JAXP SAXParser. Validates the kilim xml DTD
69  * (which is to be found in a ResourceLoader) and logs its error and warnings
70  * to a ParserErrorHandler.
71  */

72 public class TemplateDescriptionParser {
73     private static final String JavaDoc CLASSPATH_URI_PREFIX = "classpath://";
74     private static final String JavaDoc SUPER_ID = "super";
75
76     private ResourceLoader resourceLoader;
77     private SAXParser JavaDoc saxParser;
78     private ParserErrorHandler errorHandler;
79     //private ResourceBundle parsingMessages = ResourceBundle.getBundle("ParsingMessages");
80
private String JavaDoc currentTemplateName;
81         
82     /**
83      * Creates a new TemplateDescriptionParser using the JAXP SAX factory's new
84      * default parser, a new BasicErrorHandler and loads DTDs from a new
85      * ClassLoaderResourceLoader.<P>
86      * May log SAXException on parser creation exception
87      * and. ParserConfigurationException if DTD validation is impossible
88      * @param isValidating if true, requires the parsed xml template to be validated
89      * against the kilim_template.dtd, which has therefore to be in the classpath.
90      * NB: the template parser behaviour on parsing error is undetermined if there is
91      * no template DTD validation.
92      */

93     public TemplateDescriptionParser(boolean isValidating) {
94         errorHandler = new BasicParserErrorHandler(System.err);
95         resourceLoader = new ClassLoaderResourceLoader(getClass().getClassLoader());
96         try {
97             SAXParserFactory JavaDoc spf = SAXParserFactory.newInstance();
98             // if isValidating is true, let's require the parsed template to be validated against the xml DTD:
99
spf.setValidating(isValidating);
100             saxParser = spf.newSAXParser();
101         } catch (SAXException JavaDoc saxex) {
102             errorHandler.handleSAXException(saxex);
103         } catch (ParserConfigurationException JavaDoc pcex) {
104             errorHandler.handleParserConfigurationException(pcex);
105         }
106     }
107     
108     /**
109      * Creates a new TemplateDescriptionParser using the given custom template SAX parser.
110      * @param aSaxParser the custom kilim xml format parser
111      * @param anErrorHandler to be used for model & parsing errors handling delegation
112      * @param aResourceLoader where the DTDs are to be found
113      * NB: the template parser behaviour on parsing error is undetermined if the given SAX
114      * parser doesn't validate template DTD.
115      */

116     public TemplateDescriptionParser(SAXParser JavaDoc aSaxParser, ParserErrorHandler anErrorHandler, ResourceLoader aResourceLoader) {
117         saxParser = aSaxParser;
118         errorHandler = anErrorHandler;
119         resourceLoader = aResourceLoader;
120     }
121     
122     /**
123      * Method importTemplateDescription.
124      * @param is kilim xml format data
125      * @param aParsingResult holds the template dependancies & naming to be solved
126      * @param aName is the template resource name.
127      * @return the parsed Template (its template naming is not resolved yet)
128      */

129     public TemplateDescription importTemplateDescription(InputStream JavaDoc is, ResourceMapping aParsingResult, String JavaDoc aName) {
130         KilimSaxHandler handler = new KilimSaxHandler(aParsingResult);
131         currentTemplateName = aName;
132         
133         try {
134             errorHandler.setTemplateName(aName);
135             saxParser.parse(is, handler);
136         } catch (SAXException JavaDoc saxex) {
137             errorHandler.handleSAXException(saxex);
138         } catch (IOException JavaDoc ioex) {
139             errorHandler.handleIOException(ioex);
140         }
141         return handler.getParsedTemplate();
142     }
143     
144     /**
145      * This private class is just a data container used to store information on the stack. The "parsingPhase" field
146      * indicates the nature of the parsed element, objectKind the nature of the stored object and object the reference
147      * to the information itself.
148      */

149     private class ContextData {
150         int parsingPhase;
151         int objectKind;
152         Object JavaDoc object;
153         
154         /**
155          * Method ContextData.
156          * @param aPhase : the parsing phase (which identifies unambiguously to the parsed element)
157          * @param aKind : the kind of the stored object.
158          * @param aObject : the reference to the object.
159          */

160         public ContextData(int aPhase, int aKind, Object JavaDoc aObject) {
161             parsingPhase = aPhase;
162             objectKind = aKind;
163             object = aObject;
164         }
165     }
166     
167     private class KilimSaxHandler extends DefaultHandler JavaDoc {
168         private static final int PARSING_TEMPLATE = 1;
169         private static final int PARSING_INSTANCE = 2;
170         private static final int PARSING_PORT = 3;
171         private static final int PARSING_BINDING = 4;
172         private static final int PARSING_PROPERTY = 5;
173         private static final int PARSING_ARRAY = 6;
174         private static final int PARSING_TRIGGER = 7;
175         private static final int PARSING_PROVIDER = 8;
176         private static final int PARSING_TRANSFORMER = 9;
177         private static final int PARSING_METHOD = 10;
178         private static final int PARSING_PARAM = 11;
179         private static final int PARSING_ACCESSOR = 12;
180         private static final int PARSING_NEW = 13;
181         private static final int PARSING_SUPPORT = 14;
182         private static final int PARSING_CLASS = 15;
183         private static final int PARSING_VALUE = 16;
184         private static final int PARSING_SLOT = 16;
185         private static final int PARSING_PLUG = 16;
186         
187         private Locator JavaDoc locator = null;
188         private Stack JavaDoc contexts = new Stack JavaDoc();
189         private Stack JavaDoc templates = new Stack JavaDoc();
190         private Stack JavaDoc instances = new Stack JavaDoc();
191         
192         private Property currentProperty;
193         private StringBuffer JavaDoc currentCDATA;
194         private String JavaDoc parentElement;
195         
196         private TemplateDescription parsedTemplate;
197         private ResourceMapping parsingResult;
198     
199         private boolean isFirstTemplate = true;
200         private boolean parsingTrigger;
201         private boolean parsingTransformer;
202         private int arrayCount;
203                 
204         /**
205          * Method KilimSaxHandler.
206          * @param aParsingResult :the ResourceMapping object used to store and retrieve all parsing result
207          * to be used during next iterations.
208          */

209         public KilimSaxHandler(ResourceMapping aParsingResult) {
210             parsingResult = aParsingResult;
211         }
212         
213         /**
214          * Method getParsedTemplate.
215          * @return Template : the template described in the parsed resource.
216          */

217         public TemplateDescription getParsedTemplate() {
218             return parsedTemplate;
219         }
220         
221         /**
222          * Resources whose systemId start with "classpath://" are looked for in the resourceLoader
223          * @see org.xml.sax.EntityResolver#resolveEntity(String, String)
224          */

225         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXNotRecognizedException JavaDoc {
226             if (systemId.startsWith(CLASSPATH_URI_PREFIX)) {
227                 String JavaDoc entityName = systemId.substring(CLASSPATH_URI_PREFIX.length());
228                 try {
229                     return new InputSource JavaDoc(resourceLoader.getResource(entityName));
230                 } catch (ResourceNotFoundException rnfex) {
231                     // can't find entity resource
232
throw new SAXNotRecognizedException JavaDoc(rnfex.getLocalizedMessage());
233                 }
234             }
235             // requests that the parser open a regular URI connection to the system Id
236
return null;
237         }
238         
239         /**
240          * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
241          */

242         public void setDocumentLocator(Locator JavaDoc aLocator) {
243             locator = aLocator;
244         }
245         
246         /**
247          * @see org.xml.sax.ContentHandler#characters(char[], int, int)
248          */

249         public void characters(char[] characters, int start, int length) {
250             // read characters are only stored when useful (when parsing property and types)
251
if (currentCDATA != null) {
252                     currentCDATA.append(characters, start, length);
253             }
254         }
255         
256         public void fatalError(SAXParseException JavaDoc saxex) {
257             errorHandler.handleFatalSAXParseException(saxex);
258         }
259         
260         public void error(SAXParseException JavaDoc saxex) {
261             errorHandler.handleErrorSAXParseException(saxex);
262         }
263         
264         public void warning(SAXParseException JavaDoc saxex) {
265             errorHandler.handleWarningSAXParseException(saxex);
266         }
267         
268         /**
269          * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
270          */

271         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) throws SAXException JavaDoc {
272             super.startElement(uri, localName, qName, attributes);
273             currentCDATA = new StringBuffer JavaDoc();
274             char[] qNameBuffer = qName.toCharArray();
275             
276             //The startElement is the entry point for all methods dealing with a starting tag. This methods analyzes the tag
277
//and then delegates to a dedicated method. qNameContent is analyzed in order to avoid an inefficient sequence of
278
//test.
279
switch (qNameBuffer[0]) {
280                 case 'a' :
281                 case 'A' :
282                     startArray(qName, attributes);
283                     break;
284                 case 'b' :
285                 case 'B' :
286                     startBind(qName, attributes);
287                     break;
288                 case 'c' :
289                 case 'C' :
290                     switch (qNameBuffer[1]) {
291                         case 'a' :
292                         case 'A' :
293                             startCall(qName, attributes);
294                             break;
295                         case 'l' :
296                         case 'L' :
297                             startClass(qName, attributes);
298                             break;
299                     }
300                     break;
301                 case 'e' :
302                 case 'E' :
303                     startEventSource(qName, attributes);
304                     break;
305                 case 'g' :
306                 case 'G' :
307                     startGet(qName, attributes);
308                     break;
309                 case 'i' :
310                 case 'I' :
311                     startInstance(qName, attributes);
312                     break;
313                 case 'n' :
314                 case 'N' :
315                     switch(qNameBuffer[1]) {
316                         case 'a' :
317                         case 'A' :
318                             startNameMapping(qName, attributes);
319                         case 'e' :
320                         case 'E' :
321                             startNew(qName, attributes);
322                             break;
323                         case 'u' :
324                         case 'U' :
325                             startNullProvider(qName, attributes);
326                             break;
327                     }
328                     break;
329                 case 'p' :
330                 case 'P' :
331                     switch (qNameBuffer[3]) {
332                         case 'a' :
333                         case 'A' :
334                             startParam(qName, attributes);
335                             break;
336                         case 't' :
337                         case 'T' :
338                             startPort(qName, attributes);
339                             break;
340                         case 'p' :
341                         case 'P' :
342                             startProperty(qName, attributes);
343                             break;
344                         case 'r' :
345                         case 'R' :
346                             break;
347                         case 'v' :
348                         case 'V' :
349                             if (qNameBuffer.length == 8) {
350                                 startProvider(qName, attributes);
351                             } else { /*deprecated*/ }
352                             break;
353                         case 'g' :
354                         case 'G' :
355                             startPlug(qName, attributes);
356                             break;
357                         default :
358                     }
359                     break;
360                 case 'r' :
361                 case 'R' :
362                     startReference(qName, attributes);
363                     break;
364                 case 's' :
365                 case 'S' :
366                     switch (qNameBuffer[1]) {
367                         case 'e' :
368                         case 'E' :
369                             startSet(qName, attributes);
370                             break;
371                         case 'l' :
372                         case 'L' :
373                             startSlot(qName, attributes);
374                             break;
375                     }
376                     break;
377                 case 't' :
378                 case 'T' :
379                     switch (qNameBuffer[2]) {
380                         case 'm' :
381                         case 'M' :
382                             startTemplate(qName, attributes);
383                             break;
384                         case 'p' :
385                         case 'P' :
386                             startType(qName, attributes);
387                             break;
388                         case 'a' :
389                         case 'A' :
390                             if (qNameBuffer.length == 11) {
391                                 startTransformer(qName, attributes);
392                             } else { /*deprecated*/ }
393                             break;
394                         case 'i' :
395                         case 'I' :
396                             startTrigger(qName, attributes);
397                             break;
398                     }
399                     break;
400                 case 'v' :
401                 case 'V' :
402                     startValue(qName, attributes);
403                     break;
404             }
405         }
406         
407         public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
408             super.endElement(uri, localName, qName);
409             char[] qNameBuffer = qName.toCharArray();
410             
411             //The endElement is the entry point for all methods dealing with a ending tag. This methods analyzes the tag and
412
//then delegates to a dedicated method. qNameContent is analyzed in order to avoid an inefficient sequence of
413
//test.
414

415             switch (qNameBuffer[0]) {
416                 case 'a' :
417                 case 'A' :
418                     endArray(qName);
419                     break;
420                 case 'b' :
421                 case 'B' :
422                     endBind(qName);
423                     break;
424                 case 'c' :
425                 case 'C' :
426                     switch (qNameBuffer[1]) {
427                         case 'a' :
428                         case 'A' :
429                             endCall(qName);
430                             break;
431                         case 'l' :
432                         case 'L' :
433                             endClass(qName);
434                             break;
435                     }
436                     break;
437                 case 'e' :
438                 case 'E' :
439                     endEventSource(qName);
440                     break;
441                 case 'g' :
442                 case 'G' :
443                     endGet(qName);
444                     break;
445                 case 'i' :
446                 case 'I' :
447                     endInstance(qName);
448                     break;
449                 case 'n' :
450                 case 'N' :
451                     switch(qNameBuffer[1]) {
452                         case 'a' :
453                         case 'A' :
454                             endNameMapping(qName);
455                         case 'e' :
456                         case 'E' :
457                             endNew(qName);
458                             break;
459                         case 'u' :
460                         case 'U' :
461                             endNullProvider(qName);
462                             break;
463                     }
464                     break;
465                 case 'p' :
466                 case 'P' :
467                     switch (qNameBuffer[3]) {
468                         case 'a' :
469                         case 'A' :
470                             endParam(qName);
471                             break;
472                         case 'g' :
473                         case 'G' :
474                             endPlug(qName);
475                             break;
476                         case 't' :
477                         case 'T' :
478                             endPort(qName);
479                             break;
480                         case 'p' :
481                         case 'P' :
482                             endProperty(qName);
483                             break;
484                         case 'v' :
485                         case 'V' :
486                             endProvider(qName);
487                             break;
488                     }
489                     break;
490                 case 'r' :
491                 case 'R' :
492                     endReference(qName);
493                     break;
494                 case 's' :
495                 case 'S' :
496                     switch (qNameBuffer[1]) {
497                         case 'e' :
498                         case 'E' :
499                             endSet(qName);
500                             break;
501                         case 'l' :
502                         case 'L' :
503                             endSlot(qName);
504                             break;
505                     }
506                     break;
507                 case 't' :
508                 case 'T' :
509                     switch (qNameBuffer[2]) {
510                         case 'm' :
511                         case 'M' :
512                             endTemplate(qName);
513                             break;
514                         case 'p' :
515                         case 'P' :
516                             endType(qName);
517                             break;
518                         case 'a' :
519                         case 'A' :
520                             endTransformer(qName);
521                             break;
522                         case 'i' :
523                         case 'I' :
524                             endTrigger(qName);
525                             break;
526                     }
527                     break;
528                 case 'v' :
529                 case 'V' :
530                     endValue(qName);
531                     break;
532             }
533         }
534         
535         /**
536          * Method used to handle the starting <template> tag. It indicates the top template described in the
537          * current resource. This method is therefore called once at the beginning of the parsing process.
538          */

539                 
540         private void startTemplate(String JavaDoc qN, Attributes JavaDoc attributes) {
541             TemplateDescription template = null;
542             TemplateDescription superTemplate = null;
543             
544             String JavaDoc name = attributes.getValue("name");
545             if (!name.equals(currentTemplateName)) {
546                 System.err.println("WARNING : template name " + name + " differs from resource template name " + currentTemplateName);
547             }
548             
549             String JavaDoc superTemplateName = attributes.getValue("extends");
550             
551             try {
552                 //The parser creates a TemplateDescription object when it encounters a reference to a new unknown template.
553
//This TemplateDescription object is stored in parsingResult. As a consequence parsingResult is looked up
554
//in order to check whether the TemplateDescription object corresponding to the current template has been
555
//registered in parsingResult.
556
template = parsingResult.getKnownTemplate(currentTemplateName);
557                 
558                 //The current template has not been previously registered in parsingResult. The TemplateDescription object
559
//is thus created and registered. The current template name is removed from the unparsedTemplate set.
560
if (template == null) {
561                     template = new TemplateDescription(currentTemplateName);
562                     parsingResult.addKnownTemplate(currentTemplateName, template);
563                     parsingResult.removeUnparsedTemplate(currentTemplateName);
564                 }
565                                 
566                 //The current template is declared as an extension of another template.
567
if (superTemplateName != null) {
568                     //parsingResult is looked up in order to check whether the super template is already known.
569
superTemplate = parsingResult.getKnownTemplate(superTemplateName);
570                     if (superTemplate == null) {
571                         //the super template is unknown. A new TemplateDescription object is thus created and
572
//registered in resultMapping as a known template.
573
//The name of the super template is added to the set of unparsed templates.
574
superTemplate = new TemplateDescription(superTemplateName);
575                         parsingResult.addUnparsedTemplate(superTemplateName);
576                         parsingResult.addKnownTemplate(superTemplateName, superTemplate);
577                         template.setSuperTemplate(superTemplate);
578                     } else {
579                         //The superTemplate is known and is set as the super template of the current template.
580
template.setSuperTemplate(superTemplate);
581                     }
582                 }
583             } catch (KilimException ex) {
584                 logParseException(ex.toString());
585             }
586
587             //The current template is pushed in the templates stack and in the contexts stack.
588
templates.push(template);
589             contexts.push(new ContextData(PARSING_TEMPLATE, 0, template));
590             if (isFirstTemplate) {
591                 //The template to be parsed is the top template and is thus the one to be returned.
592
parsedTemplate = template;
593                 isFirstTemplate = false;
594                 try {
595                     //An instance is created corresponding to the top template.
596
Instance topInstance = new Instance("", KILIM.PUBLIC, template, null);
597                     instances.push(topInstance);
598                 } catch (KilimException exc) {
599                     System.err.println("BUG : error when creating top instance of " + template.getName());
600                 }
601             }
602         }
603         
604         /**
605          * Method used to handle the ending </template> tag. it corresponds to the starting tag encountered at the
606          * beginning of the resource.This method is therefore called once at the end of the parsing process.This
607          * method checks the stack state and invokes the method that performrs the final checks on the parsed
608          * template.
609          */

610         private void endTemplate(String JavaDoc qName) {
611             ContextData contextData = (ContextData) contexts.pop();
612             int phase = contextData.parsingPhase;
613             if (phase != PARSING_TEMPLATE) {
614                 displayContextStack("context stack problem detected in endTemplate", contextData);
615             }
616             templates.pop();
617         }
618         
619         private void startProperty(String JavaDoc qName, Attributes JavaDoc attributes) {
620             String JavaDoc name = attributes.getValue("name");
621             int status = getStatus(attributes.getValue("status"), "protected");
622             int typeKind = getTypeKind(attributes.getValue("type"));
623
624             Property property = null;
625             try {
626                 if (name != null && arrayCount == 0) {
627                     property = new Property(name, status, typeKind, getCurrentTemplate());
628                     getCurrentTemplate().addLocalProperty(property);
629                 } else {
630                     if (arrayCount > 0) {
631                         status = KILIM.PRIVATE;
632                     }
633                     if (name != null) {
634                         property = new Property("%anonymous" + name, status, typeKind, getCurrentTemplate());
635                     } else {
636                         property = new Property("%anonymous" + KILIM.getUniqueIndex(), status, typeKind, getCurrentTemplate());
637                     }
638                 }
639             } catch (KilimException ex) {
640                 logParseException(ex.toString());
641             }
642             //just a hack : typeKind is stored in the objectKind field of contextData (should be changed)
643
contexts.push(new ContextData(PARSING_PROPERTY, typeKind, property));
644             currentCDATA = new StringBuffer JavaDoc();
645         }
646         
647         private void endProperty(String JavaDoc qName) {
648             ContextData contextData = (ContextData) contexts.pop();
649             int phase = contextData.parsingPhase;
650             
651             if (phase != PARSING_PROPERTY) {
652                 displayContextStack("context stack problem detected in endProperty", contextData);
653             }
654
655             Property property = (Property) contextData.object;
656             //just a hack : typeKind is stored in the contextData in the objectKind field
657
int typeKind = contextData.objectKind;
658             String JavaDoc svalue = currentCDATA.toString();
659             Object JavaDoc value = getValue(getCDATA(svalue), typeKind);
660
661             try {
662                 if (value != null) {
663                     property.setValue(value);
664                 }
665                 ContextData newContext = (ContextData) contexts.peek();
666                 phase = newContext.parsingPhase;
667                         
668                 switch(phase) {
669                     case PARSING_PROVIDER :
670                         Provider provider = (Provider) newContext.object;
671                         provider.setSource(property);
672                         newContext.object = provider;
673                         break;
674                     case PARSING_PARAM :
675                         Parameter param = (Parameter) newContext.object;
676                         param.setTarget(property);
677                         break;
678                     case PARSING_ARRAY :
679                         ArraySource array = (ArraySource) newContext.object;
680                         array.addElement(property);
681                         break;
682                     case PARSING_BINDING :
683                         Binding binding = (Binding) newContext.object;
684                         binding.bindProvider(property);
685                         break;
686                     case PARSING_SUPPORT :
687                     case PARSING_VALUE :
688                         newContext.object = property;
689                         break;
690                     case PARSING_TRANSFORMER :
691                         Transformer transformer = (Transformer) newContext.object;
692                         transformer.setAction(property);
693                         newContext.object = transformer;
694                         break;
695                     case PARSING_TRIGGER :
696                         Trigger trig = (Trigger) newContext.object;
697                         trig.addTransformer(property);
698                         break;
699                     default :
700                         //displayContextStack("context stack problem (3) detected in endProperty", newContext);
701
break;
702                 }
703             } catch (KilimException ex) {
704                 logParseException(ex.toString());
705             }
706             currentCDATA = null;
707         }
708         
709         private void startProvider(String JavaDoc qName, Attributes JavaDoc attributes) {
710             Provider provider = null;
711             String JavaDoc name = attributes.getValue("name");
712             int status = getStatus(attributes.getValue("status"), "protected");
713             try {
714                 if (name != null) {
715                     provider = new Provider(name, status, getCurrentTemplate());
716                 } else {
717                     logParseException("no null name allowed in a provider tag");
718                     provider = new Provider("unknown", status, getCurrentTemplate());
719                 }
720             } catch (KilimException ex) {
721                 logParseException(ex.toString());
722             }
723             contexts.push(new ContextData(PARSING_PROVIDER, 0, provider));
724         }
725         
726         private void endProvider(String JavaDoc qName) {
727             ContextData contextData = (ContextData) contexts.pop();
728             int phase = contextData.parsingPhase;
729             
730             if (phase != PARSING_PROVIDER) {
731                 displayContextStack("context stack problem detected in endProvider", contextData);
732             }
733             try {
734                 getCurrentTemplate().addLocalProvider((BasicNamedElement) contextData.object);
735             } catch (KilimException ex) {
736                 logParseException(ex.toString());
737             }
738         }
739         
740         private void startTransformer(String JavaDoc qName, Attributes JavaDoc attributes) {
741             Transformer transformer = null;
742             String JavaDoc name = attributes.getValue("name");
743             int status = getStatus(attributes.getValue("status"), "protected");
744             try {
745                 if (name != null) {
746                     transformer = new Transformer(name, status, getCurrentTemplate());
747                 } else {
748                     logParseException("illegal null name in a transformer tag");
749                     transformer = new Transformer("unknown", status, getCurrentTemplate());
750                 }
751             } catch (KilimException ex) {
752                 logParseException(ex.toString());
753             }
754             contexts.push(new ContextData(PARSING_TRANSFORMER, 0, transformer));
755             parsingTransformer = true;
756         }
757         
758         private void endTransformer(String JavaDoc qName) {
759             ContextData contextData = (ContextData) contexts.pop();
760             int phase = contextData.parsingPhase;
761             
762             if (phase != PARSING_TRANSFORMER) {
763                 displayContextStack("context stack problem detected in endTransformer", contextData);
764             }
765             try {
766                 getCurrentTemplate().addLocalTransformer((BasicNamedElement) contextData.object);
767             } catch (KilimException ex) {
768                 logParseException(ex.toString());
769             }
770             
771             parsingTransformer = false;
772         }
773         
774         private void startGet(String JavaDoc qName, Attributes JavaDoc attributes) {
775             String JavaDoc field = attributes.getValue("field");
776             boolean isStatic = "true".equalsIgnoreCase(attributes.getValue("static"));
777             try {
778                 TpAccessor fieldAction = new TpGetter(null, field, isStatic, getCurrentTemplate());
779                 contexts.push(new ContextData(PARSING_ACCESSOR, 0, fieldAction));
780                 contexts.push(new ContextData(PARSING_SUPPORT, PARSING_ACCESSOR, null));
781             } catch (KilimException ex) {
782                 logParseException(ex.toString());
783             }
784         }
785         
786         private void endGet(String JavaDoc qName) {
787             ContextData currentContext = (ContextData) contexts.pop();
788                                 
789             if (currentContext.parsingPhase != PARSING_SUPPORT) {
790                 displayContextStack("context stack problem (1) detected in endGet", currentContext);
791             }
792             
793             BasicElement support = (BasicElement) currentContext.object;
794             
795             currentContext = (ContextData) contexts.pop();
796             if (currentContext.parsingPhase != PARSING_ACCESSOR) {
797                 displayContextStack("context stack problem (2) detected in endGet", currentContext);
798             }
799             
800             TpAccessor fieldSource = (TpAccessor) currentContext.object;
801             
802             ContextData newContext = (ContextData) contexts.peek();
803             int phase = newContext.parsingPhase;
804             
805             try {
806                 fieldSource.setSupport(support);
807                 switch(phase) {
808                     case PARSING_PROVIDER :
809                         Provider provider = (Provider) newContext.object;
810                         provider.setSource(fieldSource);
811                         newContext.object = provider;
812                         break;
813                     case PARSING_PARAM :
814                         Parameter param = (Parameter) newContext.object;
815                         param.setTarget(fieldSource);
816                         break;
817                     case PARSING_ARRAY :
818                         ArraySource array = (ArraySource) newContext.object;
819                         array.addElement(fieldSource);
820                         break;
821                     case PARSING_BINDING :
822                         Binding binding = (Binding) newContext.object;
823                         binding.bindProvider(fieldSource);
824                         break;
825                     case PARSING_SUPPORT :
826                     case PARSING_VALUE :
827                         newContext.object = fieldSource;
828                         break;
829                     case PARSING_TRANSFORMER :
830                         logParseException("no get is allowed in the definition of a transformer");
831                         break;
832                     case PARSING_TRIGGER :
833                         Trigger trig = (Trigger) newContext.object;
834                         trig.addTransformer(fieldSource);
835                         break;
836                     default :
837                         displayContextStack("context stack problem (3) detected in endGet", newContext);
838                         break;
839                 }
840             } catch (KilimException ex) {
841                 logParseException(ex.toString());
842             }
843         }
844         
845         private void startSet(String JavaDoc qName, Attributes JavaDoc attributes) {
846             String JavaDoc field = attributes.getValue("field");
847             boolean isStatic = "true".equalsIgnoreCase(attributes.getValue("static"));
848             try {
849                 TpAccessor fieldAction = new TpSetter(null, field, isStatic, getCurrentTemplate());
850                 contexts.push(new ContextData(PARSING_ACCESSOR, 0, fieldAction));
851                 contexts.push(new ContextData(PARSING_SUPPORT, PARSING_ACCESSOR, null));
852                 } catch (KilimException ex) {
853                     logParseException(ex.toString());
854             }
855         }
856         
857         private void endSet(String JavaDoc qName) {
858             ContextData currentContext = (ContextData) contexts.pop();
859                                 
860             if (currentContext.parsingPhase != PARSING_SUPPORT) {
861                 displayContextStack("context stack problem (1) detected in endSet", currentContext);
862             }
863             
864             BasicElement support = (BasicElement) currentContext.object;
865             
866             currentContext = (ContextData) contexts.pop();
867             if (currentContext.parsingPhase != PARSING_ACCESSOR) {
868                 displayContextStack("context stack problem (2) detected in endSet", currentContext);
869             }
870             
871             TpAccessor fieldTransformer = (TpAccessor) currentContext.object;
872             
873             ContextData newContext = (ContextData) contexts.peek();
874             int phase = newContext.parsingPhase;
875             try {
876                 fieldTransformer.setSupport(support);
877                 if (phase == PARSING_TRANSFORMER) {
878                     Transformer transformer = (Transformer) newContext.object;
879                     transformer.setAction(fieldTransformer);
880                 } else {
881                     if (phase == PARSING_TRIGGER) {
882                         Trigger trig = (Trigger) newContext.object;
883                         trig.addTransformer(fieldTransformer);
884                     } else {
885                         displayContextStack("context stack problem (3) detected in endSet", newContext);
886                     }
887                 }
888             } catch (KilimException ex) {
889                 logParseException(ex.toString());
890             }
891         }
892         
893         private void startNew(String JavaDoc qName, Attributes JavaDoc attributes) {
894             try {
895                 TpConstructor ctorAction = new TpConstructor(null, getCurrentTemplate());
896                 contexts.push(new ContextData(PARSING_NEW, 0, ctorAction));
897                 //the following line is useless. It is introduced for regularity reasons
898
contexts.push(new ContextData(PARSING_SUPPORT, 0, null));
899             } catch (KilimException ex) {
900                 logParseException(ex.toString());
901             }
902         }
903         
904         private void endNew(String JavaDoc qName) {
905             ContextData currentContext = (ContextData) contexts.pop();
906                                 
907             if (currentContext.parsingPhase != PARSING_SUPPORT) {
908                 displayContextStack("context stack problem (1) detected in endNew", currentContext);
909             }
910                     
911             BasicElement support = (BasicElement) currentContext.object;
912             currentContext = (ContextData) contexts.pop();
913                     
914             if (currentContext.parsingPhase != PARSING_NEW) {
915                 displayContextStack("context stack problem (2) detected in endNew", currentContext);
916             }
917             
918             TpConstructor ctorAction = (TpConstructor) currentContext.object;
919             
920             ContextData newContext = (ContextData) contexts.peek();
921             int phase = newContext.parsingPhase;
922             
923             try {
924                 ctorAction.setSupport(support);
925                 switch(phase) {
926                     case PARSING_TRANSFORMER :
927                         Transformer transformer = (Transformer) newContext.object;
928                         transformer.setAction(ctorAction);
929                         break;
930                     case PARSING_PROVIDER :
931                         Provider provider = (Provider) newContext.object;
932                         provider.setSource(ctorAction);
933                         break;
934                     case PARSING_PARAM :
935                         Parameter param = (Parameter) newContext.object;
936                         param.setTarget(ctorAction);
937                         break;
938                     case PARSING_ARRAY :
939                         ArraySource array = (ArraySource) newContext.object;
940                         array.addElement(ctorAction);
941                         break;
942                     case PARSING_BINDING :
943                         Binding binding = (Binding) newContext.object;
944                         binding.bindProvider(ctorAction);
945                         break;
946                     case PARSING_SUPPORT :
947                     case PARSING_VALUE :
948                         newContext.object = ctorAction;
949                         break;
950                     case PARSING_TRIGGER :
951                         Trigger trig = (Trigger) newContext.object;
952                         trig.addTransformer(ctorAction);
953                         break;
954                     default :
955                         displayContextStack("context stack problem (3) detected in endNew", newContext);
956                         break;
957                 }
958             } catch (KilimException ex) {
959                 logParseException(ex.toString());
960             }
961         }
962         
963         private void startCall(String JavaDoc qName, Attributes JavaDoc attributes) {
964             String JavaDoc method = attributes.getValue("method");
965             boolean isStatic = "true".equalsIgnoreCase(attributes.getValue("static"));
966             try {
967                 TpMethod methodAction = new TpMethod(null, method, isStatic, true, true, getCurrentTemplate());
968                 contexts.push(new ContextData(PARSING_METHOD, 0, methodAction));
969                 contexts.push(new ContextData(PARSING_SUPPORT, PARSING_METHOD, null));
970             } catch (KilimException ex) {
971                 logParseException(ex.toString());
972             }
973         }
974         
975         private void endCall(String JavaDoc qName) {
976             ContextData currentContext = (ContextData) contexts.pop();
977                                 
978             if (currentContext.parsingPhase != PARSING_SUPPORT) {
979                 displayContextStack("context stack problem (1) detected in endCAll", currentContext);
980             }
981             
982             BasicElement support = (BasicElement) currentContext.object;
983             
984             currentContext = (ContextData) contexts.pop();
985             if (currentContext.parsingPhase != PARSING_METHOD) {
986                 displayContextStack("context stack problem (2) detected in endCall", currentContext);
987             }
988             
989             TpMethod methodAction = (TpMethod) currentContext.object;
990             
991             ContextData newContext = (ContextData) contexts.peek();
992             int phase = newContext.parsingPhase;
993
994             try {
995                 methodAction.setSupport(support);
996                 switch(phase) {
997                     case PARSING_PROVIDER :
998                         Provider provider = (Provider) newContext.object;
999                         provider.setSource(methodAction);
1000                        break;
1001                    case PARSING_TRANSFORMER :
1002                        Transformer transformer = (Transformer) newContext.object;
1003                        transformer.setAction(methodAction);
1004                        break;
1005                    case PARSING_PARAM :
1006                        Parameter param = (Parameter) newContext.object;
1007                        param.setTarget(methodAction);
1008                        break;
1009                    case PARSING_ARRAY :
1010                        ArraySource array = (ArraySource) newContext.object;
1011                        array.addElement(methodAction);
1012                        break;
1013                    case PARSING_BINDING :
1014                        Binding binding = (Binding) newContext.object;
1015                        binding.bindProvider(methodAction);
1016                        break;
1017                    case PARSING_SUPPORT :
1018                    case PARSING_VALUE :
1019                        newContext.object = methodAction;
1020                        break;
1021                    case PARSING_TRIGGER :
1022                        Trigger trig = (Trigger) newContext.object;
1023                        trig.addTransformer(methodAction);
1024                        break;
1025                    default :
1026                        displayContextStack("context stack problem (3) detected in endCall", newContext);
1027                        break;
1028                }
1029            } catch (KilimException ex) {
1030                logParseException(ex.toString());
1031            }
1032        }
1033        
1034        private void startArray(String JavaDoc qName, Attributes JavaDoc attributes) {
1035            arrayCount++;
1036            String JavaDoc typeName = attributes.getValue("type");
1037            int typeKind = getTypeKind(typeName);
1038            
1039            try {
1040                ArraySource array;
1041                if (typeKind == KILIM.OBJECT) {
1042                    array = new ArraySource(typeName, getCurrentTemplate());
1043                } else {
1044                    array = new ArraySource(KILIM.CLASS_NAME[typeKind], getCurrentTemplate());
1045                }
1046                contexts.push(new ContextData(PARSING_ARRAY, 0, array));
1047            } catch (KilimException ex) {
1048                logParseException(ex.toString());
1049            }
1050        }
1051        
1052        private void endArray(String JavaDoc qName) {
1053            arrayCount--;
1054            ContextData contextData = (ContextData) contexts.pop();
1055            int phase = contextData.parsingPhase;
1056            
1057            if (phase != PARSING_ARRAY) {
1058                displayContextStack("context stack problem (1) detected in endArray", contextData);
1059            }
1060            
1061            ArraySource array = (ArraySource) contextData.object;
1062            contextData = (ContextData) contexts.peek();
1063            phase = contextData.parsingPhase;
1064            TemplateElementImpl source = null;
1065
1066            try {
1067                switch(phase) {
1068                    case PARSING_PROVIDER :
1069                        TemplateElementImpl element = (TemplateElementImpl) contextData.object;
1070                        contextData.object = array;
1071                        break;
1072                    case PARSING_SUPPORT :
1073                    case PARSING_VALUE :
1074                        contextData.object = array;
1075                        break;
1076                    case PARSING_PARAM :
1077                        Parameter param = (Parameter) contextData.object;
1078                        param.setTarget(array);
1079                        break;
1080                    case PARSING_ARRAY :
1081                        ArraySource array1 = (ArraySource) contextData.object;
1082                        array1.addElement(array);
1083                        break;
1084                    case PARSING_BINDING:
1085                        Binding binding = (Binding) contextData.object;
1086                        binding.bindProvider(array);
1087                        break;
1088                    default :
1089                        displayContextStack("context stack problem (2) detected in endArray", contextData);
1090                        break;
1091                }
1092            } catch (KilimException ex) {
1093                logParseException(ex.toString());
1094            }
1095        }
1096    
1097        private void startClass(String JavaDoc qName, Attributes JavaDoc attributes) {
1098            String JavaDoc className = attributes.getValue("name");
1099            if (className == null) {
1100                logParseException("no null name allowed in class definition");
1101            }
1102
1103            ContextData contextData = (ContextData) contexts.peek();
1104            int phase = contextData.parsingPhase;
1105            try {
1106                ClassSource classSource = new ClassSource(className, getCurrentTemplate());
1107                switch(phase) {
1108                    case PARSING_PROVIDER :
1109                        Provider provider = (Provider) contextData.object;
1110                        provider.setSource(classSource);
1111                        break;
1112                    case PARSING_SUPPORT :
1113                    case PARSING_VALUE :
1114                        contextData.object = classSource;
1115                        break;
1116                    case PARSING_PARAM :
1117                        Parameter param = (Parameter) contextData.object;
1118                        param.setTarget(classSource);
1119                        break;
1120                    case PARSING_ARRAY :
1121                        ArraySource array = (ArraySource) contextData.object;
1122                        array.addElement(classSource);
1123                        break;
1124                    case PARSING_BINDING :
1125                        Binding binding = (Binding) contextData.object;
1126                        binding.bindProvider(classSource);
1127                        break;
1128                    default :
1129                        displayContextStack("context stack problem detected in startClass", contextData);
1130                        break;
1131                }
1132            } catch (KilimException ex) {
1133                logParseException(ex.toString());
1134            }
1135        }
1136        
1137        private void endClass(String JavaDoc qName) { }
1138        
1139        private void startParam(String JavaDoc localName, Attributes JavaDoc attributes) {
1140            String JavaDoc paramName = attributes.getValue("name");
1141            String JavaDoc paramType = attributes.getValue("type");
1142            contexts.push(new ContextData(PARSING_PARAM, 0, new Parameter(paramName, paramType, null)));
1143        }
1144        
1145        private void endParam(String JavaDoc qName) {
1146            ContextData contextData = (ContextData) contexts.pop();
1147            int phase = contextData.parsingPhase;
1148            
1149            if (phase != PARSING_PARAM) {
1150                displayContextStack("context stack problem (1) detected in endParam", contextData);
1151            }
1152            
1153            Parameter parameter = (Parameter) contextData.object;
1154            contextData = (ContextData) contexts.peek();
1155            phase = contextData.parsingPhase;
1156            
1157            if (phase != PARSING_SUPPORT) {
1158                displayContextStack("context stack problem (2) detected in endParam", contextData);
1159            }
1160            
1161            contextData = (ContextData) contexts.elementAt(contexts.size() - 2);
1162            phase = contextData.parsingPhase;
1163            try {
1164                switch(phase) {
1165                    case PARSING_METHOD :
1166                    case PARSING_NEW :
1167                        TpMethod methodAction = (TpMethod) contextData.object;
1168                        methodAction.addParameter(parameter);
1169                        break;
1170                    default :
1171                        displayContextStack("context stack problem (3) detected in endParam", contextData);
1172                        break;
1173                }
1174            } catch (KilimException ex) {
1175                logParseException(ex.toString());
1176            }
1177        }
1178        
1179        private void startValue(String JavaDoc qName, Attributes JavaDoc attributes) {
1180            contexts.push(new ContextData(PARSING_VALUE, 0, null));
1181        }
1182
1183        private void endValue(String JavaDoc qName) {
1184            ContextData contextData = (ContextData) contexts.pop();
1185            int phase = contextData.parsingPhase;
1186            
1187            if (phase != PARSING_VALUE) {
1188                displayContextStack("context stack problem (1) detected in endValue", contextData);
1189            }
1190            
1191            BasicElement provider = (BasicElement) contextData.object;
1192            
1193            contextData = (ContextData) contexts.peek();
1194            phase = contextData.parsingPhase;
1195            
1196            if (phase != PARSING_SUPPORT) {
1197                displayContextStack("context stack problem (2) detected in endValue", contextData);
1198            }
1199            
1200            contextData = (ContextData) contexts.elementAt(contexts.size() - 2);
1201            phase = contextData.parsingPhase;
1202            
1203            switch(phase) {
1204                case PARSING_ACCESSOR :
1205                    TpSetter setter = (TpSetter) contextData.object;
1206                    setter.setValue(provider);
1207                    break;
1208                default :
1209                    displayContextStack("context stack problem (3) detected in endValue", contextData);
1210                    break;
1211            }
1212        }
1213        
1214        private Reference getRef(String JavaDoc aName, boolean isP, boolean isT) throws KilimException {
1215            Reference ref = getCurrentTemplate().getReference(aName, true);
1216            if (ref == null) {
1217                ref = new Reference(aName, getCurrentTemplate(), isP, isT);
1218            } else {
1219                if (!ref.providesValue()) {
1220                    throw new KilimException("attempt to reuse reference " + aName + "as a value provider in template " + getCurrentTemplate());
1221                }
1222            }
1223            return ref;
1224        }
1225        
1226        private void startReference(String JavaDoc qName, Attributes JavaDoc attributes) {
1227            String JavaDoc targetName = attributes.getValue("target");
1228            if (targetName == null) {
1229                logParseException("no null name allowed in provider reference definition");
1230            }
1231        
1232            ContextData contextData = (ContextData) contexts.peek();
1233            int phase = contextData.parsingPhase;
1234            Reference ref = null;
1235            
1236            try {
1237                switch(phase) {
1238                    case PARSING_PROVIDER :
1239                        Provider provider = (Provider) contextData.object;
1240                        ref = getRef(targetName, true, false);
1241                        provider.setSource(ref);
1242                        getCurrentTemplate().addProviderReference(ref);
1243                        break;
1244                    case PARSING_SUPPORT :
1245                        ref = getRef(targetName, true, false);
1246                        contextData.object = ref;
1247                        getCurrentTemplate().addProviderReference(ref);
1248                        break;
1249                    case PARSING_PARAM :
1250                        Parameter param = (Parameter) contextData.object;
1251                        ref = getRef(targetName, true, false);
1252                        param.setTarget(ref);
1253                        getCurrentTemplate().addProviderReference(ref);
1254                        break;
1255                    case PARSING_ARRAY :
1256                        ArraySource array = (ArraySource) contextData.object;
1257                        ref = getRef(targetName, true, false);
1258                        array.addElement(ref);
1259                        getCurrentTemplate().addProviderReference(ref);
1260                        break;
1261                    case PARSING_BINDING :
1262                        Binding binding = (Binding) contextData.object;
1263                        ref = getRef(targetName, true, false);
1264                        binding.bindProvider(ref);
1265                        getCurrentTemplate().addProviderReference(ref);
1266                        break;
1267                    case PARSING_TRANSFORMER :
1268                        Transformer transformer = (Transformer) contextData.object;
1269                        ref = getRef(targetName, false, true);
1270                        transformer.setAction(ref);
1271                        getCurrentTemplate().addTransformerReference(ref);
1272                        break;
1273                    case PARSING_TRIGGER :
1274                        Trigger trigger = (Trigger) contextData.object;
1275                        ref = getRef(targetName, false, true);
1276                        trigger.addTransformer(ref);
1277                        getCurrentTemplate().addTransformerReference(ref);
1278                        break;
1279                    case PARSING_VALUE :
1280                        ref = getRef(targetName, true, false);
1281                        contextData.object = ref;
1282                        getCurrentTemplate().addProviderReference(ref);
1283                        break;
1284                    default :
1285                        displayContextStack("context stack problem detected in startReference", contextData);
1286                        break;
1287                }
1288            } catch (KilimException ex) {
1289                logParseException(ex.toString());
1290            }
1291        }
1292        
1293        private void endReference(String JavaDoc qName) { }
1294                    
1295        private void startEventSource(String JavaDoc qName, Attributes JavaDoc attributes) {
1296            if (!parsingTransformer && !parsingTrigger) {
1297                logParseException("no event source allowed outside a trigger-transformer context");
1298            }
1299            
1300            ContextData contextData = (ContextData) contexts.peek();
1301            int phase = contextData.parsingPhase;
1302            try {
1303                switch(phase) {
1304                    case PARSING_PARAM :
1305                        Parameter param = (Parameter) contextData.object;
1306                        param.setTarget(EventSource.EVENT_SOURCE);
1307                        break;
1308                    case PARSING_SUPPORT :
1309                        contextData.object = EventSource.EVENT_SOURCE;
1310                        break;
1311                    case PARSING_ARRAY :
1312                        ArraySource array = (ArraySource) contextData.object;
1313                        array.addElement(EventSource.EVENT_SOURCE);
1314                        break;
1315                    default :
1316                        displayContextStack("context stack problem detected in startEventTemplateElement", contextData);
1317                        break;
1318                }
1319            } catch (KilimException ex) {
1320                logParseException(ex.toString());
1321            }
1322        }
1323        
1324        private void endEventSource(String JavaDoc qName) { }
1325        
1326        private void startInstance(String JavaDoc qName, Attributes JavaDoc attributes) {
1327            String JavaDoc name = attributes.getValue("name");
1328            String JavaDoc templateName = (String JavaDoc) attributes.getValue("template");
1329            int status = getStatus(attributes.getValue("status"), "protected");
1330            boolean hasUnknownSuper = false;
1331            
1332            TemplateDescription superTemplate = null;
1333            //TemplateDescription superTemplateForSuper = null;
1334
if (templateName != null) {
1335                if ("super".equalsIgnoreCase(templateName)) {
1336                    hasUnknownSuper = true;
1337                } else {
1338                    superTemplate = (TemplateDescription) parsingResult.getKnownTemplate(templateName);
1339                    if (superTemplate == null) {
1340                        try {
1341                            superTemplate = new TemplateDescription(templateName);
1342                        } catch (KilimException ex) {
1343                            logParseException(ex.toString());
1344                        }
1345                        parsingResult.addUnparsedTemplate(templateName);
1346                        parsingResult.addKnownTemplate(templateName, superTemplate);
1347                    }
1348                }
1349            }
1350            try {
1351                TemplateDescription newTemplate = new TemplateDescription("%anonymous" + KILIM.getUniqueIndex(), superTemplate);
1352                TemplateDescription contain = getCurrentInstance().getTemplate();
1353                Instance newInstance = new Instance(name, status, newTemplate, contain);
1354                contain.addLocalInstance(newInstance);
1355                templates.push(newTemplate);
1356                instances.push(newInstance);
1357                contexts.push(new ContextData(PARSING_INSTANCE, 0, newInstance));
1358                if (hasUnknownSuper) {
1359                    parsingResult.addUnknownSuperTemplateOfInstance(newInstance);
1360                }
1361            } catch (KilimException ex) {
1362                logParseException(ex.toString());
1363            }
1364        }
1365        
1366        private void endInstance(String JavaDoc localName) {
1367            ContextData contextData = (ContextData) contexts.pop();
1368            int phase = contextData.parsingPhase;
1369            
1370            if (phase != PARSING_INSTANCE) {
1371                displayContextStack("context stack problem (1) detected in endInstance", contextData);
1372            }
1373            
1374            Instance instance = (Instance) contextData.object;
1375            TemplateDescription template = instance.getTemplate();
1376            if (template == null) {
1377                logParseException("instance " + instance.getLocalName() + " without template");
1378            }
1379            try {
1380                if (!template.containsNewDefinitions()) {
1381                    instance.setTemplate(template.getSuperTemplate());
1382                }
1383            } catch (KilimException ex) {
1384                logParseException(ex.toString());
1385            }
1386            instances.pop();
1387            templates.pop();
1388        }
1389        
1390        private void startBind(String JavaDoc qName, Attributes JavaDoc attributes) {
1391            String JavaDoc portName = attributes.getValue("port");
1392            Binding binding = null;
1393            try {
1394                binding = new Binding(portName, getCurrentTemplate());
1395            } catch (KilimException ex) {
1396                try {
1397                    binding = new Binding("error_" + KILIM.getUniqueIndex(), getCurrentTemplate());
1398                } catch (KilimException ex1) { }
1399                logParseException(ex.toString());
1400            }
1401            contexts.push(new ContextData(PARSING_BINDING, 0, binding));
1402            try {
1403                getCurrentTemplate().addLocalBinding(binding);
1404            } catch (KilimException ex) {
1405                logParseException(ex.toString());
1406            }
1407        }
1408        
1409        private void endBind(String JavaDoc qName) {
1410            ContextData contextData = (ContextData) contexts.pop();
1411            int phase = contextData.parsingPhase;
1412            
1413            if (phase != PARSING_BINDING) {
1414                displayContextStack("context stack problem (1) detected in endBind", contextData);
1415            }
1416        }
1417        
1418        private void startTrigger(String JavaDoc localName, Attributes JavaDoc attributes) {
1419            String JavaDoc source = attributes.getValue("source");
1420            String JavaDoc event = attributes.getValue("event");
1421            // dtd asserts currentPort is not null
1422
Trigger trigger = null;
1423            if ("bind".equalsIgnoreCase(event)) {
1424                trigger = new BindTrigger(source);
1425            } else if ("unbind".equalsIgnoreCase(event)) {
1426                trigger = new UnBindTrigger(source);
1427            }
1428            parsingTrigger = true;
1429            contexts.push(new ContextData(PARSING_TRIGGER, 0, trigger));
1430            try {
1431                getCurrentTemplate().addLocalTrigger(trigger);
1432            } catch (KilimException ex) {
1433                logParseException(ex.toString());
1434            }
1435        }
1436        
1437        private void endTrigger(String JavaDoc qName) {
1438            ContextData contextData = (ContextData) contexts.pop();
1439            int phase = contextData.parsingPhase;
1440            
1441            if (phase != PARSING_TRIGGER) {
1442                displayContextStack("context stack problem (1) detected in endTrigger", contextData);
1443            }
1444            parsingTrigger = false;
1445        }
1446        
1447        private void startPort(String JavaDoc qName, Attributes JavaDoc attributes) {
1448            Port port = null;
1449            String JavaDoc name = attributes.getValue("name");
1450            int status = getStatus(attributes.getValue("status"), "protected");
1451            String JavaDoc sRole = attributes.getValue("role");
1452            boolean isProvided = false;
1453            if (sRole == null || "offered".equalsIgnoreCase(sRole)) {
1454                isProvided = true;
1455            }
1456            
1457            String JavaDoc sArity = attributes.getValue("arity");
1458            Arity arity = null;
1459
1460            try {
1461                if ("?".equalsIgnoreCase(sArity) || "optional".equalsIgnoreCase(sArity)) {
1462                    arity = Arity.OPTIONAL;
1463                    port = new Port(name, Arity.OPTIONAL, status, isProvided, getCurrentTemplate());
1464                } else if ("1".equalsIgnoreCase(sArity)) {
1465                    arity = Arity.REQUIRED;
1466                    port = new Port(name, Arity.REQUIRED, status, isProvided, getCurrentTemplate());
1467                } else if ("*".equalsIgnoreCase(sArity) || "any".equalsIgnoreCase(sArity)) {
1468                    arity = Arity.COLLECTION;
1469                    port = new Port(name, Arity.COLLECTION, status, isProvided, getCurrentTemplate());
1470                } else {
1471                    logParseException("unable to parse arity " + sArity);
1472                }
1473                //getCurrentTemplate().addLocalPort(port);
1474
} catch (KilimException ex) {
1475                logParseException(ex.toString());
1476            }
1477            contexts.push(new ContextData(PARSING_PORT, 0, port));
1478            return;
1479        }
1480        
1481        private void endPort(String JavaDoc qName) {
1482            ContextData contextData = (ContextData) contexts.pop();
1483            int phase = contextData.parsingPhase;
1484            if (phase != PARSING_PORT) {
1485                displayContextStack("context stack problem detected in endPort", contextData);
1486            }
1487            Port port = (Port) contextData.object;
1488            
1489            ContextData newContext = (ContextData) contexts.peek();
1490            phase = newContext.parsingPhase;
1491            try {
1492                switch(phase) {
1493                    case PARSING_SLOT :
1494                        Slot slot = (Slot) newContext.object;
1495                        slot.addPort(port);
1496                        break;
1497                    default :
1498                        getCurrentTemplate().addLocalPort(port);
1499                        break;
1500                }
1501            } catch (KilimException ex) {
1502                logParseException(ex.toString());
1503            }
1504        }
1505        
1506        private void startNullProvider(String JavaDoc qName, Attributes JavaDoc attributes) {
1507            ContextData contextData = (ContextData) contexts.peek();
1508            int phase = contextData.parsingPhase;
1509            try {
1510                NullElement nullElement = null;
1511                switch(phase) {
1512                    case PARSING_PROVIDER :
1513                        Provider provider = (Provider) contextData.object;
1514                        nullElement = new NullElement(provider.getLocalName(), provider.getStatus(), true, provider.performsAction(), getCurrentTemplate());
1515                        provider.setSource(nullElement);
1516                        break;
1517                    case PARSING_TRANSFORMER :
1518                        Transformer transformer = (Transformer) contextData.object;
1519                        nullElement = new NullElement(transformer.getLocalName(), transformer.getStatus(), transformer.performsAction(), true, getCurrentTemplate());
1520                        transformer.setAction(nullElement);
1521                        break;
1522                    case PARSING_SUPPORT :
1523                        throw new KilimException("attempt to set null to a support in template " + getCurrentTemplate());
1524                    case PARSING_VALUE :
1525                        nullElement = new NullElement("%anonymous" + KILIM.getUniqueIndex(), KILIM.PRIVATE, true, false, getCurrentTemplate());
1526                        contextData.object = nullElement;
1527                        break;
1528                    case PARSING_PARAM :
1529                        Parameter param = (Parameter) contextData.object;
1530                        nullElement = new NullElement("%anonymous" + KILIM.getUniqueIndex(), KILIM.PRIVATE, true, false, getCurrentTemplate());
1531                        param.setTarget(nullElement);
1532                        break;
1533                    case PARSING_ARRAY :
1534                        ArraySource array = (ArraySource) contextData.object;
1535                        nullElement = new NullElement("%anonymous" + KILIM.getUniqueIndex(), KILIM.PRIVATE, true, false, getCurrentTemplate());
1536                        array.addElement(nullElement);
1537                        break;
1538                    case PARSING_BINDING :
1539                        Binding binding = (Binding) contextData.object;
1540                        nullElement = new NullElement("%anonymous" + KILIM.getUniqueIndex(), KILIM.PRIVATE, true, false, getCurrentTemplate());
1541                        binding.bindProvider(nullElement);
1542                        break;
1543                    default :
1544                        displayContextStack("context stack problem detected in startClass", contextData);
1545                        break;
1546                }
1547            } catch (KilimException ex) {
1548                logParseException(ex.toString());
1549            }
1550
1551        }
1552        
1553        private void endNullProvider(String JavaDoc qName) { }
1554        
1555        private void startSlot(String JavaDoc qName, Attributes JavaDoc attributes) {
1556            String JavaDoc name = attributes.getValue("name");
1557            int status = getStatus(attributes.getValue("status"), "protected");
1558            try {
1559                Slot slot = new Slot(name, status, getCurrentTemplate());
1560                getCurrentTemplate().addLocalSlot(slot);
1561                contexts.push(new ContextData(PARSING_SLOT, 0, slot));
1562            } catch (KilimException ex) {
1563                logParseException(ex.toString());
1564            }
1565            return;
1566        }
1567    
1568        private void endSlot(String JavaDoc qName) {
1569            ContextData contextData = (ContextData) contexts.pop();
1570            int phase = contextData.parsingPhase;
1571            if (phase != PARSING_SLOT) {
1572                displayContextStack("context stack problem detected in endSlot", contextData);
1573            }
1574        }
1575        
1576        private String JavaDoc slotNameInCurrentPlug;
1577        
1578        private void startPlug(String JavaDoc qName, Attributes JavaDoc attributes) {
1579            String JavaDoc instanceName = attributes.getValue("instance");
1580            String JavaDoc slotName = attributes.getValue("slot");
1581            slotNameInCurrentPlug = slotName;
1582            try {
1583                Plug plug = new Plug(slotName, instanceName, getCurrentTemplate());
1584                getCurrentTemplate().addLocalPlug(plug);
1585                contexts.push(new ContextData(PARSING_SLOT, 0, plug));
1586            } catch (KilimException ex) {
1587                logParseException(ex.toString());
1588            }
1589            
1590            return;
1591        }
1592
1593        private void endPlug(String JavaDoc qName) {
1594            ContextData contextData = (ContextData) contexts.pop();
1595            int phase = contextData.parsingPhase;
1596            
1597            if (phase != PARSING_PLUG) {
1598                displayContextStack("context stack problem (1) detected in endPlug ", contextData);
1599            }
1600        }
1601        
1602        private void startNameMapping(String JavaDoc qName, Attributes JavaDoc attributes) {
1603            ContextData contextData = (ContextData) contexts.peek();
1604            int phase = contextData.parsingPhase;
1605            
1606            if (phase != PARSING_PLUG) {
1607                displayContextStack("context stack problem (1) detected in startNameParam ", contextData);
1608            }
1609            Plug currentPlug = (Plug) contextData.object;
1610            String JavaDoc external = attributes.getValue("external");
1611            String JavaDoc internal = attributes.getValue("internal");
1612            try {
1613                currentPlug.addNameMapping(external, internal);
1614                return;
1615            } catch (KilimException ex) {
1616                logParseException(ex.toString());
1617            }
1618        }
1619        
1620        private void endNameMapping(String JavaDoc qName) { }
1621        
1622        private void startType(String JavaDoc qName, Attributes JavaDoc attributes) {
1623            currentCDATA = new StringBuffer JavaDoc();
1624        }
1625        
1626        private void endType(String JavaDoc qName) {
1627            currentCDATA = null;
1628        }
1629
1630        
1631        /**
1632         * Method getType : returns the integer "type" constant (defined in the _Referenceable interface)
1633         * corresponding to the type passed as a String.
1634         * @param aType
1635         * @return int
1636         */

1637        private int getTypeKind(String JavaDoc aType) {
1638            if ("char".equalsIgnoreCase(aType)) {
1639                return KILIM.CHAR;
1640            } else if ("boolean".equalsIgnoreCase(aType)) {
1641                return KILIM.BOOLEAN;
1642            } else if ("byte".equalsIgnoreCase(aType)) {
1643                return KILIM.BYTE;
1644            } else if ("short".equalsIgnoreCase(aType)) {
1645                return KILIM.SHORT;
1646            } else if ("int".equalsIgnoreCase(aType)) {
1647                return KILIM.INT;
1648            } else if ("long".equalsIgnoreCase(aType)) {
1649                return KILIM.LONG;
1650            } else if ("float".equalsIgnoreCase(aType)) {
1651                return KILIM.FLOAT;
1652            } else if ("double".equalsIgnoreCase(aType)) {
1653                return KILIM.DOUBLE;
1654            } else if ("string".equalsIgnoreCase(aType)) {
1655                return KILIM.STRING;
1656            }
1657            return KILIM.OBJECT;
1658        }
1659        
1660        /**
1661         * Method getValue : returns a java wrapper containing the value of a primitive java type passed as a String.
1662         * @param aValue
1663         * @param aType
1664         * @return Object
1665         */

1666        private Object JavaDoc getValue(String JavaDoc aValue, int aType) {
1667            if (aValue == null) {
1668                return null;
1669            }
1670
1671            switch (aType) {
1672                case KILIM.CHAR :
1673                    return new Character JavaDoc(aValue.charAt(0));
1674                case KILIM.BOOLEAN :
1675                    return new Boolean JavaDoc(aValue);
1676                case KILIM.BYTE :
1677                    if ("".equals(aValue)) {
1678                        return null;
1679                    }
1680                    return new Byte JavaDoc(Byte.parseByte(aValue));
1681                case KILIM.SHORT :
1682                    if ("".equals(aValue)) {
1683                        return null;
1684                    }
1685                    return new Short JavaDoc(Short.parseShort(aValue));
1686                case KILIM.INT :
1687                    if ("".equals(aValue)) {
1688                        return null;
1689                    }
1690                    return new Integer JavaDoc(Integer.parseInt(aValue));
1691                case KILIM.LONG :
1692                    if ("".equals(aValue)) {
1693                        return null;
1694                    }
1695                    return new Long JavaDoc(Long.parseLong(aValue));
1696                case KILIM.DOUBLE :
1697                    if ("".equals(aValue)) {
1698                        return null;
1699                    }
1700                    return new Double JavaDoc(Double.parseDouble(aValue));
1701                case KILIM.FLOAT :
1702                    if ("".equals(aValue)) {
1703                        return null;
1704                    }
1705                    return new Float JavaDoc(Float.parseFloat(aValue));
1706                case KILIM.STRING :
1707                    return aValue;
1708                default :
1709                    logParseException("unable to parse Property value " + aValue);
1710                    return null;
1711            }
1712        }
1713        
1714        private int getStatus(String JavaDoc aStatus, String JavaDoc defaultStatus) {
1715            if (aStatus == null) {
1716                aStatus = defaultStatus;
1717            }
1718            if ("external".equalsIgnoreCase(aStatus) || "public".equalsIgnoreCase(aStatus)) {
1719                return KILIM.PUBLIC;
1720            } else if ("internal".equalsIgnoreCase(aStatus) || "private".equalsIgnoreCase(aStatus)) {
1721                return KILIM.PRIVATE;
1722            } else if ("protected".equalsIgnoreCase(aStatus)) {
1723                return KILIM.PROTECTED;
1724            } else {
1725                logParseException("unable to parse status " + aStatus);
1726            }
1727            return 0;
1728        }
1729        
1730        private String JavaDoc getCDATA(String JavaDoc cdata) {
1731            if (cdata == null) {
1732                return null;
1733            }
1734            cdata = cdata.trim();
1735            if (cdata.startsWith("<![CDATA[")) {
1736                cdata = cdata.substring(9);
1737                if (cdata.length() > 3) {
1738                    cdata = cdata.substring(0, cdata.length() - 3);
1739                }
1740            }
1741            return cdata;
1742        }
1743                
1744        private TemplateDescription getCurrentTemplate() {
1745            return (TemplateDescription) templates.peek();
1746        }
1747        
1748        private TemplateDescription getContainingTemplate() {
1749            return (TemplateDescription) templates.get(templates.size() - 2);
1750        }
1751            
1752        private Instance getCurrentInstance() {
1753            return (Instance) instances.peek();
1754        }
1755                
1756        private void logParseException(String JavaDoc message) {
1757            errorHandler.handleErrorSAXParseException(new SAXParseException JavaDoc(message, locator, null));
1758        }
1759        
1760        // A private method that displays in a warning message the stack state , when a stack problem is discovered.
1761
//It prints the name of the template beinig parsed followed by the current content of the stack.
1762
private void displayContextStack(String JavaDoc aMessage, ContextData top) {
1763            System.err.println("============CONTEXT STACK (begin)================");
1764            System.err.print("[TEMPLATE : " + currentTemplateName + "] ");
1765            System.err.println(aMessage);
1766            int nbE = contexts.size();
1767            System.err.println("nb Elem = " + nbE);
1768            for (int i = 0; i < nbE ; i++) {
1769                ContextData contextData = (ContextData) contexts.elementAt(i);
1770                System.err.println("elem " + i + " : phase = " + contextData.parsingPhase + " value = " + contextData.object);
1771            }
1772            System.err.println("elem " + nbE + " : phase = " + top.parsingPhase + " value = " + top.object);
1773            System.err.println("============CONTEXT STACK (end)==================");
1774        }
1775    }
1776}
Popular Tags