org.apache.sling.distribution.packaging.impl.AbstractDistributionPackageBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sling.distribution.packaging.impl.AbstractDistributionPackageBuilder.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.sling.distribution.packaging.impl;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.distribution.DistributionRequest;
import org.apache.sling.distribution.DistributionRequestType;
import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.packaging.DistributionPackage;
import org.apache.sling.distribution.packaging.DistributionPackageBuilder;
import org.apache.sling.distribution.packaging.DistributionPackageInfo;
import org.apache.sling.distribution.serialization.impl.vlt.VltUtils;
import org.apache.sling.distribution.util.DistributionJcrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * base abstract implementation of a JCR based {@link DistributionPackageBuilder}
 */
public abstract class AbstractDistributionPackageBuilder implements DistributionPackageBuilder {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final String type;

    protected AbstractDistributionPackageBuilder(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    @Nonnull
    public DistributionPackage createPackage(@Nonnull ResourceResolver resourceResolver,
            @Nonnull DistributionRequest request) throws DistributionException {
        DistributionPackage distributionPackage;

        request = VltUtils.sanitizeRequest(request);

        if (DistributionRequestType.ADD.equals(request.getRequestType())) {
            distributionPackage = createPackageForAdd(resourceResolver, request);
        } else if (DistributionRequestType.DELETE.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else if (DistributionRequestType.PULL.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else if (DistributionRequestType.TEST.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else {
            throw new DistributionException("unknown action type " + request.getRequestType());
        }

        DistributionPackageUtils.fillInfo(distributionPackage.getInfo(), request);

        return distributionPackage;
    }

    @Nonnull
    public DistributionPackage readPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull InputStream stream)
            throws DistributionException {

        if (!stream.markSupported()) {
            stream = new BufferedInputStream(stream);
        }
        Map<String, Object> headerInfo = new HashMap<String, Object>();
        DistributionPackageUtils.readInfo(stream, headerInfo);

        try {
            stream.reset();
        } catch (IOException e) {
            // do nothing
        }

        DistributionPackage distributionPackage = SimpleDistributionPackage.fromStream(stream, type);

        try {
            stream.reset();
        } catch (IOException e) {
            // do nothing
        }

        // not a simple package
        if (distributionPackage == null) {
            distributionPackage = readPackageInternal(resourceResolver, stream);
        }

        distributionPackage.getInfo().putAll(headerInfo);
        return distributionPackage;
    }

    public boolean installPackage(@Nonnull ResourceResolver resourceResolver,
            @Nonnull DistributionPackage distributionPackage) throws DistributionException {

        DistributionRequestType actionType = distributionPackage.getInfo().getRequestType();

        if (!type.equals(distributionPackage.getType())) {
            throw new DistributionException("not supported package type" + distributionPackage.getType());
        }

        boolean installed = false;
        if (DistributionRequestType.DELETE.equals(actionType)) {
            installed = installDeletePackage(resourceResolver, distributionPackage);
        } else if (DistributionRequestType.TEST.equals(actionType)) {
            // do nothing for test packages
            installed = true;
        } else if (DistributionRequestType.ADD.equals(actionType)) {
            installed = installAddPackage(resourceResolver, distributionPackage);
        }

        return installed;
    }

    @Nonnull
    @Override
    public DistributionPackageInfo installPackage(@Nonnull ResourceResolver resourceResolver,
            @Nonnull InputStream stream) throws DistributionException {
        if (!stream.markSupported()) {
            stream = new BufferedInputStream(stream);
        }
        DistributionPackageInfo packageInfo = new DistributionPackageInfo(type);

        DistributionPackageUtils.readInfo(stream, packageInfo);

        DistributionPackage distributionPackage = SimpleDistributionPackage.fromStream(stream, type);

        boolean installed;
        // not a simple package
        if (distributionPackage == null) {
            installed = installPackageInternal(resourceResolver, stream);
        } else {
            installed = installPackage(resourceResolver, distributionPackage);
            packageInfo.putAll(distributionPackage.getInfo());
        }

        if (installed) {
            return packageInfo;
        } else {
            throw new DistributionException("could not install package from stream");
        }
    }

    private boolean installDeletePackage(@Nonnull ResourceResolver resourceResolver,
            @CheckForNull DistributionPackage distributionPackage) throws DistributionException {
        Session session = null;
        try {
            if (distributionPackage != null) {
                session = getSession(resourceResolver);
                for (String path : distributionPackage.getInfo().getPaths()) {
                    if (session.itemExists(path)) {
                        session.removeItem(path);
                    }
                }
                return true;
            }
        } catch (Exception e) {
            throw new DistributionException(e);
        } finally {
            ungetSession(session);
        }

        return false;
    }

    private boolean installAddPackage(@Nonnull ResourceResolver resourceResolver,
            @Nonnull DistributionPackage distributionPackage) throws DistributionException {
        InputStream inputStream = null;
        try {
            inputStream = distributionPackage.createInputStream();
            return installPackageInternal(resourceResolver, inputStream);
        } catch (IOException e) {
            throw new DistributionException(e);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

    }

    @CheckForNull
    public DistributionPackage getPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull String id) {
        DistributionPackage distributionPackage = SimpleDistributionPackage.fromIdString(id, type);

        // not a simple package
        if (distributionPackage == null) {
            if (id.startsWith("reference")) {
                String localId = id.substring("reference-".length());
                distributionPackage = new ReferencePackage(getPackageInternal(resourceResolver, localId));
            } else {
                distributionPackage = getPackageInternal(resourceResolver, id);
            }

        }
        return distributionPackage;
    }

    protected Session getSession(ResourceResolver resourceResolver) throws RepositoryException {
        Session session = resourceResolver.adaptTo(Session.class);
        if (session != null) {
            DistributionJcrUtils.setDoNotDistribute(session);
        } else {
            throw new RepositoryException(
                    "could not obtain a session from calling user " + resourceResolver.getUserID());
        }
        return session;
    }

    protected void ungetSession(Session session) {
        if (session != null) {
            try {
                if (session.hasPendingChanges()) {
                    session.save();
                }
            } catch (RepositoryException e) {
                log.debug("Cannot save session", e);
            }
        }
    }

    @CheckForNull
    protected abstract DistributionPackage createPackageForAdd(@Nonnull ResourceResolver resourceResolver,
            @Nonnull DistributionRequest request) throws DistributionException;

    @CheckForNull
    protected abstract DistributionPackage readPackageInternal(@Nonnull ResourceResolver resourceResolver,
            @Nonnull InputStream stream) throws DistributionException;

    protected abstract boolean installPackageInternal(@Nonnull ResourceResolver resourceResolver,
            @Nonnull InputStream stream) throws DistributionException;

    @CheckForNull
    protected abstract DistributionPackage getPackageInternal(@Nonnull ResourceResolver resourceResolver,
            @Nonnull String id);

}