blob: 4d8060e91ae0762f50fec22301c470c12e990e96 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.forms.formmodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.excalibur.xml.sax.XMLizable;
import org.apache.cocoon.forms.FormsException;
import org.apache.cocoon.forms.FormsRuntimeException;
import org.apache.oro.text.regex.Pattern;
import org.outerj.expression.Expression;
/**
* The {@link WidgetDefinition} part of a AggregateField widget, see {@link AggregateField}
* for more information.
*
* @version $Id$
*/
public class AggregateFieldDefinition extends FieldDefinition {
/**
* Defines expression which combines values of nested fields into this value
*/
private Expression combineExpr;
/**
* Regular expression which splits this value on the values of the nested fields.
* It is compiled into the {@link #splitPattern}.
*/
private String splitRegexp;
/**
* Compiled pattern out of the {@link #splitRegexp} regular expression.
*/
private Pattern splitPattern;
/**
* Message to be displayed when the {@link #setSplitPattern(Pattern, String) splitPattern}
* does not match what the user entered. Optional.
*/
protected XMLizable splitFailMessage;
/**
* List containing instances of {@link SplitMapping}, i.e. the mapping between
* a group (paren) from the regular expression and corresponding field id.
*/
private List splitMappings = new ArrayList();
/**
* Set containing widgets mapped to groups to find out if a specific widget has been mapped already
*/
private Set mappedFields = new HashSet();
/**
*
*/
private WidgetDefinitionList container = new WidgetDefinitionList(this);
/**
* initialize this definition with the other, sort of like a copy constructor
*/
public void initializeFrom(WidgetDefinition definition) throws Exception {
super.initializeFrom(definition);
if (!(definition instanceof AggregateFieldDefinition)) {
throw new FormsException("Ancestor definition " + definition.getClass().getName() + " is not an AggregateFieldDefinition.",
getLocation());
}
AggregateFieldDefinition other = (AggregateFieldDefinition) definition;
this.combineExpr = other.combineExpr;
this.splitRegexp = other.splitRegexp;
this.splitPattern = other.splitPattern;
this.splitFailMessage = other.splitFailMessage;
Iterator defs = other.container.getWidgetDefinitions().iterator();
while (defs.hasNext()) {
container.addWidgetDefinition((WidgetDefinition) defs.next());
}
Collections.copy(this.splitMappings, other.splitMappings);
Iterator fields = other.mappedFields.iterator();
while (fields.hasNext()) {
this.mappedFields.add(fields.next());
}
}
public void addWidgetDefinition(WidgetDefinition widgetDefinition) throws DuplicateIdException {
checkMutable();
container.addWidgetDefinition(widgetDefinition);
}
/**
* checks completeness of this definition
*/
public void checkCompleteness() throws IncompletenessException {
super.checkCompleteness();
if (this.container.size() == 0) {
throw new IncompletenessException("Aggregate field '" + getId() + "' doesn't have any child widgets.", this);
}
if (this.combineExpr == null) {
throw new IncompletenessException("Aggregate field '" + getId() + "' requires combine expression.", this);
}
if (this.splitPattern == null) {
throw new IncompletenessException("Aggregate field '" + getId() + "' requires split regular expression.", this);
}
if (this.splitMappings.size() == 0) {
throw new IncompletenessException("Aggregate field '" + getId() + "' requires at least one group to field mapping.", this);
}
// now check children's completeness
Iterator i = container.getWidgetDefinitions().iterator();
while (i.hasNext()) {
((WidgetDefinition) i.next()).checkCompleteness();
}
}
public boolean hasWidget(String id) {
return container.hasWidget(id);
}
protected void setCombineExpression(Expression expression) {
checkMutable();
combineExpr = expression;
}
public Expression getCombineExpression() {
return combineExpr;
}
protected void setSplitPattern(Pattern pattern, String regexp) {
checkMutable();
this.splitPattern = pattern;
this.splitRegexp = regexp;
}
public Pattern getSplitPattern() {
return splitPattern;
}
public String getSplitRegexp() {
return splitRegexp;
}
public XMLizable getSplitFailMessage() {
return splitFailMessage;
}
protected void setSplitFailMessage(XMLizable splitFailMessage) {
checkMutable();
this.splitFailMessage = splitFailMessage;
}
protected void addSplitMapping(int group, String fieldId) {
checkMutable();
if (mappedFields.contains(fieldId)) {
throw new FormsRuntimeException("Field '" + fieldId + "' is already mapped to another group.",
getLocation());
}
mappedFields.add(fieldId);
splitMappings.add(new SplitMapping(group, fieldId));
}
public Iterator getSplitMappingsIterator() {
return splitMappings.iterator();
}
public Widget createInstance() {
AggregateField aggregateField = new AggregateField(this);
Iterator i = container.getWidgetDefinitions().iterator();
while (i.hasNext()) {
FieldDefinition fieldDefinition = (FieldDefinition) i.next();
aggregateField.addField((Field) fieldDefinition.createInstance());
}
return aggregateField;
}
public static class SplitMapping {
private int group;
private String fieldId;
public SplitMapping(int group, String fieldId) {
this.group = group;
this.fieldId = fieldId;
}
public int getGroup() {
return group;
}
public String getFieldId() {
return fieldId;
}
}
}