1 16 package org.apache.cocoon.forms.datatype; 17 18 import org.xml.sax.ContentHandler ; 19 import org.xml.sax.SAXException ; 20 import org.xml.sax.Attributes ; 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 ; 39 40 import java.io.IOException ; 41 import java.rmi.server.UID ; 42 import java.util.Enumeration ; 43 import java.util.Locale ; 44 45 55 public class DynamicSelectionList implements SelectionList { 56 private String src; 57 private boolean usePerRequestCache; 58 private Datatype datatype; 59 private ServiceManager serviceManager; 60 private Context context; 61 62 69 public DynamicSelectionList(Datatype datatype, String 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 83 public DynamicSelectionList(Datatype datatype, String 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 99 void generateSaxFragment(ContentHandler contentHandler, Locale locale, Source source) 100 throws ProcessingException, SAXException , IOException { 101 SelectionListHandler handler = new SelectionListHandler(locale); 102 handler.setContentHandler(contentHandler); 103 SourceUtil.toSAX(serviceManager, source, null, handler); 104 } 105 106 109 private void generateSaxFragmentFromSrc(ContentHandler contentHandler, Locale locale) throws SAXException { 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 e) { 117 throw e; 118 } catch (Exception e) { 119 throw new SAXException ("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 e) {} 124 } 125 serviceManager.release(sourceResolver); 126 } 127 } 128 } 129 130 public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException { 131 132 if (usePerRequestCache) { 133 Request request = ContextHelper.getRequest(this.context); 135 Enumeration enumeration = request.getAttributeNames(); 136 boolean cacheFound = false; 137 String name = null; 138 while (enumeration.hasMoreElements()) { 139 name = (String )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 saxBuffer = new SaxBuffer(); 151 generateSaxFragmentFromSrc(saxBuffer, locale); 152 String cacheID = (new UID ()).toString(); 153 request.setAttribute(src + cacheID, saxBuffer); 154 } 155 saxBuffer.toSAX(contentHandler); 157 } else { generateSaxFragmentFromSrc(contentHandler, locale); 159 } 160 } 161 162 165 public class SelectionListHandler extends AbstractXMLPipe { 166 private Object currentValue; 167 private String currentValueAsString; 168 private boolean hasLabel; 169 private Locale locale; 170 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 locale) { 178 this.locale = locale; 179 } 180 181 public void startDocument() 182 throws SAXException { 183 } 184 185 public void endDocument() 186 throws SAXException { 187 } 188 189 public void endDTD() 190 throws SAXException { 191 } 192 193 public void startDTD(String name, String publicId, String systemId) 194 throws SAXException { 195 } 196 197 public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) 198 throws SAXException { 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 convertor = datatype.getConvertor(); 207 } 208 hasLabel = false; 209 210 String unparsedValue = attributes.getValue("value"); 211 if (unparsedValue == null || "".equals(unparsedValue)) { 212 currentValueAsString = ""; 214 } else { 215 ConversionResult conversionResult = convertor.convertFromString(unparsedValue, locale, fromFormatCache); 216 if (!conversionResult.isSuccessful()) { 217 throw new SAXException ("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 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 LABEL_EL = "label"; 244 245 public void endElement(String namespaceURI, String localName, String qName) 246 throws SAXException { 247 if (convertorConfigNestingLevel > 0) { 248 convertorConfigNestingLevel--; 249 convertorConfigDOMBuilder.endElement(namespaceURI, localName, qName); 250 if (convertorConfigNestingLevel == 0) { 251 Element convertorElement = convertorConfigDOMBuilder.getDocument().getDocumentElement(); 252 try { 253 convertor = datatype.getBuilder().buildConvertor(convertorElement); 254 } catch (Exception e) { 255 throw new SAXException ("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 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 { 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 prefix, String uri) 288 throws SAXException { 289 if (convertorConfigNestingLevel > 0) { 290 convertorConfigDOMBuilder.startPrefixMapping(prefix, uri); 291 } else 292 super.startPrefixMapping(prefix, uri); 293 } 294 295 public void endPrefixMapping(String prefix) 296 throws SAXException { 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 { 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 { 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 target, String data) 320 throws SAXException { 321 if (convertorConfigNestingLevel > 0) { 322 convertorConfigDOMBuilder.processingInstruction(target, data); 323 } else 324 super.processingInstruction(target, data); 325 } 326 327 public void skippedEntity(String name) 328 throws SAXException { 329 if (convertorConfigNestingLevel > 0) { 330 convertorConfigDOMBuilder.skippedEntity(name); 331 } else 332 super.skippedEntity(name); 333 } 334 335 public void startEntity(String name) 336 throws SAXException { 337 if (convertorConfigNestingLevel > 0) { 338 convertorConfigDOMBuilder.startEntity(name); 339 } else 340 super.startEntity(name); 341 } 342 343 public void endEntity(String name) 344 throws SAXException { 345 if (convertorConfigNestingLevel > 0) { 346 convertorConfigDOMBuilder.endEntity(name); 347 } else 348 super.endEntity(name); 349 } 350 351 public void startCDATA() 352 throws SAXException { 353 if (convertorConfigNestingLevel > 0) { 354 convertorConfigDOMBuilder.startCDATA(); 355 } else 356 super.startCDATA(); 357 } 358 359 public void endCDATA() 360 throws SAXException { 361 if (convertorConfigNestingLevel > 0) { 362 convertorConfigDOMBuilder.endCDATA(); 363 } else 364 super.endCDATA(); 365 } 366 } 367 } 368 | Popular Tags |