Package org.apache.sling.launchpad.base.impl.bootstrapcommands

Source Code of org.apache.sling.launchpad.base.impl.bootstrapcommands.UninstallBundleCommand

/*
* 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.launchpad.base.impl.bootstrapcommands;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.VersionRange;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;

/**
* A Command that uninstalls a bundle, see
* {@link UninstallBundleCommandTest} for examples
*/
class UninstallBundleCommand implements Command {

    private static String CMD_PREFIX = "uninstall ";
    private final String bundleSymbolicName;
    private final VersionRange versionRange;

    /** Used to create a prototype object, for parsing */
    UninstallBundleCommand() {
        bundleSymbolicName = null;
        versionRange = null;
    }

    /**
     * Used to create an uninstall command with symbolic name and version range
     */
    private UninstallBundleCommand(final String bundleSymbolicName, String versionRangeStr) {
        this.bundleSymbolicName = bundleSymbolicName;

        // If versionRangeStr is not a range, make it strict
        if (!versionRangeStr.contains(",")) {
            versionRangeStr = "[" + versionRangeStr + "," + versionRangeStr + "]";
        }
        this.versionRange = VersionRange.parse(versionRangeStr);
    }

    /**
     * Used to create an uninstall command with symbolic name
     */
    private UninstallBundleCommand(String bundleSymbolicName) {
        this.bundleSymbolicName = bundleSymbolicName;
        this.versionRange = null;
    }

    /**
     * Gets the bundle's Fragment-Host header.
     */
    private static String getFragmentHostHeader(final Bundle b) {
        return (String) b.getHeaders().get( Constants.FRAGMENT_HOST );
    }

    private boolean isSystemBundleFragment(final Bundle installedBundle) {
        final String fragmentHeader = (String) installedBundle.getHeaders().get(
            Constants.FRAGMENT_HOST);
        return fragmentHeader != null
            && fragmentHeader.indexOf(Constants.EXTENSION_DIRECTIVE) > 0;
    }

    /**
     * @see org.apache.sling.launchpad.base.impl.bootstrapcommands.Command#execute(org.apache.felix.framework.Logger, org.osgi.framework.BundleContext)
     */
    public boolean execute(final Logger logger, final BundleContext ctx) throws Exception {
        final Set<String> refreshBundles = new HashSet<String>();
        // Uninstall all instances of our bundle within our version range
        boolean refreshSystemBundle = false;
        for(final Bundle b : ctx.getBundles()) {
            if (b.getSymbolicName().equals(bundleSymbolicName)) {
                if (versionRange == null || versionRange.isInRange(b.getVersion())) {
                    logger.log(Logger.LOG_INFO,
                            this + ": uninstalling bundle version " + b.getVersion());
                    final String fragmentHostHeader = getFragmentHostHeader(b);
                    if (fragmentHostHeader != null) {
                        if ( isSystemBundleFragment(b) ) {
                            logger.log(Logger.LOG_INFO, this + ": Need to do a system bundle refresh");
                            refreshSystemBundle = true;
                        } else {
                            logger.log(Logger.LOG_INFO, this + ": Need to do a refresh of the bundle's host: " + fragmentHostHeader);
                            refreshBundles.add(fragmentHostHeader);
                        }
                    }

                    b.uninstall();
                } else {
                    logger.log(Logger.LOG_INFO,
                            this + ": bundle version (" + b.getVersion()+ " not in range, ignored");
                }
            }
        }
        if ( refreshBundles.size() > 0 ) {
            final List<Bundle> bundles = new ArrayList<Bundle>();
            for(final Bundle b : ctx.getBundles() ) {
                if ( refreshBundles.contains(b.getSymbolicName()) ) {
                    logger.log(Logger.LOG_INFO, this + ": Found host bundle to refresh " + b.getBundleId());
                    bundles.add(b);
                }
            }
            if ( bundles.size() > 0 ) {
                final ServiceReference paRef = ctx.getServiceReference(PackageAdmin.class.getName());
                if ( paRef != null ) {
                    try {
                        final PackageAdmin pa = (PackageAdmin)ctx.getService(paRef);
                        if ( pa != null ) {
                            pa.refreshPackages(bundles.toArray(new Bundle[bundles.size()]));
                        }
                    } finally {
                        ctx.ungetService(paRef);
                    }
                }
            }
        }
        return refreshSystemBundle;
    }

    public Command parse(String commandLine) throws ParseException {
        if(commandLine.startsWith(CMD_PREFIX)) {
            final String [] s = commandLine.split(" ");
            if (s.length == 3) {
                return new UninstallBundleCommand(s[1].trim(), s[2].trim());
            } else if ( s.length == 2 ) {
                return new UninstallBundleCommand(s[1].trim());
            }
            throw new Command.ParseException("Syntax error: '" + commandLine + "'");
        }
        return null;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " " + bundleSymbolicName + " " + (versionRange != null ? versionRange : "");
    }
}
TOP

Related Classes of org.apache.sling.launchpad.base.impl.bootstrapcommands.UninstallBundleCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.