org.apache.wicket.resource.TextTemplateResourceReference.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.resource.TextTemplateResourceReference.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.resource;

import java.util.Locale;
import java.util.Map;

import org.apache.wicket.Application;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.request.resource.ResourceReferenceRegistry;
import org.apache.wicket.request.resource.ResourceStreamResource;
import org.apache.wicket.util.io.IClusterable;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;
import org.apache.wicket.util.template.PackageTextTemplate;
import org.apache.wicket.util.template.TextTemplate;
import org.apache.wicket.util.time.Duration;
import org.apache.wicket.util.time.Time;

/**
 * A class which adapts a {@link PackageTextTemplate} to a {@link ResourceReference}.
 * 
 * @see {@link "https://cwiki.apache.org/WICKET/dynamically-generate-a-css-stylesheet.html"}
 * 
 * @author James Carman
 */
public class TextTemplateResourceReference extends ResourceReference implements IClusterable {

    private static final long serialVersionUID = 1L;

    private final TextTemplate textTemplate;
    private final IModel<Map<String, Object>> variablesModel;
    private final ResourceStreamResource resource;

    /**
     * Creates a resource reference to a {@link PackageTextTemplate}.
     * 
     * @param scope
     *            the <code>Class</code> to be used for retrieving the classloader for loading the
     *            <code>PackagedTextTemplate</code>
     * @param fileName
     *            the file name
     * @param variablesModel
     *            the template variables as a model
     */
    public TextTemplateResourceReference(final Class<?> scope, final String fileName,
            IModel<Map<String, Object>> variablesModel) {
        this(scope, fileName, PackageTextTemplate.DEFAULT_CONTENT_TYPE, PackageTextTemplate.DEFAULT_ENCODING,
                variablesModel);
    }

    /**
     * Creates a resource reference to a {@link PackageTextTemplate}.
     * 
     * @param scope
     *            the <code>Class</code> to be used for retrieving the classloader for loading the
     *            <code>PackagedTextTemplate</code>
     * @param fileName
     *            the file name
     * @param contentType
     *            the mime type of this resource, such as "<code>image/jpeg</code>" or "
     *            <code>text/html</code>"
     * @param variablesModel
     *            the template variables as a model
     */
    public TextTemplateResourceReference(final Class<?> scope, final String fileName, final String contentType,
            IModel<Map<String, Object>> variablesModel) {
        this(scope, fileName, contentType, PackageTextTemplate.DEFAULT_ENCODING, variablesModel);
    }

    /**
     * Creates a resource reference to a {@link PackageTextTemplate}.
     * 
     * @param scope
     *            the <code>Class</code> to be used for retrieving the classloader for loading the
     *            <code>PackagedTextTemplate</code>
     * @param fileName
     *            the file name
     * @param contentType
     *            the mime type of this resource, such as "<code>image/jpeg</code>" or "
     *            <code>text/html</code>"
     * @param encoding
     *            the file's encoding, for example, "<code>UTF-8</code>"
     * @param variablesModel
     *            the template variables as a model
     */
    public TextTemplateResourceReference(final Class<?> scope, final String fileName, final String contentType,
            final String encoding, IModel<Map<String, Object>> variablesModel) {
        this(scope, fileName, contentType, encoding, variablesModel, null, null, null);
    }

    /**
     * Construct.
     * 
     * @param scope
     *            the <code>Class</code> to be used for retrieving the classloader for loading the
     *            <code>PackagedTextTemplate</code>
     * @param fileName
     *            the file name
     * @param contentType
     *            the mime type of this resource, such as "<code>image/jpeg</code>" or "
     *            <code>text/html</code>"
     * @param encoding
     *            the file's encoding, for example, "<code>UTF-8</code>"
     * @param variablesModel
     *            the template variables as a model
     * @param locale
     *            Preferred locale for the resource
     * @param style
     *            Preferred style for the resource
     * @param variation
     *            Preferred variation for the resource
     */
    public TextTemplateResourceReference(final Class<?> scope, final String fileName, final String contentType,
            final String encoding, IModel<Map<String, Object>> variablesModel, Locale locale, String style,
            String variation) {
        super(scope, fileName, locale, style, variation);

        textTemplate = new PackageTextTemplate(scope, fileName, contentType, encoding);
        this.variablesModel = variablesModel;

        resource = new ResourceStreamResource(null) {
            @Override
            protected IResourceStream getResourceStream(Attributes attributes) {
                IModel<Map<String, Object>> variables = TextTemplateResourceReference.this.variablesModel;
                String stringValue = textTemplate.asString(variables.getObject());
                variables.detach(); // We're done with the model so detach it!

                StringResourceStream resourceStream = new StringResourceStream(stringValue,
                        textTemplate.getContentType());
                resourceStream.setLastModified(Time.now());

                return resourceStream;
            }
        };
        resource.setCacheDuration(Duration.NONE);

        if (Application.exists()) {
            // TextTemplateResourceReference should not be cached due to its dynamic nature
            // Old entry in the registry would keep wrong 'variablesModel'
            ResourceReferenceRegistry resourceReferenceRegistry = Application.get().getResourceReferenceRegistry();
            resourceReferenceRegistry.unregisterResourceReference(getKey());
            resourceReferenceRegistry.registerResourceReference(this);
        }
    }

    /**
     * Creates a new resource which returns the interpolated value of the text template.
     * 
     * @return a new resource which returns the interpolated value of the text template
     */
    @Override
    public IResource getResource() {
        return resource;
    }
}