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: */package org.apache.cocoon.forms.formmodel;
017:
018: import org.apache.cocoon.environment.Request;
019: import org.apache.cocoon.forms.FormContext;
020: import org.apache.cocoon.forms.event.*;
021: import org.apache.cocoon.xml.AttributesImpl;
022:
023: /**
024: * A server-side map widget. An ImageMap widget can cause a {@link ImageMapEvent} to be triggered
025: * on the server side, which will be handled by either the event handlers defined in the
026: * form definition, and/or by the {@link org.apache.cocoon.forms.event.FormHandler FormHandler}
027: * registered with the form, if any. An ImageMap widget is basically an Action widget
028: * displayed as an image and with mouse coordinates stored upon clicking.
029: * The image's URI can be set or get, or bind via the binding framework, mouse coordinates
030: * can be either retrieved from the ImageMapEvent triggered or from the widget itself.
031: *
032: * @version $Id: ImageMap.java 462520 2006-10-10 19:39:14Z vgritsenko $
033: * @since 2.1.8
034: */
035: public class ImageMap extends AbstractWidget implements
036: ActionListenerEnabled {
037:
038: // XML element and attributes
039: public static final String COMMAND_AT = "command";
040: public static final String VALUE_EL = "imageuri";
041: public static final String ONACTION_EL = "on-action";
042: public static final String IMAGEMAP_EL = "imagemap";
043:
044: private final ImageMapDefinition definition;
045: private ActionListener listener;
046: private String imgURI; // URI of widget's image
047: private int x; // Mouse x coordinate
048: private int y; // Mouse y coordinate
049:
050: public ImageMap(ImageMapDefinition definition) {
051: super (definition);
052: this .definition = definition;
053: this .imgURI = definition.getImageURI();
054: this .x = 0;
055: this .y = 0;
056: }
057:
058: public WidgetDefinition getDefinition() {
059: return this .definition;
060: }
061:
062: // Retrieves mouse coordinates
063: public int getX() {
064: return this .x;
065: }
066:
067: public int getY() {
068: return this .y;
069: }
070:
071: // Get/set image URI
072: public String getImageURI() {
073: if (this .imgURI != null) {
074: return this .imgURI;
075: } else {
076: return "";
077: }
078: }
079:
080: public void setImageURI(String newImgURI) {
081: this .imgURI = newImgURI;
082: }
083:
084: // The set/getValue methods are used to set the widget's image URI during binding
085: public void setValue(Object newImgURI) {
086: setImageURI(newImgURI.toString());
087: }
088:
089: public Object getValue() {
090: return getImageURI();
091: }
092:
093: public void readFromRequest(final FormContext formContext) {
094: if (!getCombinedState().isAcceptingInputs()) {
095: return;
096: }
097:
098: Form form = getForm();
099:
100: // Set the submit widget if we can determine it from the request
101: String fullId = getRequestParameterName();
102: Request request = formContext.getRequest();
103:
104: // Extracts mouse coordinates from request (ignores malformed numbers)
105: try {
106: this .x = (new Integer(formContext.getRequest()
107: .getParameter(fullId + ".x"))).intValue();
108: this .y = (new Integer(formContext.getRequest()
109: .getParameter(fullId + ".y"))).intValue();
110: } catch (java.lang.NumberFormatException e) {
111: this .x = 0;
112: this .y = 0;
113: }
114:
115: String value = request.getParameter(fullId);
116: if (value != null && value.length() > 0) {
117: form.setSubmitWidget(this );
118:
119: } else {
120: // Special workaround an IE bug for <input type="image" name="foo"> :
121: // in that case, IE only sends "foo.x" and "foo.y" and not "foo" whereas
122: // standards-compliant browsers such as Mozilla do send the "foo" parameter.
123: //
124: // Note that since actions are terminal widgets, there's no chance of conflict
125: // with a child "x" or "y" widget.
126: value = request.getParameter(fullId + ".x");
127: if ((value != null) && value.length() > 0) {
128: form.setSubmitWidget(this );
129: }
130: }
131:
132: if (form.getSubmitWidget() == this ) {
133: form.addWidgetEvent(new ImageMapEvent(this , definition
134: .getActionCommand()));
135:
136: handleActivate();
137: }
138: }
139:
140: /**
141: * Adds the @imageuri attribute to the XML element
142: */
143: public AttributesImpl getXMLElementAttributes() {
144: AttributesImpl attrs = super .getXMLElementAttributes();
145: attrs.addCDATAAttribute("imageuri", this .imgURI);
146: return attrs;
147: }
148:
149: /**
150: * Handle the fact that this action was activated. The default here is to end the
151: * current form processing and redisplay the form, which means that actual behaviour
152: * should be implemented in event listeners.
153: */
154: protected void handleActivate() {
155: getForm().endProcessing(true);
156: }
157:
158: /**
159: * Always return <code>true</code> (an action has no validation)
160: */
161: public boolean validate() {
162: return true;
163: }
164:
165: public String getXMLElementName() {
166: return IMAGEMAP_EL;
167: }
168:
169: /**
170: * Adds an ActionListener to this widget instance. Listeners defined
171: * on the widget instance will be executed in addtion to any listeners
172: * that might have been defined in the widget definition.
173: */
174: public void addActionListener(ActionListener listener) {
175: this .listener = WidgetEventMulticaster.add(this .listener,
176: listener);
177: }
178:
179: public void removeActionListener(ActionListener listener) {
180: this .listener = WidgetEventMulticaster.remove(this .listener,
181: listener);
182: }
183:
184: private void fireActionEvent(ActionEvent event) {
185: if (this .listener != null) {
186: this .listener.actionPerformed(event);
187: }
188: }
189:
190: public void broadcastEvent(WidgetEvent event) {
191: if (event instanceof ActionEvent) {
192: this .definition.fireActionEvent((ActionEvent) event);
193: fireActionEvent((ActionEvent) event);
194: } else {
195: // Other kinds of events
196: super.broadcastEvent(event);
197: }
198: }
199:
200: }
|