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.FormContext;
021: import org.apache.cocoon.woody.event.WidgetEvent;
022: import org.apache.cocoon.woody.event.ValueChangedEvent;
023: import org.apache.cocoon.xml.AttributesImpl;
024: import org.xml.sax.ContentHandler;
025: import org.xml.sax.SAXException;
026:
027: import java.util.Locale;
028:
029: /**
030: * A widget to select a boolean value. Usually rendered as a checkbox.
031: *
032: * <p>You may wonder why we don't use a {@link Field} widget with an associated
033: * Boolean Datatype instead. The reason is that many of the features of the Field
034: * widget are overkill for a Boolean: validation is unnecessary (if the field is
035: * not true it is false), the selectionlist associated with a Datatype also
036: * has no purpose here (there would always be only 2 choices: true or false),
037: * and the manner in which the request parameter of this widget is interpreted
038: * is different (missing or empty request parameter means 'false', rather than null value).
039: *
040: * @version $Id: BooleanField.java 433543 2006-08-22 06:22:54Z crossley $
041: */
042: public class BooleanField extends AbstractWidget {
043: // FIXME(SW) : should the initial value be false or null ? This would allow
044: // event listeners to be triggered at bind time.
045: private Boolean value = Boolean.FALSE;
046: private BooleanFieldDefinition definition;
047:
048: public BooleanField(BooleanFieldDefinition definition) {
049: this .definition = definition;
050: setLocation(definition.getLocation());
051: }
052:
053: public String getId() {
054: return definition.getId();
055: }
056:
057: public void readFromRequest(FormContext formContext) {
058: Object oldValue = value;
059: String param = formContext.getRequest().getParameter(
060: getFullyQualifiedId());
061: if (param != null && param.equalsIgnoreCase("true"))
062: value = Boolean.TRUE;
063: else
064: value = Boolean.FALSE;
065:
066: if (value != oldValue) {
067: getForm().addWidgetEvent(
068: new ValueChangedEvent(this , oldValue, value));
069: }
070: }
071:
072: /**
073: * Always return <code>true</code> (an action has no validation)
074: *
075: * @todo is there a use case for boolean fields having validators?
076: */
077: public boolean validate(FormContext formContext) {
078: // a boolean field is always valid
079: return true;
080: }
081:
082: private static final String BOOLEAN_FIELD_EL = "booleanfield";
083: private static final String VALUE_EL = "value";
084:
085: public void generateSaxFragment(ContentHandler contentHandler,
086: Locale locale) throws SAXException {
087: AttributesImpl fieldAttrs = new AttributesImpl();
088: fieldAttrs.addCDATAAttribute("id", getFullyQualifiedId());
089: contentHandler.startElement(Constants.WI_NS, BOOLEAN_FIELD_EL,
090: Constants.WI_PREFIX_COLON + BOOLEAN_FIELD_EL,
091: fieldAttrs);
092:
093: // value element
094: contentHandler.startElement(Constants.WI_NS, VALUE_EL,
095: Constants.WI_PREFIX_COLON + VALUE_EL,
096: Constants.EMPTY_ATTRS);
097: String stringValue = String.valueOf(value != null
098: && value.booleanValue() == true ? "true" : "false");
099: contentHandler.characters(stringValue.toCharArray(), 0,
100: stringValue.length());
101: contentHandler.endElement(Constants.WI_NS, VALUE_EL,
102: Constants.WI_PREFIX_COLON + VALUE_EL);
103:
104: // generate label, help, hint, etc.
105: definition.generateDisplayData(contentHandler);
106:
107: contentHandler.endElement(Constants.WI_NS, BOOLEAN_FIELD_EL,
108: Constants.WI_PREFIX_COLON + BOOLEAN_FIELD_EL);
109: }
110:
111: public void generateLabel(ContentHandler contentHandler)
112: throws SAXException {
113: definition.generateLabel(contentHandler);
114: }
115:
116: public Object getValue() {
117: return value;
118: }
119:
120: /**
121: * Sets value of the field. If value is null, it is considered to be false
122: * (see class comment).
123: */
124: public void setValue(Object object) {
125: if (object == null) {
126: object = Boolean.FALSE;
127: }
128:
129: if (!(object instanceof Boolean)) {
130: throw new RuntimeException(
131: "Cannot set value of boolean field \""
132: + getFullyQualifiedId()
133: + "\" to a non-Boolean value.");
134: }
135:
136: Object oldValue = value;
137: value = (Boolean) object;
138: if (value != oldValue) {
139: getForm().addWidgetEvent(
140: new ValueChangedEvent(this , oldValue, value));
141: }
142: }
143:
144: public void broadcastEvent(WidgetEvent event) {
145: this .definition
146: .fireValueChangedEvent((ValueChangedEvent) event);
147: }
148: }
|