org.apache.wicket.request.resource.ResourceReference.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.request.resource.ResourceReference.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.request.resource;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.Application;
import org.apache.wicket.core.util.lang.WicketObjects;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.util.io.IClusterable;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.lang.Objects;
import org.danekja.java.util.function.serializable.SerializableSupplier;

/**
 * Reference to a resource. Can be used to reference global resources.
 * <p>
 * Even though resource reference is just a factory for resources, it still needs to be identified
 * by a globally unique identifier, combination of <code>scope</code> and <code>name</code>. Those
 * are used to generate URLs for resource references. <code>locale</code>, <code>style</code> and
 * <code>variation</code> are optional fields to allow having specific references for individual
 * locales, styles and variations.
 * 
 * @author Matej Knopp
 * @author Juergen Donnerstag
 */
public abstract class ResourceReference implements IClusterable {
    private static final long serialVersionUID = 1L;

    private final Key data;

    /**
     * Creates new {@link ResourceReference} instance.
     * 
     * @param key
     *            The data making up the resource reference
     */
    public ResourceReference(final Key key) {
        Args.notNull(key, "key");

        data = key;
    }

    /**
     * Creates new {@link ResourceReference} instance.
     * 
     * @param scope
     *            mandatory parameter
     * @param name
     *            mandatory parameter
     * @param locale
     *            resource locale
     * @param style
     *            resource style
     * @param variation
     *            resource variation
     */
    public ResourceReference(Class<?> scope, String name, Locale locale, String style, String variation) {
        Args.notNull(scope, "scope");
        Args.notNull(name, "name");

        data = new Key(scope.getName(), name, locale, style, variation);
    }

    /**
     * Creates new {@link ResourceReference} instance.
     * 
     * @param scope
     *            mandatory parameter
     * @param name
     *            mandatory parameter
     */
    public ResourceReference(Class<?> scope, String name) {
        this(scope, name, null, null, null);
    }

    /**
     * Construct.
     * 
     * @param name
     *            resource name
     */
    public ResourceReference(String name) {
        this(Application.class, name, null, null, null);
    }

    /**
     * @return Gets the data making up the resource reference. They'll be use by
     *         ResourceReferenceRegistry to make up the key under which the resource reference gets
     *         stored.
     */
    public final Key getKey() {
        return data;
    }

    /**
     * @return name
     */
    public String getName() {
        return data.getName();
    }

    /**
     * returns extension of the resource reference
     * 
     * @return extension of the resource's name in lower-case or <code>null</code> if there is no
     *         extension
     */
    public final String getExtension() {
        String name = getName();

        final int queryAt = name.indexOf('?');

        // remove query string part
        if (queryAt != -1) {
            name = name.substring(0, queryAt);
        }

        // get start of extension
        final int extPos = name.lastIndexOf('.');

        if (extPos == -1) {
            return null;
        }

        // return extension
        return name.substring(extPos + 1).toLowerCase(Locale.ROOT);
    }

    /**
     * @return scope
     */
    public Class<?> getScope() {
        return WicketObjects.resolveClass(data.getScope());
    }

    /**
     * @return locale
     */
    public Locale getLocale() {
        return data.getLocale();
    }

    /**
     * @return style
     */
    public String getStyle() {
        return data.getStyle();
    }

    /**
     * @return variation
     */
    public String getVariation() {
        return data.getVariation();
    }

    /**
     * Can be used to disable registering certain resource references in
     * {@link ResourceReferenceRegistry}.
     * 
     * @return <code>true</code> if this reference can be registered, <code>false</code> otherwise.
     */
    public boolean canBeRegistered() {
        return true;
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof ResourceReference == false) {
            return false;
        }
        ResourceReference that = (ResourceReference) obj;
        return Objects.equal(data, that.data);
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return data.hashCode();
    }

    /**
     * Returns the resource.
     * 
     * @return resource instance
     */
    public abstract IResource getResource();

    /**
     * Allows to specify which locale, style and variation values will the generated URL for this
     * resource reference have.
     * 
     * @return url attributes
     */
    public UrlAttributes getUrlAttributes() {
        return new UrlAttributes(getLocale(), getStyle(), getVariation());
    }

    /**
     * Factory method to build a resource reference that uses the provided supplier to return
     * the resource.
     * 
     * @param name
     *             The name to use with the resource
     * @param resourceSupplier
     *             Lambda supplier to build the resource
     * @return the new resource reference
     */
    public static final ResourceReference of(String name, SerializableSupplier<IResource> resourceSupplier) {
        return new LambdaResourceReference(name, resourceSupplier);
    }

    /**
     * Factory method to build a resource reference that uses the provided supplier to return
     * the resource.
     * 
     * @param key
     *             The {@link Key} to use with the resource
     * @param resourceSupplier
     *             Lambda supplier to build the resource
     * @return  the new resource reference
     */
    public static final ResourceReference of(Key key, SerializableSupplier<IResource> resourceSupplier) {
        return new LambdaResourceReference(key, resourceSupplier);
    }

    public static final class LambdaResourceReference extends ResourceReference {
        private static final long serialVersionUID = 1826862147241009289L;

        final SerializableSupplier<IResource> resourceBuilder;

        public LambdaResourceReference(String name, SerializableSupplier<IResource> resourceBuilder) {
            super(name);
            this.resourceBuilder = Args.notNull(resourceBuilder, "resourceBuilder");
        }

        public LambdaResourceReference(Key key, SerializableSupplier<IResource> resourceBuilder) {
            super(key);
            this.resourceBuilder = Args.notNull(resourceBuilder, "resourceBuilder");
        }

        @Override
        public IResource getResource() {
            return resourceBuilder.get();
        }
    }

    /**
     * @see ResourceReference#getUrlAttributes()
     * 
     * @author Matej Knopp
     */
    public static class UrlAttributes {
        private final Locale locale;
        private final String style;
        private final String variation;

        /**
         * Construct.
         * 
         * @param locale
         *            resource locale
         * @param style
         *            resource style
         * @param variation
         *            resource variation
         */
        public UrlAttributes(Locale locale, String style, String variation) {
            this.locale = locale;
            this.style = style;
            this.variation = variation;
        }

        /**
         * @return locale
         */
        public Locale getLocale() {
            return locale;
        }

        /**
         * @return style
         */
        public String getStyle() {
            return style;
        }

        /**
         * @return variation
         */
        public String getVariation() {
            return variation;
        }

        /**
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof UrlAttributes == false) {
                return false;
            }
            UrlAttributes that = (UrlAttributes) obj;
            return Objects.equal(getLocale(), that.getLocale()) && Objects.equal(getStyle(), that.getStyle())
                    && Objects.equal(getVariation(), that.getVariation());
        }

        /**
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            return Objects.hashCode(getLocale(), getStyle(), getVariation());
        }

        /**
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return "locale: " + locale + "; style: " + style + "; variation: " + variation;
        }
    }

    /**
     * A (re-usable) data store for all relevant ResourceReference data
     */
    public static class Key implements Serializable {
        private static final long serialVersionUID = 1L;

        private final String scope;
        private final String name;
        private final Locale locale;
        private final String style;
        private final String variation;

        /**
         * Construct.
         * 
         * @param reference
         *            resource reference
         */
        public Key(final ResourceReference reference) {
            this(reference.getScope().getName(), reference.getName(), reference.getLocale(), reference.getStyle(),
                    reference.getVariation());
        }

        /**
         * Construct.
         * 
         * @param scope
         *            resource scope
         * @param name
         *            resource name
         * @param locale
         *            resource locale
         * @param style
         *            resource style
         * @param variation
         *            resource variation
         */
        public Key(final String scope, final String name, final Locale locale, final String style,
                final String variation) {
            Args.notNull(scope, "scope");
            Args.notNull(name, "name");

            this.scope = scope.intern();
            this.name = name.intern();
            this.locale = locale;
            this.style = style != null ? style.intern() : null;
            this.variation = variation != null ? variation.intern() : null;
        }

        /**
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(final Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof Key == false) {
                return false;
            }
            Key that = (Key) obj;
            return Objects.equal(scope, that.scope) && //
                    Objects.equal(name, that.name) && //
                    Objects.equal(locale, that.locale) && //
                    Objects.equal(style, that.style) && //
                    Objects.equal(variation, that.variation);
        }

        /**
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            return Objects.hashCode(scope, name, locale, style, variation);
        }

        /**
         * Gets scope.
         * 
         * @return scope
         */
        public final String getScope() {
            return scope;
        }

        /**
         * @return Assuming scope ist a fully qualified class name, than get the associated class
         */
        public final Class<?> getScopeClass() {
            return WicketObjects.resolveClass(scope);
        }

        /**
         * Gets name.
         * 
         * @return name
         */
        public final String getName() {
            return name;
        }

        /**
         * Gets locale.
         * 
         * @return locale
         */
        public final Locale getLocale() {
            return locale;
        }

        /**
         * Gets style.
         * 
         * @return style
         */
        public final String getStyle() {
            return style;
        }

        /**
         * Gets variation.
         * 
         * @return variation
         */
        public final String getVariation() {
            return variation;
        }

        /**
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return "scope: " + scope + "; name: " + name + "; locale: " + locale + "; style: " + style
                    + "; variation: " + variation;
        }
    }

    @Override
    public String toString() {
        return data.toString();
    }

    /**
     * @return the resources this ResourceReference depends on.
     */
    public List<HeaderItem> getDependencies() {
        return new ArrayList<>();
    }
}