You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2015/08/11 13:57:13 UTC
[2/2] karaf git commit: [KARAF-3908] Fix shell new without dynamic
import
[KARAF-3908] Fix shell new without dynamic import
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/8f4ee1ff
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/8f4ee1ff
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/8f4ee1ff
Branch: refs/heads/master
Commit: 8f4ee1ff4370fcf8934364b7b104248ea914d08c
Parents: 2357d6b
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Tue Aug 11 13:57:02 2015 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Tue Aug 11 13:57:02 2015 +0200
----------------------------------------------------------------------
.../karaf/shell/commands/impl/NewAction.java | 66 ++++++++++++++++++--
1 file changed, 61 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/8f4ee1ff/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/NewAction.java
----------------------------------------------------------------------
diff --git a/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/NewAction.java b/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/NewAction.java
index c2d2a86..6173ca2 100644
--- a/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/NewAction.java
+++ b/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/NewAction.java
@@ -31,33 +31,51 @@ import java.util.Map;
import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.apache.karaf.shell.support.converter.DefaultConverter;
import org.apache.karaf.shell.support.converter.GenericType;
import org.apache.karaf.shell.support.converter.ReifiedType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Instantiate a new object
*/
@Command(scope = "shell", name = "new", description = "Creates a new java object.")
@Service
+@SuppressWarnings("rawtypes")
public class NewAction implements Action {
-
- @Argument(name = "class", index = 0, multiValued = false, required = true, description = "The object class")
- Class clazz;
+ private static final Logger LOG = LoggerFactory.getLogger(NewAction.class);
+ @Argument(name = "class", index = 0, multiValued = false, required = true, description = "FQN of the class to load")
+ String clazzName;
@Argument(name = "args", index = 1, multiValued = true, required = false, description = "Constructor arguments")
List<Object> args;
boolean reorderArguments;
- protected DefaultConverter converter = new DefaultConverter(getClass().getClassLoader());
+ protected DefaultConverter converter;
+
+ @Reference
+ BundleContext context;
@Override
public Object execute() throws Exception {
if (args == null) {
args = Collections.emptyList();
}
+ String packageName = getPackageName(clazzName);
+ Bundle bundle = getBundleOfferingPackage(packageName);
+ LOG.info("Using bundle {} classloader to load {}.", bundle.getSymbolicName(), clazzName);
+ ClassLoader classLoader = getClassLoader(bundle);
+ converter = new DefaultConverter(classLoader);
+ Class<?> clazz = (Class<?>)converter.convert(clazzName, Class.class);
// Handle arrays
if (clazz.isArray()) {
Object obj = Array.newInstance(clazz.getComponentType(), args.size());
@@ -66,6 +84,7 @@ public class NewAction implements Action {
}
return obj;
}
+
// Map of matching constructors
Map<Constructor, List<Object>> matches = findMatchingConstructors(clazz, args, Arrays.asList(new ReifiedType[args.size()]));
if (matches.size() == 1) {
@@ -82,12 +101,48 @@ public class NewAction implements Action {
}
}
+ private String getPackageName(String name) {
+ int nameSeperator = name.lastIndexOf(".");
+ if (nameSeperator <= 0) {
+ return null;
+ }
+ return name.substring(0, nameSeperator);
+ }
+
+ /**
+ * Get class loader offering a named package. This only works if we do not care
+ * which package we get in case of several package versions
+ *
+ * @param reqPackageName
+ * @return
+ */
+ private Bundle getBundleOfferingPackage(String reqPackageName) {
+ Bundle[] bundles = context.getBundles();
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev != null) {
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleCapability cap : caps) {
+ Map<String, Object> attr = cap.getAttributes();
+ String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
+ if (packageName.equals(reqPackageName)) {
+ return bundle;
+ }
+ }
+ }
+ }
+ return context.getBundle(0);
+ }
+
+ private ClassLoader getClassLoader(Bundle bundle) {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ return wiring.getClassLoader();
+ }
//
// Code below comes from Aries blueprint implementation. Given this code is not available
// from a public API it has been copied here.
//
-
private Object newInstance(Constructor constructor, Object... args) throws Exception {
return constructor.newInstance(args);
}
@@ -200,6 +255,7 @@ public class NewAction implements Action {
return converter.convert(obj, type);
}
+ @SuppressWarnings("unchecked")
public static boolean isAssignable(Object source, ReifiedType target) {
return source == null
|| (target.size() == 0