001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or
005: * without modification, are permitted provided that the following
006: * conditions are met:
007: *
008: * - Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: *
011: * - Redistribution in binary form must reproduce the above
012: * copyright notice, this list of conditions and the following
013: * disclaimer in the documentation and/or other materials
014: * provided with the distribution.
015: *
016: * Neither the name of Sun Microsystems, Inc. or the names of
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * This software is provided "AS IS," without a warranty of any
021: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
022: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
024: * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
025: * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
026: * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
027: * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
028: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
029: * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
030: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
031: * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
032: * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
033: *
034: * You acknowledge that this software is not designed, licensed or
035: * intended for use in the design, construction, operation or
036: * maintenance of any nuclear facility.
037: */
038:
039: package org.apache.cocoon.faces.samples.components.renderkit;
040:
041: import org.apache.cocoon.faces.samples.components.components.AreaComponent;
042: import org.apache.cocoon.faces.samples.components.components.MapComponent;
043: import org.apache.cocoon.faces.samples.components.model.ImageArea;
044:
045: import javax.faces.component.UIComponent;
046: import javax.faces.context.FacesContext;
047: import javax.faces.context.ResponseWriter;
048:
049: import java.io.IOException;
050:
051: /**
052: * This class converts the internal representation of a <code>UIArea</code>
053: * component into the output stream associated with the response to a
054: * particular request.
055: */
056:
057: public class AreaRenderer extends BaseRenderer {
058:
059: // -------------------------------------------------------- Renderer Methods
060:
061: /**
062: * <p>No decoding is required.</p>
063: *
064: * @param context <code>FacesContext</code>for the current request
065: * @param component <code>UIComponent</code> to be decoded
066: */
067: public void decode(FacesContext context, UIComponent component) {
068:
069: if ((context == null) || (component == null)) {
070: throw new NullPointerException();
071: }
072:
073: }
074:
075: /**
076: * <p>No begin encoding is required.</p>
077: *
078: * @param context <code>FacesContext</code>for the current request
079: * @param component <code>UIComponent</code> to be decoded
080: */
081: public void encodeBegin(FacesContext context, UIComponent component)
082: throws IOException {
083:
084: if ((context == null) || (component == null)) {
085: throw new NullPointerException();
086: }
087:
088: }
089:
090: /**
091: * <p>No children encoding is required.</p>
092: *
093: * @param context <code>FacesContext</code>for the current request
094: * @param component <code>UIComponent</code> to be decoded
095: */
096: public void encodeChildren(FacesContext context,
097: UIComponent component) throws IOException {
098:
099: if ((context == null) || (component == null)) {
100: throw new NullPointerException();
101: }
102:
103: }
104:
105: /**
106: * <p>Encode this component.</p>
107: *
108: * @param context <code>FacesContext</code>for the current request
109: * @param component <code>UIComponent</code> to be decoded
110: */
111: public void encodeEnd(FacesContext context, UIComponent component)
112: throws IOException {
113:
114: if ((context == null) || (component == null)) {
115: throw new NullPointerException();
116: }
117: AreaComponent area = (AreaComponent) component;
118: String targetImageId = area
119: .findComponent(area.getTargetImage()).getClientId(
120: context);
121: ImageArea iarea = (ImageArea) area.getValue();
122: ResponseWriter writer = context.getResponseWriter();
123: StringBuffer sb = null;
124:
125: writer.startElement("area", area);
126: writer.writeAttribute("alt", iarea.getAlt(), "alt");
127: writer.writeAttribute("coords", iarea.getCoords(), "coords");
128: writer.writeAttribute("shape", iarea.getShape(), "shape");
129: // PENDING(craigmcc) - onmouseout only works on first form of a page
130: sb = new StringBuffer("document.forms[0]['").append(
131: targetImageId).append("'].src='");
132: sb.append(getURI(context, (String) area.getAttributes().get(
133: "onmouseout")));
134: sb.append("'");
135: writer
136: .writeAttribute("onmouseout", sb.toString(),
137: "onmouseout");
138: // PENDING(craigmcc) - onmouseover only works on first form of a page
139: sb = new StringBuffer("document.forms[0]['").append(
140: targetImageId).append("'].src='");
141: sb.append(getURI(context, (String) area.getAttributes().get(
142: "onmouseover")));
143: sb.append("'");
144: writer.writeAttribute("onmouseover", sb.toString(),
145: "onmouseover");
146: // PENDING(craigmcc) - onclick only works on first form of a page
147: sb = new StringBuffer("document.forms[0]['");
148: sb.append(getName(context, area));
149: sb.append("'].value='");
150: sb.append(iarea.getAlt());
151: sb.append("'; document.forms[0].submit()");
152: writer.writeAttribute("onclick", sb.toString(), "value");
153: writer.endElement("area");
154:
155: }
156:
157: // --------------------------------------------------------- Private Methods
158:
159: /**
160: * <p>Return the calculated name for the hidden input field.</p>
161: *
162: * @param context Context for the current request
163: * @param component Component we are rendering
164: */
165: private String getName(FacesContext context, UIComponent component) {
166: while (component != null) {
167: if (component instanceof MapComponent) {
168: return (component.getId() + "_current");
169: }
170: component = component.getParent();
171: }
172: throw new IllegalArgumentException();
173: }
174:
175: /**
176: * <p>Return the path to be passed into JavaScript for the specified
177: * value.</p>
178: *
179: * @param context Context for the current request
180: * @param value Partial path to be (potentially) modified
181: */
182: private String getURI(FacesContext context, String value) {
183: if (value.startsWith("/")) {
184: return (context.getExternalContext()
185: .getRequestContextPath() + value);
186: } else {
187: return (value);
188: }
189: }
190:
191: }
|