KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > datatype > DynamicSelectionList


1 /*
2  * Copyright 1999-2005 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.datatype;
17
18 import org.xml.sax.ContentHandler JavaDoc;
19 import org.xml.sax.SAXException JavaDoc;
20 import org.xml.sax.Attributes JavaDoc;
21 import org.apache.avalon.framework.context.Context;
22 import org.apache.avalon.framework.service.ServiceManager;
23 import org.apache.excalibur.source.SourceResolver;
24 import org.apache.excalibur.source.Source;
25 import org.apache.cocoon.ProcessingException;
26 import org.apache.cocoon.components.ContextHelper;
27 import org.apache.cocoon.components.source.SourceUtil;
28 import org.apache.cocoon.environment.Request;
29 import org.apache.cocoon.forms.FormsConstants;
30 import org.apache.cocoon.forms.datatype.convertor.Convertor;
31 import org.apache.cocoon.forms.datatype.convertor.DefaultFormatCache;
32 import org.apache.cocoon.forms.datatype.convertor.ConversionResult;
33 import org.apache.cocoon.xml.AttributesImpl;
34 import org.apache.cocoon.xml.AbstractXMLPipe;
35 import org.apache.cocoon.xml.SaxBuffer;
36 import org.apache.cocoon.xml.XMLUtils;
37 import org.apache.cocoon.xml.dom.DOMBuilder;
38 import org.w3c.dom.Element JavaDoc;
39
40 import java.io.IOException JavaDoc;
41 import java.rmi.server.UID JavaDoc;
42 import java.util.Enumeration JavaDoc;
43 import java.util.Locale JavaDoc;
44
45 /**
46  * SelectionList implementation that always reads its content from the source
47  * each time it is requested.
48  *
49  * <p>Note: the class {@link SelectionListBuilder} also interprets the same
50  * <code>fd:selection-list</code> XML, so if anything changes here to how that
51  * XML is interpreted, it also needs to change over there and vice versa.</p>
52  *
53  * @version $Id: DynamicSelectionList.java 326838 2005-10-20 06:26:53Z sylvain $
54  */

55 public class DynamicSelectionList implements SelectionList {
56     private String JavaDoc src;
57     private boolean usePerRequestCache;
58     private Datatype datatype;
59     private ServiceManager serviceManager;
60     private Context context;
61
62     /**
63      * @param datatype
64      * @param src
65      * @param usePerRequestCache
66      * @param serviceManager
67      * @param context
68      */

69     public DynamicSelectionList(Datatype datatype, String JavaDoc src, boolean usePerRequestCache, ServiceManager serviceManager, Context context) {
70         this.datatype = datatype;
71         this.src = src;
72         this.serviceManager = serviceManager;
73         this.usePerRequestCache = usePerRequestCache;
74         this.context = context;
75     }
76
77     /**
78      * Creates a DynamicSelectionList without caching
79      * @param datatype -
80      * @param src -
81      * @param serviceManager -
82      */

83     public DynamicSelectionList(Datatype datatype, String JavaDoc src, ServiceManager serviceManager) {
84         this.usePerRequestCache = false;
85         this.context = null;
86         this.datatype = datatype;
87         this.src = src;
88         this.serviceManager = serviceManager;
89     }
90
91     public Datatype getDatatype() {
92         return datatype;
93     }
94
95     /*
96      * This method is only used by a test case and by the public version
97      * of generateSaxFragment.
98      */

99     void generateSaxFragment(ContentHandler JavaDoc contentHandler, Locale JavaDoc locale, Source source)
100     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
101         SelectionListHandler handler = new SelectionListHandler(locale);
102         handler.setContentHandler(contentHandler);
103         SourceUtil.toSAX(serviceManager, source, null, handler);
104     }
105     
106     /*
107      * This method generate SaxFragment directly from source.
108      */

109     private void generateSaxFragmentFromSrc(ContentHandler JavaDoc contentHandler, Locale JavaDoc locale) throws SAXException JavaDoc {
110         SourceResolver sourceResolver = null;
111         Source source = null;
112         try {
113             sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
114             source = sourceResolver.resolveURI(src);
115             generateSaxFragment(contentHandler, locale, source);
116         } catch (SAXException JavaDoc e) {
117             throw e;
118         } catch (Exception JavaDoc e) {
119             throw new SAXException JavaDoc("Error while generating selection list: " + e.getMessage(), e);
120         } finally {
121             if (sourceResolver != null) {
122                 if (source != null) {
123                     try { sourceResolver.release(source); } catch (Exception JavaDoc e) {}
124                 }
125                 serviceManager.release(sourceResolver);
126             }
127         }
128     }
129
130     public void generateSaxFragment(ContentHandler JavaDoc contentHandler, Locale JavaDoc locale) throws SAXException JavaDoc {
131
132         if (usePerRequestCache) {
133             // Search the cacheID in request attributes
134
Request request = ContextHelper.getRequest(this.context);
135             Enumeration JavaDoc enumeration = request.getAttributeNames();
136             boolean cacheFound = false;
137             String JavaDoc name = null;
138             while (enumeration.hasMoreElements()) {
139                 name = (String JavaDoc)enumeration.nextElement();
140                 if (name.startsWith(src)) {
141                     cacheFound = true;
142                     break;
143                 }
144             }
145             SaxBuffer saxBuffer;
146             if (cacheFound) {
147                 saxBuffer = (SaxBuffer)request.getAttribute(name);
148             } else {
149                 // Generate the usePerRequestCache and store in a request attribute.
150
saxBuffer = new SaxBuffer();
151                 generateSaxFragmentFromSrc(saxBuffer, locale);
152                 String JavaDoc cacheID = (new UID JavaDoc()).toString();
153                 request.setAttribute(src + cacheID, saxBuffer);
154             }
155             // Output the stored saxBuffer to the contentHandler
156
saxBuffer.toSAX(contentHandler);
157         } else { // We don't use usePerRequestCache => re-read from the source.
158
generateSaxFragmentFromSrc(contentHandler, locale);
159         }
160     }
161
162     /**
163      * XMLConsumer used to handle selection lists generated on the fly.
164      */

165     public class SelectionListHandler extends AbstractXMLPipe {
166         private Object JavaDoc currentValue;
167         private String JavaDoc currentValueAsString;
168         private boolean hasLabel;
169         private Locale JavaDoc locale;
170         /** The convertor used to parse the values in the selection list. */
171         private Convertor convertor;
172         private DOMBuilder convertorConfigDOMBuilder;
173         private int convertorConfigNestingLevel = 0;
174         private Convertor.FormatCache fromFormatCache = new DefaultFormatCache();
175         private Convertor.FormatCache toFormatCache = new DefaultFormatCache();
176
177         public SelectionListHandler(Locale JavaDoc locale) {
178             this.locale = locale;
179         }
180
181         public void startDocument()
182                 throws SAXException JavaDoc {
183         }
184
185         public void endDocument()
186                 throws SAXException JavaDoc {
187         }
188
189         public void endDTD()
190                 throws SAXException JavaDoc {
191         }
192
193         public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
194                 throws SAXException JavaDoc {
195         }
196
197         public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes)
198                 throws SAXException JavaDoc {
199             if (convertorConfigNestingLevel > 0) {
200                 convertorConfigNestingLevel++;
201                 convertorConfigDOMBuilder.startElement(namespaceURI, localName, qName, attributes);
202             } else if (namespaceURI.equals(FormsConstants.DEFINITION_NS)) {
203                 if (localName.equals("item")) {
204                     if (convertor == null) {
205                         // if no convertor was explicitely configured, use the default one of the datatype
206
convertor = datatype.getConvertor();
207                     }
208                     hasLabel = false;
209
210                     String JavaDoc unparsedValue = attributes.getValue("value");
211                     if (unparsedValue == null || "".equals(unparsedValue)) {
212                         // Empty (or null) value translates into the empty string
213
currentValueAsString = "";
214                     } else {
215                         ConversionResult conversionResult = convertor.convertFromString(unparsedValue, locale, fromFormatCache);
216                         if (!conversionResult.isSuccessful()) {
217                             throw new SAXException JavaDoc("Could not interpret the following value: \"" + unparsedValue + "\".");
218                         }
219                         currentValue = conversionResult.getResult();
220                         currentValueAsString = datatype.getConvertor().convertToString(currentValue, locale, toFormatCache);
221                     }
222                     AttributesImpl attrs = new AttributesImpl();
223                     attrs.addCDATAAttribute("value", currentValueAsString);
224                     super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attrs);
225                 } else if (localName.equals("label")) {
226                     hasLabel = true;
227                     super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attributes);
228                 } else if (localName.equals("selection-list")) {
229                     super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attributes);
230                 } else if (convertor == null && localName.equals("convertor")) {
231                     // record the content of this element in a dom-tree
232
convertorConfigDOMBuilder = new DOMBuilder();
233                     convertorConfigDOMBuilder.startElement(namespaceURI, localName, qName, attributes);
234                     convertorConfigNestingLevel++;
235                 } else {
236                     super.startElement(namespaceURI, localName, qName, attributes);
237                 }
238             } else {
239                 super.startElement(namespaceURI, localName, qName, attributes);
240             }
241         }
242
243         private static final String JavaDoc LABEL_EL = "label";
244
245         public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
246                 throws SAXException JavaDoc {
247             if (convertorConfigNestingLevel > 0) {
248                 convertorConfigNestingLevel--;
249                 convertorConfigDOMBuilder.endElement(namespaceURI, localName, qName);
250                 if (convertorConfigNestingLevel == 0) {
251                     Element JavaDoc convertorElement = convertorConfigDOMBuilder.getDocument().getDocumentElement();
252                     try {
253                         convertor = datatype.getBuilder().buildConvertor(convertorElement);
254                     } catch (Exception JavaDoc e) {
255                         throw new SAXException JavaDoc("Error building convertor from convertor configuration embedded in selection list XML.", e);
256                     }
257                 }
258             } else if (namespaceURI.equals(FormsConstants.DEFINITION_NS)) {
259                 if (localName.equals("item")) {
260                     if (!hasLabel) {
261                         // make the label now
262
super.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
263                         super.characters(currentValueAsString.toCharArray(), 0, currentValueAsString.length());
264                         super.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
265                     }
266                     super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
267                 } else if (localName.equals("label")) {
268                     super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
269                 } else if (localName.equals("selection-list")) {
270                     super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
271                 } else {
272                     super.endElement(namespaceURI, localName, qName);
273                 }
274             } else {
275                 super.endElement(namespaceURI, localName, qName);
276             }
277         }
278
279         public void comment(char ch[], int start, int len)
280                 throws SAXException JavaDoc {
281             if (convertorConfigNestingLevel > 0) {
282                 convertorConfigDOMBuilder.comment(ch, start, len);
283             } else
284                 super.comment(ch, start, len);
285         }
286
287         public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
288                 throws SAXException JavaDoc {
289             if (convertorConfigNestingLevel > 0) {
290                 convertorConfigDOMBuilder.startPrefixMapping(prefix, uri);
291             } else
292                 super.startPrefixMapping(prefix, uri);
293         }
294
295         public void endPrefixMapping(String JavaDoc prefix)
296                 throws SAXException JavaDoc {
297             if (convertorConfigNestingLevel > 0) {
298                 convertorConfigDOMBuilder.endPrefixMapping(prefix);
299             } else
300                 super.endPrefixMapping(prefix);
301         }
302
303         public void characters(char c[], int start, int len)
304                 throws SAXException JavaDoc {
305             if (convertorConfigNestingLevel > 0) {
306                 convertorConfigDOMBuilder.characters(c, start, len);
307             } else
308                 super.characters(c, start, len);
309         }
310
311         public void ignorableWhitespace(char c[], int start, int len)
312                 throws SAXException JavaDoc {
313             if (convertorConfigNestingLevel > 0) {
314                 convertorConfigDOMBuilder.ignorableWhitespace(c, start, len);
315             } else
316                 super.ignorableWhitespace(c, start, len);
317         }
318
319         public void processingInstruction(String JavaDoc target, String JavaDoc data)
320                 throws SAXException JavaDoc {
321             if (convertorConfigNestingLevel > 0) {
322                 convertorConfigDOMBuilder.processingInstruction(target, data);
323             } else
324                 super.processingInstruction(target, data);
325         }
326
327         public void skippedEntity(String JavaDoc name)
328                 throws SAXException JavaDoc {
329             if (convertorConfigNestingLevel > 0) {
330                 convertorConfigDOMBuilder.skippedEntity(name);
331             } else
332                 super.skippedEntity(name);
333         }
334
335         public void startEntity(String JavaDoc name)
336                 throws SAXException JavaDoc {
337             if (convertorConfigNestingLevel > 0) {
338                 convertorConfigDOMBuilder.startEntity(name);
339             } else
340                 super.startEntity(name);
341         }
342
343         public void endEntity(String JavaDoc name)
344                 throws SAXException JavaDoc {
345             if (convertorConfigNestingLevel > 0) {
346                 convertorConfigDOMBuilder.endEntity(name);
347             } else
348                 super.endEntity(name);
349         }
350
351         public void startCDATA()
352                 throws SAXException JavaDoc {
353             if (convertorConfigNestingLevel > 0) {
354                 convertorConfigDOMBuilder.startCDATA();
355             } else
356                 super.startCDATA();
357         }
358
359         public void endCDATA()
360                 throws SAXException JavaDoc {
361             if (convertorConfigNestingLevel > 0) {
362                 convertorConfigDOMBuilder.endCDATA();
363             } else
364                 super.endCDATA();
365         }
366     }
367 }
368
Popular Tags