KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > impl > SchemaElement


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

15 package org.apache.hivemind.impl;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.apache.hivemind.ApplicationRuntimeException;
26 import org.apache.hivemind.Attribute;
27 import org.apache.hivemind.Element;
28 import org.apache.hivemind.schema.AttributeModel;
29 import org.apache.hivemind.schema.ElementModel;
30 import org.apache.hivemind.schema.Rule;
31 import org.apache.hivemind.schema.SchemaProcessor;
32 import org.apache.hivemind.schema.Translator;
33 import org.apache.hivemind.schema.rules.NullTranslator;
34
35 /**
36  * A wrapper around {@link org.apache.hivemind.schema.ElementModel} used by
37  * {@link org.apache.hivemind.impl.SchemaProcessorImpl}.
38  *
39  * @author Howard Lewis Ship
40  */

41 final class SchemaElement
42 {
43     private SchemaProcessor _processor;
44
45     private ElementModel _model;
46
47     private List JavaDoc _requiredAttributes = new ArrayList JavaDoc();
48
49     private Set JavaDoc _knownAttributes = new HashSet JavaDoc();
50
51     private Map JavaDoc _nestedElements;
52
53     /**
54      * Keyed on attribute name, value is string (possibly null) used to access a translator.
55      */

56     private Map JavaDoc _attributeTranslators = new HashMap JavaDoc();
57     
58     private Map JavaDoc _attributeDefaults = new HashMap JavaDoc();
59     
60     /**
61      * Map of Maps. The outer key is an attribute name string, this indicates that the attribute
62      * values should be unique. Inner map is keyed on attribute value (as a string), the value is
63      * the {@link org.apache.hivemind.Location} defining that value.
64      */

65     private Map JavaDoc _attributeValues = new HashMap JavaDoc();
66
67     SchemaElement(SchemaProcessor processor, ElementModel model)
68     {
69         _processor = processor;
70         _model = model;
71
72         List JavaDoc attributeModels = model.getAttributeModels();
73         int count = attributeModels.size();
74
75         for (int i = 0; i < count; i++)
76         {
77             AttributeModel am = (AttributeModel) attributeModels.get(i);
78
79             String JavaDoc name = am.getName();
80
81             _knownAttributes.add(name);
82
83             if (am.isRequired())
84                 _requiredAttributes.add(name);
85
86             // If the attribute should be unique, add a map for that attribute
87
// to track unique values for that attribute.
88

89             if (am.isUnique())
90                 _attributeValues.put(name, new HashMap JavaDoc());
91
92             if (am.getDefault() != null)
93                 _attributeDefaults.put(am.getName(), am.getDefault());
94
95             _attributeTranslators.put(name, am.getTranslator());
96         }
97     }
98
99     /**
100      * Returns a {@link SchemaElement} for a nested element, or null if no such element exists.
101      */

102     SchemaElement getNestedElement(String JavaDoc elementName)
103     {
104         if (_nestedElements == null)
105             buildNestedElements();
106
107         return (SchemaElement) _nestedElements.get(elementName);
108     }
109
110     private void buildNestedElements()
111     {
112         _nestedElements = new HashMap JavaDoc();
113
114         List JavaDoc l = _model.getElementModel();
115         int count = l.size();
116
117         for (int i = 0; i < count; i++)
118         {
119             ElementModel nested = (ElementModel) l.get(i);
120
121             SchemaElement nestedElement = new SchemaElement(_processor, nested);
122
123             // TODO: Check for duplicates here, or at parse!
124

125             _nestedElements.put(nested.getElementName(), nestedElement);
126         }
127
128     }
129
130     /**
131      * Validates the attributes of the element; checks that all required attributes are present and
132      * that all attributes are defined. Validation errors result in logged error messages.
133      */

134     void validateAttributes(Element element)
135     {
136         List JavaDoc l = element.getAttributes();
137         int count = l.size();
138         Set JavaDoc required = new HashSet JavaDoc(_requiredAttributes);
139         List JavaDoc errors = new ArrayList JavaDoc();
140
141         for (int i = 0; i < count; i++)
142         {
143             Attribute a = (Attribute) l.get(i);
144             String JavaDoc name = a.getName();
145
146             if (!_knownAttributes.contains(name))
147                 errors.add(XmlImplMessages.unknownAttribute(name));
148
149             required.remove(name);
150         }
151
152         Iterator JavaDoc it = required.iterator();
153
154         while (it.hasNext())
155         {
156             String JavaDoc name = (String JavaDoc) it.next();
157             errors.add(XmlImplMessages.missingAttribute(name));
158         }
159
160         count = errors.size();
161
162         if (count == 0)
163             return;
164
165         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
166
167         buffer.append(XmlImplMessages.elementErrors(_processor, element));
168
169         for (int i = 0; i < count; i++)
170         {
171             buffer.append(' ');
172             buffer.append(errors.get(i).toString());
173         }
174
175         // TODO: refactor to use the ErrorHandler rather than throw an exception
176
// (these errors are somewhat recoverable).
177

178         throw new ApplicationRuntimeException(buffer.toString(), element.getLocation(), null);
179     }
180
181
182     void fireBegin(Element element)
183     {
184         List JavaDoc rules = _model.getRules();
185         int count = rules.size();
186
187         for (int i = 0; i < count; i++)
188         {
189             Rule r = (Rule) rules.get(i);
190
191             r.begin(_processor, element);
192
193         }
194     }
195
196     void fireEnd(Element element)
197     {
198         List JavaDoc rules = _model.getRules();
199         int count = rules.size();
200
201         for (int i = count - 1; i >= 0; i--)
202         {
203             Rule r = (Rule) rules.get(i);
204
205             r.end(_processor, element);
206
207         }
208     }
209
210     private Translator _nullTranslator = new NullTranslator();
211
212     private Translator _contentTranslator;
213
214     public Translator getContentTranslator()
215     {
216         if (_contentTranslator == null)
217             _contentTranslator = getTranslator(_model.getContentTranslator());
218
219         return _contentTranslator;
220     }
221
222     private Translator getTranslator(String JavaDoc translator)
223     {
224         if (translator == null)
225             return _nullTranslator;
226
227         return _processor.getTranslator(translator);
228     }
229
230     public Translator getAttributeTranslator(String JavaDoc attributeName)
231     {
232         String JavaDoc translator = (String JavaDoc) _attributeTranslators.get(attributeName);
233
234         return getTranslator(translator);
235     }
236
237     public String JavaDoc getAttributeDefault(String JavaDoc attributeName)
238     {
239         return (String JavaDoc) _attributeDefaults.get(attributeName);
240     }
241
242     public ElementModel getModel()
243     {
244         return _model;
245     }
246
247 }
Popular Tags