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.formmodel;
018:
019: import org.apache.cocoon.woody.Constants;
020: import org.apache.cocoon.woody.util.DomHelper;
021: import org.apache.excalibur.xml.sax.XMLizable;
022: import org.apache.oro.text.regex.MalformedPatternException;
023: import org.apache.oro.text.regex.Pattern;
024: import org.apache.oro.text.regex.Perl5Compiler;
025:
026: import org.outerj.expression.Expression;
027: import org.w3c.dom.Element;
028:
029: import java.util.HashSet;
030:
031: /**
032: * Builds {@link AggregateFieldDefinition}s.
033: *
034: * @version $Id: AggregateFieldDefinitionBuilder.java 433543 2006-08-22 06:22:54Z crossley $
035: */
036: public class AggregateFieldDefinitionBuilder extends
037: FieldDefinitionBuilder {
038:
039: public WidgetDefinition buildWidgetDefinition(Element widgetElement)
040: throws Exception {
041: AggregateFieldDefinition aggregateDefinition = new AggregateFieldDefinition();
042: buildWidgetDefinition(aggregateDefinition, widgetElement);
043:
044: // make children fields
045: Element widgetsElement = DomHelper.getChildElement(
046: widgetElement, Constants.WD_NS, "widgets", true);
047: Element[] fieldElements = DomHelper.getChildElements(
048: widgetsElement, Constants.WD_NS, "field");
049: for (int i = 0; i < fieldElements.length; i++) {
050: FieldDefinition fieldDefinition = (FieldDefinition) buildAnotherWidgetDefinition(fieldElements[i]);
051: aggregateDefinition.addWidgetDefinition(fieldDefinition);
052: }
053:
054: // compile splitpattern
055: Element splitElement = DomHelper.getChildElement(widgetElement,
056: Constants.WD_NS, "split", true);
057: String patternString = DomHelper.getAttribute(splitElement,
058: "pattern");
059: Perl5Compiler compiler = new Perl5Compiler();
060: Pattern pattern = null;
061: try {
062: pattern = compiler.compile(patternString,
063: Perl5Compiler.READ_ONLY_MASK);
064: } catch (MalformedPatternException e) {
065: throw new Exception("Invalid regular expression at "
066: + DomHelper.getLocation(splitElement) + ": "
067: + e.getMessage());
068: }
069: aggregateDefinition.setSplitPattern(pattern, patternString);
070:
071: // read split mappings
072: Element[] mapElements = DomHelper.getChildElements(
073: splitElement, Constants.WD_NS, "map");
074: HashSet encounteredFieldMappings = new HashSet();
075: for (int i = 0; i < mapElements.length; i++) {
076: int group = DomHelper.getAttributeAsInteger(mapElements[i],
077: "group");
078: String field = DomHelper.getAttribute(mapElements[i],
079: "field");
080: // check that this field exists
081: if (!aggregateDefinition.hasWidget(field)) {
082: throw new Exception("Unkwon widget id \"" + field
083: + "\", at "
084: + DomHelper.getLocation(mapElements[i]));
085: }
086: if (encounteredFieldMappings.contains(field)) {
087: throw new Exception(
088: "Two groups are mapped to the same widget id \""
089: + field + "\", at "
090: + DomHelper.getLocation(mapElements[i]));
091: }
092: encounteredFieldMappings.add(field);
093: aggregateDefinition.addSplitMapping(group, field);
094: }
095:
096: // read split fail message (if any)
097: Element failMessageElement = DomHelper.getChildElement(
098: splitElement, Constants.WD_NS, "failmessage");
099: if (failMessageElement != null) {
100: XMLizable failMessage = DomHelper
101: .compileElementContent(failMessageElement);
102: aggregateDefinition.setSplitFailMessage(failMessage);
103: }
104:
105: // compile combine expression
106: Element combineElement = DomHelper.getChildElement(
107: widgetElement, Constants.WD_NS, "combine", true);
108: String combineExprString = DomHelper.getAttribute(
109: combineElement, "expression");
110: Expression combineExpr = null;
111: try {
112: combineExpr = expressionManager.parse(combineExprString);
113: } catch (Exception e) {
114: throw new Exception(
115: "Problem with combine expression defined at "
116: + DomHelper.getLocation(combineElement)
117: + ": " + e.getMessage());
118: }
119: Class clazz = aggregateDefinition.getDatatype().getTypeClass();
120: if (combineExpr.getResultType() != null
121: && !clazz.isAssignableFrom(combineExpr.getResultType())) {
122: throw new Exception(
123: "The result of the combine expression should be "
124: + clazz.getName() + ", at "
125: + DomHelper.getLocation(combineElement));
126: }
127: aggregateDefinition.setCombineExpression(combineExpr);
128:
129: return aggregateDefinition;
130: }
131: }
|