001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.renderer;
042:
043: import com.sun.rave.web.ui.component.ImageComponent;
044: import com.sun.rave.web.ui.component.Icon;
045: import com.sun.rave.web.ui.theme.Theme;
046: import com.sun.rave.web.ui.theme.ThemeImages;
047: import com.sun.rave.web.ui.util.ClientSniffer;
048: import com.sun.rave.web.ui.util.LogUtil;
049: import com.sun.rave.web.ui.util.RenderingUtilities;
050: import com.sun.rave.web.ui.util.ThemeUtilities;
051: import java.beans.Beans;
052:
053: import java.io.IOException;
054:
055: import javax.faces.context.FacesContext;
056: import javax.faces.context.ResponseWriter;
057: import javax.faces.component.UIComponent;
058:
059: /**
060: * Image renderer
061: *
062: * @author Sean Comerford
063: */
064: public class ImageRenderer extends AbstractRenderer {
065:
066: /**
067: * <p>The set of integer pass-through attributes to be rendered.</p>
068: */
069: private static final String integerAttributes[] = { "border", //NOI18N
070: "hspace", "vspace" }; //NOI18N
071:
072: /**
073: * <p>The set of String pass-through attributes to be rendered.</p>
074: */
075: private static final String stringAttributes[] = { "align", //NOI18N
076: "onClick", "onDblClick", //NO18N
077: "onMouseDown", "onMouseMove", "onMouseOut", "onMouseOver" }; //NOI18N
078:
079: /** Creates a new instance of ImageRenderer */
080: public ImageRenderer() {
081: // default constructor
082: }
083:
084: /**
085: * Render the start of the image element
086: *
087: * @param context The current FacesContext
088: * @param component The ImageComponent object to use
089: * @param writer The current ResponseWriter
090: *
091: * @exception IOException if an input/output error occurss
092: */
093: protected void renderStart(FacesContext context,
094: UIComponent component, ResponseWriter writer)
095: throws IOException {
096: // render start of image
097: ImageComponent image = (ImageComponent) component;
098: writer.startElement("img", image); //NOI18N
099: }
100:
101: /**
102: * Render the image element's attributes
103: *
104: * @param context The current FacesContext
105: * @param component The ImageComponent object to use
106: * @param writer The current ResponseWriter
107: *
108: * @exception IOException if an input/output error occurss
109: */
110: protected void renderAttributes(FacesContext context,
111: UIComponent component, ResponseWriter writer)
112: throws IOException {
113: // render image attrs
114: ImageComponent image = (ImageComponent) component;
115:
116: String clientId = image.getClientId(context);
117: if (clientId != null) {
118: writer.writeAttribute("id", clientId, null); //NOI18N
119: }
120:
121: String url = image.getUrl();
122: String icon = image.getIcon();
123: int height = image.getHeight();
124: int width = image.getWidth();
125:
126: if (image instanceof Icon || (icon != null && url == null)) {
127: Icon themeIcon = ThemeUtilities.getTheme(context).getIcon(
128: icon);
129: url = themeIcon.getUrl();
130: // height
131: int dim = themeIcon.getHeight();
132: if (height < 0 && dim >= 0) {
133: height = dim;
134: }
135: // width
136: dim = themeIcon.getWidth();
137: if (width < 0 && dim >= 0) {
138: width = dim;
139: }
140: } else if (url == null) {
141: if (!Beans.isDesignTime()) {
142: // log an error
143: if (LogUtil.warningEnabled(ImageRenderer.class)) {
144: LogUtil
145: .warning(
146: ImageRenderer.class,
147: " URL was not "
148: + "specified and generally should be"); // NOI18N
149: }
150: }
151: } else {
152: url = context.getApplication().getViewHandler()
153: .getResourceURL(context, url);
154: }
155:
156: //<RAVE>
157: //if (url == null) {
158: // url = "";
159: //}
160:
161: //must encode the url (even though we call the function later)!
162: //url = context.getExternalContext().encodeResourceURL(url);
163:
164: if (url == null || url.trim().length() == 0) {
165: url = "";
166: } else {
167: //must encode the url (even though we call the function later)!
168: url = context.getExternalContext().encodeResourceURL(url);
169: }
170: //<RAVE>
171:
172: StringBuffer styleAdditions = null;
173: String style = image.getStyle();
174:
175: if (isPngAndIE(context, url)) {
176: // need to add stuff to the style attribute
177: styleAdditions = new StringBuffer(200);
178:
179: //take care of width
180: styleAdditions.append("width:"); // NOI18N
181: if (width > 0) {
182: styleAdditions.append(width);
183: styleAdditions.append("px;"); // NOI18N
184: } else {
185: styleAdditions.append("100px;"); // NOI18N
186: }
187:
188: //take care of height
189: styleAdditions.append("height:"); // NOI18N
190: if (height > 0) {
191: styleAdditions.append(height);
192: styleAdditions.append("px;"); // NOI18N
193: } else {
194: styleAdditions.append("100px;"); // NOI18N
195: }
196: // append special filter stuff.
197: styleAdditions
198: .append("filter:progid:DXImageTransform.Microsoft."); // NOI18N
199: styleAdditions.append("AlphaImageLoader(src='"); // NOI18N
200: styleAdditions.append(url);
201: styleAdditions.append("', sizingMethod='scale')"); // NOI18N
202:
203: Theme theme = ThemeUtilities.getTheme(context);
204: url = theme.getIcon(ThemeImages.DOT).getUrl();
205: if (style == null) {
206: style = styleAdditions.toString();
207: } else {
208: if (!style.endsWith(";")) { // NOI18N
209: style += ";"; // NOI18N
210: }
211: style += styleAdditions;
212: }
213:
214: }
215:
216: //write style class and style info
217: RenderingUtilities.renderStyleClass(context, writer, image,
218: null);
219: if (style != null) {
220: writer.writeAttribute("style", style, null); // NOI18N
221: }
222:
223: RenderingUtilities.renderURLAttribute(context, writer, image,
224: "src", //NO18N
225: url, "url"); //NO18N
226:
227: // the alternateText property should be rendered as the image's alt attr
228: String alt = image.getAlt();
229:
230: if (alt != null) {
231: writer.writeAttribute("alt", alt, null); // NOI18N
232: } else {
233: // alt is a required for XHTML compliance so output empty string
234: // IS THIS ELSE NEEDED NOW THAT DESCRIPTION IS A REQUIRED PROPERTY?
235: writer.writeAttribute("alt", "", null); //NOI18N
236: }
237:
238: // render the tooltip property as the image title attribute
239: String toolTip = image.getToolTip();
240: if (toolTip != null) {
241: writer.writeAttribute("title", toolTip, null); //NOI18N
242: }
243:
244: // render the longDescription property as the image longdesc attribute
245: String longDesc = image.getLongDesc();
246: if (longDesc != null) {
247: writer.writeAttribute("longdesc", longDesc, null); // NOI18N
248: }
249:
250: // render height
251: if (height >= 0) {
252: writer.writeAttribute("height", Integer.toString(height),
253: null); // NOI18N
254: }
255:
256: // render width
257: if (width >= 0) {
258: writer.writeAttribute("width", Integer.toString(width),
259: null); // NOI18N
260: }
261:
262: addIntegerAttributes(context, component, writer,
263: integerAttributes);
264: addStringAttributes(context, component, writer,
265: stringAttributes);
266: }
267:
268: /**
269: * Render the end of the image element
270: *
271: * @param context The current FacesContext
272: * @param component The ImageComponent object to use
273: * @param writer The current ResponseWriter
274: *
275: * @exception IOException if an input/output error occurss
276: */
277: protected void renderEnd(FacesContext context,
278: UIComponent component, ResponseWriter writer)
279: throws IOException {
280: // render end of image
281: ImageComponent image = (ImageComponent) component;
282:
283: writer.endElement("img");
284: }
285:
286: private boolean isPngAndIE(FacesContext context, String url) {
287: ClientSniffer cs = ClientSniffer.getInstance(context);
288: //Some time encodeResourceURL(url) adds the sessiod to the
289: // image URL, make sure to take that in to account
290: //<RAVE>
291: if (url.indexOf("sessionid") != -1) {
292: if (url.substring(0, url.indexOf(';')).endsWith(".png")
293: && cs.isIe5up()) {
294: return true;
295: }
296: } else { //</RAVE>
297: if (url.endsWith(".png") && cs.isIe5up()) {
298: return true;
299: }
300: }
301:
302: return false;
303: }
304: }
|