name.martingeisse.webide.plugin.PluginBundleWicketResource.java Source code

Java tutorial

Introduction

Here is the source code for name.martingeisse.webide.plugin.PluginBundleWicketResource.java

Source

/**
 * Copyright (c) 2010 Martin Geisse
 *
 * This file is distributed under the terms of the MIT license.
 */

package name.martingeisse.webide.plugin;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import name.martingeisse.common.database.EntityConnectionManager;
import name.martingeisse.webide.entity.QPluginBundles;
import name.martingeisse.webide.resources.ResourcePath;

import org.apache.commons.io.IOUtils;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.util.time.Duration;

import com.mysema.query.sql.SQLQuery;

/**
 * A Wicket resource that represents a plugin bundle JAR.
 */
public class PluginBundleWicketResource extends AbstractResource {

    /**
     * the pluginBundleId
     */
    private final long pluginBundleId;

    /**
     * the localPath
     */
    private final ResourcePath localPath;

    /**
     * Constructor.
     * @param pluginBundleId the plugin bundle ID
     * @param localPath the local path within the plugin bundle
     */
    public PluginBundleWicketResource(final long pluginBundleId, final ResourcePath localPath) {
        this.pluginBundleId = pluginBundleId;
        this.localPath = localPath;
        if (localPath != null && !localPath.isLeadingSeparator()) {
            throw new IllegalArgumentException(
                    "Cannot build a PluginBundleWicketResource from a relative path: " + localPath);
        }
    }

    /* (non-Javadoc)
     * @see org.apache.wicket.request.resource.AbstractResource#newResourceResponse(org.apache.wicket.request.resource.IResource.Attributes)
     */
    @Override
    protected ResourceResponse newResourceResponse(final Attributes attributes) {

        // fetch the JAR file
        final SQLQuery query = EntityConnectionManager.getConnection().createQuery();
        query.from(QPluginBundles.pluginBundles);
        query.where(QPluginBundles.pluginBundles.id.eq(pluginBundleId));
        final Object[] row = (Object[]) (Object) query.singleResult(QPluginBundles.pluginBundles.jarfile);
        final byte[] jarData = (byte[]) row[0];
        String matchingEntryName;
        final byte[] matchingEntryData;

        // if requested, load a single file from the JAR
        if (localPath != null) {
            final String localPathText = localPath.withLeadingSeparator(false).withTrailingSeparator(false)
                    .toString();
            try {
                final ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(jarData));
                while (true) {
                    final ZipEntry entry = zipInputStream.getNextEntry();
                    if (entry == null) {
                        zipInputStream.close();
                        final ResourceResponse response = new ResourceResponse();
                        response.setError(404, "Plugin bundle (id " + pluginBundleId + ") does not contain file: "
                                + localPathText);
                        response.setStatusCode(404);
                        return response;
                    }
                    if (localPathText.equals(entry.getName())) {
                        matchingEntryName = entry.getName();
                        matchingEntryData = IOUtils.toByteArray(zipInputStream);
                        zipInputStream.close();
                        break;
                    }
                }
            } catch (final Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            matchingEntryName = null;
            matchingEntryData = null;
        }

        // build the response
        final ResourceResponse response = new ResourceResponse();
        response.setCacheDuration(Duration.NONE);
        response.setContentDisposition(ContentDisposition.ATTACHMENT);
        if (matchingEntryData == null) {
            response.setFileName("plugin-bundle-" + pluginBundleId + ".jar");
        } else {
            final int lastSlashIndex = matchingEntryName.lastIndexOf('/');
            if (lastSlashIndex != -1) {
                matchingEntryName = matchingEntryName.substring(lastSlashIndex + 1);
            }
            response.setFileName(matchingEntryName);
        }
        response.setWriteCallback(new WriteCallback() {
            @Override
            public void writeData(final Attributes attributes) throws IOException {
                attributes.getResponse().write(matchingEntryData == null ? jarData : matchingEntryData);
            }
        });
        return response;

    }

}