001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.woody.binding;
018:
019: import java.util.Locale;
020:
021: import org.apache.cocoon.i18n.I18nUtils;
022: import org.apache.cocoon.woody.Constants;
023: import org.apache.cocoon.woody.datatype.convertor.Convertor;
024: import org.apache.cocoon.woody.util.DomHelper;
025: import org.w3c.dom.Element;
026:
027: /**
028: * RepeaterJXPathBindingBuilder provides a helper class for the Factory
029: * implemented in {@link JXPathBindingManager} that helps construct the
030: * actual {@link RepeaterJXPathBinding} out of the configuration in the
031: * provided configElement which looks like:
032: * <pre><code>
033: * <wb:repeater
034: * id="contacts"
035: * parent-path="contacts"
036: * row-path="contact"
037: * unique-row-id="id"
038: * unique-path="@id" >
039: *
040: * <wb:on-bind>
041: * <!-- nested bindings executed on updates AND right after the insert -->
042: * </wb:on-bind>
043: *
044: * <wb:on-delete-row>
045: * <!-- nested bindings executed on deletion of row -->
046: * </wb:on-delete-row>
047: *
048: * <wb:on-insert-row>
049: * <!-- nested bindings executed to prepare the insertion of a row -->
050: * </wb:on-insert-row>
051: *
052: * </wb:repeater>
053: * </code></pre>
054: *
055: * @version CVS $Id: RepeaterJXPathBindingBuilder.java 433543 2006-08-22 06:22:54Z crossley $
056: */
057: public class RepeaterJXPathBindingBuilder extends
058: JXPathBindingBuilderBase {
059:
060: /**
061: * Creates an instance of {@link RepeaterJXPathBinding} according to the
062: * attributes and nested comfiguration elements of the bindingElm.
063: *
064: * @param bindingElm
065: * @param assistant
066: * @return JXPathBindingBase
067: */
068: public JXPathBindingBase buildBinding(Element bindingElm,
069: JXPathBindingManager.Assistant assistant)
070: throws BindingException {
071:
072: try {
073: CommonAttributes commonAtts = JXPathBindingBuilderBase
074: .getCommonAttributes(bindingElm);
075:
076: String repeaterId = DomHelper
077: .getAttribute(bindingElm, "id");
078: String parentPath = DomHelper.getAttribute(bindingElm,
079: "parent-path");
080: String rowPath = DomHelper.getAttribute(bindingElm,
081: "row-path");
082: String rowPathForInsert = DomHelper.getAttribute(
083: bindingElm, "row-path-insert", rowPath);
084: String uniqueRowId = DomHelper.getAttribute(bindingElm,
085: "unique-row-id", null);
086: String uniqueRowIdPath = DomHelper.getAttribute(bindingElm,
087: "unique-path", null);
088:
089: Convertor convertor = null;
090: Locale convertorLocale = Locale.US;
091: Element convertorEl = DomHelper.getChildElement(bindingElm,
092: Constants.WD_NS, "convertor");
093: if (convertorEl != null) {
094: String datatype = DomHelper.getAttribute(convertorEl,
095: "datatype");
096: String localeStr = convertorEl.getAttribute("datatype");
097: if (!localeStr.equals("")) {
098: convertorLocale = I18nUtils.parseLocale(localeStr);
099: }
100: convertor = assistant.getDatatypeManager()
101: .createConvertor(datatype, convertorEl);
102: }
103:
104: Element childWrapElement = DomHelper.getChildElement(
105: bindingElm, BindingManager.NAMESPACE, "on-bind");
106: if (childWrapElement == null) {
107: throw new BindingException(
108: "RepeaterBinding misses '<on-bind>' child definition. "
109: + DomHelper.getLocation(bindingElm));
110: }
111: JXPathBindingBase[] childBindings = assistant
112: .makeChildBindings(childWrapElement);
113:
114: Element deleteWrapElement = DomHelper.getChildElement(
115: bindingElm, BindingManager.NAMESPACE,
116: "on-delete-row");
117: JXPathBindingBase[] deleteBindings = null;
118: if (deleteWrapElement != null) {
119: deleteBindings = assistant
120: .makeChildBindings(deleteWrapElement);
121: }
122:
123: Element insertWrapElement = DomHelper.getChildElement(
124: bindingElm, BindingManager.NAMESPACE,
125: "on-insert-row");
126: JXPathBindingBase insertBinding = null;
127: if (insertWrapElement != null) {
128: insertBinding = assistant
129: .makeChildBindings(insertWrapElement)[0];
130: }
131: /* New <wb:unique-row> child element builder */
132: Element uniqueFieldWrapElement = DomHelper.getChildElement(
133: bindingElm, BindingManager.NAMESPACE, "unique-row");
134: JXPathBindingBase[] uniqueFieldBinding = null;
135: if (uniqueFieldWrapElement != null) {
136: uniqueFieldBinding = assistant
137: .makeChildBindings(uniqueFieldWrapElement);
138: } else if (uniqueRowId == null || uniqueRowIdPath == null) {
139: throw new BindingException(
140: "RepeaterBinding misses '<unique-row>' child definition. "
141: + DomHelper.getLocation(bindingElm));
142: } else {
143: if (this .getLogger().isInfoEnabled()) {
144: this
145: .getLogger()
146: .info(
147: "<wb:repeater>: The attributes 'unique-row-id' and "
148: + "'unique-path' are deprecated. Use <unique-row> child element instead."
149: + " Located at "
150: + DomHelper
151: .getLocation(bindingElm));
152: }
153: }
154:
155: RepeaterJXPathBinding repeaterBinding = new RepeaterJXPathBinding(
156: commonAtts, repeaterId, parentPath, rowPath,
157: rowPathForInsert, uniqueRowId, uniqueRowIdPath,
158: convertor, convertorLocale, childBindings,
159: insertBinding, deleteBindings, uniqueFieldBinding);
160: return repeaterBinding;
161: } catch (BindingException e) {
162: throw e;
163: } catch (Exception e) {
164: throw new BindingException(
165: "Error building repeater binding defined at "
166: + DomHelper.getLocation(bindingElm), e);
167: }
168: }
169: }
|