Source Code Cross Referenced for ComponentInfo.java in  » Ajax » zk » org » zkoss » zk » ui » metainfo » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        /* ComponentInfo.java
002:
003:        {{IS_NOTE
004:        	Purpose:
005:        		
006:        	Description:
007:        		
008:        	History:
009:        		Tue May 31 11:27:13     2005, Created by tomyeh
010:        }}IS_NOTE
011:
012:        Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014:        {{IS_RIGHT
015:        	This program is distributed under GPL Version 2.0 in the hope that
016:        	it will be useful, but WITHOUT ANY WARRANTY.
017:        }}IS_RIGHT
018:         */
019:        package org.zkoss.zk.ui.metainfo;
020:
021:        import java.util.Map;
022:        import java.util.HashMap;
023:        import java.util.List;
024:        import java.util.LinkedList;
025:        import java.util.Iterator;
026:        import java.util.Set;
027:        import java.util.Collection;
028:        import java.util.Collections;
029:
030:        import org.zkoss.lang.D;
031:        import org.zkoss.lang.Strings;
032:        import org.zkoss.lang.Classes;
033:        import org.zkoss.util.CollectionsX;
034:
035:        import org.zkoss.zk.ui.Page;
036:        import org.zkoss.zk.ui.Component;
037:        import org.zkoss.zk.ui.Executions;
038:        import org.zkoss.zk.ui.UiException;
039:        import org.zkoss.zk.ui.ext.DynamicTag;
040:        import org.zkoss.zk.ui.event.Events;
041:        import org.zkoss.zk.ui.sys.ComponentCtrl;
042:        import org.zkoss.zk.ui.sys.ComponentsCtrl;
043:        import org.zkoss.zk.ui.util.Composer;
044:        import org.zkoss.zk.ui.util.Condition;
045:        import org.zkoss.zk.ui.util.ConditionImpl;
046:        import org.zkoss.zk.ui.util.ForEach;
047:        import org.zkoss.zk.ui.util.ForEachImpl;
048:        import org.zkoss.zk.ui.metainfo.impl.MultiComposer;
049:        import org.zkoss.zk.xel.ExValue;
050:        import org.zkoss.zk.xel.impl.EvaluatorRef;
051:
052:        /**
053:         * Represents a componennt instance defined in a ZUML page.
054:         *
055:         * <p>Though serializable, we can restore {@link #getPageDefinition}
056:         * correctly after deserialized.
057:         *
058:         * <p>Note:it is not thread-safe.
059:         *
060:         * <p>It is serializable.
061:         *
062:         * @author tomyeh
063:         */
064:        public class ComponentInfo extends NodeInfo implements  Cloneable,
065:                Condition, java.io.Externalizable {
066:            /** Note: it is NodeInfo's job to serialize _evalr. */
067:            private transient EvaluatorRef _evalr;
068:            private transient NodeInfo _parent; //it is restored by its parent
069:            private transient ComponentDefinition _compdef;
070:            /** The implemetation class (use). */
071:            private ExValue _implcls;
072:            /** A list of {@link Property}, or null if no property at all. */
073:            private List _props;
074:            /** A Map of event handler to handle events. */
075:            private EventHandlerMap _evthds;
076:            /** the annotation map. Note: it doesn't include what are defined in _compdef. */
077:            private AnnotationMap _annots;
078:            /** The tag name for the dyanmic tag. Used only if this implements {@link DynamicTag}*/
079:            private String _tag;
080:            /** The effectiveness condition (see {@link #isEffective}).
081:             * If null, it means effective.
082:             */
083:            private ConditionImpl _cond;
084:            /** The fulfill condition.
085:             */
086:            private String _fulfill;
087:            /** The apply attribute.
088:             */
089:            private ExValue _apply;
090:            /** The forward condition.
091:             */
092:            private String _forward;
093:            /** The forEach, forEachBegin and forEachEnd attribute,
094:             * which are used to evaluate this info multiple times.
095:             */
096:            private String[] _forEach;
097:
098:            /** Constructs the information about how to create component.
099:             * @param parent the parent; never null.
100:             * @param compdef the component definition; never null
101:             * @param tag the tag name; Note: if component implements
102:             * {@link DynamicTag}, this argument must be specified.
103:             * If {@link DynamicTag} is not implemented, this argument must
104:             * be null.
105:             */
106:            public ComponentInfo(NodeInfo parent, ComponentDefinition compdef,
107:                    String tag) {
108:                if (parent == null || compdef == null)
109:                    throw new IllegalArgumentException(
110:                            "parent and compdef required");
111:
112:                _parent = parent;
113:                _compdef = compdef;
114:                _tag = tag;
115:                _parent.appendChildDirectly(this );
116:                _evalr = parent.getEvaluatorRef();
117:            }
118:
119:            /** Constructs the info about how to create a component that is not
120:             * a dynamic tag.
121:             * @param parent the parent; never null.
122:             */
123:            public ComponentInfo(NodeInfo parent, ComponentDefinition compdef) {
124:                this (parent, compdef, null);
125:            }
126:
127:            /** This constructor is used only for {@link java.io.Externalizable}.
128:             * Don't call it, otherwise.
129:             * @since 3.0.0
130:             */
131:            public ComponentInfo() {
132:            }
133:
134:            /** Returns the language definition that {@link #getComponentDefinition}
135:             * belongs to, or null if the component definition is temporary.
136:             */
137:            public LanguageDefinition getLanguageDefinition() {
138:                return _compdef.getLanguageDefinition();
139:            }
140:
141:            /** Returns the component definition, or null if it is PageDefinition.
142:             */
143:            public ComponentDefinition getComponentDefinition() {
144:                return _compdef;
145:            }
146:
147:            /** Returns the tag name, or null if no tag name.
148:             * @since 3.0.0
149:             */
150:            public String getTag() {
151:                return _tag;
152:            }
153:
154:            /** Sets the parent.
155:             */
156:            public void setParent(NodeInfo parent) {
157:                //we don't check if parent is changed (since we have to move it
158:                //to the end)
159:                if (_parent != null)
160:                    _parent.removeChildDirectly(this );
161:
162:                _parent = parent;
163:
164:                if (_parent != null)
165:                    _parent.appendChildDirectly(this );
166:            }
167:
168:            /** Used for implementation only. */
169:            /*package*/void setParentDirectly(NodeInfo parent) {
170:                _parent = parent;
171:            }
172:
173:            /** Returns the property name to which the text enclosed within
174:             * the element (associated with this component definition) is assigned to.
175:             *
176:             * <p>Default: null (means to create a Label component as the child)
177:             *
178:             * @see ComponentDefinition#getTextAs
179:             * @since 3.0.0
180:             */
181:            public String getTextAs() {
182:                return _compdef.getTextAs();
183:            }
184:
185:            /** Returns the fulfill condition that controls when to create
186:             * the child components, or null if the child components
187:             * are created at the time when the page is loaded.
188:             *
189:             * <p>Default: null.
190:             *
191:             * <p>There are several forms:<br/>
192:             * "eventName", "targetId.evetName", "id1/id2.evetName",
193:             * and "${elExpr}.eventName".
194:             * <p>Since 3.0.2, you can specify a list of fulfill conditions by
195:             * separating them with comma. For example:<br/>
196:             * "id1.event1, id2/id3.event2"
197:             *
198:             * <p>If not null, the child components specified in
199:             * {@link #getChildren} are created, when the event sepcified in
200:             * the fulfill condition is received at the first time.
201:             *
202:             * <p>It is the value specified in the fulfill attribute.
203:             *
204:             * @since 2.4.0
205:             */
206:            public String getFulfill() {
207:                return _fulfill;
208:            }
209:
210:            /** Sets the fulfill condition that controls when to create
211:             * the child components.
212:             *
213:             * <p>If not null, the child components specified in
214:             * {@link #getChildren} are created, when the event sepcified in
215:             * the fulfill condition is received at the first time.
216:             *
217:             * @param fulfill the fulfill condition. There are several forms:<br/>
218:             * "eventName", "targetId.evetName", "id1/id2.evetName",
219:             * and "${elExpr}.eventName".
220:             * <p>Since 3.0.2, you can specify a list of fulfill conditions by
221:             * separating them with comma. For example:<br/>
222:             * "id1.event1, id2/id3.event2"
223:             * @since 2.4.0
224:             */
225:            public void setFulfill(String fulfill) {
226:                _fulfill = fulfill != null && fulfill.length() > 0 ? fulfill
227:                        : null;
228:            }
229:
230:            /** Returns the composer for this info, or null if not available.
231:             * It evaluates the value returned by {@link #getApply}.
232:             *
233:             * @see #getApply
234:             * @since 3.0.0
235:             */
236:            public Composer getComposer(Page page) {
237:                return getComposer(page, null);
238:            }
239:
240:            /** Returns the composer for this info, or nuull if not available.
241:             *
242:             * @param comp the component used as the self variable to resolve
243:             * EL expressions, if any.
244:             * Notice that UI engine uses the parent component for this argument.
245:             * If comp is null, it is the same as {@link #getComposer(Page)}.
246:             * If comp is not null, it is used as the self variable.
247:             * @see #getApply
248:             * @since 3.0.1
249:             */
250:            public Composer getComposer(Page page, Component comp) {
251:                if (_apply != null) {
252:                    Object o = comp != null ? _apply.getValue(_evalr
253:                            .getEvaluator(), comp) : _apply.getValue(_evalr
254:                            .getEvaluator(), page);
255:                    ;
256:                    try {
257:                        if (o instanceof  String) {
258:                            final String s = (String) o;
259:                            if (s.indexOf(',') >= 0)
260:                                o = CollectionsX.parse(null, s, ',');
261:                        }
262:
263:                        if (o instanceof  Collection) {
264:                            final Collection c = (Collection) o;
265:                            int sz = c.size();
266:                            switch (sz) {
267:                            case 0:
268:                                return null;
269:                            case 1:
270:                                o = c.iterator().next();
271:                                break;
272:                            default:
273:                                o = c.toArray(new Object[sz]);
274:                                break;
275:                            }
276:                        }
277:
278:                        if (o instanceof  Object[])
279:                            return MultiComposer
280:                                    .getComposer(page, (Object[]) o);
281:
282:                        if (o instanceof  String) {
283:                            final String clsnm = ((String) o).trim();
284:                            o = page != null ? page.resolveClass(clsnm)
285:                                    .newInstance() : Classes
286:                                    .newInstanceByThread(clsnm);
287:                        } else if (o instanceof  Class)
288:                            o = ((Class) o).newInstance();
289:
290:                        if (o instanceof  Composer)
291:                            return (Composer) o;
292:                    } catch (Exception ex) {
293:                        throw UiException.Aide.wrap(ex);
294:                    }
295:                    if (o != null)
296:                        throw new UiException(Composer.class
297:                                + " not implemented by " + o);
298:                }
299:                return null;
300:            }
301:
302:            /** Returns the apply attribute that is the class that implements
303:             * {@link Composer}, an instance of it or null.
304:             *
305:             * @since 3.0.0
306:             * @see #getComposer
307:             */
308:            public String getApply() {
309:                return _apply != null ? _apply.getRawValue() : null;
310:            }
311:
312:            /** Sets the apply attribute that is used to initialize
313:             * the component.
314:             *
315:             * @param apply the attribute which must be the class that implements
316:             * {@link org.zkoss.zk.ui.util.Composer}, an instance of it, or null.
317:             * El expressions are allowed, but self means the parent, if not null,
318:             * or page, if root, (after all, the component is not created yet).
319:             * @since 3.0.0
320:             */
321:            public void setApply(String apply) {
322:                _apply = apply != null && apply.length() > 0 ? new ExValue(
323:                        apply, Object.class) : null;
324:            }
325:
326:            /** Returns the forward condition that controls how to forward
327:             * an event, that is received by the component created
328:             * by this info, to another component.
329:             *
330:             * <p>Default: null.
331:             *
332:             * <p>If not null, when the component created by this
333:             * info receives the event specified in the forward condition,
334:             * it will forward it to the target component, which is also
335:             * specified in the forward condition.
336:             *
337:             * @since 3.0.0
338:             * @see #setForward
339:             */
340:            public String getForward() {
341:                return _forward;
342:            }
343:
344:            /** Sets the forward condition that controls when to forward
345:             * an event receiving by this component to another component.
346:             *
347:             * <p>The basic format:<br/>
348:             * <code>onEvent1=id1/id2.onEvent2</code>
349:             *
350:             * <p>It means when onEvent1 is received, onEvent2 will be posted
351:             * to the component with the specified path (id1/id2).
352:             *
353:             * <p>If onEvent1 is omitted, it is assumed to be onClick (and
354:             * the equal sign need not to be specified.
355:             * If the path is omitted, it is assumed to be the space owner
356:             * {@link Component#getSpaceOwner}.
357:             *
358:             * <p>For example, "onOK" means "onClick=onOK".
359:             *
360:             * <p>You can specify several forward conditions by separating
361:             * them with comma as follows:
362:             *
363:             * <p><code>onChanging=onChanging,onChange=onUpdate,onOK</code>
364:             *
365:             * @param forward the forward condition. There are several forms:
366:             * "onEvent1", "target.onEvent1" and "onEvent1(target.onEvent2)",
367:             * where target could be "id", "id1/id2" or "${elExpr}".
368:             * The EL expression must return either a path or a reference to
369:             * a component.
370:             * @since 3.0.0
371:             */
372:            public void setForward(String forward) {
373:                _forward = forward != null && forward.length() > 0 ? forward
374:                        : null;
375:            }
376:
377:            /** Returns a readonly list of properties ({@link Property}) (never null).
378:             * @since 2.4.0
379:             */
380:            public List getProperties() {
381:                return _props != null ? _props : Collections.EMPTY_LIST;
382:                //it is better to protect with Collections.unmodifiableList
383:                //but for better performance...
384:            }
385:
386:            /** Adds a property initializer.
387:             * It will initialize a component when created with this info.
388:             * @param name the member name. The component must have a valid setter
389:             * for it.
390:             * @param value the value. It might contain expressions (${}).
391:             */
392:            public void addProperty(String name, String value,
393:                    ConditionImpl cond) {
394:                if (name == null || name.length() == 0)
395:                    throw new IllegalArgumentException("name");
396:
397:                if (_props == null)
398:                    _props = new LinkedList();
399:                _props.add(new Property(_evalr, name, value, cond));
400:            }
401:
402:            /** Adds an event handler.
403:             *
404:             * @param name the event name.
405:             * @param zscript the script.
406:             */
407:            public void addEventHandler(String name, ZScript zscript,
408:                    ConditionImpl cond) {
409:                if (name == null || zscript == null)
410:                    throw new IllegalArgumentException(
411:                            "name and zscript cannot be null");
412:                //if (!Events.isValid(name))
413:                //	throw new IllegalArgumentException("Invalid event name: "+name);
414:                //AbstractParser has checked it, so no need to check again
415:
416:                final EventHandler evthd = new EventHandler(_evalr, zscript,
417:                        cond);
418:                if (_evthds == null)
419:                    _evthds = new EventHandlerMap();
420:                _evthds.add(name, evthd);
421:            }
422:
423:            /** Returns a readonly collection of event names (String),
424:             * or an empty collection if no event name is registered.
425:             *
426:             * <p>To add an event handler, use {@link #addEventHandler} instead.
427:             *
428:             * @since 3.0.2
429:             */
430:            public Set getEventHandlerNames() {
431:                return _evthds != null ? _evthds.getEventNames()
432:                        : Collections.EMPTY_SET;
433:            }
434:
435:            /** Sets the effectiveness condition.
436:             */
437:            public void setCondition(ConditionImpl cond) {
438:                _cond = cond;
439:            }
440:
441:            /** Returns the forEach object if the forEach attribute is defined
442:             * (or {@link #setForEach} is called).
443:             *
444:             * <p>If comp is not null, both pagedef and page are ignored.
445:             * If comp is null, page must be specified.
446:             *
447:             * @param page the page. It is used only if comp is null.
448:             * @param comp the component.
449:             * @return the forEach object to iterate this info multiple times,
450:             * or null if this info shall be interpreted only once.
451:             */
452:            public ForEach getForEach(Page page, Component comp) {
453:                return _forEach == null ? null : comp != null ? ForEachImpl
454:                        .getInstance(_evalr, comp, _forEach[0], _forEach[1],
455:                                _forEach[2]) : ForEachImpl.getInstance(_evalr,
456:                        page, _forEach[0], _forEach[1], _forEach[2]);
457:            }
458:
459:            /** Sets the forEach attribute, which is usually an expression.
460:             * @param expr the expression to return a collection of objects, or
461:             * null/empty to denote no iteration.
462:             */
463:            public void setForEach(String expr, String begin, String end) {
464:                _forEach = expr != null && expr.length() > 0 ? new String[] {
465:                        expr, begin, end } : null;
466:            }
467:
468:            /** Returns whether the forEach condition is defined.
469:             * @since 3.0.0
470:             */
471:            public boolean withForEach() {
472:                return _forEach != null;
473:            }
474:
475:            /** Returns the class name (String) that implements the component.
476:             */
477:            public String getImplementationClass() {
478:                return _implcls != null ? _implcls.getRawValue() : null;
479:            }
480:
481:            /** Sets the class name to implements the component.
482:             */
483:            public void setImplementationClass(String clsnm) {
484:                _implcls = clsnm != null && clsnm.length() > 0 ? new ExValue(
485:                        clsnm, Object.class) : null;
486:            }
487:
488:            /** Creates an component based on this info (never null).
489:             *
490:             * <p>Like {@link ComponentDefinition#newInstance},
491:             * this method doesn't invoke {@link #applyProperties}.
492:             * It is caller's job to invoke them if necessary.
493:             * Since the value of properties might depend on the component tree,
494:             * it is better to assign the component with a proper parent
495:             * before calling {@link #applyProperties}.
496:             *
497:             * @since 3.0.2
498:             */
499:            public Component newInstance(Page page, Component parent) {
500:                Object implcls = evalImplClass(page, parent);
501:                ComponentsCtrl.setCurrentInfo(this );
502:                final Component comp;
503:                try {
504:                    comp = implcls instanceof  Class ? _compdef
505:                            .newInstance((Class) implcls) : _compdef
506:                            .newInstance(page, (String) implcls);
507:                } catch (Exception ex) {
508:                    throw UiException.Aide.wrap(ex);
509:                } finally {
510:                    ComponentsCtrl.setCurrentInfo((ComponentInfo) null);
511:                }
512:                if (comp instanceof  DynamicTag)
513:                    ((DynamicTag) comp).setTag(_tag);
514:                return comp;
515:            }
516:
517:            /** Evaluates the implementation claas, and rerturn either a class (Class),
518:             * a class name (String), or null.
519:             */
520:            private Object evalImplClass(Page page, Component parent) {
521:                return _implcls == null ? null : parent != null ? _implcls
522:                        .getValue(_evalr.getEvaluator(), parent) : _implcls
523:                        .getValue(_evalr.getEvaluator(), page);
524:            }
525:
526:            /** Creates an component based on this info (never null).
527:             * It is the same as newInstance(page, null).
528:             *
529:             * <p>If the implementation class ({@link #getImplementationClass})
530:             * doesn't have any EL expression, or its EL expresson doesn't
531:             * referece to the self variable, the result is the same.
532:             *
533:             * <p>This method is preserved for backward compatibility.
534:             * It is better to use {@link #newInstance(Page, Component)}.
535:             */
536:            public Component newInstance(Page page) {
537:                return newInstance(page, null);
538:            }
539:
540:            /** Resolves and returns the class for the component represented
541:             * by this info (never null).
542:             *
543:             * <p>Unlike {@link #getImplementationClass},
544:             * this method will resolve a class name (String) to a class (Class),
545:             * if necessary.
546:             *
547:             * @param page the page to check whether the class is defined
548:             * in its interpreters. Ignored if null.
549:             * This method will search the class loader of the current thread.
550:             * If not found, it will search the interpreters of the specifed
551:             * page ({@link Page#getLoadedInterpreters}).
552:             * Note: this method won't attach the component to the specified page.
553:             * @exception ClassNotFoundException if the class not found
554:             * @since 3.0.2
555:             */
556:            public Class resolveImplementationClass(Page page, Component parent)
557:                    throws ClassNotFoundException {
558:                Object implcls = evalImplClass(page, parent);
559:                return implcls instanceof  Class ? (Class) implcls : _compdef
560:                        .resolveImplementationClass(page, (String) implcls);
561:            }
562:
563:            /** Resolves and returns the class for the component represented
564:             * by this info (never null).
565:             * It is the same as resolveImplementationClass(page, null).
566:             *
567:             * <p>If the implementation class ({@link #getImplementationClass})
568:             * doesn't have any EL expression, or its EL expresson doesn't
569:             * referece to the self variable, the result is the same.
570:             *
571:             * <p>This method is preserved for backward compatibility.
572:             * It is better to use {@link #resolveImplementationClass(Page, Component)}.
573:             * @since 3.0.0
574:             */
575:            public Class resolveImplementationClass(Page page)
576:                    throws ClassNotFoundException {
577:                return resolveImplementationClass(page, null);
578:            }
579:
580:            /** Returns the annotation map defined in this info, or null
581:             * if no annotation is ever defined.
582:             */
583:            public AnnotationMap getAnnotationMap() {
584:                return _annots;
585:            }
586:
587:            /** Applies the event handlers, annotations, properties and
588:             * custom attributes to the specified component.
589:             *
590:             * <p>It also invokes {@link ComponentDefinition#applyProperties}.
591:             *
592:             * @since 3.0.0
593:             */
594:            public void applyProperties(Component comp) {
595:                _compdef.applyProperties(comp);
596:
597:                if (_evthds != null)
598:                    ((ComponentCtrl) comp).addSharedEventHandlerMap(_evthds);
599:
600:                if (_props != null) {
601:                    for (Iterator it = _props.iterator(); it.hasNext();) {
602:                        final Property prop = (Property) it.next();
603:                        prop.assign(comp);
604:                    }
605:                }
606:            }
607:
608:            /** Evaluates and retrieves properties to the specified map from
609:             * {@link ComponentDefinition} (and {@link ComponentInfo}).
610:             *
611:             * @param propmap the map to store the retrieved properties
612:             * (String name, Object value).
613:             * If null, a HashMap instance is created.
614:             * @param owner the owner page; used if parent is null
615:             * @param parent the parent component (may be null)
616:             * @param defIncluded whether to call {@link ComponentDefinition#evalProperties}.
617:             */
618:            public Map evalProperties(Map propmap, Page owner,
619:                    Component parent, boolean defIncluded) {
620:                if (defIncluded)
621:                    propmap = _compdef.evalProperties(propmap, owner, parent);
622:                else if (propmap == null)
623:                    propmap = new HashMap();
624:
625:                if (_props != null) {
626:                    for (Iterator it = _props.iterator(); it.hasNext();) {
627:                        final Property prop = (Property) it.next();
628:                        if (parent != null) {
629:                            if (prop.isEffective(parent))
630:                                propmap.put(prop.getName(), prop
631:                                        .getValue(parent));
632:                        } else {
633:                            if (prop.isEffective(owner))
634:                                propmap.put(prop.getName(), prop
635:                                        .getValue(owner));
636:                        }
637:                    }
638:                }
639:                return propmap;
640:            }
641:
642:            /** Associates an annotation to this component info.
643:             *
644:             * @param annotName the annotation name (never null, nor empty).
645:             * @param annotAttrs a map of attributes, or null if no attribute at all.
646:             * The attribute must be in a pair of strings (String name, String value).
647:             */
648:            public void addAnnotation(String annotName, Map annotAttrs) {
649:                if (_annots == null)
650:                    _annots = new AnnotationMap();
651:                _annots.addAnnotation(annotName, annotAttrs);
652:            }
653:
654:            /** Adds an annotation to the specified proeprty of this component
655:             * info.
656:             *
657:             * @param propName the property name (never nul, nor empty).
658:             * @param annotName the annotation name (never null, nor empty).
659:             * @param annotAttrs a map of attributes, or null if no attribute at all.
660:             * The attribute must be in a pair of strings (String name, String value).
661:             */
662:            public void addAnnotation(String propName, String annotName,
663:                    Map annotAttrs) {
664:                if (_annots == null)
665:                    _annots = new AnnotationMap();
666:                _annots.addAnnotation(propName, annotName, annotAttrs);
667:            }
668:
669:            //Condition//
670:            public boolean isEffective(Component comp) {
671:                return _cond == null || _cond.isEffective(_evalr, comp);
672:            }
673:
674:            public boolean isEffective(Page page) {
675:                return _cond == null || _cond.isEffective(_evalr, page);
676:            }
677:
678:            //NodeInfo//
679:            public PageDefinition getPageDefinition() {
680:                return _evalr.getPageDefinition();
681:            }
682:
683:            public NodeInfo getParent() {
684:                return _parent;
685:            }
686:
687:            protected EvaluatorRef getEvaluatorRef() {
688:                return _evalr;
689:            }
690:
691:            //Cloneable//
692:            /** Clones this info.
693:             * After cloned, {@link #getParent} is null.
694:             */
695:            public Object clone() {
696:                try {
697:                    final ComponentInfo info = (ComponentInfo) super .clone();
698:                    info._parent = null;
699:                    if (_annots != null)
700:                        info._annots = (AnnotationMap) _annots.clone();
701:                    if (_props != null)
702:                        info._props = new LinkedList(_props);
703:                    if (_evthds != null)
704:                        info._evthds = (EventHandlerMap) _evthds.clone();
705:                    return info;
706:                } catch (CloneNotSupportedException ex) {
707:                    throw new InternalError();
708:                }
709:            }
710:
711:            //Object//
712:            public String toString() {
713:                final StringBuffer sb = new StringBuffer(64).append(
714:                        "[ComponentInfo: ").append(_compdef.getName());
715:                if (_tag != null)
716:                    sb.append(" <").append(_tag).append('>');
717:                return sb.append(']').toString();
718:            }
719:
720:            //Externalizable//
721:            public final void writeExternal(java.io.ObjectOutput out)
722:                    throws java.io.IOException {
723:                if (getSerializingEvalRef() != _evalr) {
724:                    pushSerializingEvalRef(_evalr);
725:                    try {
726:                        out.writeObject(_evalr);
727:                        writeMembers(out);
728:                    } finally {
729:                        popSerializingEvalRef();
730:                    }
731:                } else {
732:                    out.writeObject(null); //to save space, don't need to write evalr
733:                    writeMembers(out);
734:                }
735:            }
736:
737:            /** Don't override this method. Rather, override {@link #readMembers}.
738:             * @since 3.0.0
739:             */
740:            public final void readExternal(java.io.ObjectInput in)
741:                    throws java.io.IOException, ClassNotFoundException {
742:                _evalr = (EvaluatorRef) in.readObject();
743:                final EvaluatorRef top = getSerializingEvalRef();
744:                if (_evalr == null)
745:                    _evalr = top;
746:
747:                if (_evalr != null && top != _evalr) {
748:                    pushSerializingEvalRef(_evalr);
749:                    try {
750:                        readMembers(in);
751:                    } finally {
752:                        popSerializingEvalRef();
753:                    }
754:                } else {
755:                    readMembers(in);
756:                }
757:            }
758:
759:            private void writeMembers(java.io.ObjectOutput out)
760:                    throws java.io.IOException {
761:                out.writeObject(_children);
762:
763:                final LanguageDefinition langdef = _compdef
764:                        .getLanguageDefinition();
765:                if (langdef != null) {
766:                    out.writeObject(langdef.getName());
767:                    out.writeObject(_compdef.getName());
768:                } else {
769:                    out.writeObject(_compdef);
770:                }
771:
772:                out.writeObject(_implcls);
773:                out.writeObject(_props);
774:                out.writeObject(_evthds);
775:                out.writeObject(_annots);
776:                out.writeObject(_tag);
777:                out.writeObject(_cond);
778:                out.writeObject(_fulfill);
779:                out.writeObject(_apply);
780:                out.writeObject(_forward);
781:                out.writeObject(_forEach);
782:            }
783:
784:            private void readMembers(java.io.ObjectInput in)
785:                    throws java.io.IOException, ClassNotFoundException {
786:                _children = (List) in.readObject();
787:                for (Iterator it = _children.iterator(); it.hasNext();) {
788:                    final Object o = it.next();
789:                    if (o instanceof  ComponentInfo)
790:                        ((ComponentInfo) o).setParentDirectly(this );
791:                }
792:
793:                final Object v = in.readObject();
794:                if (v instanceof  String) {
795:                    final LanguageDefinition langdef = LanguageDefinition
796:                            .lookup((String) v);
797:                    _compdef = langdef.getComponentDefinition((String) in
798:                            .readObject());
799:                } else {
800:                    _compdef = (ComponentDefinition) v;
801:                }
802:
803:                _implcls = (ExValue) in.readObject();
804:                _props = (List) in.readObject();
805:                _evthds = (EventHandlerMap) in.readObject();
806:                _annots = (AnnotationMap) in.readObject();
807:                _tag = (String) in.readObject();
808:                _cond = (ConditionImpl) in.readObject();
809:                _fulfill = (String) in.readObject();
810:                _apply = (ExValue) in.readObject();
811:                _forward = (String) in.readObject();
812:                _forEach = (String[]) in.readObject();
813:            }
814:
815:            /** Writes the evaluator reference.
816:             * It is called by {@link EvalRefStub} to serialize
817:             * the evaluator reference, in order to minimize the number of bytes
818:             * to serialize.
819:             */
820:            /*package*/static final void writeEvalRef(
821:                    java.io.ObjectOutputStream s, EvaluatorRef evalr)
822:                    throws java.io.IOException {
823:                s.writeObject(getSerializingEvalRef() != evalr ? evalr : null);
824:            }
825:
826:            /*package*/static final EvaluatorRef readEvalRef(
827:                    java.io.ObjectInputStream s) throws java.io.IOException,
828:                    ClassNotFoundException {
829:                final EvaluatorRef evalr = (EvaluatorRef) s.readObject();
830:                return evalr != null ? evalr : getSerializingEvalRef();
831:            }
832:
833:            /** Returns the evaluator reference of the info that is being serialized.
834:             * It is used to minimize the bytes to write when serialized.
835:             */
836:            private static final EvaluatorRef getSerializingEvalRef() {
837:                final List stack = (List) _evalRefStack.get();
838:                return stack == null || stack.isEmpty() ? null
839:                        : (EvaluatorRef) stack.get(0);
840:            }
841:
842:            /** Pushes the sepcified evaluator referene to be the current one.
843:             */
844:            private static final void pushSerializingEvalRef(EvaluatorRef evalr) {
845:                List stack = (List) _evalRefStack.get();
846:                if (stack == null)
847:                    _evalRefStack.set(stack = new LinkedList());
848:                stack.add(0, evalr);
849:            }
850:
851:            /** Pops out the current evaluator reference.
852:             */
853:            private static final void popSerializingEvalRef() {
854:                ((List) _evalRefStack.get()).remove(0);
855:            }
856:
857:            private static final ThreadLocal _evalRefStack = new ThreadLocal();
858:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.