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;
018
019import java.util.Locale;
020
021import org.apache.wicket.request.resource.IResource;
022import org.apache.wicket.request.resource.ResourceReference;
023import org.apache.wicket.request.resource.ResourceReference.Key;
024import org.apache.wicket.request.resource.ResourceReferenceRegistry;
025import org.apache.wicket.util.lang.Args;
026
027/**
028 * Class which holds shared resources. Resources can be shared by name. An optional scope can be
029 * given to prevent naming conflicts and a locale and/or style can be given as well.
030 * 
031 * <p>
032 * Unlike component hosted resources, shared resources have stable URLs, which makes them suitable
033 * for indexing by web crawlers and caching by web browsers. As they are also not synchronised on
034 * the {@link Session}, they can be loaded asynchronously, which is important with images and
035 * resources such as JavaScript and CSS.
036 */
037public class SharedResources
038{
039        private final ResourceReferenceRegistry registry;
040
041        /**
042         * Construct.
043         * 
044         * @param registry
045         */
046        public SharedResources(ResourceReferenceRegistry registry)
047        {
048                this.registry = Args.notNull(registry, "registry");
049        }
050
051        /**
052         * A {@link ResourceReference} that is used to register a reference to a known {@link IResource}
053         */
054        private static final class AutoResourceReference extends ResourceReference
055        {
056                private static final long serialVersionUID = 1L;
057
058                private final IResource resource;
059
060                private AutoResourceReference(Class<?> scope, String name, Locale locale, String style,
061                        String variation, IResource resource)
062                {
063                        super(scope, name, locale, style, variation);
064                        this.resource = resource;
065                }
066
067                @Override
068                public IResource getResource()
069                {
070                        return resource;
071                }
072        }
073
074        /**
075         * Adds a resource.
076         * 
077         * @param scope
078         *            Scope of resource
079         * @param name
080         *            Logical name of resource
081         * @param locale
082         *            The locale of the resource
083         * @param style
084         *            The resource style (see {@link org.apache.wicket.Session})
085         * @param variation
086         *            The component specific variation of the style
087         * @param resource
088         *            Resource to store
089         */
090        public final void add(final Class<?> scope, final String name, final Locale locale,
091                final String style, final String variation, final IResource resource)
092        {
093                ResourceReference ref = new AutoResourceReference(scope, name, locale, style, variation,
094                        resource);
095                registry.registerResourceReference(ref);
096        }
097
098        /**
099         * Adds a resource.
100         * 
101         * @param name
102         *            Logical name of resource
103         * @param locale
104         *            The locale of the resource
105         * @param resource
106         *            Resource to store
107         */
108        public final void add(final String name, final Locale locale, final IResource resource)
109        {
110                add(Application.class, name, locale, null, null, resource);
111        }
112
113        /**
114         * Adds a resource.
115         * 
116         * @param name
117         *            Logical name of resource
118         * @param resource
119         *            Resource to store
120         */
121        public final void add(final String name, final IResource resource)
122        {
123                add(Application.class, name, null, null, null, resource);
124        }
125
126        /**
127         * Resolves a {@link ResourceReference} for a shared resource by using
128         * {@link org.apache.wicket.Application} as a scope and {@code null} for
129         * locale, style and variation.
130         *
131         * @param name
132         *            Logical name of resource
133         */
134        public final ResourceReference get(String name)
135        {
136                return get(Application.class, name, null, null, null, false);
137        }
138
139        /**
140         * Resolves a {@link ResourceReference} for a shared resource.
141         * 
142         * @param scope
143         *            Scope of resource
144         * @param name
145         *            Logical name of resource
146         * @param locale
147         *            The locale of the resource
148         * @param style
149         *            The resource style (see {@link org.apache.wicket.Session})
150         * @param variation
151         *            The component specific variation of the style
152         * @param strict
153         *            If true, "weaker" combination of scope, name, locale etc. are not tested
154         * @return Either the resource reference found in the registry or, if requested, a resource
155         *         reference automatically created based on the parameters provided. The automatically
156         *         created resource reference will automatically be added to the registry.
157         */
158        public ResourceReference get(Class<?> scope, String name, Locale locale, String style,
159                String variation, boolean strict)
160        {
161                return registry.getResourceReference(scope, name, locale, style, variation, strict, true);
162        }
163
164        /**
165         * Removes a resource.
166         * 
167         * @param key
168         *            the resource reference's identifier
169         * @return the removed {@link ResourceReference}. {@code null} if there was no registration for
170         *         this {@link Key}
171         */
172        public final ResourceReference remove(final Key key)
173        {
174                return registry.unregisterResourceReference(key);
175        }
176}