/* * Licensed 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.aries.subsystem.core.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.jar.Attributes; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import org.osgi.framework.Version; import org.osgi.framework.startlevel.BundleStartLevel; import org.osgi.framework.wiring.BundleRevision; import org.osgi.service.coordinator.Coordination; public class RegionContextBundleHelper { public static final String SYMBOLICNAME_PREFIX = Constants.RegionContextBundleSymbolicNamePrefix; public static final Version VERSION = Version.parseVersion("1.0.0"); public static void installRegionContextBundle(final BasicSubsystem subsystem, Coordination coordination) throws Exception { String symbolicName = SYMBOLICNAME_PREFIX + subsystem.getSubsystemId(); String location = subsystem.getLocation() + '/' + subsystem.getSubsystemId(); Bundle b = subsystem.getRegion().getBundle(symbolicName, VERSION); if (b == null) { b = subsystem.getRegion().installBundleAtLocation(location, createRegionContextBundle(symbolicName)); // The start level of all managed bundles, including the region // context bundle, should be 1. b.adapt(BundleStartLevel.class).setStartLevel(1); } ResourceInstaller.newInstance(coordination, b.adapt(BundleRevision.class), subsystem).install(); // The region context bundle must be started persistently. b.start(); subsystem.setRegionContextBundle(b); } public static void uninstallRegionContextBundle(BasicSubsystem subsystem) { String symbolicName = SYMBOLICNAME_PREFIX + subsystem.getSubsystemId(); Bundle bundle = subsystem.getRegion().getBundle(symbolicName, VERSION); if (bundle == null) return; BundleRevision revision = bundle.adapt(BundleRevision.class); try { bundle.uninstall(); } catch (BundleException e) { // TODO Should we really eat this? At least log it? } ResourceUninstaller.newInstance(revision, subsystem).uninstall(); subsystem.setRegionContextBundle(null); } private static Manifest createManifest(String symbolicName) { Manifest manifest = new Manifest(); manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); manifest.getMainAttributes().putValue(org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION, "2"); manifest.getMainAttributes().putValue(Constants.BundleSymbolicName, symbolicName); manifest.getMainAttributes().putValue(Constants.BundleVersion, VERSION.toString()); return manifest; } private static InputStream createRegionContextBundle(String symbolicName) throws IOException { Manifest manifest = createManifest(symbolicName); ByteArrayOutputStream baos = new ByteArrayOutputStream(); JarOutputStream jos = new JarOutputStream(baos, manifest); jos.close(); return new ByteArrayInputStream(baos.toByteArray()); } }