blob: 7f81dbdb76c50c4b2aa95d1ad43ad20a97bcc5ed [file] [log] [blame]
/*
* 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.karaf.shell.dev;
import java.io.IOException;
import static java.lang.String.format;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.felix.gogo.commands.Argument;
import org.apache.felix.gogo.commands.Command;
import org.apache.karaf.shell.console.OsgiCommandSupport;
import org.ops4j.pax.url.wrap.Handler;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Command for enabling/disabling debug logging on a bundle and calculating the difference in
* wired imports.
*/
@Command(scope = "dev", name = "dynamic-import", description = "Enables/disables dynamic-import for a given bundle.")
public class DynamicImport extends AbstractBundleCommand {
private final Logger LOG = LoggerFactory.getLogger(DynamicImport.class);
/**
* The header key where we store the active wires when we enable DynamicImport=*
*/
protected static final String ORIGINAL_WIRES = "Original-Wires";
@Override
protected void doExecute(Bundle bundle) throws Exception {
if (bundle.getHeaders().get(ORIGINAL_WIRES) == null) {
enableDynamicImports(bundle);
} else {
disableDynamicImports(bundle);
}
}
/*
* Enable DynamicImport=* on the bundle
*/
private void enableDynamicImports(Bundle bundle) throws IOException, BundleException {
System.out.printf("Enabling dynamic imports on bundle %s%n", 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));
URL url = new URL(location);
bundle.update(url.openStream());
getPackageAdmin().refreshPackages(new Bundle[] {bundle});
}
/*
* 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
*/
private void disableDynamicImports(Bundle bundle) throws BundleException {
System.out.printf("Disabling dynamic imports on bundle %s%n", bundle);
Set<String> current = getWiredBundles(bundle).keySet();
for (String original : bundle.getHeaders().get(ORIGINAL_WIRES).toString().split(",")) {
current.remove(original);
}
if (current.isEmpty()) {
System.out.println("(no additional packages have been wired since dynamic import was enabled)");
} else {
System.out.printf("%nAdditional packages wired since dynamic import was enabled:%n");
for (String pkg : current) {
System.out.printf("- %s%n", pkg);
}
}
bundle.update();
}
/*
* 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();
}
}