1 16 package org.apache.cocoon.woody.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.service.ServiceManager; 22 import org.apache.excalibur.source.SourceResolver; 23 import org.apache.excalibur.source.Source; 24 import org.apache.cocoon.ProcessingException; 25 import org.apache.cocoon.components.source.SourceUtil; 26 import org.apache.cocoon.xml.AttributesImpl; 27 import org.apache.cocoon.xml.AbstractXMLPipe; 28 import org.apache.cocoon.xml.dom.DOMBuilder; 29 import org.apache.cocoon.woody.Constants; 30 import org.apache.cocoon.woody.datatype.convertor.Convertor; 31 import org.apache.cocoon.woody.datatype.convertor.DefaultFormatCache; 32 import org.w3c.dom.Element ; 33 34 import java.io.IOException ; 35 import java.util.Locale ; 36 37 46 public class DynamicSelectionList implements SelectionList { 47 private String src; 48 private Datatype datatype; 49 private ServiceManager serviceManager; 50 51 public DynamicSelectionList(Datatype datatype, String src, ServiceManager serviceManager) { 52 this.datatype = datatype; 53 this.src = src; 54 this.serviceManager = serviceManager; 55 } 56 57 public Datatype getDatatype() { 58 return datatype; 59 } 60 61 65 void generateSaxFragment(ContentHandler contentHandler, Locale locale, Source source) throws ProcessingException, SAXException , IOException { 66 SelectionListHandler handler = new SelectionListHandler(locale); 67 handler.setContentHandler(contentHandler); 68 SourceUtil.toSAX(serviceManager, source, null, handler); 69 } 70 71 public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException { 72 SourceResolver sourceResolver = null; 73 Source source = null; 74 try { 75 sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE); 76 source = sourceResolver.resolveURI(src); 77 generateSaxFragment(contentHandler, locale, source); 78 } catch (Exception e) { 79 throw new SAXException ("Error while generating selection list: " + e.getMessage(), e); 80 } finally { 81 if (sourceResolver != null) { 82 if (source != null) 83 try { sourceResolver.release(source); } catch (Exception e) {} 84 serviceManager.release(sourceResolver); 85 } 86 } 87 } 88 89 92 public class SelectionListHandler extends AbstractXMLPipe { 93 private Object currentValue; 94 private String currentValueAsString; 95 private boolean hasLabel; 96 private Locale locale; 97 98 private Convertor convertor; 99 private DOMBuilder convertorConfigDOMBuilder; 100 private int convertorConfigNestingLevel = 0; 101 private Convertor.FormatCache fromFormatCache = new DefaultFormatCache(); 102 private Convertor.FormatCache toFormatCache = new DefaultFormatCache(); 103 104 public SelectionListHandler(Locale locale) { 105 this.locale = locale; 106 } 107 108 public void startDocument() 109 throws SAXException { 110 } 111 112 public void endDocument() 113 throws SAXException { 114 } 115 116 public void endDTD() 117 throws SAXException { 118 } 119 120 public void startDTD(String name, String publicId, String systemId) 121 throws SAXException { 122 } 123 124 public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) 125 throws SAXException { 126 if (convertorConfigNestingLevel > 0) { 127 convertorConfigNestingLevel++; 128 convertorConfigDOMBuilder.startElement(namespaceURI, localName, qName, attributes); 129 } else if (namespaceURI.equals(Constants.WD_NS)) { 130 if (localName.equals("item")) { 131 if (convertor == null) { 132 convertor = datatype.getConvertor(); 134 } 135 hasLabel = false; 136 137 String unparsedValue = attributes.getValue("value"); 138 if (unparsedValue == null || "".equals(unparsedValue)) { 139 currentValueAsString = ""; 141 } else { 142 currentValue = convertor.convertFromString(unparsedValue, locale, fromFormatCache); 143 if (currentValue == null) { 144 throw new SAXException ("Could not interpret the following value: \"" + unparsedValue + "\"."); 145 } 146 currentValueAsString = datatype.getConvertor().convertToString(currentValue, locale, toFormatCache); 147 } 148 AttributesImpl attrs = new AttributesImpl(); 149 attrs.addCDATAAttribute("value", currentValueAsString); 150 super.startElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName, attrs); 151 } else if (localName.equals("label")) { 152 hasLabel = true; 153 super.startElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName, attributes); 154 } else if (localName.equals("selection-list")) { 155 super.startElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName, attributes); 156 } else if (convertor == null && localName.equals("convertor")) { 157 convertorConfigDOMBuilder = new DOMBuilder(); 159 convertorConfigDOMBuilder.startElement(namespaceURI, localName, qName, attributes); 160 convertorConfigNestingLevel++; 161 } else { 162 super.startElement(namespaceURI, localName, qName, attributes); 163 } 164 } else { 165 super.startElement(namespaceURI, localName, qName, attributes); 166 } 167 } 168 169 private static final String LABEL_EL = "label"; 170 171 public void endElement(String namespaceURI, String localName, String qName) 172 throws SAXException { 173 if (convertorConfigNestingLevel > 0) { 174 convertorConfigNestingLevel--; 175 convertorConfigDOMBuilder.endElement(namespaceURI, localName, qName); 176 if (convertorConfigNestingLevel == 0) { 177 Element convertorElement = convertorConfigDOMBuilder.getDocument().getDocumentElement(); 178 try { 179 convertor = datatype.getBuilder().buildConvertor(convertorElement); 180 } catch (Exception e) { 181 throw new SAXException ("Error building convertor from convertor configuration embedded in selection list XML.", e); 182 } 183 } 184 } else if (namespaceURI.equals(Constants.WD_NS)) { 185 if (localName.equals("item")) { 186 if (!hasLabel) { 187 super.startElement(Constants.WI_NS, LABEL_EL, Constants.WI_PREFIX_COLON + LABEL_EL, new AttributesImpl()); 189 super.characters(currentValueAsString.toCharArray(), 0, currentValueAsString.length()); 190 super.endElement(Constants.WI_NS, LABEL_EL, Constants.WI_PREFIX_COLON + LABEL_EL); 191 } 192 super.endElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName); 193 } else if (localName.equals("label")) { 194 super.endElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName); 195 } else if (localName.equals("selection-list")) { 196 super.endElement(Constants.WI_NS, localName, Constants.WI_PREFIX_COLON + localName); 197 } else { 198 super.endElement(namespaceURI, localName, qName); 199 } 200 } else { 201 super.endElement(namespaceURI, localName, qName); 202 } 203 } 204 205 public void comment(char ch[], int start, int len) 206 throws SAXException { 207 if (convertorConfigNestingLevel > 0) { 208 convertorConfigDOMBuilder.comment(ch, start, len); 209 } else 210 super.comment(ch, start, len); 211 } 212 213 public void startPrefixMapping(String prefix, String uri) 214 throws SAXException { 215 if (convertorConfigNestingLevel > 0) { 216 convertorConfigDOMBuilder.startPrefixMapping(prefix, uri); 217 } else 218 super.startPrefixMapping(prefix, uri); 219 } 220 221 public void endPrefixMapping(String prefix) 222 throws SAXException { 223 if (convertorConfigNestingLevel > 0) { 224 convertorConfigDOMBuilder.endPrefixMapping(prefix); 225 } else 226 super.endPrefixMapping(prefix); 227 } 228 229 public void characters(char c[], int start, int len) 230 throws SAXException { 231 if (convertorConfigNestingLevel > 0) { 232 convertorConfigDOMBuilder.characters(c, start, len); 233 } else 234 super.characters(c, start, len); 235 } 236 237 public void ignorableWhitespace(char c[], int start, int len) 238 throws SAXException { 239 if (convertorConfigNestingLevel > 0) { 240 convertorConfigDOMBuilder.ignorableWhitespace(c, start, len); 241 } else 242 super.ignorableWhitespace(c, start, len); 243 } 244 245 public void processingInstruction(String target, String data) 246 throws SAXException { 247 if (convertorConfigNestingLevel > 0) { 248 convertorConfigDOMBuilder.processingInstruction(target, data); 249 } else 250 super.processingInstruction(target, data); 251 } 252 253 public void skippedEntity(String name) 254 throws SAXException { 255 if (convertorConfigNestingLevel > 0) { 256 convertorConfigDOMBuilder.skippedEntity(name); 257 } else 258 super.skippedEntity(name); 259 } 260 261 public void startEntity(String name) 262 throws SAXException { 263 if (convertorConfigNestingLevel > 0) { 264 convertorConfigDOMBuilder.startEntity(name); 265 } else 266 super.startEntity(name); 267 } 268 269 public void endEntity(String name) 270 throws SAXException { 271 if (convertorConfigNestingLevel > 0) { 272 convertorConfigDOMBuilder.endEntity(name); 273 } else 274 super.endEntity(name); 275 } 276 277 public void startCDATA() 278 throws SAXException { 279 if (convertorConfigNestingLevel > 0) { 280 convertorConfigDOMBuilder.startCDATA(); 281 } else 282 super.startCDATA(); 283 } 284 285 public void endCDATA() 286 throws SAXException { 287 if (convertorConfigNestingLevel > 0) { 288 convertorConfigDOMBuilder.endCDATA(); 289 } else 290 super.endCDATA(); 291 } 292 } 293 } 294 | Popular Tags |