blob: b73763ecb5592f3e1bedfd3bc6839aaacd0676a0 [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 org.apache.cocoon.forms.FormContext;
import org.apache.cocoon.forms.validation.WidgetValidator;
import org.apache.cocoon.forms.event.WidgetEvent;
import org.apache.cocoon.util.location.Locatable;
import org.apache.cocoon.util.location.Location;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import java.util.Locale;
/**
* Interface to be implemented by Widgets. In CForms, a form consists of a number
* of widgets. Each widget:
*
* <ul>
* <li>has an unique id within its parent context widget. See {@link #getId()}.</li>
* <li>can have a parent (see {@link #getParent()}.</li>
* <li>can hold a value (which can be any kind of object). See {@link #getValue()}.</li>
* <li>can read its value from a request object (and convert it from a string to its native type).
* See {@link #readFromRequest(FormContext)}.</li>
* <li>can validate itself. See {@link #validate()}.</li>
* <li>can generate an XML representation of itself.</li>
* </ul>
*
* <p>When a request is submitted, first the {@link #readFromRequest(FormContext)} method of all widgets
* will be called so that they can read their value(s). Next, the {@link #validate()} method will
* be called. Doing this in two steps allows the validation to compare values between widgets.
* See also the method {@link Form#process(FormContext)}.</p>
*
* <p>A Widget is created by calling the createInstance method on the a
* {@link WidgetDefinition}. A Widget holds all the data that is specific for
* a certain use of the widget (its value, validationerrors, ...), while the
* WidgetDefinition holds the data that is static accross all widgets. This
* keeps the Widgets small and light to create. This mechanism is similar to
* classes and objects in Java.
*
* @version $Id$
*/
public interface Widget extends Locatable {
/**
* Widget-Separator used in path-like notations
* @see #lookupWidget(String)
*/
char PATH_SEPARATOR = '/';
/**
* Called after widget's environment has been setup,
* to allow for any contextual initalization such as
* looking up case widgets for union widgets.
*/
void initialize();
/**
* @return the source location of this widget.
*/
Location getLocation();
/**
* @return the name of this widget. This should never be <code>null</code>
* Top-level container widgets (like 'form') should return <code>""</code>
*/
String getName();
/**
* @return the id of this widget. This should never be <code>null</code>
* Top-level container widgets (like 'form') should return <code>""</code>
*/
String getId();
/**
* @return the parent of this widget. If this widget is the root widget,
* this method returns null.
*/
Widget getParent();
/**
* This method is called on a widget when it is added to a container.
* You shouldn't call this method unless youre implementing a widget yourself (in
* which case it should be called when a widget is added as child of your widget).
*/
void setParent(Widget widget);
/**
* @return the {@link Form} to which this widget belongs. The form is the top-most ancestor
* of the widget.
*/
Form getForm();
/**
* Get this widget's definition.
*
* @return the widget's definition
*/
WidgetDefinition getDefinition();
/**
* Get the widget's own state. Note that this state is <em>not</em> the one actually considered
* for handling requests and producing output. For these matters, the combined state is used.
*
* @see #getCombinedState()
* @return the widget's own state
*/
WidgetState getState();
/**
* Set the widget's own state. This may change its combined state, and those of its
* children, if any.
*
* @param state the new wiget state
*/
void setState(WidgetState state);
/**
* Get the widget's combined state, which is the strictest of its own state and parent state.
* This combined state is the one that will be used by the widget to know if request
* parameters should be considered and if some output must be produced.
*
* @see WidgetState#strictest(WidgetState, WidgetState)
* @return the combined state
*/
WidgetState getCombinedState();
/**
* @return the name prefixed with the namespace, this name should be unique
* accross all widgets on the form.
*/
String getFullName();
/**
* @return the id prefixed with the namespace, this name should be unique
* accross all widgets on the form.
*/
String getRequestParameterName();
/**
* @deprecated getWidget got removed, use lookupWidget or getChild instead.
* @throws UnsupportedOperationException indicating this method has been
* deprecated from the API, and will be removed from future releases.
*/
Widget getWidget(String id);
/**
* Finds a widget relative to this one based on a path-like
* string (/-delimted) into the widget-tree structure.
* This supports '../' and '/' to point to
* @return the found widget or <code>null</code> if allong the traversal
* of the path an invalid section was encountered.
*/
Widget lookupWidget(String path);
/**
* Lets this widget read its data from a request. At this point the Widget
* may try to convert the request parameter to its native datatype (if it
* is not a string), but it should not yet generate any validation errors.
*/
void readFromRequest(FormContext formContext);
/**
* Validates this widget and returns the outcome. Possible error messages are
* remembered by the widget itself and will be part of the XML produced by
* this widget in its {@link #generateSaxFragment(ContentHandler, Locale)} method.
*
* @return <code>true</code> to indicate all validations were ok,
* <code>false</code> otherwise
*/
boolean validate();
void addValidator(WidgetValidator validator);
boolean removeValidator(WidgetValidator validator);
/**
* Return the current validation state.
* This method delivers the same result as the last call to {@link #validate()}.
* The validation process is not started again. If the value of this widget has
* changed since the latest call to {@link #validate()}, the result of this method
* is out of date.
* @return The result of the last call to {@link #validate()}.
*/
boolean isValid();
/**
* Generates an XML representation of this widget. The startDocument and endDocument
* SAX events will not be called. It is assumed that the prefix for the CForms namespace
* mentioned in Constants.FI_PREFIX is already declared (by the caller or otherwise).
*/
void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException;
/**
* Generates SAX events for the label of this widget. The label will not be wrapped
* inside another element.
*/
void generateLabel(ContentHandler contentHandler) throws SAXException;
/**
* Get the value of a widget.
* <p>
* Not all widgets do have a value (notably {@link ContainerWidget}s,
* but this method is provided here as a convenience to ease writing and avoiding casts.
*
* @return the value of the widget.
* @throws UnsupportedOperationException if this widget doesn't have a value.
*/
Object getValue() throws UnsupportedOperationException;
/**
* Sets the value of this widget.
* <p>
* Not all widgets do have a value (notably {@link ContainerWidget}s,
* but this method is provided here as a convenience to ease writing and avoiding casts.
*
* @param value the new widget's value.
* @throws UnsupportedOperationException if this widget doesn't have a value.
*/
void setValue(Object value) throws UnsupportedOperationException;
/**
* @return whether this widget is required to be filled in. As with {@link #getValue()},
* for some widgets this may not make sense, those should return false here.
*/
boolean isRequired();
/**
* Broadcast an event previously queued by this widget to its event listeners.
*/
void broadcastEvent(WidgetEvent event);
/**
* Retrieves an attribute on this widget.
*
* @param name of the attribute to lookup
* @return the found attribute or <code>null</code> if none was found with that name.
*/
Object getAttribute(String name);
/**
* Sets an attribute on this widget. This can be used to store custom
* data with each widget.
*/
void setAttribute(String name, Object value);
/**
* Removes the named attribute from this widget.
*
* @param name of the attribute
*/
void removeAttribute(String name);
}