Source Code Cross Referenced for AbstractWidget.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » forms » formmodel » 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 » Content Management System » apache lenya 2.0 » org.apache.cocoon.forms.formmodel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.forms.formmodel;
018:
019:        import java.util.ArrayList;
020:        import java.util.HashMap;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.Locale;
024:        import java.util.Map;
025:
026:        import org.apache.cocoon.forms.FormsConstants;
027:        import org.apache.cocoon.forms.event.CreateEvent;
028:        import org.apache.cocoon.forms.event.ValueChangedListenerEnabled;
029:        import org.apache.cocoon.forms.event.WidgetEvent;
030:        import org.apache.cocoon.forms.validation.ValidationErrorAware;
031:        import org.apache.cocoon.forms.validation.WidgetValidator;
032:        import org.apache.cocoon.util.location.Location;
033:        import org.apache.cocoon.xml.AttributesImpl;
034:
035:        import org.xml.sax.ContentHandler;
036:        import org.xml.sax.SAXException;
037:
038:        /**
039:         * Abstract base class for Widget implementations. Provides functionality
040:         * common to many widgets.
041:         *
042:         * @version $Id: AbstractWidget.java 449149 2006-09-23 03:58:05Z crossley $
043:         */
044:        public abstract class AbstractWidget implements  Widget {
045:
046:            /**
047:             * Containing parent-widget to this widget.
048:             * NOTE: avoid directly accessing this member since subclasses can mask this
049:             * property through own implemented getParent()
050:             */
051:            private Widget parent;
052:
053:            /**
054:             * The widget's own state
055:             */
056:            private WidgetState state = WidgetState.ACTIVE;
057:
058:            /**
059:             * Lazy loaded reference to the top-level form.
060:             */
061:            private Form form;
062:
063:            /**
064:             * Validation-rules local to the widget instance
065:             */
066:            private List validators;
067:
068:            /**
069:             * Storage for the widget allocated attributes
070:             */
071:            private Map attributes;
072:
073:            /**
074:             * The result of the last call to {@link #validate()}.
075:             */
076:            protected boolean wasValid = true;
077:
078:            protected AbstractWidget(AbstractWidgetDefinition definition) {
079:                this .state = definition.getState();
080:            }
081:
082:            /**
083:             * Called after widget's environment has been setup,
084:             * to allow for any contextual initalization, such as
085:             * looking up case widgets for union widgets.
086:             */
087:            public void initialize() {
088:                ((AbstractWidgetDefinition) getDefinition())
089:                        .widgetCreated(this );
090:            }
091:
092:            /**
093:             * Gets the id of this widget.
094:             */
095:            public String getId() {
096:                return getDefinition().getId();
097:            }
098:
099:            public String getName() {
100:                return getId();
101:            }
102:
103:            /**
104:             * Concrete subclasses should allow access to their underlaying Definition
105:             * through this method.
106:             *
107:             * If subclasses decide to return <code>null</code> they should also organize
108:             * own implementations of {@link #getId()}, {@link #getLocation()},
109:             * {@link #validate()}, {@link #generateLabel(ContentHandler)} and
110:             * {@link #generateDisplayData(ContentHandler)} to avoid NPE's.
111:             *
112:             * @return the widgetDefinition from which this widget was instantiated.
113:             *        (See {@link org.apache.cocoon.forms.formmodel.WidgetDefinition#createInstance()})
114:             */
115:            public abstract WidgetDefinition getDefinition();
116:
117:            /**
118:             * @return the location-information (file, line and column) where this widget was
119:             * configured.
120:             */
121:            public Location getLocation() {
122:                return getDefinition().getLocation();
123:            }
124:
125:            /**
126:             * @return The parent-widget of this widget.
127:             */
128:            // This method is final in order for other methods in this class to use this.parent
129:            public final Widget getParent() {
130:                return this .parent;
131:            }
132:
133:            /**
134:             * Sets the parent-widget of this widget.
135:             * This is a write-once property.
136:             *
137:             * @param widget the parent-widget of this one.
138:             * @throws IllegalStateException when the parent had already been set.
139:             */
140:            public void setParent(Widget widget) {
141:                if (this .parent != null) {
142:                    throw new IllegalStateException("The parent of widget "
143:                            + getRequestParameterName()
144:                            + " should only be set once.");
145:                }
146:                this .parent = widget;
147:            }
148:
149:            /**
150:             * @return the form where this widget belongs to.
151:             */
152:            public Form getForm() {
153:                if (this .form == null) {
154:                    Widget myParent = getParent();
155:                    if (myParent == null) {
156:                        this .form = (Form) this ;
157:                    } else {
158:                        this .form = myParent.getForm();
159:                    }
160:                }
161:                return this .form;
162:            }
163:
164:            public WidgetState getState() {
165:                return this .state;
166:            }
167:
168:            public void setState(WidgetState state) {
169:                if (state == null) {
170:                    throw new IllegalArgumentException(
171:                            "A widget state cannot be set to null");
172:                }
173:                this .state = state;
174:
175:                // Update the browser
176:                getForm().addWidgetUpdate(this );
177:            }
178:
179:            public WidgetState getCombinedState() {
180:                if (this .parent == null) {
181:                    return this .state;
182:                }
183:                return WidgetState.strictest(this .state, this .parent
184:                        .getCombinedState());
185:            }
186:
187:            // Cached param names, used to speed up execution of the method below while
188:            // still allowing ids to change (e.g. repeater rows when they are reordered).
189:            private String cachedParentParamName;
190:            private String cachedParamName;
191:
192:            /**
193:             * Should be called when a widget's own name has changed, in order to clear
194:             * internal caches used to compute request parameters.
195:             */
196:            protected void widgetNameChanged() {
197:                this .cachedParentParamName = null;
198:                this .cachedParamName = null;
199:            }
200:
201:            public String getFullName() {
202:                return getRequestParameterName();
203:            }
204:
205:            public String getRequestParameterName() {
206:
207:                if (this .parent == null) {
208:                    return getId();
209:                }
210:
211:                String parentParamName = parent.getRequestParameterName();
212:                if (parentParamName.equals(this .cachedParentParamName)) {
213:                    // Parent name hasn't changed, so ours hasn't changed too
214:                    return this .cachedParamName;
215:                }
216:
217:                // Compute our name and cache it
218:                this .cachedParentParamName = parentParamName;
219:                if (this .cachedParentParamName.length() == 0) {
220:                    // the top level form returns an id == ""
221:                    this .cachedParamName = getId();
222:                } else {
223:                    this .cachedParamName = this .cachedParentParamName + "."
224:                            + getId();
225:                }
226:
227:                return this .cachedParamName;
228:            }
229:
230:            public Widget lookupWidget(String path) {
231:
232:                if (path == null || path.length() == 0) {
233:                    return this ;
234:                }
235:
236:                Widget relativeWidget;
237:                String relativePath;
238:                int sepPosition = path.indexOf("" + Widget.PATH_SEPARATOR);
239:
240:                if (sepPosition < 0) {
241:                    //last step
242:                    if (path.startsWith(".."))
243:                        return getParent();
244:                    return getChild(path);
245:                } else if (sepPosition == 0) {
246:                    //absolute path
247:                    relativeWidget = getForm();
248:                    relativePath = path.substring(1);
249:                } else {
250:                    if (path.startsWith(".." + Widget.PATH_SEPARATOR)) {
251:                        relativeWidget = getParent();
252:                        relativePath = path.substring(3);
253:                    } else {
254:                        String childId = path.substring(0, sepPosition);
255:                        relativeWidget = getChild(childId);
256:                        relativePath = path.substring(sepPosition + 1);
257:                    }
258:                }
259:
260:                if (relativeWidget == null) {
261:                    return null;
262:                }
263:
264:                return relativeWidget.lookupWidget(relativePath);
265:            }
266:
267:            /**
268:             * Concrete widgets that contain actual child widgets should override to
269:             * return the actual child-widget.
270:             *
271:             * @param id of the child-widget
272:             * @return <code>null</code> if not overriden.
273:             */
274:            protected Widget getChild(String id) {
275:                return null;
276:            }
277:
278:            public Widget getWidget(String id) {
279:                throw new UnsupportedOperationException(
280:                        "getWidget(id) got deprecated from the API. \n"
281:                                + "Consider using getChild(id) or even lookupWidget(path) instead.");
282:            }
283:
284:            public Object getValue() {
285:                throw new UnsupportedOperationException("Widget " + this 
286:                        + " has no value, at " + getLocation());
287:            }
288:
289:            public void setValue(Object object) {
290:                throw new UnsupportedOperationException("Widget " + this 
291:                        + " has no value, at " + getLocation());
292:            }
293:
294:            public boolean isRequired() {
295:                return false;
296:            }
297:
298:            /**
299:             * {@inheritDoc}
300:             *
301:             * Abstract implementation throws a {@link UnsupportedOperationException}.
302:             * Concrete subclass widgets need to override when supporting event broadcasting.
303:             */
304:            public void broadcastEvent(WidgetEvent event) {
305:                if (event instanceof  CreateEvent) {
306:                    ((AbstractWidgetDefinition) getDefinition())
307:                            .fireCreateEvent((CreateEvent) event);
308:                } else {
309:                    throw new UnsupportedOperationException("Widget "
310:                            + getRequestParameterName()
311:                            + " doesn't handle events.");
312:                }
313:            }
314:
315:            /**
316:             * Add a validator to this widget instance.
317:             *
318:             * @param validator
319:             */
320:            public void addValidator(WidgetValidator validator) {
321:                if (this .validators == null) {
322:                    this .validators = new ArrayList();
323:                }
324:                this .validators.add(validator);
325:            }
326:
327:            /**
328:             * Remove a validator from this widget instance
329:             *
330:             * @param validator
331:             * @return <code>true</code> if the validator was found.
332:             */
333:            public boolean removeValidator(WidgetValidator validator) {
334:                if (this .validators != null) {
335:                    return this .validators.remove(validator);
336:                }
337:                return false;
338:            }
339:
340:            /**
341:             * @see org.apache.cocoon.forms.formmodel.Widget#validate()
342:             */
343:            public boolean validate() {
344:                // Consider widget valid if it is not validating values.
345:                if (!getCombinedState().isValidatingValues()) {
346:                    this .wasValid = true;
347:                    return true;
348:                }
349:
350:                // Test validators from the widget definition
351:                if (!getDefinition().validate(this )) {
352:                    // Failed
353:                    this .wasValid = false;
354:                    return false;
355:                }
356:                // Definition successful, test local validators
357:                if (this .validators != null) {
358:                    Iterator iter = this .validators.iterator();
359:                    while (iter.hasNext()) {
360:                        WidgetValidator validator = (WidgetValidator) iter
361:                                .next();
362:                        if (!validator.validate(this )) {
363:                            this .wasValid = false;
364:                            return false;
365:                        }
366:                    }
367:                }
368:
369:                // Successful validation
370:
371:                if (this  instanceof  ValidationErrorAware) {
372:                    // Clear validation error if any
373:                    ((ValidationErrorAware) this ).setValidationError(null);
374:                }
375:
376:                this .wasValid = true;
377:                return true;
378:            }
379:
380:            /**
381:             * @see org.apache.cocoon.forms.formmodel.Widget#isValid()
382:             */
383:            public boolean isValid() {
384:                return this .wasValid;
385:            }
386:
387:            /**
388:             * {@inheritDoc}
389:             *
390:             * Delegates to the {@link #getDefinition()} to generate the 'label' part of
391:             * the display-data of this widget.
392:             *
393:             * Subclasses should override if the getDefinition can return <code>null</code>
394:             * to avoid NPE's
395:             *
396:             * @param contentHandler
397:             * @throws SAXException
398:             */
399:            public void generateLabel(ContentHandler contentHandler)
400:                    throws SAXException {
401:                if (getCombinedState().isDisplayingValues()) {
402:                    getDefinition()
403:                            .generateDisplayData("label", contentHandler);
404:                }
405:            }
406:
407:            /**
408:             * Generates nested additional content nested inside the main element for this
409:             * widget which is generated by {@link #generateSaxFragment(ContentHandler, Locale)}
410:             *
411:             * The implementation on the AbstractWidget level inserts no additional XML.
412:             * Subclasses need to override to insert widget specific content.
413:             *
414:             * @param contentHandler to send the SAX events to
415:             * @param locale in which context potential content needs to be put.
416:             * @throws SAXException
417:             */
418:            protected void generateItemSaxFragment(
419:                    ContentHandler contentHandler, Locale locale)
420:                    throws SAXException {
421:                // Do nothing
422:            }
423:
424:            /**
425:             * The XML element name used in {@link #generateSaxFragment(ContentHandler, Locale)}
426:             * to produce the wrapping element for all the XML-instance-content of this Widget.
427:             *
428:             * @return the main elementname for this widget's sax-fragment.
429:             */
430:            protected abstract String getXMLElementName();
431:
432:            /**
433:             * The XML attributes used in {@link #generateSaxFragment(ContentHandler, Locale)}
434:             * to be placed on the wrapping element for all the XML-instance-content of this Widget.
435:             *
436:             * This automatically adds @id={@link #getRequestParameterName()} to that element.
437:             * Concrete subclasses should call super.getXMLElementAttributes and possibly
438:             * add additional attributes.
439:             *
440:             * Note: the @id is not added for those widgets who's getId() returns <code>null</code>
441:             * (e.g. top-level container widgets like 'form').  The contract of returning a non-null
442:             * {@link AttributesImpl} is however maintained.
443:             *
444:             * @return the attributes for the main element for this widget's sax-fragment.
445:             */
446:            protected AttributesImpl getXMLElementAttributes() {
447:                AttributesImpl attrs = new AttributesImpl();
448:                // top-level widget-containers like forms might have their id set to ""
449:                // for those the @id should not be included.
450:                if (getId().length() != 0) {
451:                    attrs.addCDATAAttribute("id", getRequestParameterName());
452:                }
453:
454:                // Add the "state" attribute
455:                attrs.addCDATAAttribute("state", getCombinedState().getName());
456:
457:                // Add the "listening" attribute is the value has change listeners
458:                if (this  instanceof  ValueChangedListenerEnabled
459:                        && ((ValueChangedListenerEnabled) this )
460:                                .hasValueChangedListeners()) {
461:                    attrs.addCDATAAttribute("listening", "true");
462:                }
463:                return attrs;
464:            }
465:
466:            /**
467:             * Delegates to the {@link #getDefinition()} of this widget to generate a common
468:             * set of 'display' data. (i.e. help, label, hint,...)
469:             *
470:             * Subclasses should override if the getDefinition can return <code>null</code>
471:             * to avoid NPE's.
472:             *
473:             * @param contentHandler where to send the SAX events to.
474:             * @throws SAXException
475:             *
476:             * @see WidgetDefinition#generateDisplayData(ContentHandler)
477:             */
478:            protected void generateDisplayData(ContentHandler contentHandler)
479:                    throws SAXException {
480:                getDefinition().generateDisplayData(contentHandler);
481:            }
482:
483:            /**
484:             * {@inheritDoc}
485:             *
486:             * This will generate some standard XML consisting of a simple wrapper
487:             * element (name provided by {@link #getXMLElementName()}) with attributes
488:             * (provided by {@link #getXMLElementAttributes()} around anything injected
489:             * in by both {@link #generateDisplayData(ContentHandler)} and
490:             * {@link #generateItemSaxFragment(ContentHandler, Locale)}.
491:             *
492:             * <pre>
493:             * &lt;fi:{@link #getXMLElementName()} {@link #getXMLElementAttributes()} &gt;
494:             *   {@link #generateDisplayData(ContentHandler)} (i.e. help, label, ...)
495:             *
496:             *   {@link #generateItemSaxFragment(ContentHandler, Locale)}
497:             * &lt;/fi:{@link #getXMLElementName()} &gt;
498:             * </pre>
499:             *
500:             * @param contentHandler to send the SAX events to
501:             * @param locale in which context potential content needs to be put.
502:             * @throws SAXException
503:             */
504:            public void generateSaxFragment(ContentHandler contentHandler,
505:                    Locale locale) throws SAXException {
506:
507:                if (getCombinedState().isDisplayingValues()) {
508:                    // FIXME: we may want to strip out completely widgets that aren't updated when in AJAX mode
509:                    String element = this .getXMLElementName();
510:                    AttributesImpl attrs = getXMLElementAttributes();
511:                    contentHandler.startElement(FormsConstants.INSTANCE_NS,
512:                            element, FormsConstants.INSTANCE_PREFIX_COLON
513:                                    + element, attrs);
514:
515:                    generateDisplayData(contentHandler);
516:
517:                    if (locale == null) {
518:                        locale = getForm().getLocale();
519:                    }
520:
521:                    generateItemSaxFragment(contentHandler, locale);
522:
523:                    contentHandler.endElement(FormsConstants.INSTANCE_NS,
524:                            element, FormsConstants.INSTANCE_PREFIX_COLON
525:                                    + element);
526:
527:                } else {
528:                    // Generate a placeholder that can be used later by AJAX updates
529:                    AttributesImpl attrs = new AttributesImpl();
530:                    attrs.addCDATAAttribute("id", getRequestParameterName());
531:                    contentHandler.startElement(FormsConstants.INSTANCE_NS,
532:                            "placeholder", FormsConstants.INSTANCE_PREFIX_COLON
533:                                    + "placeholder", attrs);
534:                    contentHandler.endElement(FormsConstants.INSTANCE_NS,
535:                            "placeholder", FormsConstants.INSTANCE_PREFIX_COLON
536:                                    + "placeholder");
537:                }
538:            }
539:
540:            public Object getAttribute(String name) {
541:                Object result = null;
542:
543:                // First check locally
544:                if (this .attributes != null) {
545:                    result = this .attributes.get(name);
546:                }
547:
548:                // Fall back to the definition's attributes
549:                if (result == null) {
550:                    result = getDefinition().getAttribute(name);
551:                }
552:
553:                return result;
554:            }
555:
556:            public void setAttribute(String name, Object value) {
557:                if (this .attributes == null) {
558:                    this .attributes = new HashMap();
559:                }
560:                this .attributes.put(name, value);
561:            }
562:
563:            public void removeAttribute(String name) {
564:                if (this .attributes != null) {
565:                    this .attributes.remove(name);
566:                }
567:            }
568:
569:            public String toString() {
570:                String className = this .getClass().getName();
571:                int last = className.lastIndexOf('.');
572:                if (last != -1) {
573:                    className = className.substring(last + 1);
574:                }
575:
576:                String name = getRequestParameterName();
577:                return name.length() == 0 ? className : className + " '"
578:                        + getRequestParameterName() + "'";
579:            }
580:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.