org.eclipse.skalli.core.rest.admin.StatisticsBackupResource.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.skalli.core.rest.admin.StatisticsBackupResource.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2014 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.skalli.core.rest.admin;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.eclipse.skalli.commons.Statistics;
import org.eclipse.skalli.commons.Statistics.BrowserInfo;
import org.eclipse.skalli.commons.Statistics.RefererInfo;
import org.eclipse.skalli.commons.Statistics.ResponseTimeInfo;
import org.eclipse.skalli.commons.Statistics.SearchInfo;
import org.eclipse.skalli.commons.Statistics.UsageInfo;
import org.eclipse.skalli.commons.Statistics.UserInfo;
import org.eclipse.skalli.services.extension.rest.ResourceBase;
import org.eclipse.skalli.services.extension.rest.ResourceRepresentation;
import org.eclipse.skalli.services.permit.Permits;
import org.restlet.data.Disposition;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.representation.OutputRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Put;

import com.thoughtworks.xstream.XStreamException;

public class StatisticsBackupResource extends ResourceBase {

    private static final String FILE_NAME = "statistics.zip"; //$NON-NLS-1$
    private static final String ENTRY_NAME = "statistics.xml"; //$NON-NLS-1$

    private static final String ID_PREFIX = "rest:api/admin/statistics/backup:"; //$NON-NLS-1$
    private static final String ERROR_ID_IO_ERROR = ID_PREFIX + "00"; //$NON-NLS-1$
    private static final String ERROR_ID_INVALID_BACKUP = ID_PREFIX + ":30"; //$NON-NLS-1$
    private static final String ERROR_ID_PARSING_FAILED = ID_PREFIX + ":40"; //$NON-NLS-1$
    private static final String ERROR_ID_CLASS_MISMATCH = ID_PREFIX + ":50"; //$NON-NLS-1$

    @Get
    public Representation backup() {
        if (!Permits.isAllowed(getAction(), getPath())) {
            return createUnauthorizedRepresentation();
        }
        StatisticsQuery query = new StatisticsQuery(getQueryAttributes());
        Statistics statistics = new Statistics(Statistics.getDefault(), query.getFrom(), query.getTo());
        ZipOutputRepresentation zipRepresentation = new ZipOutputRepresentation(statistics);
        Disposition disposition = new Disposition(Disposition.TYPE_ATTACHMENT);
        disposition.setFilename(FILE_NAME);
        zipRepresentation.setDisposition(disposition);
        return zipRepresentation;
    }

    @Put
    public Representation restore(Representation entity) {
        if (!Permits.isAllowed(getAction(), getPath())) {
            return createUnauthorizedRepresentation();
        }

        ZipInputStream zipStream = null;
        try {
            zipStream = new ZipInputStream(entity.getStream());
            ZipEntry entry = zipStream.getNextEntry();
            try {
                String entryName = entry.getName();
                if (!entryName.equals(ENTRY_NAME)) {
                    return createErrorRepresentation(Status.CLIENT_ERROR_BAD_REQUEST, ERROR_ID_INVALID_BACKUP,
                            "Invalid backup file: Expected entry ''statistics.xml'', but found ''{0}''", entryName); //$NON-NLS-1$
                }
                ResourceRepresentation<Statistics> representation = new ResourceRepresentation<Statistics>();
                addAliases(representation);
                Statistics.getDefault().restore(representation.read(zipStream, Statistics.class));
            } finally {
                zipStream.closeEntry();
            }
        } catch (IOException e) {
            return createIOErrorRepresentation(ERROR_ID_IO_ERROR, e);
        } catch (XStreamException e) {
            return createErrorRepresentation(Status.CLIENT_ERROR_BAD_REQUEST, ERROR_ID_PARSING_FAILED,
                    "Invalid backup file: {0}", e.getMessage()); //$NON-NLS-1$
        } catch (ClassCastException e) {
            return createErrorRepresentation(Status.CLIENT_ERROR_BAD_REQUEST, ERROR_ID_CLASS_MISMATCH,
                    "Invalid backup file: {0}", e.getMessage()); //$NON-NLS-1$
        } finally {
            IOUtils.closeQuietly(zipStream);
        }
        setStatus(Status.SUCCESS_NO_CONTENT);
        return null;
    }

    private static class ZipOutputRepresentation extends OutputRepresentation {

        private Statistics statistics;

        public ZipOutputRepresentation(Statistics statistics) {
            super(MediaType.APPLICATION_ZIP);
            this.statistics = statistics;
        }

        @Override
        public void write(OutputStream out) throws IOException {
            ZipOutputStream zipStream = null;
            try {
                zipStream = new ZipOutputStream(new BufferedOutputStream(out));
                ZipEntry entry = new ZipEntry(ENTRY_NAME);
                zipStream.putNextEntry(entry);
                ResourceRepresentation<Statistics> representation = new ResourceRepresentation<Statistics>(
                        statistics);
                addAliases(representation);
                representation.write(zipStream);
            } finally {
                IOUtils.closeQuietly(zipStream);
            }
        }
    }

    @SuppressWarnings("nls")
    private static void addAliases(ResourceRepresentation<Statistics> representation) {
        representation.addAlias("statistics", Statistics.class);
        representation.addAlias("user", UserInfo.class);
        representation.addAlias("usage", UsageInfo.class);
        representation.addAlias("referer", RefererInfo.class);
        representation.addAlias("browser", BrowserInfo.class);
        representation.addAlias("search", SearchInfo.class);
        representation.addAlias("responseTime", ResponseTimeInfo.class);
    }
}