KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > kilim > model > ComponentFactory


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
19 package org.objectweb.kilim.model;
20
21 import java.lang.reflect.Array JavaDoc;
22
23 import java.util.LinkedHashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Stack JavaDoc;
28
29 import org.objectweb.kilim.InternalException;
30 import org.objectweb.kilim.KilimConfiguration;
31 import org.objectweb.kilim.KilimException;
32 import org.objectweb.kilim.description.ArraySource;
33 import org.objectweb.kilim.description.BasicElement;
34 import org.objectweb.kilim.description.BasicNamedElement;
35 import org.objectweb.kilim.description.Binding;
36 import org.objectweb.kilim.description.ClassSource;
37 import org.objectweb.kilim.description.EventSource;
38 import org.objectweb.kilim.description.Instance;
39 import org.objectweb.kilim.description.KILIM;
40 import org.objectweb.kilim.description.NullElement;
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
57 import org.objectweb.kilim.model.instanciation.InstanciationStrategy;
58
59 import org.objectweb.kilim.model.mapping.Mapper;
60 import org.objectweb.kilim.model.mapping.MappingContext;
61
62 import org.objectweb.kilim.model.services.DefaultNamingContext;
63 import org.objectweb.kilim.model.services.DefaultRuntimeClassLoader;
64
65 /**
66  * @author horn
67  */

68 public class ComponentFactory extends DefaultNamingContext implements Factory {
69     private String JavaDoc localName;
70     private ComponentFactory containingFactory;
71     private List JavaDoc subFactories;
72     
73     private TemplateDescription currentTemplate;
74     private TemplateDescription containingTemplate;
75     
76     private RtComponent currentComponent;
77     private RtComponent containingComponent;
78
79     private LinkedHashMap JavaDoc references;
80     
81     /* ************************************************************************************/
82     //inner class for a runtime descriptor of a getter
83

84     private static class RTGetter extends RtComponentProvider {
85                         
86         RTGetter(TpGetter aGetter, Component aComponent, RuntimeSource aSupport) {
87             super(aGetter, aComponent, aSupport);
88         }
89                     
90         String JavaDoc getFieldName() {
91             return ((TpAccessor) getElementDescription()).getFieldName();
92         }
93         
94         boolean isStatic() {
95             return ((TpAccessor) getElementDescription()).isStatic();
96         }
97                 
98         public Object JavaDoc specificGetValue() throws KilimException {
99             if (mappingContext != null) {
100                 mappingContext.getContextStack().push(this);
101             }
102             mapper.enterContext(mappingContext);
103             
104             Object JavaDoc eventSrcValue = getEventSourceValue();
105             
106             //specific part of the getValue
107
RuntimeSource support = (RuntimeSource) getSupport();
108             if (support == null) {
109                 throw new KilimException("attempt to get the value of a non initialized getter");
110             }
111             
112             Object JavaDoc suppObject = null;
113             if (support instanceof RTEventSource) {
114                 suppObject = eventSrcValue;
115             } else {
116                 suppObject = support.getValue();
117             }
118             
119             String JavaDoc fieldName = getFieldName();
120             
121             //call to the mapper that performs the real task
122
if (mappingContext != null) {
123                 mappingContext.getCallStack().push(this);
124             }
125
126             Object JavaDoc resultValue = mapper.getGetterValue(suppObject, isStatic(), fieldName, mappingContext);
127
128             if (mappingContext != null) {
129                 mappingContext.getCallStack().pop();
130             }
131             mapper.leaveContext(mappingContext);
132             
133             return resultValue;
134         }
135         
136         public boolean hasValue() throws KilimException {
137             return getSupport().hasValue();
138         }
139         
140         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
141             RuntimeSource lSupport = (RuntimeSource) getSupport().getTarget();
142
143             if (exclude == null || lSupport.hasValue()) {
144                 return true;
145             }
146             
147             int eSize = exclude.size();
148             for (int i = 0; i < eSize; i++) {
149                 if (lSupport == exclude.get(i)) {
150                     return false;
151                 }
152             }
153
154             exclude.push(this);
155             boolean isOK = lSupport.checkValue(exclude);
156             exclude.pop();
157             return isOK;
158         }
159     }
160
161     /* ************************************************************************************/
162     //inner class for a runtime descriptor of a setter
163

164     private static class RTSetter extends RtComponentElement implements RuntimeAction {
165         private String JavaDoc name;
166         private Object JavaDoc source;
167         private RuntimeSource value;
168         private RuntimeSource support;
169         private Mapper mapper;
170         private MappingContext mappingContext;
171                 
172         RTSetter(TpSetter aGetter, Component aComponent, RuntimeSource aSupport, RuntimeSource aValue) {
173             super(aGetter, aComponent);
174             mapper = KilimConfiguration.getMappingStrategy().getDefaultMapper();
175             mappingContext = KilimConfiguration.getMappingContext();
176             support = aSupport;
177             value = aValue;
178         }
179         
180         /**
181         * @see org.objectweb.kilim.model.ComponentElement#getLocalName()
182         */

183         public String JavaDoc getLocalName() {
184             return name;
185         }
186         
187         public void setEventSourceValue(Object JavaDoc aValue) {
188             source = aValue;
189         }
190
191         public Object JavaDoc getEventSourceValue() throws KilimException {
192             return source;
193         }
194         
195         String JavaDoc getFieldName() {
196             return ((TpAccessor) getElementDescription()).getFieldName();
197         }
198         
199         boolean isStatic() {
200             return ((TpAccessor) getElementDescription()).isStatic();
201         }
202     
203         public void execute() throws KilimException {
204             if (support == null) {
205                 throw new KilimException("attempt to get the value of a non initialized setter");
206             }
207
208             if (mappingContext != null) {
209                 mappingContext.getCallStack().push(this);
210             }
211             mapper.enterContext(mappingContext);
212             
213             Object JavaDoc suppObject = null;
214             
215             if (support instanceof RTEventSource) {
216                 suppObject = ((RuntimeSource) source).getEventSourceValue();
217             } else {
218                 suppObject = support.getValue();
219             }
220             
221             String JavaDoc fieldName = getFieldName();
222
223             Object JavaDoc toBeSet = null;
224             if (value instanceof RTEventSource) {
225                 toBeSet = source;
226             } else {
227                 toBeSet = value.getValue();
228             }
229
230             mapper.executeSetter(suppObject, isStatic(), fieldName, toBeSet, mappingContext);
231             if (mappingContext != null) {
232                 mappingContext.getCallStack().pop();
233             }
234             mapper.leaveContext(mappingContext);
235         }
236         
237         public boolean checkAction(Stack JavaDoc exclude) throws KilimException {
238             RuntimeSource lSupport = (RuntimeSource) support.getTarget();
239             if (exclude == null || lSupport.hasValue()) {
240                 return true;
241             }
242             
243             int eSize = exclude.size();
244             for (int i = 0; i < eSize; i++) {
245                 if (lSupport == exclude.get(i)) {
246                     return false;
247                 }
248             }
249
250             exclude.push(this);
251             boolean isOK = lSupport.checkValue(exclude);
252             exclude.pop();
253             return isOK;
254         }
255     }
256     
257     /* ************************************************************************************/
258         //inner class for a runtime descriptor of an array
259

260     private static class RTArray extends RuntimeSourceImpl1 {
261         private RuntimeSource[] arrayElements;
262         private String JavaDoc typeName;
263         
264         RTArray(ArraySource aArray, Component aComponent, RuntimeSource[] elements, String JavaDoc aTypeName) {
265             super(aArray, aComponent);
266
267             typeName = aTypeName;
268             arrayElements = elements;
269         }
270                     
271         /**
272          * @see org.objectweb.kilim.model.RuntimeSource#getValue()
273          */

274         public Object JavaDoc getValue() throws KilimException {
275             Object JavaDoc eventSrcValue = getEventSourceValue();
276             int size = arrayElements.length;
277             Class JavaDoc elementClass = DefaultRuntimeClassLoader.instance.getClass(typeName);
278             Object JavaDoc[] resultValue = (Object JavaDoc[]) Array.newInstance(elementClass, size);
279
280             for (int i = 0; i < size; i++) {
281                 if (arrayElements[i] instanceof RTEventSource) {
282                     resultValue[i] = eventSrcValue;
283                 } else {
284                     RuntimeSource rtS = (RuntimeSource) arrayElements[i];
285                     //recursive transmission of the event source ...
286
rtS.setEventSourceValue(eventSrcValue);
287                     resultValue[i] = rtS.getValue();
288                 }
289             }
290             return resultValue;
291         }
292         
293         /**
294          * @see org.objectweb.kilim.model.RuntimeSource#checkValue()
295          */

296         public boolean hasValue() throws KilimException {
297             int size = arrayElements.length;
298             for (int i = 0; i < size; i++) {
299                 if (!arrayElements[i].hasValue()) {
300                     return false;
301                 }
302             }
303             return true;
304         }
305         
306         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
307             int size = arrayElements.length;
308             for (int i = 0; i < size; i++) {
309                 if (!arrayElements[i].hasValue()) {
310                     exclude.push(arrayElements[i]);
311                     boolean isOK = arrayElements[i].checkValue(exclude);
312                     exclude.pop();
313                     if (!isOK) {
314                         return false;
315                     }
316                 }
317             }
318             return true;
319         }
320     }
321     
322     /* ************************************************************************************/
323     //inner class for a runtime descriptor of a class source
324

325     private static class RTClassSource extends RtComponentProvider {
326         private Class JavaDoc support;
327         private boolean gotAValue;
328         
329         RTClassSource(ClassSource aSource, Component aComponent) {
330             super(aSource, aComponent, null);
331         }
332             
333         String JavaDoc getClassName() {
334             return ((ClassSource) getElementDescription()).getClassName();
335         }
336                 
337         public Object JavaDoc specificGetValue() throws KilimException {
338             if (mappingContext != null) {
339                 mappingContext.getCallStack().push(this);
340             }
341             mapper.enterContext(mappingContext);
342             
343             Object JavaDoc resultValue = mapper.getClassValue(getClassName(), mappingContext);
344             gotAValue = true;
345             
346             if (mappingContext != null) {
347                 mappingContext.getCallStack().pop();
348             }
349             mapper.leaveContext(mappingContext);
350             return resultValue;
351         }
352         
353         public void addInterfaceListener(RtCollectionPort aInterface) throws KilimException { }
354     
355         public void removeInterfaceListener(RtCollectionPort aInterface) throws KilimException { }
356         
357         public void setEventSourceValue(Object JavaDoc aValue) throws KilimException { }
358         
359         /**
360          * @see org.objectweb.kilim.model.ComponentSource#checkValue()
361          */

362         public boolean hasValue() {
363             return gotAValue;
364         }
365         
366         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
367             return true;
368         }
369     }
370     
371     /* ************************************************************************************/
372     //inner class for a runtime descriptor of an event source.
373

374     private static class RTEventSource extends RtComponentElement implements RuntimeSource {
375         private Object JavaDoc target;
376         private boolean gotAValue;
377     
378         RTEventSource() {
379             super(null, null);
380         }
381         
382         /**
383         * @see org.objectweb.kilim.model.ComponentElement#getLocalName()
384         */

385         public String JavaDoc getLocalName() {
386             return null;
387         }
388     
389         public void setEventSourceValue(Object JavaDoc aTarget) {
390             target = aTarget;
391             gotAValue = true;
392         }
393         
394         public boolean isEventSource() {
395             return true;
396         }
397         
398         public Object JavaDoc getEventSourceValue() throws KilimException {
399             return target;
400         }
401             
402         public Object JavaDoc getValue() throws KilimException {
403             return getEventSourceValue();
404         }
405         
406         public void addInterfaceListener(RtCollectionPort aInterface) throws KilimException { }
407     
408         public void removeInterfaceListener(RtCollectionPort aInterface) throws KilimException { }
409         
410         public boolean hasValue() {
411             return gotAValue;
412         }
413         
414         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
415             return true;
416         }
417     }
418     
419     /* ************************************************************************************/
420     //inner class for a runtime descriptor of a null element
421

422     private static class RTNullElement extends RtComponentProvider implements RuntimeAction {
423             
424         RTNullElement(NullElement aNullElement, Component aComponent) {
425             super(aNullElement, aComponent, null);
426         }
427             
428         public Object JavaDoc specificGetValue() throws KilimException {
429             if (mappingContext != null) {
430                 mappingContext.getCallStack().push(this);
431             }
432             mapper.enterContext(mappingContext);
433             mapper.getNullElementValue(mappingContext);
434             if (mappingContext != null) {
435                 mappingContext.getCallStack().pop();
436             }
437             mapper.leaveContext(mappingContext);
438             return null;
439         }
440
441         public void execute() throws KilimException {
442             mapper.executeNullElement(mappingContext);
443         }
444         
445         public boolean hasValue() {
446             return true;
447         }
448         
449         public boolean checkAction(Stack JavaDoc aStack) {
450             return true;
451         }
452         
453         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
454             return true;
455         }
456     }
457     
458     /* ************************************************************************************/
459     //inner class for a runtime descriptor of a method
460

461     private static class RTMethod extends RtComponentProvider implements RuntimeAction {
462         private RuntimeSource[] parameters;
463         private String JavaDoc[] typeNames;
464
465         RTMethod(TpMethod aMethod, Component aComponent, RuntimeSource aSupport, RuntimeSource[] params, String JavaDoc[] tpNames) {
466             super(aMethod, aComponent, aSupport);
467             parameters = params;
468             typeNames = tpNames;
469         }
470                 
471         boolean isStatic() {
472             return ((TpMethod) getElementDescription()).isStatic();
473         }
474         
475         String JavaDoc getMethodName() {
476             return ((TpMethod) getElementDescription()).getMethodName();
477         }
478         
479         private Object JavaDoc perform(boolean provides) throws KilimException {
480             Object JavaDoc eventSrcValue = getEventSourceValue();
481             //specific part of getValue
482
RuntimeSource support = (RuntimeSource) getSupport();
483
484             Object JavaDoc resultValue = null;
485             if (mappingContext != null) {
486                 mappingContext.getCallStack().push(this);
487             }
488             mapper.enterContext(mappingContext);
489             
490             callStack.push(this);
491             
492             Object JavaDoc suppObject = null;
493             if (support instanceof RTEventSource) {
494                 suppObject = eventSrcValue;
495             } else {
496                 //recursive transmission of the event source ...
497
support.setEventSourceValue(eventSrcValue);
498                 suppObject = support.getValue();
499             }
500             
501             //this test does not work with a null mapper..
502
//if (suppObject == null) {
503
// throw new KilimException("attempt to invoke a method " + getMethodName() + " with a null support " + ((RTMethod) support.getTarget()).getMethodName());
504
//}
505

506             RtSingleValuePort svp = getCurrentSVP();
507             //If the method is performed for obtaining the value of a single value port, this value may have been obtained
508
//as a result of an evaluation cycle...
509
if (provides && svp != null && svp.hasValue()) {
510                 callStack.pop();
511                 List JavaDoc iter = svp.getTriggerList(Trigger.BIND);
512                 if (iter != KILIM.EMPTY_LIST) {
513                     System.err.println("warning : execution of transformers associated to the port " + svp.getQualifiedName() + " may not follow the tree order : " + svpStack.toString());
514                 }
515                 return svp.getBufferedValue();
516             }
517             
518             int paramNumber = parameters.length;
519             Object JavaDoc[] paramObjects = new Object JavaDoc[paramNumber];
520
521             for (int i = 0; i < paramNumber; i++) {
522                 //If the method is performed for obtaining the value of a single value port, this value may have
523
//been obtained as a result of an evaluation cycle...
524
if (provides && svp != null && svp.hasValue()) {
525                     callStack.pop();
526                     List JavaDoc iter = svp.getTriggerList(Trigger.BIND);
527                     if (iter != KILIM.EMPTY_LIST) {
528                         System.err.println("warning : execution of transformers associated to the port " + svp.getQualifiedName() + " may not follow the tree order : " + svpStack.toString());
529                     }
530                     return svp.getBufferedValue();
531                 }
532                 paramObjects[i] = null;
533                 if (parameters[i] != null) {
534                     if (parameters[i] instanceof RTEventSource) {
535                         paramObjects[i] = eventSrcValue;
536                     } else {
537                         //recursive transmission of the event source ...
538
parameters[i].setEventSourceValue(eventSrcValue);
539                         paramObjects[i] = parameters[i].getValue();
540                     }
541                 }
542             }
543
544             //call to the mapper that performs the real task ....
545
if (provides) {
546                 if (svp != null && svp.hasValue()) {
547                     callStack.pop();
548                     List JavaDoc iter = svp.getTriggerList(Trigger.BIND);
549                     if (iter != KILIM.EMPTY_LIST) {
550                         System.err.println("warning : execution of transformers associated to the port " + svp.getQualifiedName() + " may not follow the tree order : " + svpStack.toString());
551                     }
552                     return svp.getBufferedValue();
553                 } else {
554                     resultValue = mapper.getMethodValue(suppObject, isStatic(), getMethodName(), paramObjects, typeNames, mappingContext);
555                 }
556             } else {
557                 mapper.executeMethod(suppObject, isStatic(), getMethodName(), paramObjects, typeNames, mappingContext);
558             }
559             callStack.pop();
560             if (mappingContext != null) {
561                 mappingContext.getCallStack().pop();
562             }
563             mapper.leaveContext(mappingContext);
564
565             return resultValue;
566         }
567         
568         /**
569          * @see org.objectweb.kilim.model.RtComponentInterface#specificGetValue()
570          */

571         public Object JavaDoc specificGetValue() throws KilimException {
572             Object JavaDoc resultValue = perform(true);
573             return resultValue;
574         }
575     
576         /**
577          * @see org.objectweb.kilim.model.RuntimeAction#execute()
578          */

579         public void execute() throws KilimException {
580             perform(false);
581         }
582         
583         /**
584          * @see org.objectweb.kilim.model.ComponentSource#checkValue()
585          */

586         public boolean hasValue() throws KilimException {
587             if (!getSupport().hasValue()) {
588                 return false;
589             }
590             
591             int paramNumber = parameters.length;
592             for (int i = 0; i < paramNumber; i++) {
593                 if (!parameters[i].hasValue()) {
594                     return false;
595                 }
596             }
597             return true;
598         }
599         
600         /**
601          * @see org.objectweb.kilim.model.ComponentSource#checkValue()
602          */

603         public boolean checkValue(Stack JavaDoc exclude) throws KilimException {
604             if (exclude == null) {
605                 return true;
606             }
607             
608             int eSize = exclude.size();
609             
610             RuntimeSource lSupport = (RuntimeSource) getSupport().getTarget();
611             if (!lSupport.hasValue()) {
612                 for (int i = 0; i < eSize; i++) {
613                     if (lSupport == exclude.get(i)) {
614                         return false;
615                     }
616                 }
617                 
618                 exclude.push(lSupport);
619                 boolean isOK = lSupport.checkValue(exclude);
620                 exclude.pop();
621                 if (!isOK) {
622                     return false;
623                 }
624             }
625             
626             int paramNumber = parameters.length;
627             
628             for (int i = 0; i < paramNumber; i++) {
629                 RuntimeSource parm = (RuntimeSource) parameters[i].getTarget();
630                 if (parm.hasValue()) {
631                     continue;
632                 }
633                 
634                 for (int j = 0; j < eSize; j++) {
635                     if (parm == exclude.get(j)) {
636                         return false;
637                     }
638                 }
639                 
640                 exclude.push(this);
641                 boolean isOK = parm.checkValue(exclude);
642                 exclude.pop();
643                 
644                 if (!isOK) {
645                     return false;
646                 }
647             }
648             return true;
649         }
650
651         /**
652          * @see org.objectweb.kilim.model.RuntimeAction#checkAction()
653          */

654         public boolean checkAction(Stack JavaDoc aStack) throws KilimException {
655             RuntimeSource lSupport = (RuntimeSource) getSupport().getTarget();
656             if (aStack == null) {
657                 return true;
658             }
659             
660             if (!lSupport.checkValue(aStack)) {
661                 return false;
662             }
663             
664             int stackSize = aStack.size();
665             int paramNumber = parameters.length;
666             for (int i = 0; i < paramNumber; i++) {
667                 RuntimeSource parm = (RuntimeSource) parameters[i].getTarget();
668                 if (!parm.checkValue(aStack)) {
669                     return false;
670                 }
671             }
672             return true;
673         }
674     }
675     
676     /* ************************************************************************************/
677     //inner class for a runtime descriptor of a constructor
678

679     private static class RTConstructor extends RtComponentProvider implements RuntimeAction {
680         private RuntimeSource[] parameters;
681         private String JavaDoc[] typeNames;
682
683         RTConstructor(TpConstructor aCtor, Component aComponent, RuntimeSource aSupport, RuntimeSource[] params, String JavaDoc[] tNames) {
684             super(aCtor, aComponent, aSupport);
685             parameters = params;
686             typeNames = tNames;
687         }
688                 
689         public Object JavaDoc specificGetValue() throws KilimException {
690             Object JavaDoc resultValue = perform(true);
691             return resultValue;
692         }
693             
694         private Object JavaDoc perform(boolean provides) throws KilimException {
695             if (mappingContext != null) {
696                 mappingContext.getCallStack().push(this);
697             }
698             mapper.enterContext(mappingContext);
699                         
700             callStack.push(this);
701                         
702             Object JavaDoc eventSrcValue = getEventSourceValue();
703             RuntimeSource support = (RuntimeSource) getSupport();
7