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