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.avalon.framework.service.ServiceException;
020: import org.apache.avalon.framework.service.ServiceManager;
021: import org.apache.avalon.framework.service.Serviceable;
022: import org.apache.cocoon.forms.datatype.Datatype;
023: import org.apache.cocoon.forms.datatype.DynamicSelectionList;
024: import org.apache.cocoon.forms.datatype.FlowJXPathSelectionList;
025: import org.apache.cocoon.forms.datatype.SelectionList;
026: import org.apache.cocoon.forms.event.ValueChangedEvent;
027: import org.apache.cocoon.forms.event.ValueChangedListener;
028: import org.apache.cocoon.forms.event.WidgetEventMulticaster;
029: import org.apache.cocoon.forms.FormsException;
030: import org.apache.cocoon.forms.FormsRuntimeException;
031:
032: /**
033: * Base class for WidgetDefinitions that use a Datatype and SelectionList.
034: *
035: * @version $Id: AbstractDatatypeWidgetDefinition.java 449149 2006-09-23 03:58:05Z crossley $
036: */
037: public abstract class AbstractDatatypeWidgetDefinition extends
038: AbstractWidgetDefinition implements Serviceable {
039:
040: private Datatype datatype;
041: private Object initialValue;
042: private SelectionList selectionList;
043: private ValueChangedListener listener;
044: private ServiceManager manager;
045:
046: public void service(ServiceManager manager) throws ServiceException {
047: checkMutable();
048: this .manager = manager;
049: }
050:
051: /**
052: * checks definition's completeness
053: */
054: public void checkCompleteness() throws IncompletenessException {
055: super .checkCompleteness();
056:
057: if (this .datatype == null) {
058: throw new IncompletenessException("Widget '" + getId()
059: + "' must have a datatype element.", this );
060: }
061: }
062:
063: /**
064: * initialize this definition with the other, sort of like a copy constructor
065: */
066: public void initializeFrom(WidgetDefinition definition)
067: throws Exception {
068: super .initializeFrom(definition);
069:
070: if (!(definition instanceof AbstractDatatypeWidgetDefinition)) {
071: throw new FormsException("Ancestor definition "
072: + definition.getClass().getName()
073: + " is not an AbstractDatatypeWidgetDefinition.",
074: getLocation());
075: }
076:
077: AbstractDatatypeWidgetDefinition other = (AbstractDatatypeWidgetDefinition) definition;
078:
079: this .datatype = other.datatype;
080: this .initialValue = other.initialValue;
081: this .selectionList = other.selectionList;
082: this .listener = other.listener;
083: }
084:
085: public Datatype getDatatype() {
086: return datatype;
087: }
088:
089: public Object getInitialValue() {
090: return this .initialValue;
091: }
092:
093: public void setDatatype(Datatype datatype, Object initialValue) {
094: checkMutable();
095: this .datatype = datatype;
096: this .initialValue = initialValue;
097: }
098:
099: public void setSelectionList(SelectionList selectionList) {
100: checkMutable();
101: if (selectionList != null
102: && selectionList.getDatatype() != getDatatype()) {
103: throw new FormsRuntimeException(
104: "Tried to assign a selection list that is not associated with this widget's datatype.",
105: getLocation());
106: }
107: this .selectionList = selectionList;
108: }
109:
110: public SelectionList getSelectionList() {
111: return selectionList;
112: }
113:
114: /**
115: * Builds a dynamic selection list from a source. This is a helper method for widget instances whose selection
116: * list source has to be changed dynamically, and it does not modify this definition's selection list,
117: * if any.
118: * @param uri The URI of the source.
119: */
120: public SelectionList buildSelectionList(String uri) {
121: return new DynamicSelectionList(datatype, uri, this .manager);
122: }
123:
124: /**
125: * Builds a dynamic selection list from an in-memory collection.
126: * This is a helper method for widget instances whose selection
127: * list has to be changed dynamically, and it does not modify this definition's selection list,
128: * if any.
129: * @see org.apache.cocoon.forms.formmodel.Field#setSelectionList(Object model, String valuePath, String labelPath)
130: * @param model The collection used as a model for the selection list.
131: * @param valuePath An XPath expression referring to the attribute used
132: * to populate the values of the list's items.
133: * @param labelPath An XPath expression referring to the attribute used
134: * to populate the labels of the list's items.
135: */
136: public SelectionList buildSelectionListFromModel(Object model,
137: String valuePath, String labelPath) {
138: return new FlowJXPathSelectionList(model, valuePath, labelPath,
139: datatype);
140: }
141:
142: public void addValueChangedListener(ValueChangedListener listener) {
143: checkMutable();
144: this .listener = WidgetEventMulticaster.add(this .listener,
145: listener);
146: }
147:
148: public void fireValueChangedEvent(ValueChangedEvent event) {
149: if (this .listener != null) {
150: this .listener.valueChanged(event);
151: }
152: }
153:
154: public boolean hasValueChangedListeners() {
155: return this .listener != null;
156: }
157:
158: public ValueChangedListener getValueChangedListener() {
159: return this.listener;
160: }
161: }
|