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.link;
018
019import org.apache.wicket.IRequestListener;
020import org.apache.wicket.request.cycle.RequestCycle;
021import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
022import org.apache.wicket.request.mapper.parameter.PageParameters;
023import org.apache.wicket.request.resource.IResource;
024import org.apache.wicket.request.resource.IResource.Attributes;
025import org.apache.wicket.request.resource.ResourceReference;
026
027/**
028 * A link to any ResourceReference.
029 * 
030 * @author Jonathan Locke
031 * @param <T>
032 *            type of model object
033 */
034public class ResourceLink<T> extends Link<T> implements IRequestListener
035{
036        private static final long serialVersionUID = 1L;
037
038        /** The Resource reference */
039        private final ResourceReference resourceReference;
040
041        /** The Resource */
042        private final IResource resource;
043
044        /** The resource parameters */
045        private final PageParameters resourceParameters;
046
047
048        /**
049         * Constructs an ResourceLink from an resourcereference. That resource reference will bind its
050         * resource to the current SharedResources.
051         * 
052         * @param id
053         *            See Component
054         * @param resourceReference
055         *            The shared resource to link to
056         */
057        public ResourceLink(final String id, final ResourceReference resourceReference)
058        {
059                this(id, resourceReference, null);
060        }
061
062        /**
063         * Constructs an ResourceLink from an resourcereference. That resource reference will bind its
064         * resource to the current SharedResources.
065         * 
066         * @param id
067         *            See Component
068         * @param resourceReference
069         *            The shared resource to link to
070         * @param resourceParameters
071         *            The resource parameters
072         */
073        public ResourceLink(final String id, final ResourceReference resourceReference,
074                PageParameters resourceParameters)
075        {
076                super(id);
077                this.resourceReference = resourceReference;
078                this.resourceParameters = resourceParameters;
079                resource = null;
080        }
081
082        /**
083         * Constructs a link directly to the provided resource.
084         * 
085         * @param id
086         *            See Component
087         * @param resource
088         *            The resource
089         */
090        public ResourceLink(final String id, final IResource resource)
091        {
092                super(id);
093                this.resource = resource;
094                resourceReference = null;
095                resourceParameters = null;
096        }
097
098        @Override
099        public void onClick()
100        {
101        }
102
103        @Override
104        public boolean rendersPage()
105        {
106                return false;
107        }
108        
109        /**
110         * For {@link ResourceReference}s this link is stateless.
111         * 
112         * @return <code>true</code> if a resourceReference was provided to the
113         *         constructor
114         * 
115         * @see ResourceLink#ResourceLink(String, ResourceReference)
116         * @see ResourceLink#ResourceLink(String, ResourceReference, PageParameters)
117         */
118        @Override
119        protected boolean getStatelessHint()
120        {
121                return resourceReference != null;
122        }   
123
124        @Override
125        protected final CharSequence getURL()
126        {
127                if (resourceReference != null)
128                {
129                        // TODO post 1.2: should we have support for locale changes when the
130                        // resource reference (or resource??) is set manually..
131                        // We should get a new resource reference for the current locale
132                        // then
133                        // that points to the same resource but with another locale if it
134                        // exists.
135                        // something like
136                        // SharedResource.getResourceReferenceForLocale(resourceReference);
137                        if (resourceReference.canBeRegistered())
138                        {
139                                getApplication().getResourceReferenceRegistry().registerResourceReference(
140                                        resourceReference);
141                        }
142
143                        return getRequestCycle().urlFor(
144                                new ResourceReferenceRequestHandler(resourceReference, resourceParameters));
145                }
146                return urlForListener(resourceParameters);
147        }
148        
149        @Override
150        public final void onRequest()
151        {
152                Attributes a = new Attributes(RequestCycle.get().getRequest(), RequestCycle.get()
153                        .getResponse(), null);
154                resource.respond(a);
155                
156                super.onRequest();
157        }       
158}