Added: karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java?rev=1309898&view=auto ============================================================================== --- karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java (added) +++ karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java Thu Apr 5 15:21:55 2012 @@ -0,0 +1,221 @@ +/* + * 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.karaf.dev.core.internal; + +import static java.lang.String.format; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.utils.properties.Properties; +import org.apache.karaf.dev.core.DevService; +import org.apache.karaf.dev.core.FrameworkType; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.wiring.BundleRevision; +import org.osgi.framework.wiring.BundleRevisions; +import org.osgi.framework.wiring.BundleWire; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.framework.wiring.FrameworkWiring; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DevServiceImpl implements DevService { + private static Logger LOG = LoggerFactory.getLogger(DevServiceImpl.class); + /** + * The header key where we store the active wires when we enable DynamicImport=* + */ + private static final String ORIGINAL_WIRES = "Original-Wires"; + + private BundleContext bundleContext; + + public DevServiceImpl(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public FrameworkType getFramework() { + if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) { + return FrameworkType.felix; + } else { + return FrameworkType.equinox; + } + } + + private Properties loadProps() throws IOException { + return new Properties(new File(System.getProperty("karaf.base"), "etc/config.properties")); + } + + public void setFramework(FrameworkType framework) { + if (framework == null) { + return; + } + try { + Properties properties = loadProps(); + properties.put("karaf.framework", framework.name()); + properties.save(); + } catch (IOException e) { + throw new RuntimeException("Error settting framework: " + e.getMessage(), e); + } + } + + public void setFrameworkDebug(boolean debug) { + try { + Properties properties = loadProps(); + if (debug) { + properties.put("felix.log.level", "4"); + properties.put("osgi.debug", "etc/equinox-debug.properties"); + } else { + properties.remove("felix.log.level"); + properties.remove("osgi.debug"); + } + // TODO populate the equinox-debug.properties file with the one provided in shell/dev module + properties.save(); + } catch (IOException e) { + throw new RuntimeException("Error settting framework debugging: " + e.getMessage(), e); + } + } + + public void restart(boolean clean) { + System.setProperty("karaf.restart", "true"); + System.setProperty("karaf.restart.clean", Boolean.toString(clean)); + try { + bundleContext.getBundle(0).stop(); + } catch (BundleException e) { + throw new RuntimeException("Error stopping framework bundle: " + e.getMessage(), e); + } + } + + @Override + public String setSystemProperty(String key, String value, boolean persist) { + if (persist) { + try { + String base = System.getProperty("karaf.base"); + Properties props = new Properties(new File(base, "etc/system.properties")); + props.put(key, value); + props.save(); + } catch (IOException e) { + throw new RuntimeException("Error persisting system property", e); + } + } + return System.setProperty(key, value); + } + + /* + * Enable DynamicImport=* on the bundle + */ + public void enableDynamicImports(Bundle bundle) { + String location = + String.format("wrap:%s$" + + "Bundle-UpdateLocation=%s&" + + "DynamicImport-Package=*&" + + "%s=%s&" + + "overwrite=merge", + bundle.getLocation(), + bundle.getLocation(), + ORIGINAL_WIRES, + explode(getWiredBundles(bundle).keySet())); + LOG.debug(format("Updating %s with URL %s", bundle, location)); + + try { + URL url = new URL(location); + bundle.update(url.openStream()); + bundleContext.getBundle(0).adapt(FrameworkWiring.class).refreshBundles(Collections.singleton(bundle)); + } catch (Exception e) { + throw new RuntimeException("Error enabling dynamic imports on bundle" + bundle.getBundleId(), e); + } + } + + /* + * Disable DynamicImport=* on the bundle + * + * At this time, we will also calculate the difference in package wiring for the bundle compared to + * when we enabled the DynamicImport + */ + public void disableDynamicImports(Bundle bundle) { + Set<String> current = getWiredBundles(bundle).keySet(); + for (String original : bundle.getHeaders().get(ORIGINAL_WIRES).toString().split(",")) { + current.remove(original); + } + + if (current.isEmpty()) { + LOG.debug("No additional packages have been wired since dynamic import was enabled"); + } else { + LOG.debug("Additional packages wired since dynamic import was enabled"); + for (String pkg : current) { + LOG.debug("- " + pkg); + } + } + + try { + bundle.update(); + } catch (BundleException e) { + throw new RuntimeException("Error disabling dynamic imports on bundle" + bundle.getBundleId(), e); + } + } + + /* + * Explode a set of string values in to a ,-delimited string + */ + private String explode(Set<String> set) { + StringBuffer result = new StringBuffer(); + Iterator<String> it = set.iterator(); + while (it.hasNext()) { + result.append(it.next()); + if (it.hasNext()) { + result.append(","); + } + } + if (result.length() == 0) { + return "--none--"; + } + return result.toString(); + } + + /* + * Get the list of bundles from which the given bundle imports packages + */ + public Map<String, Bundle> getWiredBundles(Bundle bundle) { + // the set of bundles from which the bundle imports packages + Map<String, Bundle> exporters = new HashMap<String, Bundle>(); + + for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions()) { + BundleWiring wiring = revision.getWiring(); + if (wiring != null) { + List<BundleWire> wires = wiring.getRequiredWires(BundleRevision.PACKAGE_NAMESPACE); + if (wires != null) { + for (BundleWire wire : wires) { + if (wire.getProviderWiring().getBundle().getBundleId() != 0) { + exporters.put(wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString(), + wire.getProviderWiring().getBundle()); + } + } + } + } + } + return exporters; + } + + @Override + public boolean isDynamicImport(Bundle bundle) { + return bundle.getHeaders().get(ORIGINAL_WIRES) != null; + } +}
Copied: karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml (from r1309676, karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml) URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml?p2=karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml&p1=karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml&r1=1309676&r2=1309898&rev=1309898&view=diff ============================================================================== --- karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml (original) +++ karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml Thu Apr 5 15:21:55 2012 @@ -12,25 +12,36 @@ See the License for the specific language governing permissions and limitations under the License. --> -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" + xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"> - <!-- Reference to the MBean server --> - <reference id="mbeanServer" interface="javax.management.MBeanServer"> - <reference-listener ref="mbeanRegistrer" bind-method="registerMBeanServer" unbind-method="unregisterMBeanServer"/> - </reference> - - <!-- Dev MBean --> - <bean id="devMBean" class="org.apache.karaf.management.mbeans.dev.internal.DevMBeanImpl"> - <property name="bundleContext" ref="blueprintBundleContext"/> + <ext:property-placeholder /> + + <reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/> + <reference id="packageAdmin" interface="org.osgi.service.packageadmin.PackageAdmin"/> + + <bean id="watcher" class="org.apache.karaf.dev.core.internal.BundleWatcherImpl" init-method="start" destroy-method="stop"> + <argument ref="blueprintBundleContext"/> + <argument ref="configurationAdmin"/> + <argument ref="packageAdmin"/> + </bean> + + <service ref="watcher" interface="org.apache.karaf.dev.core.BundleWatcher"/> + + <bean id="devService" class="org.apache.karaf.dev.core.internal.DevServiceImpl"> + <argument ref="blueprintBundleContext"/> </bean> - <!-- Register Dev MBean in the MBean Server --> - <bean id="mbeanRegistrer" class="org.apache.karaf.management.MBeanRegistrer"> - <property name="mbeans"> - <map> - <entry value="org.apache.karaf:type=dev,name=${karaf.name}" key-ref="devMBean"/> - </map> - </property> + <bean id="devMBean" class="org.apache.karaf.dev.core.internal.Dev"> + <argument ref="devService" /> </bean> + + <service ref="devService" interface="org.apache.karaf.dev.core.DevService" /> -</blueprint> \ No newline at end of file + <service ref="devMBean" auto-export="interfaces"> + <service-properties> + <entry key="jmx.objectname" value="org.apache.karaf:type=dev,name=${karaf.name}"/> + </service-properties> + </service> +</blueprint> Modified: karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info?rev=1309898&r1=1309676&r2=1309898&view=diff ============================================================================== --- karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info (original) +++ karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info Thu Apr 5 15:21:55 2012 @@ -9,7 +9,7 @@ Maven URL: h1. Description -The dev mbean management bundle exposes a Dev MBean that can be used with any JMX client (for instance JConsole). +Core services and mbeans for developers. The dev MBean allows quite the same actions that can be performed using dev:* commands: * framework() Added: karaf/trunk/dev/pom.xml URL: http://svn.apache.org/viewvc/karaf/trunk/dev/pom.xml?rev=1309898&view=auto ============================================================================== --- karaf/trunk/dev/pom.xml (added) +++ karaf/trunk/dev/pom.xml Thu Apr 5 15:21:55 2012 @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.karaf</groupId> + <artifactId>karaf</artifactId> + <version>3.0.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>org.apache.karaf.dev</groupId> + <artifactId>dev</artifactId> + <packaging>pom</packaging> + <name>Apache Karaf :: Dev</name> + + <modules> + <module>core</module> + <module>command</module> + </modules> + +</project> \ No newline at end of file Modified: karaf/trunk/management/mbeans/pom.xml URL: http://svn.apache.org/viewvc/karaf/trunk/management/mbeans/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff ============================================================================== --- karaf/trunk/management/mbeans/pom.xml (original) +++ karaf/trunk/management/mbeans/pom.xml Thu Apr 5 15:21:55 2012 @@ -34,7 +34,6 @@ <name>Apache Karaf :: Management :: MBeans</name> <modules> - <module>dev</module> <module>obr</module> </modules> Modified: karaf/trunk/pom.xml URL: http://svn.apache.org/viewvc/karaf/trunk/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff ============================================================================== --- karaf/trunk/pom.xml (original) +++ karaf/trunk/pom.xml Thu Apr 5 15:21:55 2012 @@ -386,6 +386,17 @@ </dependency> <dependency> + <groupId>org.apache.karaf.dev</groupId> + <artifactId>org.apache.karaf.dev.core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.karaf.dev</groupId> + <artifactId>org.apache.karaf.dev.command</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>org.apache.karaf.log</groupId> <artifactId>org.apache.karaf.log.core</artifactId> <version>${project.version}</version> @@ -456,11 +467,6 @@ </dependency> <dependency> <groupId>org.apache.karaf.management.mbeans</groupId> - <artifactId>org.apache.karaf.management.mbeans.dev</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.karaf.management.mbeans</groupId> <artifactId>org.apache.karaf.management.mbeans.log</artifactId> <version>${project.version}</version> </dependency> @@ -619,11 +625,6 @@ <artifactId>org.apache.karaf.shell.commands</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.apache.karaf.shell</groupId> - <artifactId>org.apache.karaf.shell.dev</artifactId> - <version>${project.version}</version> - </dependency> <dependency> <groupId>org.apache.karaf.jaas</groupId> Modified: karaf/trunk/shell/pom.xml URL: http://svn.apache.org/viewvc/karaf/trunk/shell/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff ============================================================================== --- karaf/trunk/shell/pom.xml (original) +++ karaf/trunk/shell/pom.xml Thu Apr 5 15:21:55 2012 @@ -36,7 +36,6 @@ <modules> <module>commands</module> <module>console</module> - <module>dev</module> <module>obr</module> <module>ssh</module> </modules>
