1 /******************************************************************************* 2 * Copyright (c) 2006, 2014 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Raymond Augé <raymond.auge@liferay.com> - Bug 436698 14 *******************************************************************************/ 15 package org.eclipse.equinox.http.servlet.tests.bundle; 16 17 import java.io.IOException; 18 import java.net.URL; 19 import java.util.ArrayList; 20 import java.util.HashMap; 21 import java.util.Map; 22 23 import org.eclipse.osgi.service.urlconversion.URLConverter; 24 import org.osgi.framework.Bundle; 25 import org.osgi.framework.BundleContext; 26 import org.osgi.framework.BundleException; 27 import org.osgi.framework.InvalidSyntaxException; 28 import org.osgi.util.tracker.ServiceTracker; 29 30 public class BundleInstaller { 31 private BundleContext context; 32 private String rootLocation; 33 private HashMap<String, Bundle> bundles = new HashMap<>(); 34 private ServiceTracker<Object, Object> converter; 35 BundleInstaller(String bundlesRoot, BundleContext context)36 public BundleInstaller(String bundlesRoot, BundleContext context) throws InvalidSyntaxException { 37 this.context = context; 38 rootLocation = bundlesRoot; 39 converter = new ServiceTracker<>(context, context.createFilter("(&(objectClass=" + URLConverter.class.getName() + ")(protocol=bundleentry))"), null); 40 converter.open(); 41 } 42 installBundle(String name)43 synchronized public Bundle installBundle(String name) throws BundleException { 44 return installBundle(name, true); 45 } 46 installBundle(String name, boolean track)47 synchronized public Bundle installBundle(String name, boolean track) throws BundleException { 48 if (bundles == null && track) { 49 return null; 50 } 51 String location = getBundleLocation(name); 52 Bundle bundle = context.installBundle(location); 53 if (track) { 54 bundles.put(name, bundle); 55 } 56 return bundle; 57 } 58 getBundleLocation(String name)59 public String getBundleLocation(String name) throws BundleException { 60 String bundleFileName = rootLocation + "/" + name; 61 URL bundleURL = context.getBundle().getEntry(bundleFileName); 62 if (bundleURL == null) { 63 bundleURL = context.getBundle().getEntry(bundleFileName + ".jar"); 64 } 65 if (bundleURL == null) { 66 throw new BundleException("Could not find bundle to install at: " + name); 67 } 68 try { 69 bundleURL = ((URLConverter) converter.getService()).resolve(bundleURL); 70 } catch (IOException e) { 71 throw new BundleException("Converter error", e); 72 } 73 String location = bundleURL.toExternalForm(); 74 if ("file".equals(bundleURL.getProtocol())) { 75 location = "reference:" + location; 76 } 77 return location; 78 } 79 updateBundle(String fromName, String toName)80 synchronized public Bundle updateBundle(String fromName, String toName) throws BundleException { 81 if (bundles == null) { 82 return null; 83 } 84 Bundle fromBundle = bundles.get(fromName); 85 if (fromBundle == null) { 86 throw new BundleException("The bundle to update does not exist!! " + fromName); 87 } 88 String bundleFileName = rootLocation + "/" + toName; 89 URL bundleURL = context.getBundle().getEntry(bundleFileName); 90 if (bundleURL == null) { 91 bundleURL = context.getBundle().getEntry(bundleFileName + ".jar"); 92 } 93 try { 94 bundleURL = ((URLConverter) converter.getService()).resolve(bundleURL); 95 } catch (IOException e) { 96 throw new BundleException("Converter error", e); 97 } 98 String location = bundleURL.toExternalForm(); 99 if ("file".equals(bundleURL.getProtocol())) { 100 location = "reference:" + location; 101 } 102 try { 103 fromBundle.update(new URL(location).openStream()); 104 } catch (Exception e) { 105 throw new BundleException("Errors when updating bundle " + fromBundle, e); 106 } 107 bundles.remove(fromName); 108 bundles.put(toName, fromBundle); 109 return fromBundle; 110 } 111 uninstallBundle(String name)112 synchronized public Bundle uninstallBundle(String name) throws BundleException { 113 if (bundles == null) { 114 return null; 115 } 116 Bundle bundle = bundles.remove(name); 117 if (bundle == null) { 118 return null; 119 } 120 bundle.uninstall(); 121 return bundle; 122 } 123 uninstallBundle(Bundle b)124 synchronized public void uninstallBundle(Bundle b) throws BundleException { 125 if (bundles == null) { 126 return; 127 } 128 if (bundles.containsValue(b)) { 129 for (Map.Entry<String, Bundle> entry : bundles.entrySet()) { 130 if (entry.getValue().equals(b)) { 131 bundles.remove(entry.getKey()); 132 break; 133 } 134 } 135 } 136 b.uninstall(); 137 } 138 uninstallAllBundles()139 synchronized public Bundle[] uninstallAllBundles() throws BundleException { 140 if (bundles == null) { 141 return null; 142 } 143 ArrayList<Bundle> result = new ArrayList<>(bundles.size()); 144 for (Object element : bundles.values()) { 145 Bundle bundle = (Bundle) element; 146 try { 147 bundle.uninstall(); 148 } catch (IllegalStateException e) { 149 // ignore; bundle probably already uninstalled 150 } 151 result.add(bundle); 152 } 153 bundles.clear(); 154 return result.toArray(new Bundle[result.size()]); 155 } 156 getBundle(String name)157 synchronized public Bundle getBundle(String name) { 158 if (bundles == null) { 159 return null; 160 } 161 return bundles.get(name); 162 } 163 shutdown()164 synchronized public Bundle[] shutdown() throws BundleException { 165 if (bundles == null) { 166 return null; 167 } 168 Bundle[] result = uninstallAllBundles(); 169 converter.close(); 170 bundles = null; 171 return result; 172 } 173 } 174