1 16 package org.outerj.daisy.frontend.editor; 17 18 import org.apache.cocoon.forms.formmodel.Form; 19 import org.apache.cocoon.forms.formmodel.Widget; 20 import org.apache.cocoon.forms.formmodel.MultiValueField; 21 import org.apache.cocoon.forms.formmodel.ContainerWidget; 22 import org.apache.cocoon.forms.validation.WidgetValidator; 23 import org.apache.cocoon.forms.validation.ValidationErrorAware; 24 import org.apache.cocoon.forms.validation.ValidationError; 25 import org.apache.cocoon.forms.event.ValueChangedListener; 26 import org.apache.cocoon.forms.event.ValueChangedEvent; 27 import org.apache.cocoon.forms.event.ValueChangedListenerEnabled; 28 import org.apache.cocoon.forms.datatype.StaticSelectionList; 29 import org.apache.cocoon.forms.util.StringMessage; 30 import org.apache.cocoon.xml.SaxBuffer; 31 import org.apache.cocoon.xml.AttributesImpl; 32 import org.apache.excalibur.xml.sax.XMLizable; 33 import org.outerj.daisy.repository.*; 34 import org.outerj.daisy.repository.variant.VariantManager; 35 import org.outerj.daisy.repository.schema.FieldType; 36 import org.outerj.daisy.repository.schema.SelectionList; 37 import org.outerj.daisy.publisher.Publisher; 38 import org.outerx.daisy.x10Publisher.PublisherRequestDocument; 39 import org.outerx.daisy.x10Publisher.ResolveDocumentIdsDocument; 40 import org.xml.sax.helpers.DefaultHandler ; 41 import org.xml.sax.Attributes ; 42 import org.xml.sax.SAXException ; 43 44 import java.util.Map ; 45 import java.util.HashMap ; 46 47 public class DefaultFieldEditor implements FieldEditor { 48 private FieldType fieldType; 49 50 private static final Map FORM_DEFINITION_FRAGMENTS; 51 private static final String FORM_DEF_NS = "http://apache.org/cocoon/forms/1.0#definition"; 52 static { 53 try { 54 FORM_DEFINITION_FRAGMENTS = new HashMap (); 55 56 ValueType[] valueTypes = new ValueType[] { 57 ValueType.STRING, 58 ValueType.LONG, 59 ValueType.DOUBLE, 60 ValueType.DECIMAL, 61 ValueType.DATE, 62 ValueType.DATETIME, 63 ValueType.BOOLEAN, 64 ValueType.LINK 65 }; 66 67 for (int i = 0; i < valueTypes.length; i++) { 68 SaxBuffer buffer = new SaxBuffer(); 69 buffer.startPrefixMapping("", FORM_DEF_NS); 70 AttributesImpl attrs = new AttributesImpl(); 71 attrs.addCDATAAttribute("id", "field"); 72 buffer.startElement(FORM_DEF_NS, "multivaluefield", "multivaluefield", attrs); 73 addFieldConfig(buffer, valueTypes[i]); 74 buffer.endElement(FORM_DEF_NS, "multivaluefield", "multivaluefield"); 75 buffer.endPrefixMapping(""); 76 77 FORM_DEFINITION_FRAGMENTS.put(valueTypes[i].toString() + "-mv", buffer); 78 } 79 80 for (int i = 0; i < valueTypes.length; i++) { 81 SaxBuffer buffer = new SaxBuffer(); 82 buffer.startPrefixMapping("", FORM_DEF_NS); 83 AttributesImpl attrs = new AttributesImpl(); 84 attrs.addCDATAAttribute("id", "field"); 85 buffer.startElement(FORM_DEF_NS, "field", "field", attrs); 86 addFieldConfig(buffer, valueTypes[i]); 87 buffer.endElement(FORM_DEF_NS, "field", "field"); 88 89 if (valueTypes[i] == ValueType.LINK) { 90 attrs.clear(); 91 attrs.addCDATAAttribute("id", "field-label"); 92 buffer.startElement(FORM_DEF_NS, "output", "output", attrs); 93 addFieldConfig(buffer, valueTypes[i]); 94 buffer.endElement(FORM_DEF_NS, "output", "output"); 95 } 96 buffer.endPrefixMapping(""); 97 98 FORM_DEFINITION_FRAGMENTS.put(valueTypes[i].toString(), buffer); 99 } 100 101 SaxBuffer buffer = new SaxBuffer(); 103 buffer.startPrefixMapping("", FORM_DEF_NS); 104 AttributesImpl attrs = new AttributesImpl(); 105 attrs.addCDATAAttribute("id", "field"); 106 buffer.startElement(FORM_DEF_NS, "booleanfield", "booleanfield", attrs); 107 buffer.endElement(FORM_DEF_NS, "booleanfield", "booleanfield"); 108 buffer.endPrefixMapping(""); 109 FORM_DEFINITION_FRAGMENTS.put("boolean", buffer); 110 111 } catch (Exception e) { 112 throw new RuntimeException ("Unexpected error in " + DefaultFieldEditor.class.getName() + " initialisation.", e); 113 } 114 } 115 116 private static void addFieldConfig(SaxBuffer buffer, ValueType valueType) throws Exception { 117 AttributesImpl attrs = new AttributesImpl(); 118 if (valueType == ValueType.DATETIME) { 119 attrs.addCDATAAttribute("base", "date"); 120 } else if (valueType == ValueType.LINK) { 121 attrs.addCDATAAttribute("base", "string"); 122 } else { 123 attrs.addCDATAAttribute("base", valueType.toString()); 124 } 125 buffer.startElement(FORM_DEF_NS, "datatype", "datatype", attrs); 126 127 if (valueType == ValueType.DATETIME) { 128 attrs.clear(); 129 attrs.addCDATAAttribute("type", "formatting"); 130 attrs.addCDATAAttribute("variant", "datetime"); 131 buffer.startElement(FORM_DEF_NS, "convertor", "convertor", attrs); 132 buffer.endElement(FORM_DEF_NS, "convertor", "convertor"); 133 } 134 135 buffer.endElement(FORM_DEF_NS, "datatype", "datatype"); 136 } 137 138 public DefaultFieldEditor(FieldType fieldType) { 139 this.fieldType = fieldType; 140 } 141 142 public XMLizable getFormDefinitionFragment() { 143 String key; 144 if (fieldType.isMultiValue()) 145 key = fieldType.getValueType().toString() + "-mv"; 146 else 147 key = fieldType.getValueType().toString(); 148 SaxBuffer buffer = (SaxBuffer)FORM_DEFINITION_FRAGMENTS.get(key); 149 if (buffer == null) { 150 throw new RuntimeException ("DefaultFieldEditor cannot handle " + key); 151 } 152 return buffer; 153 } 154 155 public String getTemplateName() { 156 return "default"; 157 } 158 159 public FieldType getFieldType() { 160 return fieldType; 161 } 162 163 public boolean hasValue(Widget parentWidget) { 164 Widget widget = ((ContainerWidget)parentWidget).getChild("field"); 165 if (widget.getValue() == null && widget.validate()) { 166 return false; 167 } else if (fieldType.isMultiValue() && widget.validate()) { 168 Object [] values = (Object [])widget.getValue(); 169 if (values.length == 0) 170 return false; 171 } 172 return true; 173 } 174 175 public void setValidationError(ValidationError error, Widget widget) { 176 ValidationErrorAware valueWidget = (ValidationErrorAware)((ContainerWidget)widget).getChild("field"); 177 valueWidget.setValidationError(error); 178 } 179 180 public void init(Widget parentWidget, DocumentEditorForm documentEditorForm) { 181 Widget widget = ((ContainerWidget)parentWidget).getChild("field"); 183 SelectionList selectionList = fieldType.getSelectionList(); 184 if (selectionList != null && !fieldType.getAllowFreeEntry()) { 185 if (widget instanceof org.apache.cocoon.forms.formmodel.Field) { 186 org.apache.cocoon.forms.formmodel.Field field = (org.apache.cocoon.forms.formmodel.Field)widget; 187 field.setSelectionList(new SelectionListAdapter(field.getDatatype(), selectionList, true, fieldType.getValueType(), documentEditorForm.getRepository().getVariantManager(), documentEditorForm.getDocumentBranchId(), documentEditorForm.getDocumentLanguageId())); 188 } else if (widget instanceof MultiValueField) { 189 MultiValueField field = (MultiValueField)widget; 190 field.setSelectionList(new SelectionListAdapter(field.getDatatype(), selectionList, false, fieldType.getValueType(), documentEditorForm.getRepository().getVariantManager(), documentEditorForm.getDocumentBranchId(), documentEditorForm.getDocumentLanguageId())); 191 } 192 } 193 if (fieldType.getValueType() == ValueType.LINK) { 195 widget.addValidator(new LinkValidator(documentEditorForm)); 196 if (fieldType.getAllowFreeEntry() || fieldType.getSelectionList() == null) 197 ((ValueChangedListenerEnabled)widget).addValueChangedListener(new LinkLabelLoader(documentEditorForm)); 198 } 199 } 200 201 public void load(Form form, Field field, Document document, Repository repository) throws Exception { 202 Object value = field.getValue(); 203 204 if (fieldType.getValueType() == ValueType.LINK) { 206 if (fieldType.isMultiValue()) { 207 Object [] variantKeys = (Object [])value; 208 String [] values = new String [variantKeys.length]; 209 for (int i = 0; i < variantKeys.length; i++) { 210 values[i] = LinkFieldHelper.variantKeyToString((VariantKey)variantKeys[i], repository.getVariantManager()); 211 } 212 value = values; 213 } else { 214 value = LinkFieldHelper.variantKeyToString((VariantKey)value, repository.getVariantManager()); 215 } 216 } 217 218 getWidget(form).setValue(value); 219 } 220 221 private Widget getWidget(Form form) { 222 ContainerWidget parentWidget = (ContainerWidget)form.getChild("field_" + fieldType.getId()); 223 return parentWidget.getChild("field"); 224 } 225 226 public void save(Form form, Document document, Repository repository) throws Exception { 227 long fieldTypeId = fieldType.getId(); 228 Object value = getWidget(form).getValue(); 229 if (value == null) { 230 document.deleteField(fieldTypeId); 231 } else if (value instanceof Object []) { 232 Object [] values = (Object [])value; 233 if (values.length > 0) 234 document.setField(fieldTypeId, getValueToSave(values, repository)); 235 else 236 document.deleteField(fieldTypeId); 237 } else { 238 document.setField(fieldTypeId, getValueToSave(value, repository)); 239 } 240 } 241 242 private Object getValueToSave(Object value, Repository repository) { 243 if (fieldType.getValueType() == ValueType.LINK) { 244 VariantManager variantManager = repository.getVariantManager(); 245 if (value instanceof Object []) { 246 Object [] values = (Object [])value; 247 Object [] newValues = new Object [values.length]; 248 for (int i = 0; i < values.length; i++) 249 newValues[i] = LinkFieldHelper.parseVariantKey((String )values[i], variantManager); 250 value = newValues; 251 } else { 252 value = LinkFieldHelper.parseVariantKey((String )value, repository.getVariantManager());; 253 } 254 } 255 return value; 256 } 257 258 static class LinkValidator implements WidgetValidator { 259 private VariantManager variantManager; 260 261 public LinkValidator(DocumentEditorForm documentEditorForm) { 262 this.variantManager = documentEditorForm.getRepository().getVariantManager(); 263 } 264 265 public boolean validate(Widget widget) { 266 return LinkFieldHelper.validate(widget, variantManager); 267 } 268 } 269 270 274 static class LinkLabelLoader implements ValueChangedListener { 275 private DocumentEditorForm documentEditorForm; 276 277 public LinkLabelLoader(DocumentEditorForm documentEditorForm) { 278 this.documentEditorForm = documentEditorForm; 279 } 280 281 public void valueChanged(ValueChangedEvent valueChangedEvent) { 282 try { 283 Object value = valueChangedEvent.getNewValue(); 284 if (value == null) { 285 if (valueChangedEvent.getSourceWidget() instanceof Field) 286 valueChangedEvent.getSourceWidget().lookupWidget("../field-label").setValue(null); 287 return; 288 } 289 290 PublisherRequestDocument pubReqDoc = PublisherRequestDocument.Factory.newInstance(); 291 PublisherRequestDocument.PublisherRequest pubReq = pubReqDoc.addNewPublisherRequest(); 292 ResolveDocumentIdsDocument.ResolveDocumentIds resolveDocIds = pubReq.addNewResolveDocumentIds(); 293 resolveDocIds.setBranch(String.valueOf(documentEditorForm.getDocumentBranchId())); 294 resolveDocIds.setLanguage(String.valueOf(documentEditorForm.getDocumentLanguageId())); 295 296 if (!(value instanceof Object [])) { 297 value = new Object [] {value}; 298 } 299 300 VariantManager variantManager = documentEditorForm.getRepository().getVariantManager(); 301 Object [] values = (Object [])value; 302 for (int i = 0; i < values.length; i++) { 303 VariantKey variantKey = LinkFieldHelper.parseVariantKey((String )values[i], variantManager); 304 ResolveDocumentIdsDocument.ResolveDocumentIds.Document doc = resolveDocIds.addNewDocument(); 305 doc.setId(variantKey.getDocumentId()); 306 if (variantKey.getBranchId() != -1) 307 doc.setBranch(String.valueOf(variantKey.getBranchId())); 308 if (variantKey.getLanguageId() != -1) 309 doc.setLanguage(String.valueOf(variantKey.getLanguageId())); 310 } 311 312 Publisher publisher = (Publisher)documentEditorForm.getRepository().getExtension("Publisher"); 313 DocNamesReceiver docNamesReceiver = new DocNamesReceiver(values.length); 314 publisher.processRequest(pubReqDoc, docNamesReceiver); 315 String [] names = docNamesReceiver.getNames(); 316 317 if (valueChangedEvent.getSourceWidget() instanceof MultiValueField) { 318 MultiValueField field = (MultiValueField)valueChangedEvent.getSourceWidget(); 319 StaticSelectionList selectionList = new StaticSelectionList(field.getDatatype()); 320 for (int i = 0; i < values.length; i++) 321 selectionList.addItem(values[i], new StringMessage(names[i])); 322 field.setSelectionList(selectionList); 323 } else { 324 valueChangedEvent.getSourceWidget().lookupWidget("../field-label").setValue(names[0]); 325 } 326 } catch (Exception e) { 327 } 329 } 330 } 331 332 static class DocNamesReceiver extends DefaultHandler { 333 private String [] names; 334 private int pos = 0; 335 336 public DocNamesReceiver(int count) { 337 this.names = new String [count]; 338 } 339 340 public String [] getNames() { 341 return names; 342 } 343 344 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 345 if (uri.equals("http://outerx.org/daisy/1.0#publisher") && localName.equals("document")) { 346 names[pos++] = attributes.getValue("name"); 347 } 348 } 349 } 350 } | Popular Tags |