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.head;
018
019import java.util.Arrays;
020import java.util.List;
021import java.util.Objects;
022
023import org.apache.wicket.markup.html.CrossOrigin;
024import org.apache.wicket.request.IRequestHandler;
025import org.apache.wicket.request.Response;
026import org.apache.wicket.request.cycle.RequestCycle;
027import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
028import org.apache.wicket.request.mapper.parameter.PageParameters;
029import org.apache.wicket.request.resource.ResourceReference;
030import org.apache.wicket.resource.bundles.IResourceBundle;
031import org.apache.wicket.util.string.Strings;
032
033/**
034 * {@link HeaderItem} for style tags that are rendered using a {@link ResourceReference}.
035 * 
036 * @author papegaaij
037 */
038public class CssReferenceHeaderItem extends AbstractCssReferenceHeaderItem implements IReferenceHeaderItem
039{
040        private static final long serialVersionUID = 1L;
041
042        private final ResourceReference reference;
043        private final PageParameters pageParameters;
044
045        /**
046         * Creates a new {@code CSSReferenceHeaderItem}.
047         * 
048         * @param reference
049         *            resource reference pointing to the CSS resource
050         * @param pageParameters
051         *            the parameters for this CSS resource reference
052         * @param media
053         *            the media type for this CSS ("print", "screen", etc.)
054         */
055        public CssReferenceHeaderItem(ResourceReference reference, PageParameters pageParameters,
056                String media)
057        {
058                super(media, null);
059                
060                this.reference = reference;
061                this.pageParameters = pageParameters;
062        }
063
064        /**
065         * Creates a new {@code CSSReferenceHeaderItem}.
066         * 
067         * @param reference
068         *            resource reference pointing to the CSS resource
069         * @param pageParameters
070         *            the parameters for this CSS resource reference
071         * @param media
072         *            the media type for this CSS ("print", "screen", etc.)
073         * @param rel
074         *            the rel attribute content
075         */
076        public CssReferenceHeaderItem(ResourceReference reference, PageParameters pageParameters,
077                String media, String rel)
078        {
079                super(media, rel); 
080                
081                this.reference = reference;
082                this.pageParameters = pageParameters;
083        }
084
085        /**
086         * @return resource reference pointing to the CSS resource
087         * @see IReferenceHeaderItem#getReference()
088         */
089        @Override
090        public ResourceReference getReference()
091        {
092                return reference;
093        }
094
095        /**
096         * @return the parameters for this CSS resource reference
097         */
098        public PageParameters getPageParameters()
099        {
100                return pageParameters;
101        }
102
103        @Override
104        public CrossOrigin getCrossOrigin()
105        {
106                return null;
107        }
108        
109        @Override
110        public String getIntegrity()
111        {
112                return null;
113        }
114        
115        @Override
116        public List<HeaderItem> getDependencies()
117        {
118                return getReference().getDependencies();
119        }
120
121        @Override
122        public Iterable<? extends HeaderItem> getProvidedResources()
123        {
124                if (getReference() instanceof IResourceBundle)
125                        return ((IResourceBundle)getReference()).getProvidedResources();
126                return super.getProvidedResources();
127        }
128
129        @Override
130        public void render(Response response)
131        {
132                internalRenderCSSReference(response, getUrl());
133        }
134
135        @Override
136        public Iterable<?> getRenderTokens()
137        {
138                return Arrays.asList("css-" + Strings.stripJSessionId(getUrl()) + "-" + getMedia());
139        }
140
141        @Override
142        public String toString()
143        {
144                return "CSSReferenceHeaderItem(" + getReference() + ", " + getPageParameters() + ")";
145        }
146
147        private String getUrl()
148        {
149                IRequestHandler handler = new ResourceReferenceRequestHandler(getReference(),
150                        getPageParameters());
151                return RequestCycle.get().urlFor(handler).toString();
152        }
153
154        @Override
155        public int hashCode()
156        {
157                // Not using `Objects.hash` for performance reasons
158                int result = super.hashCode();
159                result = 31 * result + ((reference != null) ? reference.hashCode() : 0);
160                result = 31 * result + ((getMedia() != null) ? getMedia().hashCode() : 0);
161                result = 31 * result + ((pageParameters != null) ? pageParameters.hashCode() : 0);
162                result = 31 * result + ((getRel() != null) ? getRel().hashCode() : 0);
163                return result;
164        }
165
166        @Override
167        public boolean equals(Object o)
168        {
169                if (this == o)
170                        return true;
171                if (o == null || getClass() != o.getClass())
172                        return false;
173                if (!super.equals(o))
174                        return false;
175                CssReferenceHeaderItem that = (CssReferenceHeaderItem)o;
176                return Objects.equals(reference, that.reference) && Objects.equals(getMedia(), that.getMedia()) &&
177                        Objects.equals(getRel(), that.getRel()) && Objects.equals(pageParameters, that.pageParameters);
178        }
179}