org.apache.servicemix.jbi.deployer.impl.AbstractInstaller.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.servicemix.jbi.deployer.impl.AbstractInstaller.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.servicemix.jbi.deployer.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import javax.jbi.JBIException;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.jbi.deployer.artifacts.AbstractLifecycleJbiArtifact;
import org.apache.servicemix.jbi.deployer.descriptor.Descriptor;
import org.apache.servicemix.jbi.deployer.handler.Transformer;
import org.apache.servicemix.jbi.deployer.utils.FileUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * Installers are used to controll the installation / deployment process of JBI artifacts
 * and manage the installed OSGi bundle.
 *
 * TODO: refactor the use of installRoot and reuse the Deployer#jbiRootDir
 */
public abstract class AbstractInstaller {

    public static final String LAST_INSTALL = "jbi.deployer.install";

    protected final Log LOGGER = LogFactory.getLog(getClass());

    protected Deployer deployer;
    protected Descriptor descriptor;
    protected Bundle bundle;
    protected boolean autoStart = false;
    protected File jbiArtifact;
    protected File installRoot;
    protected boolean uninstallFromOsgi;
    protected boolean isFirstInstall;
    protected boolean isModified;

    protected AbstractInstaller(Deployer deployer, Descriptor descriptor, File jbiArtifact, boolean autoStart) {
        this.deployer = deployer;
        this.descriptor = descriptor;
        this.jbiArtifact = jbiArtifact;
        this.autoStart = autoStart;
    }

    public void setBundle(Bundle bundle) {
        this.bundle = bundle;
    }

    public Bundle getBundle() {
        return bundle;
    }

    protected BundleContext getBundleContext() {
        return deployer.getBundleContext();
    }

    public abstract String getName();

    public void init() throws Exception {
        Preferences prefs = getPreferences();
        long lastInstall = prefs.getLong(LAST_INSTALL, 0);
        isFirstInstall = lastInstall == 0;
        isModified = lastInstall == 0 || getBundle().getLastModified() > lastInstall;
        if (isModified && installRoot != null) {
            extractBundle(installRoot, getBundle(), "/");
            lastInstall = getBundle().getLastModified();
            prefs.put(AbstractLifecycleJbiArtifact.STATE,
                    isAutoStart() ? AbstractLifecycleJbiArtifact.State.Started.name()
                            : AbstractLifecycleJbiArtifact.State.Shutdown.name());
        }
    }

    protected void postInstall() throws Exception {
        Preferences prefs = getPreferences();
        prefs.putLong(LAST_INSTALL, getBundle().getLastModified());
        prefs.flush();
    }

    public abstract ObjectName install() throws JBIException;

    public abstract void stop(boolean force) throws Exception;

    public abstract void uninstall(boolean force) throws Exception;

    public void installBundle() throws Exception {
        InputStream is = null;
        try {
            deployer.setJmxManaged(this);
            File artifact = new File(jbiArtifact.getCanonicalPath());
            String bundleName = artifact.getName().substring(0, artifact.getName().length() - 4) + ".jar";
            File osgi = new File(getGenerateDir(), bundleName);
            Transformer.transformToOSGiBundle(artifact, osgi);
            is = new BufferedInputStream(new FileInputStream(osgi));
            bundle = getBundleContext().installBundle(artifact.getCanonicalFile().toURI().toString(), is);
            bundle.start();
        } catch (Exception e) {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException io) {
                    LOGGER.info("Failed to close stream. " + io, io);
                }
            }
            throw e;
        } finally {
            deployer.setJmxManaged(null);
        }
    }

    protected void uninstallBundle() throws BundleException {
        if (bundle != null && bundle.getState() != Bundle.UNINSTALLED && !uninstallFromOsgi) {
            try {
                deployer.setJmxManaged(this);
                bundle.uninstall();
            } finally {
                deployer.setJmxManaged(null);
            }
        }
    }

    private File getGenerateDir() {
        String base = System.getProperty("servicemix.base", ".");
        return new File(base, "data/generated-bundles");
    }

    protected Preferences getPreferences() {
        return deployer.getPreferencesService().getUserPreferences(getName());
    }

    protected void deletePreferences() throws BackingStoreException {
        Preferences prefs = getPreferences();
        prefs.clear();
        prefs.flush();
    }

    public boolean isAutoStart() {
        return autoStart;
    }

    public void setAutoStart(boolean autoStart) {
        this.autoStart = autoStart;
    }

    public boolean isUninstallFromOsgi() {
        return uninstallFromOsgi;
    }

    public void setUninstallFromOsgi(boolean uninstallFromOsgi) {
        this.uninstallFromOsgi = uninstallFromOsgi;
    }

    protected void extractBundle(File installRoot, Bundle bundle, String path) throws IOException {
        Enumeration e = bundle.getEntryPaths(path);
        while (e != null && e.hasMoreElements()) {
            String entry = (String) e.nextElement();
            File fout = new File(installRoot, entry);
            if (entry.endsWith("/")) {
                fout.mkdirs();
                extractBundle(installRoot, bundle, entry);
            } else {
                InputStream in = bundle.getEntry(entry).openStream();
                OutputStream out = new FileOutputStream(fout);
                try {
                    FileUtil.copyInputStream(in, out);
                } finally {
                    in.close();
                    out.close();
                }
            }
        }
    }

}