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

Java tutorial

Introduction

Here is the source code for org.apache.wicket.request.resource.ResourceStreamResource.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.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.wicket.Application;
import org.apache.wicket.util.lang.Bytes;
import org.apache.wicket.util.lang.Checks;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.IResourceStreamWriter;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.apache.wicket.util.time.Duration;
import org.apache.wicket.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A {@link AbstractResource resource} that loads its data from {@link IResourceStream}
 */
public class ResourceStreamResource extends AbstractResource {
    private static final long serialVersionUID = 1L;

    private static final Logger logger = LoggerFactory.getLogger(ResourceStreamResource.class);

    private final IResourceStream stream;
    private String fileName;
    private ContentDisposition contentDisposition = ContentDisposition.INLINE;
    private String textEncoding;

    private Duration cacheDuration;

    /**
     * Constructor.
     */
    public ResourceStreamResource() {
        this(null);
    }

    /**
     * Constructor.
     * 
     * @param stream
     *      the resource stream to read from
     */
    public ResourceStreamResource(IResourceStream stream) {
        this.stream = stream;
    }

    /**
     * @param fileName
     * @return this object, for chaining
     */
    public ResourceStreamResource setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    /**
     * @param contentDisposition
     * @return this object, for chaining
     */
    public ResourceStreamResource setContentDisposition(ContentDisposition contentDisposition) {
        this.contentDisposition = contentDisposition;
        return this;
    }

    /**
     * @param textEncoding
     * @return this object, for chaining
     */
    public ResourceStreamResource setTextEncoding(String textEncoding) {
        this.textEncoding = textEncoding;
        return this;
    }

    /**
     * @return the duration for which the resource will be cached by the browser
     */
    public Duration getCacheDuration() {
        return cacheDuration;
    }

    /**
     * @param cacheDuration
     *            the duration for which the resource will be cached by the browser
     * @return this object, for chaining
     */
    public ResourceStreamResource setCacheDuration(Duration cacheDuration) {
        this.cacheDuration = cacheDuration;
        return this;
    }

    /**
     * Lazy or dynamic initialization of the wrapped IResourceStream(Writer)
     *
     * @param attributes
     *          The request attributes
     * @return the underlying IResourceStream. May be {@code null}.
     */
    protected IResourceStream getResourceStream(Attributes attributes) {
        return stream;
    }

    private IResourceStream internalGetResourceStream(Attributes attributes) {
        final IResourceStream resourceStream = getResourceStream(attributes);
        Checks.notNull(resourceStream, "%s#getResourceStream(attributes) should not return null!",
                getClass().getName());
        return resourceStream;
    }

    @Override
    protected ResourceResponse newResourceResponse(Attributes attributes) {
        final IResourceStream resourceStream = internalGetResourceStream(attributes);
        ResourceResponse data = new ResourceResponse();
        Time lastModifiedTime = resourceStream.lastModifiedTime();
        if (lastModifiedTime != null) {
            data.setLastModified(lastModifiedTime);
        }

        if (cacheDuration != null) {
            data.setCacheDuration(cacheDuration);
        }

        // performance check; don't bother to do anything if the resource is still cached by client
        if (data.dataNeedsToBeWritten(attributes)) {
            InputStream inputStream = null;
            if (resourceStream instanceof IResourceStreamWriter == false) {
                try {
                    inputStream = resourceStream.getInputStream();
                } catch (ResourceStreamNotFoundException e) {
                    data.setError(HttpServletResponse.SC_NOT_FOUND);
                    close(resourceStream);
                }
            }

            data.setContentDisposition(contentDisposition);
            Bytes length = resourceStream.length();
            if (length != null) {
                data.setContentLength(length.bytes());
            }
            data.setFileName(fileName);

            String contentType = resourceStream.getContentType();
            if (contentType == null && fileName != null && Application.exists()) {
                contentType = Application.get().getMimeType(fileName);
            }
            data.setContentType(contentType);
            data.setTextEncoding(textEncoding);

            if (resourceStream instanceof IResourceStreamWriter) {
                data.setWriteCallback(new WriteCallback() {
                    @Override
                    public void writeData(Attributes attributes) throws IOException {
                        ((IResourceStreamWriter) resourceStream).write(attributes.getResponse().getOutputStream());
                        close(resourceStream);
                    }
                });
            } else {
                final InputStream s = inputStream;
                data.setWriteCallback(new WriteCallback() {
                    @Override
                    public void writeData(Attributes attributes) throws IOException {
                        try {
                            writeStream(attributes, s);
                        } finally {
                            close(resourceStream);
                        }
                    }
                });
            }
        }

        return data;
    }

    private void close(IResourceStream stream) {
        try {
            stream.close();
        } catch (IOException e) {
            logger.error("Couldn't close ResourceStream", e);
        }
    }
}