Author: cschneider
Date: Mon Jun 18 12:30:52 2012
New Revision: 1351321

URL: http://svn.apache.org/viewvc?rev=1351321&view=rev
Log:
KARAF-1524 kar:create command support for naming features and completion

Modified:
    
karaf/trunk/features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml
    
karaf/trunk/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
    
karaf/trunk/kar/command/src/main/resources/OSGI-INF/blueprint/kar-command.xml
    karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/KarService.java
    
karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java

Modified: 
karaf/trunk/features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml?rev=1351321&r1=1351320&r2=1351321&view=diff
==============================================================================
--- 
karaf/trunk/features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml
 (original)
+++ 
karaf/trunk/features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml
 Mon Jun 18 12:30:52 2012
@@ -102,5 +102,11 @@
     <bean id="installedRepoNameCompleter" 
class="org.apache.karaf.features.command.completers.InstalledRepoNameCompleter">
         <property name="featuresService" ref="featuresService"/>
     </bean>
+    
+    <service ref="installedRepoNameCompleter" 
interface="org.apache.karaf.shell.console.Completer">
+        <service-properties>
+            <entry key="name" value="installedRepoNameCompleter"/>
+        </service-properties>
+    </service>
 
 </blueprint>

Modified: 
karaf/trunk/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java?rev=1351321&r1=1351320&r2=1351321&view=diff
==============================================================================
--- 
karaf/trunk/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
 (original)
+++ 
karaf/trunk/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
 Mon Jun 18 12:30:52 2012
@@ -16,7 +16,7 @@
  */
 package org.apache.karaf.kar.command;
 
-import java.util.Set;
+import java.util.List;
 
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
@@ -27,8 +27,8 @@ public class CreateKarCommand extends Ka
     @Argument(index = 0, name = "repoName", description = "Repository name. 
The kar will contain all features of the named repository by default", required 
= true, multiValued = false)
     private String repoName;
     
-    @Argument(index = 1, name = "features", description = "Names of the 
features to include. If set then only these features will be added", required = 
false, multiValued = false)
-    private Set<String> features;
+    @Argument(index = 1, name = "features", description = "Names of the 
features to include. If set then only these features will be added", required = 
false, multiValued = true)
+    private List<String> features;
     
     public Object doExecute() throws Exception {
         this.getKarService().create(repoName, features, System.out);

Modified: 
karaf/trunk/kar/command/src/main/resources/OSGI-INF/blueprint/kar-command.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/kar/command/src/main/resources/OSGI-INF/blueprint/kar-command.xml?rev=1351321&r1=1351320&r2=1351321&view=diff
==============================================================================
--- 
karaf/trunk/kar/command/src/main/resources/OSGI-INF/blueprint/kar-command.xml 
(original)
+++ 
karaf/trunk/kar/command/src/main/resources/OSGI-INF/blueprint/kar-command.xml 
Mon Jun 18 12:30:52 2012
@@ -17,6 +17,14 @@
     -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"; 
default-activation="lazy">
 
+    <reference id="karService" interface="org.apache.karaf.kar.KarService"/>
+    
+    <bean id="karCompleter" 
class="org.apache.karaf.kar.command.completers.KarCompleter">
+        <property name="karService" ref="karService"/>
+    </bean>
+
+    <reference id="installedRepoNameCompleter" 
interface="org.apache.karaf.shell.console.Completer" 
filter="(name=installedRepoNameCompleter)"/>
+
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0";>
         <command>
             <action class="org.apache.karaf.kar.command.ListKarCommand">
@@ -40,13 +48,10 @@
             <action class="org.apache.karaf.kar.command.CreateKarCommand">
                 <property name="karService" ref="karService"/>
             </action>
+            <completers>
+                <ref component-id="installedRepoNameCompleter"/>
+            </completers>
         </command>
     </command-bundle>
 
-    <reference id="karService" interface="org.apache.karaf.kar.KarService"/>
-
-    <bean id="karCompleter" 
class="org.apache.karaf.kar.command.completers.KarCompleter">
-        <property name="karService" ref="karService"/>
-    </bean>
-
 </blueprint>
\ No newline at end of file

Modified: 
karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/KarService.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/KarService.java?rev=1351321&r1=1351320&r2=1351321&view=diff
==============================================================================
--- karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/KarService.java 
(original)
+++ karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/KarService.java Mon 
Jun 18 12:30:52 2012
@@ -19,7 +19,6 @@ package org.apache.karaf.kar;
 import java.io.PrintStream;
 import java.net.URI;
 import java.util.List;
-import java.util.Set;
 
 /**
  * The service managing KAR.
@@ -69,6 +68,6 @@ public interface KarService {
      * @param features 
      * @param console
      */
-    void create(String repoName, Set<String> features, PrintStream console);
+    void create(String repoName, List<String> features, PrintStream console);
     
 }

Modified: 
karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java?rev=1351321&r1=1351320&r2=1351321&view=diff
==============================================================================
--- 
karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
 (original)
+++ 
karaf/trunk/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
 Mon Jun 18 12:30:52 2012
@@ -26,11 +26,14 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -46,6 +49,7 @@ import javax.xml.parsers.DocumentBuilder
 
 import org.apache.karaf.features.BundleInfo;
 import org.apache.karaf.features.ConfigFileInfo;
+import org.apache.karaf.features.Dependency;
 import org.apache.karaf.features.Feature;
 import org.apache.karaf.features.FeaturesService;
 import org.apache.karaf.features.Repository;
@@ -387,58 +391,102 @@ public class KarServiceImpl implements K
     }
     
     @Override
-    public void create(String repoName, Set<String> features, PrintStream 
console) {
+    public void create(String repoName, List<String> features, PrintStream 
console) {
         FileOutputStream fos = null;
         JarOutputStream jos = null;
         try {
-            String karPath = base + File.separator + "data" + File.separator + 
"kar" + File.separator + repoName + ".kar";
+            Repository repo = featuresService.getRepository(repoName);
+            if (repo == null) {
+                throw new RuntimeException("Could not find a repository with 
name " + repoName);
+            }
+            String karPath = storage + File.separator + repoName + ".kar";
             File karFile = new File(karPath);
             karFile.getParentFile().mkdirs();
             fos = new FileOutputStream(karFile);
-            String manifestSt = "Manifest-Version: 1.0\n" +
-                MANIFEST_ATTR_KARAF_FEATURE_START +": true\n";
-            InputStream manifestIs = new 
ByteArrayInputStream(manifestSt.getBytes("UTF-8"));
-            Manifest manifest = new Manifest(manifestIs);
+            Manifest manifest = createNonAutoStartManifest();
             jos = new JarOutputStream(new BufferedOutputStream(fos, 100000), 
manifest);
             
             Map<URI, Integer> locationMap = new HashMap<URI, Integer>();
-
-            Repository repo = featuresService.getRepository(repoName);
             copyResourceToJar(jos, repo.getURI(), locationMap, console);
-            
+        
+            Map<String, Feature> featureMap = new HashMap<String, Feature>();
             for (Feature feature : repo.getFeatures()) {
-                List<BundleInfo> bundles = feature.getBundles();
-                for (BundleInfo bundleInfo : bundles) {
-                    URI location = new URI(bundleInfo.getLocation());
-                    copyResourceToJar(jos, location, locationMap, console);
-                }
-                List<ConfigFileInfo> configFiles = 
feature.getConfigurationFiles();
-                for (ConfigFileInfo configFileInfo : configFiles) {
-                    URI location = new URI(configFileInfo.getLocation());
-                    copyResourceToJar(jos, location, locationMap, console);
-                }
+                featureMap.put(feature.getName(), feature);
+            }
+            
+            Set<Feature> featuresToCopy = getFeatures(featureMap, features, 1);
+            
+            for (Feature feature : featuresToCopy) {
+                console.println("Adding feature " + feature.getName());
+                copyFeatureToJar(jos, feature, locationMap, console);
             }
             
             console.println("Kar file created : " + karPath);
         } catch (Exception e) {
-            throw new RuntimeException("Error creating kar " + e.getMessage(), 
e);
+            throw new RuntimeException("Error creating kar: " + 
e.getMessage(), e);
         } finally {
-            if (jos != null) {
-                try {
-                    jos.close();
-                } catch (IOException e) {
-                    LOGGER.warn("Error closing jar stream", e);
+            closeStream(jos);
+            closeStream(fos);
+        }
+        
+    }
+
+    private Set<Feature> getFeatures(Map<String, Feature> featureMap, 
List<String> features, int depth) {
+        Set<Feature> featureSet = new HashSet<Feature>();
+        if (depth > 5) {
+            // Break after some recursions to avoid endless loops 
+            return featureSet;
+        }
+        if (features == null) {
+            featureSet.addAll(featureMap.values());
+            return featureSet;
+        }
+        for (String featureName : features) {
+            Feature feature = featureMap.get(featureName);
+            if (feature == null) {
+                System.out.println("Feature " + featureName + " not found in 
repository.");
+                //throw new RuntimeException();
+            } else {
+                featureSet.add(feature);
+                List<Dependency> deps = feature.getDependencies();
+                List<String> depNames = new ArrayList<String>();
+                for (Dependency dependency : deps) {
+                    depNames.add(dependency.getName());
                 }
+                featureSet.addAll(getFeatures(featureMap, depNames, depth ++));
             }
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                    LOGGER.warn("Error closing jar file stream", e);
-                }
+        }
+        return featureSet;
+    }
+
+    private Manifest createNonAutoStartManifest() throws 
UnsupportedEncodingException, IOException {
+        String manifestSt = "Manifest-Version: 1.0\n" +
+            MANIFEST_ATTR_KARAF_FEATURE_START +": true\n";
+        InputStream manifestIs = new 
ByteArrayInputStream(manifestSt.getBytes("UTF-8"));
+        Manifest manifest = new Manifest(manifestIs);
+        return manifest;
+    }
+
+    private void closeStream(OutputStream os) {
+        if (os != null) {
+            try {
+                os.close();
+            } catch (IOException e) {
+                LOGGER.warn("Error closing stream", e);
             }
         }
-        
+    }
+
+    private void copyFeatureToJar(JarOutputStream jos, Feature feature, 
Map<URI, Integer> locationMap, PrintStream console)
+        throws URISyntaxException {
+        for (BundleInfo bundleInfo : feature.getBundles()) {
+            URI location = new URI(bundleInfo.getLocation());
+            copyResourceToJar(jos, location, locationMap, console);
+        }
+        for (ConfigFileInfo configFileInfo : feature.getConfigurationFiles()) {
+            URI location = new URI(configFileInfo.getLocation());
+            copyResourceToJar(jos, location, locationMap, console);
+        }
     }
 
     private void copyResourceToJar(JarOutputStream jos, URI location, Map<URI, 
Integer> locationMap, PrintStream console) {
@@ -446,7 +494,6 @@ public class KarServiceImpl implements K
             return;
         }
         try {
-            console.println("Adding " + location);
             String noPrefixLocation = 
location.toString().substring(location.toString().lastIndexOf(":") + 1);
             Parser parser = new Parser(noPrefixLocation);
             InputStream is = location.toURL().openStream();
@@ -497,34 +544,18 @@ public class KarServiceImpl implements K
         }
     }
 
-    public FeaturesService getFeaturesService() {
-        return featuresService;
-    }
-
     public void setFeaturesService(FeaturesService featuresService) {
         this.featuresService = featuresService;
     }
 
-    public String getStorage() {
-        return storage;
-    }
-
     public void setStorage(String storage) {
         this.storage = storage;
     }
 
-    public String getBase() {
-        return base;
-    }
-
     public void setBase(String base) {
         this.base = base;
     }
 
-    public String getLocalRepo() {
-        return localRepo;
-    }
-
     public void setLocalRepo(String localRepo) {
         this.localRepo = localRepo;
     }


Reply via email to