org.apache.geronimo.console.bundlemanager.BundleManagerPortlet.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.geronimo.console.bundlemanager.BundleManagerPortlet.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.geronimo.console.bundlemanager;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;
import org.apache.geronimo.console.BasePortlet;
import org.apache.geronimo.console.util.PortletManager;
import org.apache.geronimo.kernel.config.ConfigurationInfo;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.xbean.osgi.bundle.util.BundleDescription;
import org.apache.xbean.osgi.bundle.util.VersionRange;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.blueprint.container.BlueprintContainer;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BundleManagerPortlet extends BasePortlet {

    private static final Logger logger = LoggerFactory.getLogger(BundleManagerPortlet.class);

    private PortletRequestDispatcher helpView;

    private PortletRequestDispatcher bundleManagerView;

    private PortletRequestDispatcher showManifestView;

    private PortletRequestDispatcher showWiredBundlesView;

    private PortletRequestDispatcher showServicesView;

    private PortletRequestDispatcher findPackagesView;

    private static final String VIEW_MANIFEST_PAGE = "view_manifest";

    private static final String VIEW_WIRED_BUNDLES_PAGE = "view_wired_bundles";

    private static final String VIEW_SERVICES_PAGE = "view_services";

    private static final String FIND_PACKAGES_PAGE = "find_packages";

    private static final String SERACH_ACTION = "search";

    private static final String LIST_ACTION = "list";

    private static final String INSTALL_ACTION = "install";

    private static final String BUNDLE_ACTION = "bundle";

    private static final String START_OPERATION = "start";

    private static final String STOP_OPERATION = "stop";

    private static final String UPDATE_OPERATION = "update";

    private static final String REFRESH_OPERATION = "refresh";

    private static final String UNINSTALL_OPERATION = "uninstall";

    protected void doHelp(RenderRequest renderRequest, RenderResponse renderResponse)
            throws PortletException, IOException {
        helpView.include(renderRequest, renderResponse);
    }

    public void init(PortletConfig portletConfig) throws PortletException {
        super.init(portletConfig);
        helpView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/BundleManager.jsp");
        bundleManagerView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/BundleManager.jsp");
        showManifestView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/ShowManifest.jsp");
        showWiredBundlesView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/ShowWiredBundles.jsp");
        showServicesView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/ShowServices.jsp");
        findPackagesView = portletConfig.getPortletContext()
                .getRequestDispatcher("/WEB-INF/view/bundlemanager/FindPackages.jsp");
    }

    public void destroy() {
        bundleManagerView = null;
        super.destroy();
    }

    public void processAction(ActionRequest actionRequest, ActionResponse actionResponse)
            throws PortletException, IOException {

        actionResponse.setRenderParameter("message", ""); // set to blank first

        String page = actionRequest.getParameter("page");

        if (VIEW_MANIFEST_PAGE.equals(page)) {
            // no actions in this page
            actionResponse.setRenderParameter("page", VIEW_MANIFEST_PAGE);

        } else if (VIEW_WIRED_BUNDLES_PAGE.equals(page)) {
            String id = actionRequest.getParameter("bundleId");
            String perspectiveType = actionRequest.getParameter("perspectiveType");
            //set render params
            actionResponse.setRenderParameter("page", VIEW_WIRED_BUNDLES_PAGE);
            actionResponse.setRenderParameter("bundleId", id);
            actionResponse.setRenderParameter("perspectiveTypeValue", perspectiveType);

        } else if (FIND_PACKAGES_PAGE.equals(page)) {
            String packageString = actionRequest.getParameter("packageString");
            //set render params
            actionResponse.setRenderParameter("page", FIND_PACKAGES_PAGE);
            actionResponse.setRenderParameter("packageStringValue", packageString);

        } else { //main page

            //we use session to control the listType and searchString for filtering list so that
            //user can easily turn back to the page that he just jumped out.
            Object sessionListType = actionRequest.getPortletSession().getAttribute("listTypeValue");
            if (sessionListType == null || "".equals((String) sessionListType)) {
                //default value
                actionRequest.getPortletSession().setAttribute("listTypeValue", "all");
            }
            String listType = (String) actionRequest.getPortletSession().getAttribute("listTypeValue");

            Object sessionSearchString = actionRequest.getPortletSession().getAttribute("searchStringValue");
            if (sessionSearchString == null) {
                //default value
                actionRequest.getPortletSession().setAttribute("searchStringValue", "");
            }
            String searchString = (String) actionRequest.getPortletSession().getAttribute("searchStringValue");
            ;

            // process action
            String action = actionRequest.getParameter("action");
            if (INSTALL_ACTION.equals(action)) {
                BundleContext bundleContext = getBundleContext(actionRequest);

                //get the StartLeval object
                ServiceReference startLevelRef = bundleContext
                        .getServiceReference(StartLevel.class.getCanonicalName());
                StartLevel startLevelService = (StartLevel) bundleContext.getService(startLevelRef);

                processInstallAction(actionRequest, bundleContext, startLevelService);

                listType = "all";
                searchString = "";

            } else if (SERACH_ACTION.equals(action)) {
                searchString = actionRequest.getParameter("searchString");

            } else if (LIST_ACTION.equals(action)) {
                listType = actionRequest.getParameter("listType");
                searchString = "";

            } else if (BUNDLE_ACTION.equals(action)) { //start/stop/restart/update/uninstall actions

                String id = actionRequest.getParameter("bundleId");
                ;
                BundleContext bundleContext = getBundleContext(actionRequest);

                String operation = actionRequest.getParameter("operation");

                try {
                    Bundle bundle = bundleContext.getBundle(Long.parseLong(id));
                    String symbolicName = bundle.getSymbolicName();

                    if (START_OPERATION.equals(operation)) {
                        bundle.start();
                        addInfoMessage(actionRequest, getLocalizedString(actionRequest,
                                "consolebase.bundlemanager.info.start", symbolicName, id));
                    } else if (STOP_OPERATION.equals(operation)) {
                        bundle.stop();
                        addInfoMessage(actionRequest, getLocalizedString(actionRequest,
                                "consolebase.bundlemanager.info.stop", symbolicName, id));
                    } else if (UNINSTALL_OPERATION.equals(operation)) {
                        bundle.uninstall();
                        addInfoMessage(actionRequest, getLocalizedString(actionRequest,
                                "consolebase.bundlemanager.info.uninstall", symbolicName, id));
                    } else if (UPDATE_OPERATION.equals(operation)) {
                        bundle.update();
                        addInfoMessage(actionRequest, getLocalizedString(actionRequest,
                                "consolebase.bundlemanager.info.update", symbolicName, id));
                    } else if (REFRESH_OPERATION.equals(operation)) {
                        ServiceReference reference = bundleContext
                                .getServiceReference(PackageAdmin.class.getName());
                        PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(reference);
                        packageAdmin.refreshPackages(new Bundle[] { bundle });
                        addInfoMessage(actionRequest, getLocalizedString(actionRequest,
                                "consolebase.bundlemanager.info.refresh", symbolicName, id));
                    } else {
                        // should never happen
                        addWarningMessage(actionRequest,
                                getLocalizedString(actionRequest, "consolebase.bundlemanager.warn.invalidAction")
                                        + action);
                    }
                } catch (Throwable e) {
                    addErrorMessage(actionRequest,
                            getLocalizedString(actionRequest, "consolebase.bundlemanager.err.actionError") + action,
                            e.getMessage());
                    logger.error("Exception", e);
                }
            }

            // set listType and searchString in session
            actionRequest.getPortletSession().setAttribute("listTypeValue", listType);
            actionRequest.getPortletSession().setAttribute("searchStringValue", searchString);

            // set the values, which come from session, to render parameter
            actionResponse.setRenderParameter("listTypeValue", listType);
            actionResponse.setRenderParameter("searchStringValue", searchString);
        }

    }

    protected void doView(RenderRequest renderRequest, RenderResponse renderResponse)
            throws IOException, PortletException {

        if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) { // minimal view
            return;

        } else { // normal and maximal view

            String page = renderRequest.getParameter("page");

            if (FIND_PACKAGES_PAGE.equals(page)) {
                BundleContext bundleContext = getBundleContext(renderRequest);

                ServiceReference reference = bundleContext.getServiceReference(PackageAdmin.class.getName());
                PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(reference);

                String packageString = renderRequest.getParameter("packageStringValue");

                Map<PackageInfo, List<BundleInfo>> packageExportBundles = new HashMap<PackageInfo, List<BundleInfo>>();
                Map<PackageInfo, List<BundleInfo>> packageImportBundles = new HashMap<PackageInfo, List<BundleInfo>>();

                for (Bundle bundle : bundleContext.getBundles()) {
                    ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(bundle);
                    if (exportedPackages != null) {

                        // construct the export bundle info
                        BundleInfo exportBundleInfo = new SimpleBundleInfo(bundle);

                        for (ExportedPackage exportedPackage : exportedPackages) {
                            // filter by keyword and ignore case. if the keyword is null, then return all the packages
                            if (packageString == null || exportedPackage.getName().toLowerCase()
                                    .indexOf(packageString.trim().toLowerCase()) != -1) {
                                // construct the package info
                                // fill in its export bundle
                                PackageInfo packageInfo = new PackageInfo(exportedPackage.getName(),
                                        exportedPackage.getVersion().toString());
                                fillPackageBundlesMap(packageExportBundles, packageInfo, exportBundleInfo);

                                Bundle[] importingBundles = exportedPackage.getImportingBundles();
                                if (importingBundles != null) {
                                    for (Bundle importingBundle : importingBundles) {

                                        // construct the import bundle info
                                        // fill in its import bundle
                                        BundleInfo importBundleInfo = new SimpleBundleInfo(importingBundle);
                                        fillPackageBundlesMap(packageImportBundles, packageInfo, importBundleInfo);

                                    }

                                }
                            }
                        }
                    }
                }

                List<PackageWiredBundles> packageWiredBundlesList = new ArrayList<PackageWiredBundles>();
                BundleSymbolicComparator bsc = new BundleSymbolicComparator();
                for (Entry<PackageInfo, List<BundleInfo>> entry : packageExportBundles.entrySet()) {
                    PackageInfo pkg = entry.getKey();
                    List<BundleInfo> exportBundles = entry.getValue();
                    List<BundleInfo> importBundles = packageImportBundles.get(pkg) == null
                            ? new ArrayList<BundleInfo>()
                            : packageImportBundles.get(pkg);

                    PackageWiredBundles pwb = new PackageWiredBundles(pkg, exportBundles, importBundles);
                    pwb.sortBundleInfos(bsc);
                    packageWiredBundlesList.add(pwb);
                }

                Collections.sort(packageWiredBundlesList);

                renderRequest.setAttribute("packageWiredBundlesList", packageWiredBundlesList);
                renderRequest.setAttribute("packageStringValue", packageString);
                findPackagesView.include(renderRequest, renderResponse);

            } else if (VIEW_MANIFEST_PAGE.equals(page)) {
                BundleContext bundleContext = getBundleContext(renderRequest);

                long id = Long.valueOf(renderRequest.getParameter("bundleId"));
                Bundle bundle = bundleContext.getBundle(id);

                List<ManifestHeader> manifestHeaders = new ArrayList<ManifestHeader>();
                Dictionary<String, String> headers = bundle.getHeaders();
                Enumeration<String> keys = headers.keys();
                while (keys.hasMoreElements()) {
                    String key = (String) keys.nextElement();
                    if (key.equals("Import-Package") || key.equals("Export-Package") || key.equals("Ignore-Package")
                            || key.equals("Private-Package") || key.equals("Export-Service")) {
                        manifestHeaders.add(new ManifestHeader(key,
                                ManifestHeader.formatPackageHeader((String) headers.get(key))));
                    } else {
                        manifestHeaders.add(new ManifestHeader(key, (String) headers.get(key)));
                    }
                }

                SimpleBundleInfo bundleInfo = new SimpleBundleInfo(bundle);

                Collections.sort(manifestHeaders);
                renderRequest.setAttribute("manifestHeaders", manifestHeaders);
                renderRequest.setAttribute("bundleInfo", bundleInfo);
                showManifestView.include(renderRequest, renderResponse);

            } else if (VIEW_SERVICES_PAGE.equals(page)) {

                BundleContext bundleContext = getBundleContext(renderRequest);

                long id = Long.valueOf(renderRequest.getParameter("bundleId"));
                Bundle bundle = bundleContext.getBundle(id);

                // because this page should not be very complex ,so we only have a Service Perspective
                // if user wants 2 perspective like wired bundle page, we can extend this page to add a new Bundle Perspective.
                List<ServicePerspective> usingServicePerspectives = getUsingServicePerspectives(bundle);
                List<ServicePerspective> registeredServicePerspectives = getRegisteredServicePerspectives(bundle);

                Collections.sort(usingServicePerspectives);
                Collections.sort(registeredServicePerspectives);

                renderRequest.setAttribute("usingServicePerspectives", usingServicePerspectives);
                renderRequest.setAttribute("registeredServicePerspectives", registeredServicePerspectives);

                SimpleBundleInfo bundleInfo = new SimpleBundleInfo(bundle);

                renderRequest.setAttribute("bundleInfo", bundleInfo);

                showServicesView.include(renderRequest, renderResponse);

            } else if (VIEW_WIRED_BUNDLES_PAGE.equals(page)) {

                BundleContext bundleContext = getBundleContext(renderRequest);

                long id = Long.valueOf(renderRequest.getParameter("bundleId"));
                Bundle bundle = bundleContext.getBundle(id);

                String perspectiveType = renderRequest.getParameter("perspectiveTypeValue");
                if (perspectiveType == null || perspectiveType == "")
                    perspectiveType = "bundle"; //when we access this page with a renderURL, we need the default value

                ServiceReference reference = bundleContext.getServiceReference(PackageAdmin.class.getName());
                PackageAdmin packageAdmin = (PackageAdmin) bundle.getBundleContext().getService(reference);

                Set<String> wiredPackages = new HashSet<String>();
                Set<PackageBundlePair> importingPairs = getImportingPairs(packageAdmin, bundle, wiredPackages);
                Set<PackageBundlePair> dynamicImportingPairs = getDynamicImportingPairs(packageAdmin, bundle,
                        wiredPackages);
                Set<PackageBundlePair> requireBundlesImportingPairs = getRequireBundlesImportingPairs(packageAdmin,
                        bundle);
                Set<PackageBundlePair> exportingPairs = getExportingPairs(packageAdmin, bundle);

                if ("package".equals(perspectiveType)) {
                    List<PackagePerspective> importingPackagePerspectives = getPackagePerspectives(importingPairs);
                    List<PackagePerspective> dynamicImportingPackagePerspectives = getPackagePerspectives(
                            dynamicImportingPairs);
                    List<PackagePerspective> requireBundlesImportingPackagePerspectives = getPackagePerspectives(
                            requireBundlesImportingPairs);
                    List<PackagePerspective> exportingPackagePerspectives = getPackagePerspectives(exportingPairs);

                    Collections.sort(importingPackagePerspectives);
                    Collections.sort(dynamicImportingPackagePerspectives);
                    Collections.sort(requireBundlesImportingPackagePerspectives);
                    Collections.sort(exportingPackagePerspectives);

                    renderRequest.setAttribute("importingPackagePerspectives", importingPackagePerspectives);
                    renderRequest.setAttribute("dynamicImportingPackagePerspectives",
                            dynamicImportingPackagePerspectives);
                    renderRequest.setAttribute("requireBundlesImportingPackagePerspectives",
                            requireBundlesImportingPackagePerspectives);
                    renderRequest.setAttribute("exportingPackagePerspectives", exportingPackagePerspectives);

                } else { //"bundle".equals(perspectiveType)){
                    List<BundlePerspective> importingBundlePerspectives = getBundlePerspectives(importingPairs);
                    List<BundlePerspective> dynamicImportingBundlePerspectives = getBundlePerspectives(
                            dynamicImportingPairs);
                    List<BundlePerspective> requireBundlesImportingBundlePerspectives = getBundlePerspectives(
                            requireBundlesImportingPairs);
                    List<BundlePerspective> exportingBundlePerspectives = getBundlePerspectives(exportingPairs);

                    Collections.sort(importingBundlePerspectives);
                    Collections.sort(dynamicImportingBundlePerspectives);
                    Collections.sort(requireBundlesImportingBundlePerspectives);
                    Collections.sort(exportingBundlePerspectives);

                    renderRequest.setAttribute("importingBundlePerspectives", importingBundlePerspectives);
                    renderRequest.setAttribute("dynamicImportingBundlePerspectives",
                            dynamicImportingBundlePerspectives);
                    renderRequest.setAttribute("requireBundlesImportingBundlePerspectives",
                            requireBundlesImportingBundlePerspectives);
                    renderRequest.setAttribute("exportingBundlePerspectives", exportingBundlePerspectives);
                }

                SimpleBundleInfo bundleInfo = new SimpleBundleInfo(bundle);

                renderRequest.setAttribute("bundleInfo", bundleInfo);
                renderRequest.setAttribute("perspectiveTypeValue", perspectiveType);

                showWiredBundlesView.include(renderRequest, renderResponse);

            } else { // main page

                String listType = renderRequest.getParameter("listTypeValue");
                if (listType == null || listType == "")
                    listType = "all"; //when we access this page with a renderURL, we need the default value
                String searchString = renderRequest.getParameter("searchStringValue");
                if (searchString == null)
                    searchString = ""; //when we access this page with a renderURL, we need the default value

                BundleContext bundleContext = getBundleContext(renderRequest);

                // retrieve bundle infos
                List<ExtendedBundleInfo> bundleInfos = new ArrayList<ExtendedBundleInfo>();

                // get the StartLeval object
                ServiceReference startLevelRef = bundleContext
                        .getServiceReference(StartLevel.class.getCanonicalName());
                StartLevel startLevelService = (StartLevel) bundleContext.getService(startLevelRef);

                // get configured bundle Ids
                Set<Long> configurationBundleIds = getConfigurationBundleIds();

                Bundle[] bundles = bundleContext.getBundles();
                for (Bundle bundle : bundles) {

                    if (searchString != "" && !matchBundle(bundle, searchString)) {
                        continue;
                    }

                    // construct the result bundleInfos by listType
                    if ("wab".equals(listType)) {
                        if (checkWABBundle(bundle)) {
                            ExtendedBundleInfo info = createExtendedBundleInfo(bundle, startLevelService,
                                    configurationBundleIds);
                            info.addContextPath(getContextPath(bundle));
                            bundleInfos.add(info);
                        }
                    } else if ("blueprint".equals(listType)) {
                        if (checkBlueprintBundle(bundle)) {
                            ExtendedBundleInfo info = createExtendedBundleInfo(bundle, startLevelService,
                                    configurationBundleIds);

                            // currently, we try get the the blueprintContainer service to determine if a blueprint bundle is created
                            // TODO A better way is using a BlueprintListener to track all blueprint bundle events
                            String filter = "(&(osgi.blueprint.container.symbolicname=" + bundle.getSymbolicName()
                                    + ")(osgi.blueprint.container.version=" + bundle.getVersion() + "))";
                            ServiceReference[] serviceReferences = null;
                            try {
                                serviceReferences = bundleContext
                                        .getServiceReferences(BlueprintContainer.class.getName(), filter);
                            } catch (InvalidSyntaxException e) {
                                throw new RuntimeException(e);
                            }
                            if (serviceReferences != null && serviceReferences.length > 0) {
                                info.setBlueprintState(BlueprintState.CREATED);
                            }

                            bundleInfos.add(info);
                        }
                    } else if ("system".equals(listType)) {
                        if (checkSysBundle(bundle, startLevelService)) {
                            ExtendedBundleInfo info = createExtendedBundleInfo(bundle, startLevelService,
                                    configurationBundleIds);
                            bundleInfos.add(info);
                        }
                    } else if ("configuration".equals(listType)) {
                        if (checkConfigurationBundle(bundle, configurationBundleIds)) {
                            ExtendedBundleInfo info = createExtendedBundleInfo(bundle, startLevelService,
                                    configurationBundleIds);
                            bundleInfos.add(info);
                        }
                    } else {
                        ExtendedBundleInfo info = createExtendedBundleInfo(bundle, startLevelService,
                                configurationBundleIds);
                        bundleInfos.add(info);
                    }
                }

                Collections.sort(bundleInfos, new BundleIdDescComparator());
                renderRequest.setAttribute("extendedBundleInfos", bundleInfos);

                // set the values to render attribute
                renderRequest.setAttribute("listTypeValue", listType);
                renderRequest.setAttribute("searchStringValue", searchString);

                renderRequest.setAttribute("initStartLevel", startLevelService.getInitialBundleStartLevel());

                if (bundleInfos.size() == 0) {
                    addWarningMessage(renderRequest,
                            getLocalizedString(renderRequest, "consolebase.bundlemanager.warn.nobundlesfound"));
                }

                bundleManagerView.include(renderRequest, renderResponse);

            }
        }
    }

    private ExtendedBundleInfo createExtendedBundleInfo(Bundle bundle, StartLevel startLevelService,
            Set<Long> configurationBundleIds) {
        ExtendedBundleInfo info = new ExtendedBundleInfo(bundle);

        if (checkWABBundle(bundle)) {
            info.addType(BundleType.WAB);
        }

        if (checkBlueprintBundle(bundle)) {
            info.addType(BundleType.BLUEPRINT);
        }

        if (checkSysBundle(bundle, startLevelService)) {
            info.addType(BundleType.SYSTEM);
        }

        if (checkConfigurationBundle(bundle, configurationBundleIds)) {
            info.addType(BundleType.CONFIGURATION);
        }

        return info;
    }

    private BundleContext getBundleContext(PortletRequest request) {
        return (BundleContext) request.getPortletSession().getPortletContext().getAttribute("osgi-bundlecontext");
    }

    private static boolean matchBundle(Bundle bundle, String searchString) {
        if (bundle.getSymbolicName() == null || (bundle.getSymbolicName() != null
                && bundle.getSymbolicName().toLowerCase().indexOf(searchString.trim().toLowerCase()) == -1)) { // match ignore case
            return false;
        }
        return true;
    }

    private static String getContextPath(Bundle bundle) {
        Object path = bundle.getHeaders().get(BundleUtil.WEB_CONTEXT_PATH_HEADER);
        if (path != null) {
            return (String) path;
        }
        return null;
    }

    private static boolean checkWABBundle(Bundle bundle) {
        String contextPath = getContextPath(bundle);
        if (contextPath != null && contextPath != "") {
            return true;
        }
        return false;
    }

    private static boolean checkBlueprintBundle(Bundle bundle) {
        // OSGi enterprise spec(r4.2) 121.3.4 (Page 206)
        // check blueprint header
        Object bpHeader = bundle.getHeaders().get(BundleUtil.BLUEPRINT_HEADER);
        if (bpHeader != null && (String) bpHeader != "")
            return true;

        // check blueprint definitions
        Enumeration<URL> enu = bundle.findEntries("OSGI-INF/blueprint/", "*.xml", false);
        if (enu != null && enu.hasMoreElements())
            return true;

        return false;
    }

    private static boolean checkSysBundle(Bundle bundle, StartLevel startLevelService) {
        //config.properties set karaf.systemBundlesStartLevel=50
        if (startLevelService != null && startLevelService.getBundleStartLevel(bundle) <= 50) {
            return true;
        }
        return false;
    }

    private static boolean checkConfigurationBundle(Bundle bundle, Set<Long> configurationBundleIds) {
        // check configuration bundle
        if (configurationBundleIds.contains(bundle.getBundleId())) {
            return true;
        }
        return false;
    }

    private Set<Long> getConfigurationBundleIds() {
        Set<Long> configurationBundleIds = new HashSet<Long>();

        ConfigurationManager configManager = PortletManager.getConfigurationManager();
        List<ConfigurationInfo> infos = configManager.listConfigurations();

        for (ConfigurationInfo info : infos) {
            Bundle configurationBundle = configManager.getBundle(info.getConfigID());
            if (configurationBundle != null) {
                configurationBundleIds.add(configurationBundle.getBundleId());
            } else {
                logger.info("Can not find the bundle for configuration: " + info.getConfigID()
                        + " in configuration manager");
            }
        }

        return configurationBundleIds;
    }

    /*******************************
     * Bundle comparators
     *******************************/
    private static class BundleIdComparator implements Comparator<BundleInfo> {
        @Override
        public int compare(BundleInfo infoA, BundleInfo infoB) {
            if (infoA == null && infoB == null)
                return 0;
            if (infoA == null)
                return -1;
            if (infoB == null)
                return 1;
            return (int) (infoA.getBundleId() - infoB.getBundleId());
        }
    }

    private static class BundleIdDescComparator implements Comparator<BundleInfo> {
        @Override
        public int compare(BundleInfo infoA, BundleInfo infoB) {
            if (infoA == null && infoB == null)
                return 0;
            if (infoA == null)
                return 1;
            if (infoB == null)
                return -1;
            return (int) (infoB.getBundleId() - infoA.getBundleId());
        }
    }

    private static class BundleSymbolicComparator implements Comparator<BundleInfo> {
        @Override
        public int compare(BundleInfo infoA, BundleInfo infoB) {
            if (infoA == null && infoB == null)
                return 0;
            if (infoA == null)
                return -1;
            if (infoB == null)
                return 1;
            return infoA.getSymbolicName().compareTo(infoB.getSymbolicName());
        }
    }

    private static class ServiceObjectClassComparator implements Comparator<ServiceInfo> {
        @Override
        public int compare(ServiceInfo infoA, ServiceInfo infoB) {
            if (infoA == null && infoB == null)
                return 0;
            if (infoA == null)
                return -1;
            if (infoB == null)
                return 1;

            String objectClassA = "";
            for (String str : infoA.getObjectClass()) {
                objectClassA += str + ",";
            }
            String objectClassB = "";
            for (String str : infoB.getObjectClass()) {
                objectClassB += str + ",";
            }
            return objectClassA.compareTo(objectClassB);
        }
    }

    /*************************************************************
     * Perspective definitions for Wired bundles page
     *************************************************************/
    public static class PackagePerspective implements Comparable<PackagePerspective> {

        private PackageInfo packageInfo;
        private List<BundleInfo> bundleInfos = new ArrayList<BundleInfo>();

        public PackagePerspective(String packageName, String packageVersion) {
            this.packageInfo = new PackageInfo(packageName, packageVersion);
        }

        public PackagePerspective(PackageInfo packageInfo) {
            this.packageInfo = packageInfo;
        }

        public PackagePerspective(PackageInfo packageInfo, List<BundleInfo> bundleInfos) {
            this.packageInfo = packageInfo;
            this.bundleInfos = bundleInfos;
        }

        @Override
        public int compareTo(PackagePerspective another) {
            if (another != null) {
                return packageInfo.compareTo(another.packageInfo);
            } else {
                return -1;
            }
        }

        public PackageInfo getPackageInfo() {
            return packageInfo;
        }

        public List<BundleInfo> getBundleInfos() {
            return bundleInfos;
        }

        public void addBundleInfo(BundleInfo info) {
            this.bundleInfos.add(info);
        }

        public void sortBundleInfos(Comparator<BundleInfo> comparator) {
            Collections.sort(bundleInfos, comparator);
        }
    }

    public static class BundlePerspective implements Comparable<BundlePerspective> {

        private BundleInfo bundleInfo;
        private List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
        private final Comparator<BundleInfo> comparator = new BundleSymbolicComparator();

        public BundlePerspective(Bundle bundle) {
            this.bundleInfo = new SimpleBundleInfo(bundle);
        }

        public BundlePerspective(BundleInfo info) {
            this.bundleInfo = info;
        }

        public BundlePerspective(BundleInfo info, List<PackageInfo> packageInfos) {
            this.bundleInfo = info;
            this.packageInfos = packageInfos;
        }

        @Override
        public int compareTo(BundlePerspective another) {
            if (another != null) {
                return comparator.compare(bundleInfo, another.bundleInfo);
            } else {
                return -1;
            }
        }

        public BundleInfo getBundleInfo() {
            return bundleInfo;
        }

        public List<PackageInfo> getPackageInfos() {
            return packageInfos;
        }

        public void addPackageInfo(PackageInfo info) {
            packageInfos.add(info);
        }

        public void sortPackageInfos() {
            Collections.sort(packageInfos);
        }
    }

    private boolean containsBundle(Bundle[] bundles, Bundle bundle) {
        if (bundles != null) {
            for (Bundle importingBundle : bundles) {
                if (importingBundle == bundle) {
                    return true;
                }
            }
        }
        return false;
    }

    private String toString(ExportedPackage exportedPackage) {
        return exportedPackage.getName() + ":" + exportedPackage.getVersion().toString();
    }

    private Set<PackageBundlePair> getImportingPairs(PackageAdmin packageAdmin, Bundle bundle,
            Set<String> wiredPackages) {

        BundleDescription description = new BundleDescription(bundle.getHeaders());

        Set<PackageBundlePair> importingPairs = new HashSet<PackageBundlePair>();

        List<BundleDescription.ImportPackage> imports = description.getImportPackage();
        for (BundleDescription.ImportPackage packageImport : imports) {
            //find the packages that we are importing
            ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(packageImport.getName());
            if (exportedPackages == null) {
                importingPairs.add(new PackageBundlePair(packageImport.getName(),
                        packageImport.getVersionRange().toString(), null));
            } else {
                for (ExportedPackage exportedPackage : exportedPackages) {
                    Bundle exportingBundle = exportedPackage.getExportingBundle();
                    if (exportingBundle != bundle
                            && containsBundle(exportedPackage.getImportingBundles(), bundle)) {
                        importingPairs.add(new PackageBundlePair(packageImport.getName(),
                                packageImport.getVersionRange().toString(), exportedPackage.getExportingBundle()));
                        wiredPackages.add(toString(exportedPackage));
                    }
                }
            }

        }
        return importingPairs;
    }

    private Set<PackageBundlePair> getRequireBundlesImportingPairs(PackageAdmin packageAdmin, Bundle bundle) {

        Set<PackageBundlePair> requireBundlesImportingPairs = new HashSet<PackageBundlePair>();

        BundleDescription description = new BundleDescription(bundle.getHeaders());

        List<BundleDescription.RequireBundle> requireBundles = description.getRequireBundle();
        if (!requireBundles.isEmpty()) {

            Map<String, VersionRange> requireBundlesMap = new HashMap<String, VersionRange>();

            for (BundleDescription.RequireBundle requireBundle : requireBundles) {
                requireBundlesMap.put(requireBundle.getName(), requireBundle.getVersionRange());
            }

            Set<String> requireBundleNames = requireBundlesMap.keySet();
            for (Bundle b : bundle.getBundleContext().getBundles()) {
                if (requireBundleNames.contains(b.getSymbolicName())
                        && requireBundlesMap.get(b.getSymbolicName()).isInRange(b.getVersion())) {

                    // find the packages that importing from the require bundle
                    ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(b);
                    if (exportedPackages != null) {
                        for (ExportedPackage exportedPackage : exportedPackages) {
                            Bundle[] importingBundles = exportedPackage.getImportingBundles();
                            if (containsBundle(importingBundles, bundle)) {
                                requireBundlesImportingPairs.add(new PackageBundlePair(exportedPackage, b));
                            }
                        }
                    }

                }

            }
        }

        return requireBundlesImportingPairs;

    }

    private Set<PackageBundlePair> getDynamicImportingPairs(PackageAdmin packageAdmin, Bundle bundle,
            Set<String> wiredPackages) {
        BundleDescription description = new BundleDescription(bundle.getHeaders());

        Set<PackageBundlePair> dynamicImportingPairs = new HashSet<PackageBundlePair>();

        if (!description.getDynamicImportPackage().isEmpty()) {
            for (Bundle b : bundle.getBundleContext().getBundles()) {

                // find the packages that importing from the bundle
                ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(b);
                if (exportedPackages != null) {
                    for (ExportedPackage exportedPackage : exportedPackages) {
                        if (wiredPackages.contains(toString(exportedPackage))) {
                            continue;
                        }
                        Bundle[] importingBundles = exportedPackage.getImportingBundles();
                        if (containsBundle(importingBundles, bundle)) {
                            dynamicImportingPairs.add(new PackageBundlePair(exportedPackage, b));
                        }
                    }
                }

            }
        }

        return dynamicImportingPairs;
    }

    private Set<PackageBundlePair> getExportingPairs(PackageAdmin packageAdmin, Bundle bundle) {

        Set<PackageBundlePair> exportingPairs = new HashSet<PackageBundlePair>();

        ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(bundle);

        if (exportedPackages != null) {
            for (ExportedPackage exportedPackage : exportedPackages) {
                Bundle[] importingBundles = exportedPackage.getImportingBundles();
                if (importingBundles == null || importingBundles.length == 0) {
                    exportingPairs.add(new PackageBundlePair(exportedPackage, null));
                } else {
                    for (Bundle importingBundle : importingBundles) {
                        exportingPairs.add(new PackageBundlePair(exportedPackage, importingBundle));
                    }
                }
            }
        }

        return exportingPairs;

    }

    private static class PackageBundlePair {
        private final String packageName;
        private final String version;
        private final Bundle bundle;

        public PackageBundlePair(String packageName, String version, Bundle bundle) {
            this.packageName = packageName;
            this.version = version;
            this.bundle = bundle;
        }

        public PackageBundlePair(ExportedPackage exportedPackage, Bundle bundle) {
            this.packageName = exportedPackage.getName();
            this.version = exportedPackage.getVersion().toString();
            this.bundle = bundle;
        }

        public String getPackageName() {
            return packageName;
        }

        public String getVersion() {
            return version;
        }

        public Bundle getBundle() {
            return bundle;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((bundle == null) ? 0 : (int) bundle.getBundleId());
            result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
            result = prime * result + ((version == null) ? 0 : version.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }

            PackageBundlePair other = (PackageBundlePair) obj;

            if (bundle == null) {
                if (other.bundle != null) {
                    return false;
                }
            } else if (bundle.getBundleId() != other.bundle.getBundleId()) {
                return false;
            }

            if (packageName == null) {
                if (other.packageName != null) {
                    return false;
                }
            } else if (!packageName.equals(other.packageName)) {
                return false;
            }

            if (version == null) {
                if (other.version != null) {
                    return false;
                }
            } else if (!version.equals(other.version)) {
                return false;
            }

            return true;
        }

    }

    private List<PackagePerspective> getPackagePerspectives(Set<PackageBundlePair> pairs) {
        Map<PackageInfo, List<BundleInfo>> pbs = new HashMap<PackageInfo, List<BundleInfo>>();

        for (PackageBundlePair pair : pairs) {

            PackageInfo packageInfo = new PackageInfo(pair.getPackageName(), pair.getVersion());
            BundleInfo bundleInfo = new SimpleBundleInfo(pair.getBundle());

            fillPackageBundlesMap(pbs, packageInfo, bundleInfo);

        }

        List<PackagePerspective> packagePerspectives = new ArrayList<PackagePerspective>();
        BundleSymbolicComparator bsc = new BundleSymbolicComparator();
        for (Entry<PackageInfo, List<BundleInfo>> entry : pbs.entrySet()) {
            PackagePerspective pp = new PackagePerspective(entry.getKey(), entry.getValue());
            pp.sortBundleInfos(bsc);
            packagePerspectives.add(pp);
        }

        return packagePerspectives;
    }

    private List<BundlePerspective> getBundlePerspectives(Set<PackageBundlePair> pairs) {
        Map<BundleInfo, List<PackageInfo>> bps = new HashMap<BundleInfo, List<PackageInfo>>();

        for (PackageBundlePair pair : pairs) {

            BundleInfo bundleInfo = new SimpleBundleInfo(pair.getBundle());
            PackageInfo packageInfo = new PackageInfo(pair.getPackageName(), pair.getVersion());

            fillBundlePackagesMap(bps, bundleInfo, packageInfo);

        }

        List<BundlePerspective> bundlePerspectives = new ArrayList<BundlePerspective>();
        for (Entry<BundleInfo, List<PackageInfo>> entry : bps.entrySet()) {
            BundlePerspective bp = new BundlePerspective(entry.getKey(), entry.getValue());
            bp.sortPackageInfos();
            bundlePerspectives.add(bp);
        }

        return bundlePerspectives;
    }

    private void fillPackageBundlesMap(Map<PackageInfo, List<BundleInfo>> pbmap, PackageInfo packageInfo,
            BundleInfo bundleInfo) {
        if (pbmap.keySet().contains(packageInfo)) {
            if (!pbmap.get(packageInfo).contains(bundleInfo)) {
                pbmap.get(packageInfo).add(bundleInfo);
            }
        } else {
            List<BundleInfo> bundleInfos = new ArrayList<BundleInfo>();
            bundleInfos.add(bundleInfo);
            pbmap.put(packageInfo, bundleInfos);
        }
    }

    private void fillBundlePackagesMap(Map<BundleInfo, List<PackageInfo>> bpmap, BundleInfo bundleInfo,
            PackageInfo packageInfo) {
        if (bpmap.keySet().contains(bundleInfo)) {
            if (!bpmap.get(bundleInfo).contains(packageInfo)) {
                bpmap.get(bundleInfo).add(packageInfo);
            }
        } else {
            List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
            packageInfos.add(packageInfo);
            bpmap.put(bundleInfo, packageInfos);
        }
    }

    /******************************
     * Install Action
     ******************************/
    private void processInstallAction(ActionRequest request, BundleContext bundleContext,
            StartLevel startLevelService) throws PortletException, IOException {
        if (!PortletFileUpload.isMultipartContent(request)) {
            throw new PortletException("Expected file upload");
        }

        // use commons-fileupload to process the request
        File rootDir = new File(System.getProperty("java.io.tmpdir"));
        PortletFileUpload uploader = new PortletFileUpload(new DiskFileItemFactory(10240, rootDir));

        File bundleFile = null;
        String startAfterInstalled = null;
        String str_startLevel = null;

        List<?> items;
        try {
            items = uploader.parseRequest(request);
        } catch (FileUploadException e) {
            addErrorMessage(request, getLocalizedString(request, "consolebase.bundlemanager.err.file.uploadError"));
            logger.error("FileUploadException", e);
            return;
        }

        // deal with the multipart form data items;
        for (Iterator<?> i = items.iterator(); i.hasNext();) {
            FileItem item = (FileItem) i.next();
            if (!item.isFormField()) {
                String fieldName = item.getFieldName();
                String fileName = item.getName().trim();
                if (fileName.length() != 0) {
                    int index = fileName.lastIndexOf('\\');
                    if (index != -1) {
                        fileName = fileName.substring(index + 1);
                    }
                    if ("bundleFile".equals(fieldName)) {
                        bundleFile = new File(rootDir, fileName);
                    }
                }
                if (bundleFile != null) {
                    try {
                        item.write(bundleFile);
                    } catch (Exception e) {
                        addErrorMessage(request,
                                getLocalizedString(request, "consolebase.bundlemanager.err.file.writeError"));
                        logger.error("Exception", e);
                        return;
                    }
                } else {
                    //should never happen
                    addErrorMessage(request,
                            getLocalizedString(request, "consolebase.bundlemanager.err.file.nullError"));
                    logger.error("The uploaded file is null!");
                    return;
                }
            } else {
                if ("startAfterInstalled".equalsIgnoreCase(item.getFieldName())) {
                    startAfterInstalled = item.getString();
                } else if ("startLevel".equalsIgnoreCase(item.getFieldName())) {
                    str_startLevel = item.getString();
                }
            }
        }

        // install the uploaded bundle file
        String url = "file:///" + bundleFile.getCanonicalPath();

        Bundle installedBundle;
        try {
            installedBundle = bundleContext.installBundle(url);
            addInfoMessage(request, getLocalizedString(request, "consolebase.bundlemanager.info.install",
                    installedBundle.getSymbolicName(), installedBundle.getBundleId()));
        } catch (BundleException e) {
            addErrorMessage(request,
                    getLocalizedString(request, "consolebase.bundlemanager.err.actionError") + "install",
                    e.getMessage());
            logger.error("BundleException", e);
            return;
        }

        // set start level for the installed bundle
        int startLevel = -1;
        try {
            startLevel = Integer.parseInt(str_startLevel);
        } catch (NumberFormatException e) {
            // if can't generated, use the default initialBundleStartLevel
        }
        int defaultStartLevel = startLevelService.getInitialBundleStartLevel();
        if (startLevel != defaultStartLevel && startLevel >= 0) {
            startLevelService.setBundleStartLevel(installedBundle, startLevel);
        }

        // if check box "Start" checked, then start the bundle
        if ("yes".equals(startAfterInstalled)) {
            try {
                installedBundle.start();
                addInfoMessage(request, getLocalizedString(request, "consolebase.bundlemanager.info.start",
                        installedBundle.getSymbolicName(), installedBundle.getBundleId()));
            } catch (BundleException e) {
                addErrorMessage(request,
                        getLocalizedString(request, "consolebase.bundlemanager.err.actionError") + "start",
                        e.getMessage());
                logger.error("BundleException", e);
                return;
            }

        }
    }

    /************************************************
     * Show services definitions
     ************************************************/
    public static class ServicePerspective implements Comparable<ServicePerspective> {

        private ServiceInfo serviceInfo;
        private List<BundleInfo> bundleInfos = new ArrayList<BundleInfo>();
        private final Comparator<ServiceInfo> comparator = new ServiceObjectClassComparator();

        public ServicePerspective(ServiceInfo serviceInfo) {
            this.serviceInfo = serviceInfo;
        }

        public ServicePerspective(ServiceInfo serviceInfo, List<BundleInfo> bundleInfos) {
            this.serviceInfo = serviceInfo;
            this.bundleInfos = bundleInfos;
        }

        @Override
        public int compareTo(ServicePerspective another) {
            if (another != null) {
                return comparator.compare(serviceInfo, another.serviceInfo);
            } else {
                return -1;
            }
        }

        public ServiceInfo getServiceInfo() {
            return serviceInfo;
        }

        public List<BundleInfo> getBundleInfos() {
            return bundleInfos;
        }

        public void addBundleInfo(BundleInfo info) {
            this.bundleInfos.add(info);
        }

        public void sortBundleInfos(Comparator<BundleInfo> comparator) {
            Collections.sort(bundleInfos, comparator);
        }
    }

    private List<ServicePerspective> getUsingServicePerspectives(Bundle bundle) {
        ServiceReference[] serviceRefs = bundle.getServicesInUse();

        List<ServicePerspective> usingServicePerspectives = new ArrayList<ServicePerspective>();

        if (serviceRefs != null && serviceRefs.length != 0) {
            for (ServiceReference ref : serviceRefs) {
                ServiceInfo info = new ServiceInfo(ref);
                ServicePerspective perspective = new ServicePerspective(info);
                perspective.addBundleInfo(new SimpleBundleInfo(ref.getBundle()));
                usingServicePerspectives.add(perspective);
            }
        }

        return usingServicePerspectives;
    }

    private List<ServicePerspective> getRegisteredServicePerspectives(Bundle bundle) {
        ServiceReference[] serviceRefs = bundle.getRegisteredServices();

        List<ServicePerspective> registeredServicePerspectives = new ArrayList<ServicePerspective>();

        if (serviceRefs != null && serviceRefs.length != 0) {
            for (ServiceReference ref : serviceRefs) {
                ServiceInfo info = new ServiceInfo(ref);
                ServicePerspective perspective = new ServicePerspective(info);

                Bundle[] usingBundles = ref.getUsingBundles();
                if (usingBundles != null && usingBundles.length != 0) {
                    for (Bundle usingBundle : usingBundles) {
                        perspective.addBundleInfo(new SimpleBundleInfo(usingBundle));
                    }
                }

                registeredServicePerspectives.add(perspective);
            }
        }

        return registeredServicePerspectives;
    }

    /*************************************************************
     * definitions for find packages page
     *************************************************************/
    public static class PackageWiredBundles implements Comparable<PackageWiredBundles> {

        private PackageInfo packageInfo;
        private List<BundleInfo> importBundleInfos = new ArrayList<BundleInfo>();
        private List<BundleInfo> exportBundleInfos = new ArrayList<BundleInfo>();

        public PackageWiredBundles(String packageName, String packageVersion) {
            this.packageInfo = new PackageInfo(packageName, packageVersion);
        }

        public PackageWiredBundles(PackageInfo packageInfo) {
            this.packageInfo = packageInfo;
        }

        public PackageWiredBundles(PackageInfo packageInfo, List<BundleInfo> exportBundleInfos,
                List<BundleInfo> importBundleInfos) {
            this.packageInfo = packageInfo;
            this.importBundleInfos = importBundleInfos;
            this.exportBundleInfos = exportBundleInfos;
        }

        @Override
        public int compareTo(PackageWiredBundles another) {
            if (another != null) {
                return packageInfo.compareTo(another.packageInfo);
            } else {
                return -1;
            }
        }

        public PackageInfo getPackageInfo() {
            return packageInfo;
        }

        public List<BundleInfo> getImportBundleInfos() {
            return importBundleInfos;
        }

        public void addImportBundleInfo(BundleInfo info) {
            this.importBundleInfos.add(info);
        }

        public List<BundleInfo> getExportBundleInfos() {
            return exportBundleInfos;
        }

        public void addExportBundleInfo(BundleInfo info) {
            this.exportBundleInfos.add(info);
        }

        public void sortBundleInfos(Comparator<BundleInfo> comparator) {
            Collections.sort(importBundleInfos, comparator);
            Collections.sort(exportBundleInfos, comparator);
        }
    }
}