KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > formmodel > WidgetDefinitionList


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.formmodel;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.ListIterator JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.cocoon.util.location.Location;
26
27 // TODO: Refine and i18n the exception messages.
28
/**
29  * Helper class for the Definition implementation of widgets containing
30  * other widgets.
31  *
32  * @version $Id: WidgetDefinitionList.java 289538 2005-09-16 13:46:22Z sylvain $
33  */

34 public class WidgetDefinitionList {
35
36     private List JavaDoc widgetDefinitions = new ArrayList JavaDoc();
37     private Map JavaDoc widgetDefinitionsById = new HashMap JavaDoc();
38     private WidgetDefinition containerDefinition;
39     private boolean wasHere;
40     private ListIterator JavaDoc definitionsIt = widgetDefinitions.listIterator();
41
42     /**
43      * @param definition the widget definition to which this container delegate belongs
44      */

45     public WidgetDefinitionList(WidgetDefinition definition) {
46         this.containerDefinition = definition;
47         wasHere = false;
48     }
49     
50     public int size() {
51         return widgetDefinitions.size();
52     }
53
54     public void addWidgetDefinition(WidgetDefinition widgetDefinition) throws DuplicateIdException {
55         String JavaDoc id = widgetDefinition.getId();
56         // Do not add NewDefinition id's hash.
57
if (!(widgetDefinition instanceof NewDefinition)) {
58             if (widgetDefinitionsById.containsKey(id)) {
59                 Location duplicateLocation = widgetDefinition.getLocation();
60                 Location containerLocation = containerDefinition.getLocation();
61                 Location firstLocation = getWidgetDefinition(id).getLocation();
62                 throw new DuplicateIdException(
63                     "Duplicate widget id \"" + id + "\" detected at " + duplicateLocation + ".\n" +
64                     "Container widget \"" + containerDefinition.getId() + "\" at " + containerLocation + "\n" +
65                     "already contains a widget with id \"" + id + "\" at " + firstLocation + ".");
66             }
67             widgetDefinitionsById.put(widgetDefinition.getId(), widgetDefinition);
68         }
69         this.definitionsIt.add(widgetDefinition);
70     }
71
72     public List JavaDoc getWidgetDefinitions() {
73         return widgetDefinitions;
74     }
75
76     public boolean hasWidget(String JavaDoc id) {
77         return widgetDefinitionsById.containsKey(id);
78     }
79
80     public WidgetDefinition getWidgetDefinition(String JavaDoc id) {
81         return (WidgetDefinition)widgetDefinitionsById.get(id);
82     }
83
84     public void resolve(List JavaDoc parents, WidgetDefinition parent) throws Exception JavaDoc {
85         if (!wasHere) {
86             wasHere = true;
87             this.definitionsIt = widgetDefinitions.listIterator();
88             parents.add(containerDefinition);
89             while (this.definitionsIt.hasNext()) {
90                 WidgetDefinition widgetDefinition = (WidgetDefinition)this.definitionsIt.next();
91                 // ClassDefinition's get resolved by NewDefinition rather than here.
92
if (!(widgetDefinition instanceof ClassDefinition)) {
93                     if (widgetDefinition instanceof NewDefinition) {
94                         // Remove NewDefinition in preparation for its referenced class of widget definitions to be added.
95
this.definitionsIt.remove();
96                         ((NewDefinition)widgetDefinition).resolve(parents, containerDefinition);
97                     } else {
98                         if (widgetDefinition instanceof ContainerDefinition)
99                             ((ContainerDefinition)widgetDefinition).resolve(parents, containerDefinition);
100                     }
101                 }
102             }
103             parents.remove(parents.size()-1);
104             wasHere = false;
105         } else {
106             // Non-terminating recursion detection
107
// Search up parent list in hopes of finding a "Union" or "Repeater" before finding previous "New" for this "Class".
108
ListIterator JavaDoc parentsIt = parents.listIterator(parents.size());
109             while(parentsIt.hasPrevious()) {
110                 WidgetDefinition widgetDefinition = (WidgetDefinition)parentsIt.previous();
111                 if (widgetDefinition instanceof UnionDefinition) break;
112                 if (widgetDefinition instanceof RepeaterDefinition) break;
113                 if (widgetDefinition == containerDefinition) {
114                     Location location = containerDefinition.getLocation();
115                     if (parent instanceof FormDefinition) {
116                         throw new Exception JavaDoc("Container: Non-terminating recursion detected in form definition (" + location + ")");
117                     }
118                     throw new Exception JavaDoc("Container: Non-terminating recursion detected in widget definition: "
119                         + parent.getId() + " (" + location + ")");
120                 }
121             }
122         }
123     }
124  
125     public void createWidget(Widget parent, String JavaDoc id) {
126         WidgetDefinition widgetDefinition = (WidgetDefinition)widgetDefinitionsById.get(id);
127         if (widgetDefinition == null) {
128             throw new RuntimeException JavaDoc(containerDefinition.getId() + ": WidgetDefinition \"" + id +
129                     "\" does not exist (" + containerDefinition.getLocation() + ")");
130         }
131         Widget widget = widgetDefinition.createInstance();
132         if (widget != null)
133             ((ContainerWidget)parent).addChild(widget);
134     }
135
136     public void createWidgets(Widget parent) {
137         Iterator JavaDoc definitionsIt = widgetDefinitions.iterator();
138         while (definitionsIt.hasNext()) {
139             WidgetDefinition widgetDefinition = (WidgetDefinition)definitionsIt.next();
140             Widget widget = widgetDefinition.createInstance();
141             if (widget != null)
142                 ((ContainerWidget)parent).addChild(widget);
143         }
144     }
145
146     public void checkCompleteness() throws IncompletenessException {
147         if (!wasHere) {
148             wasHere = true;
149 // FIXME: is it legal to have no widgets in a container? There are some cases of this in Swan
150
// if(size() == 0)
151
// throw new IncompletenessException(this.containerDefinition.getClass().getName() +
152
// " requires at least one child widget!", this.containerDefinition);
153

154             // now check children's completeness
155
Iterator JavaDoc it = widgetDefinitions.iterator();
156             while(it.hasNext()) {
157                 ((WidgetDefinition)it.next()).checkCompleteness();
158             }
159             wasHere = false;
160         }
161     }
162 }
163
Popular Tags