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 */
017package org.apache.wicket.markup.html.form;
018
019import org.apache.wicket.IRequestListener;
020import org.apache.wicket.markup.ComponentTag;
021import org.apache.wicket.markup.html.image.resource.LocalizedImageResource;
022import org.apache.wicket.model.IModel;
023import org.apache.wicket.model.Model;
024import org.apache.wicket.request.mapper.parameter.PageParameters;
025import org.apache.wicket.request.resource.IResource;
026import org.apache.wicket.request.resource.ResourceReference;
027
028
029/**
030 * <input type="image"> component - like {@link Button} only with an image.
031 * <p>
032 * For details of how ImageButtons load, generate and manage images, see
033 * {@link LocalizedImageResource}.
034 * 
035 * @author Jonathan Locke
036 */
037public class ImageButton extends Button implements IRequestListener
038{
039        private static final long serialVersionUID = 1L;
040
041        /** The image resource this image component references */
042        private final LocalizedImageResource localizedImageResource = new LocalizedImageResource(this);
043
044        /**
045         * Constructs an image button from an image <code>ResourceReference</code>. That resource
046         * reference will bind its resource to the current SharedResources.
047         * 
048         * If you are using non sticky session clustering and the resource reference is pointing to a
049         * <code>Resource</code> that isn't guaranteed to be on every server, for example a dynamic
050         * image or resources that aren't added with a <code>IInitializer</code> at application startup.
051         * Then if only that resource is requested from another server, without the rendering of the
052         * page, the image won't be there and will result in a broken link.
053         * 
054         * @param id
055         *            See Component
056         * @param resourceReference
057         *            The shared image resource
058         */
059        public ImageButton(final String id, final ResourceReference resourceReference)
060        {
061                this(id, resourceReference, null);
062        }
063
064        /**
065         * Constructs an image button from an image <code>ResourceReference</code>. That resource
066         * reference will bind its resource to the current SharedResources.
067         * 
068         * If you are using non sticky session clustering and the resource reference is pointing to a
069         * <code>Resource</code> that isn't guaranteed to be on every server, for example a dynamic
070         * image or resources that aren't added with a <code>IInitializer</code> at application startup.
071         * Then if only that resource is requested from another server, without the rendering of the
072         * page, the image won't be there and will result in a broken link.
073         * 
074         * @param id
075         *            See Component
076         * @param resourceReference
077         *            The shared image resource
078         * @param resourceParameters
079         *            The resource parameters
080         */
081        public ImageButton(final String id, final ResourceReference resourceReference,
082                PageParameters resourceParameters)
083        {
084                super(id);
085                setImageResourceReference(resourceReference, resourceParameters);
086        }
087
088        /**
089         * Constructs an image directly from an image resource.
090         * 
091         * This one doesn't have the 'non sticky session clustering' problem that the
092         * <code>ResourceReference</code> constructor has. But this will result in a non 'stable' url
093         * and the url will have request parameters.
094         * 
095         * @param id
096         *            See Component
097         * 
098         * @param imageResource
099         *            The image resource
100         */
101        public ImageButton(final String id, final IResource imageResource)
102        {
103                super(id);
104                setImageResource(imageResource);
105        }
106
107        /**
108         * @param id
109         * @param model
110         * @see org.apache.wicket.Component#Component(String, IModel)
111         */
112        public ImageButton(final String id, final IModel<String> model)
113        {
114                super(id, model);
115        }
116
117        /**
118         * @param id
119         *            See Component
120         * @param string
121         *            Name of image
122         * @see org.apache.wicket.Component#Component(String, IModel)
123         */
124        public ImageButton(final String id, final String string)
125        {
126                this(id, new Model<String>(string));
127        }
128
129        @Override
130        public boolean rendersPage()
131        {
132                return false;
133        }
134
135        @Override
136        public void onRequest()
137        {
138                localizedImageResource.onResourceRequested(null);
139        }
140
141        /**
142         * @param imageResource
143         *            The new ImageResource to set.
144         */
145        public void setImageResource(final IResource imageResource)
146        {
147                localizedImageResource.setResource(imageResource);
148        }
149
150        /**
151         * @param resourceReference
152         *            The shared ImageResource to set.
153         */
154        public void setImageResourceReference(final ResourceReference resourceReference)
155        {
156                localizedImageResource.setResourceReference(resourceReference);
157        }
158
159        /**
160         * @param resourceReference
161         *            The shared ImageResource to set.
162         * @param parameters
163         *            Set the resource parameters for the resource.
164         */
165        public void setImageResourceReference(final ResourceReference resourceReference,
166                final PageParameters parameters)
167        {
168                localizedImageResource.setResourceReference(resourceReference, parameters);
169        }
170
171        /**
172         * @see org.apache.wicket.Component#setDefaultModel(org.apache.wicket.model.IModel)
173         */
174        @Override
175        public ImageButton setDefaultModel(IModel<?> model)
176        {
177                // Null out the image resource, so we reload it (otherwise we'll be
178                // stuck with the old model.
179                localizedImageResource.setResourceReference(null);
180                localizedImageResource.setResource(null);
181                return (ImageButton)super.setDefaultModel(model);
182        }
183
184        /**
185         * @return Resource returned from subclass
186         */
187        protected IResource getImageResource()
188        {
189                return localizedImageResource.getResource();
190        }
191
192        /**
193         * @return ResourceReference returned from subclass
194         */
195        protected ResourceReference getImageResourceReference()
196        {
197                return localizedImageResource.getResourceReference();
198        }
199
200        /**
201         * Processes the component tag.
202         * 
203         * @param tag
204         *            Tag to modify
205         * @see org.apache.wicket.Component#onComponentTag(ComponentTag)
206         */
207        @Override
208        protected final void onComponentTag(final ComponentTag tag)
209        {
210                checkComponentTag(tag, "input");
211                checkComponentTagAttribute(tag, "type", "image");
212
213                final IResource resource = getImageResource();
214                if (resource != null)
215                {
216                        localizedImageResource.setResource(resource);
217                }
218                final ResourceReference resourceReference = getImageResourceReference();
219                if (resourceReference != null)
220                {
221                        localizedImageResource.setResourceReference(resourceReference);
222                }
223                localizedImageResource.setSrcAttribute(tag);
224                super.onComponentTag(tag);
225        }
226
227        /**
228         * @see org.apache.wicket.markup.html.form.Button#getStatelessHint()
229         */
230        @Override
231        protected boolean getStatelessHint()
232        {
233                return getImageResource() == null && localizedImageResource.isStateless();
234        }
235}