001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.frontend.editor;
017:
018: import org.apache.cocoon.forms.datatype.Datatype;
019: import org.apache.cocoon.forms.datatype.convertor.Convertor;
020: import org.apache.cocoon.forms.datatype.convertor.DefaultFormatCache;
021: import org.apache.cocoon.forms.FormsConstants;
022: import org.apache.cocoon.xml.XMLUtils;
023: import org.apache.cocoon.xml.AttributesImpl;
024: import org.xml.sax.ContentHandler;
025: import org.xml.sax.SAXException;
026: import org.outerj.daisy.repository.schema.SelectionList;
027: import org.outerj.daisy.repository.schema.ListItem;
028: import org.outerj.daisy.repository.ValueType;
029: import org.outerj.daisy.repository.VariantKey;
030: import org.outerj.daisy.repository.RepositoryException;
031: import org.outerj.daisy.repository.variant.VariantManager;
032:
033: import java.util.Locale;
034: import java.util.List;
035:
036: /**
037: * Adapts a Daisy selection list to a CForms selection list.
038: */
039: public class SelectionListAdapter implements
040: org.apache.cocoon.forms.datatype.SelectionList {
041: private Datatype datatype;
042: private SelectionList selectionList;
043: private boolean includeEmpty;
044: private ValueType fieldValueType;
045: private boolean hierarchicalFieldType;
046: private VariantManager variantManager;
047: private long documentBranchId;
048: private long documentLanguageId;
049:
050: public SelectionListAdapter(Datatype datatype,
051: SelectionList selectionList, boolean includeEmpty,
052: ValueType fieldValueType, boolean hierarchicalFieldType,
053: VariantManager variantManager, long documentBranchId,
054: long documentLanguageId) {
055: this .datatype = datatype;
056: this .selectionList = selectionList;
057: this .includeEmpty = includeEmpty;
058: this .fieldValueType = fieldValueType;
059: this .hierarchicalFieldType = hierarchicalFieldType;
060: this .variantManager = variantManager;
061: this .documentBranchId = documentBranchId;
062: this .documentLanguageId = documentLanguageId;
063: }
064:
065: public Datatype getDatatype() {
066: return datatype;
067: }
068:
069: public void generateSaxFragment(ContentHandler contentHandler,
070: Locale locale) throws SAXException {
071: generateSaxFragment(contentHandler, locale, false);
072: }
073:
074: /**
075: *
076: * @param hierarchical should a hierarchical list be generated, that is, a list in which items can again contain
077: * items. Note that a Daisy hierarchical selection list can be generated as either a flat
078: * or hierarchical CForms list.
079: */
080: public void generateSaxFragment(ContentHandler contentHandler,
081: Locale locale, boolean hierarchical) throws SAXException {
082: List<? extends ListItem> items = selectionList.getItems(
083: documentBranchId, documentLanguageId, locale);
084: Convertor.FormatCache formatCache = new DefaultFormatCache();
085: AttributesImpl rootAttrs = new AttributesImpl();
086: rootAttrs.addCDATAAttribute("hierarchical", String
087: .valueOf(hierarchical));
088: contentHandler.startElement(FormsConstants.INSTANCE_NS,
089: SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON
090: + SELECTION_LIST_EL, rootAttrs);
091:
092: if (includeEmpty) {
093: AttributesImpl itemAttrs = new AttributesImpl();
094: itemAttrs.addCDATAAttribute("value", "");
095: contentHandler.startElement(FormsConstants.INSTANCE_NS,
096: ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON
097: + ITEM_EL, itemAttrs);
098: contentHandler.startElement(FormsConstants.INSTANCE_NS,
099: LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON
100: + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
101: contentHandler.endElement(FormsConstants.INSTANCE_NS,
102: LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON
103: + LABEL_EL);
104: contentHandler.endElement(FormsConstants.INSTANCE_NS,
105: ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON
106: + ITEM_EL);
107: }
108:
109: generateSaxFragment(items, contentHandler, locale,
110: hierarchical, null, null, null, formatCache);
111:
112: contentHandler.endElement(FormsConstants.INSTANCE_NS,
113: SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON
114: + SELECTION_LIST_EL);
115: }
116:
117: /**
118: *
119: * @param hierarchical indicates whether the list should be generated hierarchically, not whether the field type
120: * itself is hierarchical
121: */
122: private void generateSaxFragment(List<? extends ListItem> items,
123: ContentHandler contentHandler, Locale locale,
124: boolean hierarchical, String parentValue,
125: String parentLabelPrefix, String parentHierarchicalLabel,
126: Convertor.FormatCache formatCache) throws SAXException {
127: for (ListItem item : items) {
128: // convert value to string
129: String stringValue;
130: if (fieldValueType == ValueType.LINK)
131: stringValue = variantKeyToString((VariantKey) item
132: .getValue());
133: else
134: stringValue = datatype.getConvertor().convertToString(
135: item.getValue(), locale, formatCache);
136:
137: // make value hierarchical if needed
138: String fullStringValue = parentValue != null
139: && hierarchicalFieldType ? parentValue + " / "
140: + stringValue : stringValue;
141:
142: List<? extends ListItem> children = item.getItems();
143:
144: // Determine label
145: String label = item.getLabel(locale);
146: if (label == null)
147: label = stringValue;
148: if (label == null) // label for null value: empty string
149: label = "";
150:
151: String hierarchicalLabel = parentHierarchicalLabel == null ? label
152: : parentHierarchicalLabel + " / " + label;
153:
154: if (!hierarchical) {
155: // if a hierarchical list is generated as flat list, the labels are indented a bit
156: label = parentLabelPrefix == null ? label
157: : parentLabelPrefix + label;
158: }
159:
160: String labelPrefix = null;
161: if (children.size() > 0) {
162: labelPrefix = parentLabelPrefix == null ? "\u00A0\u00A0"
163: : parentLabelPrefix + "\u00A0\u00A0";
164: }
165:
166: AttributesImpl itemAttrs = new AttributesImpl();
167: itemAttrs.addCDATAAttribute("value", fullStringValue);
168: if (hierarchicalLabel != null)
169: itemAttrs.addCDATAAttribute("hierarchicalLabel",
170: hierarchicalLabel);
171: contentHandler.startElement(FormsConstants.INSTANCE_NS,
172: ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON
173: + ITEM_EL, itemAttrs);
174: contentHandler.startElement(FormsConstants.INSTANCE_NS,
175: LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON
176: + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
177:
178: contentHandler.characters(label.toCharArray(), 0, label
179: .length());
180:
181: contentHandler.endElement(FormsConstants.INSTANCE_NS,
182: LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON
183: + LABEL_EL);
184:
185: if (hierarchical) {
186: generateSaxFragment(children, contentHandler, locale,
187: hierarchical, fullStringValue, labelPrefix,
188: hierarchicalLabel, formatCache);
189: }
190:
191: contentHandler.endElement(FormsConstants.INSTANCE_NS,
192: ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON
193: + ITEM_EL);
194:
195: if (!hierarchical) {
196: generateSaxFragment(children, contentHandler, locale,
197: hierarchical, fullStringValue, labelPrefix,
198: hierarchicalLabel, formatCache);
199: }
200: }
201: }
202:
203: /**
204: * Converts a variant key to string representation, but does not add the branch and language if they
205: * are the same as the document that is being edited.
206: */
207: private String variantKeyToString(VariantKey variantKey) {
208: StringBuilder text = new StringBuilder(20);
209: text.append("daisy:");
210: text.append(variantKey.getDocumentId());
211: long branchId = variantKey.getBranchId() == -1 ? documentBranchId
212: : variantKey.getBranchId();
213: long languageId = variantKey.getLanguageId() == -1 ? documentLanguageId
214: : variantKey.getLanguageId();
215: if (branchId != documentBranchId
216: || languageId != documentLanguageId) {
217: text.append("@");
218: if (branchId != documentBranchId) {
219: String branchName;
220: try {
221: branchName = variantManager.getBranch(
222: variantKey.getBranchId(), false).getName();
223: } catch (RepositoryException e) {
224: branchName = String.valueOf(variantKey
225: .getBranchId());
226: }
227: text.append(branchName);
228: }
229: if (languageId != documentLanguageId) {
230: text.append(":");
231: String languageName;
232: try {
233: languageName = variantManager.getLanguage(
234: variantKey.getLanguageId(), false)
235: .getName();
236: } catch (RepositoryException e) {
237: languageName = String.valueOf(variantKey
238: .getLanguageId());
239: }
240: text.append(languageName);
241: }
242: }
243: return text.toString();
244: }
245: }
|