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 2016/12/20 14:51:06 UTC

karaf git commit: [KARAF-4902] Create config from metatype information

Repository: karaf
Updated Branches:
  refs/heads/master 63db4c207 -> 93fa899f7


[KARAF-4902] Create config from metatype information


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/93fa899f
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/93fa899f
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/93fa899f

Branch: refs/heads/master
Commit: 93fa899f763718e0591deb7d7c48d5d4f09eb30a
Parents: 63db4c2
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Tue Dec 20 15:49:55 2016 +0100
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Tue Dec 20 15:50:55 2016 +0100

----------------------------------------------------------------------
 .../karaf/config/command/MetaCommand.java       | 138 ++++++++++++-------
 .../command/completers/MetaCompleter.java       |  91 ++++++++++++
 .../config/core/impl/MetaServiceCaller.java     |  45 ++++++
 .../config/core/impl/MetatypeCallable.java      |  23 ++++
 4 files changed, 246 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/93fa899f/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java b/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
index b7554ae..8443f93 100644
--- a/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
+++ b/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
@@ -16,10 +16,17 @@
  */
 package org.apache.karaf.config.command;
 
+import static org.apache.karaf.config.core.impl.MetaServiceCaller.withMetaTypeService;
+
+import java.io.IOException;
+import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Map;
 
-import org.apache.karaf.config.command.completers.ConfigurationCompleter;
+import org.apache.karaf.config.command.completers.MetaCompleter;
+import org.apache.karaf.config.core.impl.MetatypeCallable;
+import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Completion;
 import org.apache.karaf.shell.api.action.Option;
@@ -28,7 +35,7 @@ import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.apache.karaf.shell.support.table.ShellTable;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
 import org.osgi.service.metatype.AttributeDefinition;
 import org.osgi.service.metatype.MetaTypeInformation;
 import org.osgi.service.metatype.MetaTypeService;
@@ -37,10 +44,13 @@ import org.osgi.service.metatype.ObjectClassDefinition;
 @Command(scope = "config", name = "meta", description = "Lists meta type information.")
 @Service
 public class MetaCommand extends ConfigCommandSupport {
-    @Option(name = "-p", aliases = "--pid", description = "The configuration pid", required = true, multiValued = false)
-    @Completion(ConfigurationCompleter.class)
+    @Argument(name = "pid", description = "The configuration pid", required = true, multiValued = false)
+    @Completion(MetaCompleter.class)
     protected String pid;
 
+    @Option(name = "-c", description = "Create respective config from metatype defaults", required = false, multiValued = false)
+    protected boolean create;
+
     @Reference
     BundleContext context;
 
@@ -62,55 +72,16 @@ public class MetaCommand extends ConfigCommandSupport {
 
     @Override
     public Object doExecute() throws Exception {
-        try {
-            new InnerCommand().doExecute();
-        } catch (NoClassDefFoundError e) {
-            System.out
-                    .println("No MetaTypeService present. You need to install an implementation to use this command.");
+        if (create) {
+            withMetaTypeService(context, new Create());
+        } else {
+            withMetaTypeService(context, new Print());
         }
         return null;
     }
-
-    class InnerCommand {
-
-        protected Object doExecute() throws Exception {
-
-            ServiceReference<MetaTypeService> ref = context.getServiceReference(MetaTypeService.class);
-            if (ref == null) {
-                System.out
-                        .println("No MetaTypeService present. You need to install an implementation to use this command.");
-            }
-            MetaTypeService metaTypeService = context.getService(ref);
-            ObjectClassDefinition def = getMetatype(metaTypeService, pid);
-            context.ungetService(ref);
-
-            if (def == null) {
-                System.out.println("No meta type definition found for pid: " + pid);
-                return null;
-            }
-            System.out.println("Meta type informations for pid: " + pid);
-            ShellTable table = new ShellTable();
-            table.column("key");
-            table.column("name");
-            table.column("type");
-            table.column("default");
-            table.column("description");
-            AttributeDefinition[] attrs = def.getAttributeDefinitions(ObjectClassDefinition.ALL);
-            if (attrs != null) {
-                for (AttributeDefinition attr : attrs) {
-                    table.addRow().addContent(attr.getID(), attr.getName(), getType(attr.getType()),
-                            getDefaultValueStr(attr.getDefaultValue()), attr.getDescription());
-                }
-            }
-            table.print(System.out);
-            return null;
-        }
-
-        private String getType(int type) {
-            return typeMap.get(type);
-        }
-
-        private String getDefaultValueStr(String[] defaultValues) {
+        
+    abstract class AbstractMeta implements MetatypeCallable<Void> {
+        protected String getDefaultValueStr(String[] defaultValues) {
             if (defaultValues == null) {
                 return "";
             }
@@ -127,7 +98,7 @@ public class MetaCommand extends ConfigCommandSupport {
             return result.toString();
         }
 
-        public ObjectClassDefinition getMetatype(MetaTypeService metaTypeService, String pid) {
+        protected ObjectClassDefinition getMetatype(MetaTypeService metaTypeService, String pid) {
             for (Bundle bundle : context.getBundles()) {
                 MetaTypeInformation info = metaTypeService.getMetaTypeInformation(bundle);
                 if (info == null) {
@@ -142,6 +113,71 @@ public class MetaCommand extends ConfigCommandSupport {
             }
             return null;
         }
+    }
+    
+    class Create extends AbstractMeta {
+
+        public Void callWith(MetaTypeService metaTypeService) {
+            ObjectClassDefinition def = getMetatype(metaTypeService, pid);
+            if (def == null) {
+                System.out.println("No meta type definition found for pid: " + pid);
+                return null;
+            }
+            
+            try {
+                createDefaultConfig(pid, def);
+            } catch (IOException e) {
+                 throw new RuntimeException(e.getMessage(), e);
+            }
+            return null;
+        }
+        
+        private void createDefaultConfig(String pid, ObjectClassDefinition def) throws IOException {
+            AttributeDefinition[] attrs = def.getAttributeDefinitions(ObjectClassDefinition.ALL);
+            if (attrs == null) {
+                return;
+            }
+            Configuration config = configRepository.getConfigAdmin().getConfiguration(pid);
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            for (AttributeDefinition attr : attrs) {
+                String valueStr = getDefaultValueStr(attr.getDefaultValue());
+                if (valueStr != null) {
+                    props.put(attr.getID(), valueStr);
+                }
+            }
+            config.update(props);
+        }
+
+    }
+    
+    class Print extends AbstractMeta {
+        public Void callWith(MetaTypeService metaTypeService) {
+            ObjectClassDefinition def = getMetatype(metaTypeService, pid);
+            if (def == null) {
+                System.out.println("No meta type definition found for pid: " + pid);
+                return null;
+            }
+            System.out.println("Meta type informations for pid: " + pid);
+            ShellTable table = new ShellTable();
+            table.column("key");
+            table.column("name");
+            table.column("type");
+            table.column("default");
+            table.column("description").wrap();
+            AttributeDefinition[] attrs = def.getAttributeDefinitions(ObjectClassDefinition.ALL);
+            if (attrs != null) {
+                for (AttributeDefinition attr : attrs) {
+                    table.addRow().addContent(attr.getID(), attr.getName(), getType(attr.getType()),
+                            getDefaultValueStr(attr.getDefaultValue()), attr.getDescription());
+                }
+            }
+            table.print(System.out);
+            return null;
+        }
+
+        private String getType(int type) {
+            return typeMap.get(type);
+        }
 
     }
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/93fa899f/config/src/main/java/org/apache/karaf/config/command/completers/MetaCompleter.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/completers/MetaCompleter.java b/config/src/main/java/org/apache/karaf/config/command/completers/MetaCompleter.java
new file mode 100644
index 0000000..a258334
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/completers/MetaCompleter.java
@@ -0,0 +1,91 @@
+/*
+ * 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.config.command.completers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.karaf.config.core.impl.MetaServiceCaller;
+import org.apache.karaf.config.core.impl.MetatypeCallable;
+import org.apache.karaf.shell.api.action.lifecycle.Init;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.service.metatype.MetaTypeInformation;
+import org.osgi.service.metatype.MetaTypeService;
+
+@Service
+public class MetaCompleter implements Completer, BundleListener {
+    private final StringsCompleter delegate = new StringsCompleter();
+    
+    @Reference
+    BundleContext context;
+    
+    @Init
+    public void init() {
+        context.registerService(BundleListener.class, this, null);
+        updateMeta();
+    }
+
+    @Override
+    public synchronized int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
+        return delegate.complete(session, commandLine, candidates);
+    }
+
+    @Override
+    public void bundleChanged(BundleEvent event) {
+        updateMeta();
+    }
+
+    private synchronized void updateMeta() {
+        List<String> pids = MetaServiceCaller.withMetaTypeService(context, new MetatypeCallable<List<String>>() {
+
+            @Override
+            public List<String> callWith(MetaTypeService metatypeService) {
+                List<String> pids = new ArrayList<String>();
+                Bundle[] bundles = context.getBundles();
+                for (Bundle bundle : bundles) {
+                    
+                    MetaTypeInformation info = metatypeService.getMetaTypeInformation(bundle);
+                    if (info == null) {
+                        continue;
+                    }
+                    if (info.getFactoryPids() != null) {
+                        pids.addAll(Arrays.asList(info.getFactoryPids()));
+                    }
+                    if (info.getPids() != null) {
+                        pids.addAll(Arrays.asList(info.getPids()));
+                    }
+                }
+                return pids;
+            }
+        });
+        if (pids != null) {
+            delegate.getStrings().clear();
+            delegate.getStrings().addAll(pids);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/93fa899f/config/src/main/java/org/apache/karaf/config/core/impl/MetaServiceCaller.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/MetaServiceCaller.java b/config/src/main/java/org/apache/karaf/config/core/impl/MetaServiceCaller.java
new file mode 100644
index 0000000..88bc1f3
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/MetaServiceCaller.java
@@ -0,0 +1,45 @@
+/*
+ * 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.config.core.impl;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.metatype.MetaTypeService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Allows to use the MetaTypeService as an optional dependency
+ */
+public class MetaServiceCaller {
+    private static Logger LOG = LoggerFactory.getLogger(MetaServiceCaller.class);
+
+    public static <T> T withMetaTypeService(BundleContext context, MetatypeCallable<T> callable) {
+        try {
+            ServiceReference<MetaTypeService> ref = context.getServiceReference(MetaTypeService.class);
+            try {
+                MetaTypeService metaService = context.getService(ref);
+                return callable.callWith(metaService);
+            } finally {
+                context.ungetService(ref);
+            }
+        } catch (NoClassDefFoundError e) {
+            LOG.warn("No Metatype Service present");
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/93fa899f/config/src/main/java/org/apache/karaf/config/core/impl/MetatypeCallable.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/MetatypeCallable.java b/config/src/main/java/org/apache/karaf/config/core/impl/MetatypeCallable.java
new file mode 100644
index 0000000..39075f9
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/MetatypeCallable.java
@@ -0,0 +1,23 @@
+/*
+ * 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.config.core.impl;
+
+import org.osgi.service.metatype.MetaTypeService;
+
+public interface MetatypeCallable <T> {
+    T callWith(MetaTypeService metatypeService);
+}