001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.html;
016
017 import org.apache.hivemind.ApplicationRuntimeException;
018 import org.apache.tapestry.*;
019 import org.apache.tapestry.components.ILinkComponent;
020 import org.apache.tapestry.form.IFormComponent;
021 import org.apache.tapestry.form.LinkSubmit;
022
023 import java.util.HashMap;
024 import java.util.Map;
025
026 /**
027 * Combines a link component (such as
028 * {@link org.apache.tapestry.link.DirectLink}) with an <img> and
029 * JavaScript code to create a rollover effect that works with both Netscape
030 * Navigator and Internet Explorer. [ <a
031 * href="../../../../../ComponentReference/Rollover.html">Component Reference
032 * </a>]
033 *
034 * @author Howard Lewis Ship
035 */
036
037 public abstract class Rollover extends AbstractComponent
038 {
039
040 /**
041 * Converts an {@link IAsset}binding into a usable URL. Returns null if the
042 * binding does not exist or the binding's value is null.
043 *
044 * @param asset
045 * The asset to generate a url for.
046 * @return The url to the asset resource, or null if it couldn't be generated.
047 */
048
049 protected String getAssetURL(IAsset asset)
050 {
051 if (asset == null)
052 return null;
053
054 return asset.buildURL();
055 }
056
057 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
058 {
059 // No body, so we skip it all if not rewinding
060 // (assumes no side effects on accessors).
061
062 if (cycle.isRewinding())
063 return;
064
065 String imageURL = null;
066 String mouseOverURL = null;
067 String mouseOutURL = null;
068 boolean dynamic = false;
069 String imageId;
070 boolean linkDisabled = false;
071
072 PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
073
074 Object serviceLink = cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
075 if (serviceLink == null)
076 {
077 serviceLink = cycle.getAttribute(LinkSubmit.ATTRIBUTE_NAME);
078
079 if (serviceLink != null)
080 linkDisabled = ((IFormComponent) serviceLink).isDisabled();
081 } else
082 {
083 linkDisabled = ((ILinkComponent) serviceLink).isDisabled();
084 }
085
086 if (serviceLink == null)
087 throw new ApplicationRuntimeException(Tapestry.getMessage("Rollover.must-be-contained-by-link"), this, null, null);
088
089 if (linkDisabled)
090 {
091 imageURL = getAssetURL(getDisabled());
092
093 if (imageURL == null)
094 imageURL = getAssetURL(getImage());
095 }
096 else
097 {
098 imageURL = getAssetURL(getImage());
099 mouseOverURL = getAssetURL(getMouseOver());
100 mouseOutURL = getAssetURL(getMouseOut());
101
102 dynamic = (mouseOverURL != null) || (mouseOutURL != null);
103 }
104
105 if (imageURL == null)
106 throw Tapestry.createRequiredParameterException(this, "image");
107
108 writer.beginEmpty("img");
109
110 writer.attribute("src", imageURL);
111
112 if (dynamic)
113 {
114 if (mouseOverURL == null)
115 mouseOverURL = imageURL;
116
117 if (mouseOutURL == null)
118 mouseOutURL = imageURL;
119
120 imageId = writeScript(cycle, pageRenderSupport, serviceLink, mouseOverURL, mouseOutURL);
121
122 writer.attribute("id", imageId);
123 }
124
125 renderInformalParameters(writer, cycle);
126
127 writer.closeTag();
128
129 }
130
131 // Injected
132
133 public abstract IScript getScript();
134
135 private String writeScript(IRequestCycle cycle, PageRenderSupport pageRenderSupport,
136 Object link, String mouseOverImageURL, String mouseOutImageURL)
137 {
138 String imageId = pageRenderSupport.getUniqueString(getId());
139
140 String preloadedMouseOverImageURL = pageRenderSupport.getPreloadedImageReference(this, mouseOverImageURL);
141 String preloadedMouseOutImageURL = pageRenderSupport.getPreloadedImageReference(this, mouseOutImageURL);
142
143 Map symbols = new HashMap();
144
145 symbols.put("link", link);
146 symbols.put("imageId", imageId);
147 symbols.put("mouseOverImageURL", preloadedMouseOverImageURL);
148 symbols.put("mouseOutImageURL", preloadedMouseOutImageURL);
149
150 getScript().execute(this, cycle, pageRenderSupport, symbols);
151
152 return imageId;
153 }
154
155 public abstract IAsset getMouseOut();
156
157 public abstract IAsset getDisabled();
158
159 public abstract IAsset getMouseOver();
160
161 public abstract IAsset getImage();
162 }