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.event.impl;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import org.apache.avalon.framework.configuration.Configurable;
024: import org.apache.avalon.framework.configuration.Configuration;
025: import org.apache.avalon.framework.configuration.ConfigurationException;
026: import org.apache.cocoon.forms.event.ProcessingPhase;
027: import org.apache.cocoon.forms.event.ProcessingPhaseEvent;
028: import org.apache.cocoon.forms.event.ProcessingPhaseListener;
029: import org.apache.cocoon.forms.formmodel.Field;
030: import org.apache.cocoon.forms.formmodel.Widget;
031:
032: /**
033: * This processing phase listener can be used to dynamically change the
034: * required fields in a form.
035: * A field can be required depending on the value of another field or
036: * depending on the pressed submit button.
037: *
038: * @version $Id: RequiredControl.java 449149 2006-09-23 03:58:05Z crossley $
039: */
040: public class RequiredControl implements ProcessingPhaseListener,
041: Configurable {
042:
043: protected final List descriptions = new ArrayList();
044:
045: /**
046: * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
047: */
048: public void configure(Configuration config)
049: throws ConfigurationException {
050: final Configuration[] children = config.getChildren("required");
051: for (int i = 0; i < children.length; i++) {
052: final Configuration current = children[i];
053: RequiredDescription desc;
054: final String refId = current.getAttribute("widget-id");
055: if (current.getAttribute("submit-id", null) != null) {
056: desc = new RequiredDescription(refId, current
057: .getAttribute("submit-id"));
058: } else {
059: final String path = current.getAttribute("widget-path");
060: final String value = current
061: .getAttribute("widget-value");
062: desc = new RequiredDescription(refId, path, value);
063: }
064: this .descriptions.add(desc);
065: }
066: }
067:
068: /**
069: * @see org.apache.cocoon.forms.event.ProcessingPhaseListener#phaseEnded(org.apache.cocoon.forms.event.ProcessingPhaseEvent)
070: */
071: public void phaseEnded(ProcessingPhaseEvent event) {
072: if (event.getPhase().getValue() == ProcessingPhase.READ_FROM_REQUEST_VALUE
073: || event.getPhase().getValue() == ProcessingPhase.LOAD_MODEL_VALUE) {
074: final Iterator i = this .descriptions.iterator();
075: while (i.hasNext()) {
076: final RequiredDescription desc = (RequiredDescription) i
077: .next();
078: desc.process(event.getSourceWidget());
079: }
080: }
081: }
082:
083: protected static final class RequiredDescription {
084:
085: final static int DEPENDS_REQUIRED_MODE = 1;
086: final static int SUBMIT_REQUIRED_MODE = 2;
087:
088: protected final int mode;
089: protected final String referenceId;
090: protected String widgetName;
091: protected String widgetValue;
092:
093: public RequiredDescription(String referenceId, String submitId) {
094: this .mode = SUBMIT_REQUIRED_MODE;
095: this .referenceId = referenceId;
096: this .widgetName = submitId;
097: }
098:
099: public RequiredDescription(String referenceId, String widget,
100: String value) {
101: this .mode = DEPENDS_REQUIRED_MODE;
102: this .referenceId = referenceId;
103: this .widgetName = widget;
104: this .widgetValue = value;
105: }
106:
107: /**
108: * @see org.apache.cocoon.forms.validation.WidgetValidator#validate(org.apache.cocoon.forms.formmodel.Widget)
109: */
110: public void process(Widget form) {
111: final Widget widget = form.lookupWidget(this .referenceId);
112: if (widget == null) {
113: throw new IllegalArgumentException("Widget '"
114: + this .referenceId + "' not found in form.");
115: }
116: if (!(widget instanceof Field)) {
117: // Invalid widget type
118: throw new IllegalArgumentException("Widget '"
119: + widget.getRequestParameterName()
120: + "' is not a Field");
121: }
122:
123: boolean required = false;
124: if (mode == DEPENDS_REQUIRED_MODE) {
125: final Widget w = form.lookupWidget(this .widgetName);
126: if (w != null) {
127: if (w.getValue() != null
128: && w.getValue().equals(this .widgetValue)) {
129: required = true;
130: }
131: }
132: } else if (mode == SUBMIT_REQUIRED_MODE) {
133: if (widget.getForm().getSubmitWidget() != null) {
134: if (this .widgetName.equals(widget.getForm()
135: .getSubmitWidget().getId())) {
136: required = true;
137: }
138: }
139: }
140: ((Field) widget).setRequired(required);
141: }
142: }
143: }
|