/**
* 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);
}
}
}