KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > frontend > editor > DefaultFieldEditor


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
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.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 JavaDoc;
41 import org.xml.sax.Attributes JavaDoc;
42 import org.xml.sax.SAXException JavaDoc;
43
44 import java.util.Map JavaDoc;
45 import java.util.HashMap JavaDoc;
46
47 public class DefaultFieldEditor implements FieldEditor {
48     private FieldType fieldType;
49
50     private static final Map JavaDoc FORM_DEFINITION_FRAGMENTS;
51     private static final String JavaDoc FORM_DEF_NS = "http://apache.org/cocoon/forms/1.0#definition";
52     static {
53         try {
54             FORM_DEFINITION_FRAGMENTS = new HashMap JavaDoc();
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             // special case: non-multivalue boolean field
102
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 JavaDoc e) {
112             throw new RuntimeException JavaDoc("Unexpected error in " + DefaultFieldEditor.class.getName() + " initialisation.", e);
113         }
114     }
115
116     private static void addFieldConfig(SaxBuffer buffer, ValueType valueType) throws Exception JavaDoc {
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 JavaDoc 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 JavaDoc("DefaultFieldEditor cannot handle " + key);
151         }
152         return buffer;
153     }
154
155     public String JavaDoc 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 JavaDoc[] values = (Object JavaDoc[])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         // set selection list
182
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         // for link field types: add validator and value changed listener to load document name(s)
194
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 JavaDoc {
202         Object JavaDoc value = field.getValue();
203
204         // special handling for link-field type: convert VariantKey objects to string
205
if (fieldType.getValueType() == ValueType.LINK) {
206             if (fieldType.isMultiValue()) {
207                 Object JavaDoc[] variantKeys = (Object JavaDoc[])value;
208                 String JavaDoc[] values = new String JavaDoc[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 JavaDoc {
227         long fieldTypeId = fieldType.getId();
228         Object JavaDoc value = getWidget(form).getValue();
229         if (value == null) {
230             document.deleteField(fieldTypeId);
231         } else if (value instanceof Object JavaDoc[]) {
232             Object JavaDoc[] values = (Object JavaDoc[])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 JavaDoc getValueToSave(Object JavaDoc value, Repository repository) {
243         if (fieldType.getValueType() == ValueType.LINK) {
244             VariantManager variantManager = repository.getVariantManager();
245             if (value instanceof Object JavaDoc[]) {
246                 Object JavaDoc[] values = (Object JavaDoc[])value;
247                 Object JavaDoc[] newValues = new Object JavaDoc[values.length];
248                 for (int i = 0; i < values.length; i++)
249                     newValues[i] = LinkFieldHelper.parseVariantKey((String JavaDoc)values[i], variantManager);
250                 value = newValues;
251             } else {
252                 value = LinkFieldHelper.parseVariantKey((String JavaDoc)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     /**
271      * A listener for the link fields that retrieves the document names of
272      * the link targets.
273      */

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 JavaDoc 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 JavaDoc[])) {
297                     value = new Object JavaDoc[] {value};
298                 }
299
300                 VariantManager variantManager = documentEditorForm.getRepository().getVariantManager();
301                 Object JavaDoc[] values = (Object JavaDoc[])value;
302                 for (int i = 0; i < values.length; i++) {
303                     VariantKey variantKey = LinkFieldHelper.parseVariantKey((String JavaDoc)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 JavaDoc[] 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 JavaDoc e) {
327                 // ignore (link in wrong format, ...)
328
}
329         }
330     }
331
332     static class DocNamesReceiver extends DefaultHandler JavaDoc {
333         private String JavaDoc[] names;
334         private int pos = 0;
335
336         public DocNamesReceiver(int count) {
337             this.names = new String JavaDoc[count];
338         }
339
340         public String JavaDoc[] getNames() {
341             return names;
342         }
343
344         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) throws SAXException JavaDoc {
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