You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/11 19:20:54 UTC
[32/33] git commit: Revert "[KARAF-2852] Merge features/core and
features/command"
Revert "[KARAF-2852] Merge features/core and features/command"
This reverts commit 999f4970fecd3710da36b709f2d484cd0db38d09.
We actually need to split the commands from the core service
in order to avoid a refresh when the shell is installed.
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/0c8e8a81
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/0c8e8a81
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/0c8e8a81
Branch: refs/heads/master
Commit: 0c8e8a81e9d8103013f986604c5e840fe32cef5a
Parents: f2669e1
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Fri Apr 11 19:01:02 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Fri Apr 11 19:20:04 2014 +0200
----------------------------------------------------------------------
assemblies/apache-karaf/pom.xml | 2 +-
.../standard/src/main/feature/feature.xml | 1 +
features/command/NOTICE | 71 +
features/command/pom.xml | 90 ++
.../command/FeaturesCommandSupport.java | 42 +
.../features/command/InfoFeatureCommand.java | 290 ++++
.../features/command/InstallFeatureCommand.java | 69 +
.../command/ListFeatureVersionsCommand.java | 62 +
.../features/command/ListFeaturesCommand.java | 106 ++
.../karaf/features/command/RepoAddCommand.java | 54 +
.../karaf/features/command/RepoListCommand.java | 73 +
.../features/command/RepoRefreshCommand.java | 65 +
.../features/command/RepoRemoveCommand.java | 56 +
.../command/UninstallFeatureCommand.java | 62 +
.../command/completers/AllFeatureCompleter.java | 33 +
.../completers/AvailableFeatureCompleter.java | 33 +
.../completers/AvailableRepoNameCompleter.java | 48 +
.../completers/FeatureCompleterSupport.java | 65 +
.../completers/InstalledRepoNameCompleter.java | 58 +
.../completers/InstalledRepoUriCompleter.java | 59 +
.../completers/RequiredFeatureCompleter.java | 33 +
.../src/main/resources/OSGI-INF/bundle.info | 30 +
features/core/NOTICE | 71 +
features/core/pom.xml | 141 ++
.../org/apache/karaf/features/BootFinished.java | 24 +
.../org/apache/karaf/features/BundleInfo.java | 32 +
.../org/apache/karaf/features/Capability.java | 23 +
.../org/apache/karaf/features/Conditional.java | 35 +
.../apache/karaf/features/ConfigFileInfo.java | 27 +
.../org/apache/karaf/features/Dependency.java | 29 +
.../apache/karaf/features/EventConstants.java | 46 +
.../java/org/apache/karaf/features/Feature.java | 63 +
.../org/apache/karaf/features/FeatureEvent.java | 50 +
.../apache/karaf/features/FeaturesListener.java | 25 +
.../karaf/features/FeaturesNamespaces.java | 41 +
.../apache/karaf/features/FeaturesService.java | 104 ++
.../karaf/features/RegionsPersistence.java | 26 +
.../org/apache/karaf/features/Repository.java | 37 +
.../apache/karaf/features/RepositoryEvent.java | 50 +
.../org/apache/karaf/features/Requirement.java | 23 +
.../org/apache/karaf/features/Resolver.java | 25 +
.../internal/deployment/DeploymentBuilder.java | 354 +++++
.../internal/deployment/Downloader.java | 35 +
.../internal/deployment/StreamProvider.java | 26 +
.../management/FeaturesServiceMBeanImpl.java | 290 ++++
.../management/StandardEmitterMBean.java | 65 +
.../karaf/features/internal/model/Bundle.java | 198 +++
.../features/internal/model/Capability.java | 91 ++
.../features/internal/model/Conditional.java | 69 +
.../karaf/features/internal/model/Config.java | 110 ++
.../features/internal/model/ConfigFile.java | 136 ++
.../karaf/features/internal/model/Content.java | 199 +++
.../features/internal/model/Dependency.java | 121 ++
.../karaf/features/internal/model/Feature.java | 374 +++++
.../karaf/features/internal/model/Features.java | 155 ++
.../karaf/features/internal/model/JaxbUtil.java | 224 +++
.../features/internal/model/ObjectFactory.java | 111 ++
.../features/internal/model/Requirement.java | 87 ++
.../features/internal/model/package-info.java | 21 +
.../karaf/features/internal/osgi/Activator.java | 208 +++
.../repository/AggregateRepository.java | 55 +
.../internal/repository/BaseRepository.java | 86 ++
.../internal/repository/CacheRepository.java | 59 +
.../repository/HttpMetadataProvider.java | 88 ++
.../internal/repository/MetadataProvider.java | 29 +
.../internal/repository/MetadataRepository.java | 43 +
.../internal/repository/StaticRepository.java | 33 +
.../features/internal/resolver/BaseClause.java | 114 ++
.../internal/resolver/CandidateComparator.java | 129 ++
.../internal/resolver/CapabilityImpl.java | 165 ++
.../internal/resolver/CapabilitySet.java | 612 ++++++++
.../internal/resolver/FeatureNamespace.java | 72 +
.../internal/resolver/FeatureResource.java | 133 ++
.../internal/resolver/IdentityCapability.java | 63 +
.../internal/resolver/RequirementImpl.java | 80 +
.../internal/resolver/ResolveContextImpl.java | 102 ++
.../internal/resolver/ResourceBuilder.java | 1129 ++++++++++++++
.../internal/resolver/ResourceImpl.java | 110 ++
.../internal/resolver/ServiceNamespace.java | 30 +
.../internal/resolver/SimpleFilter.java | 649 ++++++++
.../internal/resolver/Slf4jResolverLog.java | 49 +
.../internal/resolver/UriNamespace.java | 47 +
.../features/internal/service/Artifact.java | 56 +
.../internal/service/BootFeaturesInstaller.java | 171 +++
.../internal/service/EventAdminListener.java | 91 ++
.../service/FeatureConfigInstaller.java | 167 +++
.../internal/service/FeatureFinder.java | 68 +
.../internal/service/FeatureValidationUtil.java | 37 +
.../internal/service/FeaturesServiceImpl.java | 1416 ++++++++++++++++++
.../features/internal/service/Overrides.java | 132 ++
.../internal/service/RepositoryImpl.java | 102 ++
.../internal/service/RequirementSort.java | 84 ++
.../internal/service/SimpleDownloader.java | 51 +
.../karaf/features/internal/service/State.java | 34 +
.../features/internal/service/StateStorage.java | 175 +++
.../features/internal/util/ChecksumUtils.java | 56 +
.../features/internal/util/JsonReader.java | 349 +++++
.../features/internal/util/JsonWriter.java | 120 ++
.../karaf/features/internal/util/Macro.java | 142 ++
.../features/internal/util/MultiException.java | 95 ++
.../management/FeaturesServiceMBean.java | 142 ++
.../features/management/codec/JmxFeature.java | 323 ++++
.../management/codec/JmxFeatureEvent.java | 80 +
.../management/codec/JmxRepository.java | 132 ++
.../management/codec/JmxRepositoryEvent.java | 77 +
.../src/main/resources/OSGI-INF/bundle.info | 20 +
.../karaf/features/karaf-features-1.0.0.xsd | 239 +++
.../karaf/features/karaf-features-1.1.0.xsd | 237 +++
.../karaf/features/karaf-features-1.2.0.xsd | 254 ++++
.../karaf/features/karaf-features-1.3.0.xsd | 280 ++++
.../apache/karaf/features/ConditionalTest.java | 54 +
.../org/apache/karaf/features/FeatureTest.java | 32 +
.../karaf/features/FeaturesServiceTest.java | 430 ++++++
.../apache/karaf/features/RepositoryTest.java | 140 ++
.../org/apache/karaf/features/TestBase.java | 105 ++
.../service/BootFeaturesInstallerTest.java | 93 ++
.../internal/service/BundleManagerTest.java | 64 +
.../service/FeaturesServiceImplTest.java | 167 +++
.../service/FeaturesValidationTest.java | 102 ++
.../internal/service/OverridesTest.java | 208 +++
.../karaf/features/internal/service/f01.xml | 92 ++
.../karaf/features/internal/service/f02.xml | 164 ++
.../karaf/features/internal/service/f03.xml | 27 +
.../karaf/features/internal/service/f04.xml | 28 +
.../karaf/features/internal/service/f05.xml | 28 +
.../karaf/features/internal/service/f06.xml | 36 +
.../karaf/features/internal/service/f07.xml | 35 +
.../internal/service/overrides.properties | 23 +
.../karaf/features/internal/service/repo2.xml | 41 +
.../org/apache/karaf/features/repo1.xml | 35 +
.../org/apache/karaf/features/repo2.xml | 37 +
.../org/apache/karaf/features/repo3.xml | 27 +
features/pom.xml | 127 +-
.../org/apache/karaf/features/BootFinished.java | 24 -
.../org/apache/karaf/features/BundleInfo.java | 32 -
.../org/apache/karaf/features/Capability.java | 23 -
.../org/apache/karaf/features/Conditional.java | 35 -
.../apache/karaf/features/ConfigFileInfo.java | 27 -
.../org/apache/karaf/features/Dependency.java | 29 -
.../apache/karaf/features/EventConstants.java | 46 -
.../java/org/apache/karaf/features/Feature.java | 63 -
.../org/apache/karaf/features/FeatureEvent.java | 50 -
.../apache/karaf/features/FeaturesListener.java | 25 -
.../karaf/features/FeaturesNamespaces.java | 41 -
.../apache/karaf/features/FeaturesService.java | 104 --
.../karaf/features/RegionsPersistence.java | 26 -
.../org/apache/karaf/features/Repository.java | 37 -
.../apache/karaf/features/RepositoryEvent.java | 50 -
.../org/apache/karaf/features/Requirement.java | 23 -
.../org/apache/karaf/features/Resolver.java | 25 -
.../command/FeaturesCommandSupport.java | 42 -
.../features/command/InfoFeatureCommand.java | 290 ----
.../features/command/InstallFeatureCommand.java | 69 -
.../command/ListFeatureVersionsCommand.java | 62 -
.../features/command/ListFeaturesCommand.java | 106 --
.../karaf/features/command/RepoAddCommand.java | 54 -
.../karaf/features/command/RepoListCommand.java | 73 -
.../features/command/RepoRefreshCommand.java | 65 -
.../features/command/RepoRemoveCommand.java | 56 -
.../command/UninstallFeatureCommand.java | 62 -
.../command/completers/AllFeatureCompleter.java | 33 -
.../completers/AvailableFeatureCompleter.java | 33 -
.../completers/AvailableRepoNameCompleter.java | 48 -
.../completers/FeatureCompleterSupport.java | 65 -
.../completers/InstalledRepoNameCompleter.java | 58 -
.../completers/InstalledRepoUriCompleter.java | 59 -
.../completers/RequiredFeatureCompleter.java | 33 -
.../internal/deployment/DeploymentBuilder.java | 354 -----
.../internal/deployment/Downloader.java | 35 -
.../internal/deployment/StreamProvider.java | 26 -
.../management/FeaturesServiceMBeanImpl.java | 290 ----
.../management/StandardEmitterMBean.java | 65 -
.../karaf/features/internal/model/Bundle.java | 198 ---
.../features/internal/model/Capability.java | 89 --
.../features/internal/model/Conditional.java | 69 -
.../karaf/features/internal/model/Config.java | 110 --
.../features/internal/model/ConfigFile.java | 136 --
.../karaf/features/internal/model/Content.java | 199 ---
.../features/internal/model/Dependency.java | 121 --
.../karaf/features/internal/model/Feature.java | 374 -----
.../karaf/features/internal/model/Features.java | 155 --
.../karaf/features/internal/model/JaxbUtil.java | 224 ---
.../features/internal/model/ObjectFactory.java | 111 --
.../features/internal/model/Requirement.java | 87 --
.../features/internal/model/package-info.java | 21 -
.../karaf/features/internal/osgi/Activator.java | 208 ---
.../repository/AggregateRepository.java | 55 -
.../internal/repository/BaseRepository.java | 86 --
.../internal/repository/CacheRepository.java | 59 -
.../repository/HttpMetadataProvider.java | 88 --
.../internal/repository/MetadataProvider.java | 29 -
.../internal/repository/MetadataRepository.java | 43 -
.../internal/repository/StaticRepository.java | 33 -
.../features/internal/resolver/BaseClause.java | 114 --
.../internal/resolver/CandidateComparator.java | 129 --
.../internal/resolver/CapabilityImpl.java | 165 --
.../internal/resolver/CapabilitySet.java | 612 --------
.../internal/resolver/FeatureNamespace.java | 72 -
.../internal/resolver/FeatureResource.java | 133 --
.../internal/resolver/IdentityCapability.java | 63 -
.../internal/resolver/RequirementImpl.java | 80 -
.../internal/resolver/ResolveContextImpl.java | 102 --
.../internal/resolver/ResourceBuilder.java | 1129 --------------
.../internal/resolver/ResourceImpl.java | 110 --
.../internal/resolver/ServiceNamespace.java | 30 -
.../internal/resolver/SimpleFilter.java | 649 --------
.../internal/resolver/Slf4jResolverLog.java | 49 -
.../internal/resolver/UriNamespace.java | 47 -
.../features/internal/service/Artifact.java | 56 -
.../internal/service/BootFeaturesInstaller.java | 170 ---
.../internal/service/EventAdminListener.java | 91 --
.../service/FeatureConfigInstaller.java | 167 ---
.../internal/service/FeatureFinder.java | 68 -
.../internal/service/FeatureValidationUtil.java | 37 -
.../internal/service/FeaturesServiceImpl.java | 1416 ------------------
.../features/internal/service/Overrides.java | 132 --
.../internal/service/RepositoryImpl.java | 102 --
.../internal/service/RequirementSort.java | 84 --
.../internal/service/SimpleDownloader.java | 51 -
.../karaf/features/internal/service/State.java | 34 -
.../features/internal/service/StateStorage.java | 174 ---
.../features/internal/util/ChecksumUtils.java | 56 -
.../features/internal/util/JsonReader.java | 349 -----
.../features/internal/util/JsonWriter.java | 120 --
.../karaf/features/internal/util/Macro.java | 142 --
.../features/internal/util/MultiException.java | 95 --
.../management/FeaturesServiceMBean.java | 142 --
.../features/management/codec/JmxFeature.java | 323 ----
.../management/codec/JmxFeatureEvent.java | 80 -
.../management/codec/JmxRepository.java | 132 --
.../management/codec/JmxRepositoryEvent.java | 77 -
.../src/main/resources/OSGI-INF/bundle.info | 20 -
.../karaf/features/karaf-features-1.0.0.xsd | 239 ---
.../karaf/features/karaf-features-1.1.0.xsd | 237 ---
.../karaf/features/karaf-features-1.2.0.xsd | 254 ----
.../karaf/features/karaf-features-1.3.0.xsd | 280 ----
.../apache/karaf/features/ConditionalTest.java | 54 -
.../org/apache/karaf/features/FeatureTest.java | 32 -
.../karaf/features/FeaturesServiceTest.java | 429 ------
.../apache/karaf/features/RepositoryTest.java | 140 --
.../org/apache/karaf/features/TestBase.java | 105 --
.../service/BootFeaturesInstallerTest.java | 93 --
.../internal/service/BundleManagerTest.java | 64 -
.../service/FeaturesServiceImplTest.java | 167 ---
.../service/FeaturesValidationTest.java | 102 --
.../internal/service/OverridesTest.java | 202 ---
.../karaf/features/internal/service/f01.xml | 92 --
.../karaf/features/internal/service/f02.xml | 164 --
.../karaf/features/internal/service/f03.xml | 27 -
.../karaf/features/internal/service/f04.xml | 28 -
.../karaf/features/internal/service/f05.xml | 28 -
.../karaf/features/internal/service/f06.xml | 36 -
.../karaf/features/internal/service/f07.xml | 35 -
.../internal/service/overrides.properties | 23 -
.../karaf/features/internal/service/repo2.xml | 41 -
.../org/apache/karaf/features/repo1.xml | 35 -
.../org/apache/karaf/features/repo2.xml | 37 -
.../org/apache/karaf/features/repo3.xml | 27 -
instance/pom.xml | 2 +-
kar/pom.xml | 2 +-
pom.xml | 5 +
261 files changed, 16137 insertions(+), 15828 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index ce631b8..a799b0a 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -161,8 +161,8 @@
</installedFeatures>
<bootFeatures>
<feature>aries-blueprint</feature>
- <feature>shell-compat</feature>
<feature>shell</feature>
+ <feature>shell-compat</feature>
<feature>jaas</feature>
<feature>ssh</feature>
<feature>management</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 86f8270..5e3fd11 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -73,6 +73,7 @@
<bundle dependency="true" start-level="30">mvn:org.jledit/core/${jledit.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.shell/org.apache.karaf.shell.core/${project.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.shell/org.apache.karaf.shell.commands/${project.version}</bundle>
+ <bundle start-level="30">mvn:org.apache.karaf.features/org.apache.karaf.features.command/${project.version}</bundle>
</feature>
<feature name="shell-compat" description="Karaf Shell Compatibility" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/NOTICE
----------------------------------------------------------------------
diff --git a/features/command/NOTICE b/features/command/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/features/command/NOTICE
@@ -0,0 +1,71 @@
+Apache Karaf
+Copyright 2010-2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+OW2 (http://www.ow2.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+OPS4J (http://www.ops4j.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Eclipse Foundation (http://www.eclipse.org/).
+Licensed under the EPL.
+
+This product includes software written by
+Antony Lesuisse.
+Licensed under Public Domain.
+
+
+II. Used Software
+
+This product uses software developed at
+FUSE Source (http://www.fusesource.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+AOP Alliance (http://aopalliance.sourceforge.net/).
+Licensed under the Public Domain.
+
+This product uses software developed at
+Tanuki Software (http://www.tanukisoftware.com/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+Jasypt (http://jasypt.sourceforge.net/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JLine (http://jline.sourceforge.net).
+Licensed under the BSD License.
+
+This product uses software developed at
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product uses software developed at
+SpringSource (http://www.springsource.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software from http://www.json.org.
+Copyright (c) 2002 JSON.org
+
+
+III. License Summary
+- Apache License 2.0
+- BSD License
+- EPL License
+- MIT License
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/pom.xml
----------------------------------------------------------------------
diff --git a/features/command/pom.xml b/features/command/pom.xml
new file mode 100644
index 0000000..4f49bb1
--- /dev/null
+++ b/features/command/pom.xml
@@ -0,0 +1,90 @@
+<?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.features</groupId>
+ <artifactId>features</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.karaf.features.command</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Features :: Command</name>
+ <description>This bundle provides the Karaf shell commands to manipulate features.</description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.info</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Karaf-Commands>org.apache.karaf.features.command.*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java b/features/command/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
new file mode 100644
index 0000000..076650d
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
@@ -0,0 +1,42 @@
+/*
+ * 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.features.command;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+
+public abstract class FeaturesCommandSupport implements Action {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ @Override
+ public Object execute() throws Exception {
+ if (featuresService == null) {
+ throw new IllegalStateException("FeaturesService not found");
+ }
+ doExecute(featuresService);
+ return null;
+ }
+
+ protected abstract void doExecute(FeaturesService admin) throws Exception;
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
new file mode 100644
index 0000000..5ad855c
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
@@ -0,0 +1,290 @@
+/*
+ * 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.features.command;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Conditional;
+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.command.completers.AllFeatureCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "info", description = "Shows information about selected feature.")
+@Service
+public class InfoFeatureCommand extends FeaturesCommandSupport {
+
+ private static final String INDENT = " ";
+ private static final String FEATURE_CONTENT = "Feature";
+ private static final String CONDITIONAL_CONTENT = "Conditional(%s)";
+
+ @Argument(index = 0, name = "name", description = "The name of the feature", required = true, multiValued = false)
+ @Completion(AllFeatureCompleter.class)
+ private String name;
+
+ @Argument(index = 1, name = "version", description = "The version of the feature", required = false, multiValued = false)
+ private String version;
+
+ @Option(name = "-c", aliases={"--configuration"}, description="Display configuration info", required = false, multiValued = false)
+ private boolean config;
+
+ @Option(name = "-d", aliases={"--dependency"}, description="Display dependencies info", required = false, multiValued = false)
+ private boolean dependency;
+
+ @Option(name = "-b", aliases={"--bundle"}, description="Display bundles info", required = false, multiValued = false)
+ private boolean bundle;
+
+ @Option(name = "--conditional", description="Display conditional info", required = false, multiValued = false)
+ private boolean conditional;
+
+ @Option(name = "-t", aliases={"--tree"}, description="Display feature tree", required = false, multiValued = false)
+ private boolean tree;
+
+ protected void doExecute(FeaturesService admin) throws Exception {
+ Feature feature = null;
+
+ if (version != null && version.length() > 0) {
+ feature = admin.getFeature(name, version);
+ } else {
+ feature = admin.getFeature(name);
+ }
+
+ if (feature == null) {
+ System.out.println("Feature not found");
+ return;
+ }
+
+ // default behavior
+ if (!config && !dependency && !bundle && !conditional) {
+ config = true;
+ dependency = true;
+ bundle = true;
+ conditional = true;
+ }
+
+ System.out.println("Feature " + feature.getName() + " " + feature.getVersion());
+ if (feature.getDescription() != null) {
+ System.out.println("Description:");
+ System.out.println(INDENT + feature.getDescription());
+ }
+
+ if(feature.getDetails() != null) {
+ System.out.println("Details:");
+ printWithIndent(feature.getDetails());
+ }
+
+ if (config) {
+ displayConfigInformation(feature, FEATURE_CONTENT);
+ displayConfigFileInformation(feature, FEATURE_CONTENT);
+ }
+
+ if (dependency) {
+ displayDependencyInformation(feature, FEATURE_CONTENT);
+ }
+
+ if (bundle) {
+ displayBundleInformation(feature, FEATURE_CONTENT);
+ }
+
+ if(conditional) {
+ displayConditionalInfo(feature);
+ }
+
+ if (tree) {
+ if (config || dependency || bundle) {
+ System.out.println("\nFeature tree");
+ }
+
+ int unresolved = displayFeatureTree(admin, feature.getName(), feature.getVersion(), "");
+ if (unresolved > 0) {
+ System.out.println("Tree contains " + unresolved + " unresolved dependencies");
+ System.out.println(" * means that node declares dependency but the dependent feature is not available.");
+ }
+ }
+ }
+
+ private void printWithIndent(String details) {
+ String[] lines = details.split("\r?\n");
+ for (String line : lines) {
+ System.out.println(INDENT + line);
+ }
+ }
+
+ private void displayBundleInformation(Feature feature, String contentType) {
+ List<BundleInfo> bundleInfos = feature.getBundles();
+ if (bundleInfos.isEmpty()) {
+ System.out.println(contentType + " has no bundles.");
+ } else {
+ System.out.println(contentType + " contains followed bundles:");
+ for (BundleInfo featureBundle : bundleInfos) {
+ int startLevel = featureBundle.getStartLevel();
+ StringBuilder sb = new StringBuilder();
+ sb.append(INDENT).append(featureBundle.getLocation());
+ if(startLevel > 0) {
+ sb.append(" start-level=").append(startLevel);
+ }
+ System.out.println(sb.toString());
+ }
+ }
+ }
+
+ private void displayDependencyInformation(Feature feature, String contentType) {
+ List<Dependency> dependencies = feature.getDependencies();
+ if (dependencies.isEmpty()) {
+ System.out.println(contentType + " has no dependencies.");
+ } else {
+ System.out.println(contentType + " depends on:");
+ for (Dependency featureDependency : dependencies) {
+ System.out.println(INDENT + featureDependency.getName() + " " + featureDependency.getVersion());
+ }
+ }
+ }
+
+ private void displayConfigInformation(Feature feature, String contentType) {
+ Map<String, Map<String, String>> configurations = feature.getConfigurations();
+ if (configurations.isEmpty()) {
+ System.out.println(contentType + " has no configuration");
+ } else {
+ System.out.println(contentType + " configuration:");
+ for (String name : configurations.keySet()) {
+ System.out.println(INDENT + name);
+ }
+ }
+ }
+
+ private void displayConfigFileInformation(Feature feature, String contentType) {
+ List<ConfigFileInfo> configurationFiles = feature.getConfigurationFiles();
+ if (configurationFiles.isEmpty()) {
+ System.out.println(contentType + " has no configuration files");
+ } else {
+ System.out.println(contentType + " configuration files: ");
+ for (ConfigFileInfo configFileInfo : configurationFiles) {
+ System.out.println(INDENT + configFileInfo.getFinalname());
+ }
+ }
+ }
+
+ /**
+ * Called originally with featureName and featureVersion that have already been resolved successfully.
+ *
+ * @param admin
+ * @param featureName
+ * @param featureVersion
+ * @param prefix
+ * @return
+ * @throws Exception
+ */
+ private int displayFeatureTree(FeaturesService admin, String featureName, String featureVersion, String prefix) throws Exception {
+ int unresolved = 0;
+
+ Feature resolved = admin.getFeature(featureName, featureVersion);
+ if (resolved != null) {
+ System.out.println(prefix + " " + resolved.getName() + " " + resolved.getVersion());
+ } else {
+ System.out.println(prefix + " " + featureName + " " + featureVersion + " *");
+ unresolved++;
+ }
+
+ if (resolved != null) {
+ if (bundle) {
+ List<String> bundleLocation = new LinkedList<String>();
+ List<BundleInfo> bundles = resolved.getBundles();
+ for (BundleInfo bundleInfo : bundles) {
+ bundleLocation.add(bundleInfo.getLocation());
+ }
+
+ if (conditional) {
+ for (Conditional cond : resolved.getConditional()) {
+ List<String> condition = cond.getCondition();
+ List<BundleInfo> conditionalBundles = cond.getBundles();
+ for (BundleInfo bundleInfo : conditionalBundles) {
+ bundleLocation.add(bundleInfo.getLocation() + "(condition:"+condition+")");
+ }
+ }
+ }
+ for (int i = 0, j = bundleLocation.size(); i < j; i++) {
+ System.out.println(prefix + " " + (i + 1 == j ? "\\" : "+") + " " + bundleLocation.get(i));
+ }
+ }
+ prefix += " ";
+ List<Dependency> dependencies = resolved.getDependencies();
+ for (int i = 0, j = dependencies.size(); i < j; i++) {
+ Dependency toDisplay = dependencies.get(i);
+ unresolved += displayFeatureTree(admin, toDisplay.getName(), toDisplay.getVersion(), prefix +1);
+ }
+
+ if (conditional) {
+ for (Conditional cond : resolved.getConditional()) {
+ List<Dependency> conditionDependencies = cond.getDependencies();
+ for (int i = 0, j = conditionDependencies.size(); i < j; i++) {
+ Dependency toDisplay = dependencies.get(i);
+ unresolved += displayFeatureTree(admin, toDisplay.getName(), toDisplay.getVersion(), prefix +1);
+ }
+ }
+ }
+ }
+
+ return unresolved;
+ }
+
+ private void displayConditionalInfo(Feature feature) {
+ List<? extends Conditional> conditionals = feature.getConditional();
+ if (conditionals.isEmpty()) {
+ System.out.println("Feature has no conditionals.");
+ } else {
+ System.out.println("Feature contains followed conditionals:");
+ for (Conditional featureConditional : conditionals) {
+ String conditionDescription = getConditionDescription(featureConditional);
+ Feature wrappedConditional = featureConditional.asFeature(feature.getName(), feature.getVersion());
+ if (config) {
+ displayConfigInformation(wrappedConditional, String.format(CONDITIONAL_CONTENT, conditionDescription));
+ displayConfigFileInformation(wrappedConditional, String.format(CONDITIONAL_CONTENT, conditionDescription));
+ }
+
+ if (dependency) {
+ displayDependencyInformation(wrappedConditional, String.format(CONDITIONAL_CONTENT, conditionDescription));
+ }
+
+ if (bundle) {
+ displayBundleInformation(wrappedConditional, String.format(CONDITIONAL_CONTENT, conditionDescription));
+ }
+ }
+ }
+ }
+
+ private String getConditionDescription(Conditional cond) {
+ StringBuffer sb = new StringBuffer();
+ for (String dep : cond.getCondition()) {
+ if (sb.length() > 0) {
+ sb.append(" ");
+ }
+ sb.append(dep);
+ }
+ return sb.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
new file mode 100644
index 0000000..b7f8184
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.features.command;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.command.completers.AvailableFeatureCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "install", description = "Installs a feature with the specified name and version.")
+@Service
+public class InstallFeatureCommand extends FeaturesCommandSupport {
+
+ private static String DEFAULT_VERSION = "0.0.0";
+
+ @Argument(index = 0, name = "feature", description = "The name and version of the features to install. A feature id looks like name/version. The version is optional.", required = true, multiValued = true)
+ @Completion(AvailableFeatureCompleter.class)
+ List<String> features;
+
+ @Option(name = "-r", aliases = "--no-auto-refresh", description = "Do not automatically refresh bundles", required = false, multiValued = false)
+ boolean noRefresh;
+
+ @Option(name = "-s", aliases = "--no-auto-start", description = "Do not start the bundles", required = false, multiValued = false)
+ boolean noStart;
+
+ @Option(name = "-v", aliases = "--verbose", description = "Explain what is being done", required = false, multiValued = false)
+ boolean verbose;
+
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only", required = false, multiValued = false)
+ boolean simulate;
+
+ protected void doExecute(FeaturesService admin) throws Exception {
+ EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
+ if (noStart) {
+ options.add(FeaturesService.Option.NoAutoStartBundles);
+ }
+ if (noRefresh) {
+ options.add(FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (verbose) {
+ options.add(FeaturesService.Option.Verbose);
+ }
+ admin.installFeatures(new HashSet<String>(features), options);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
new file mode 100644
index 0000000..b2c5e42
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
@@ -0,0 +1,62 @@
+/*
+ * 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.features.command;
+
+import java.util.Arrays;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.command.completers.AllFeatureCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "feature", name = "version-list", description = "Lists all versions of a feature available from the currently available repositories.")
+@Service
+public class ListFeatureVersionsCommand extends FeaturesCommandSupport {
+
+ @Argument(index = 0, name = "feature", description = "Name of feature.", required = true, multiValued = false)
+ @Completion(AllFeatureCompleter.class)
+ String feature;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected void doExecute(FeaturesService admin) throws Exception {
+ ShellTable table = new ShellTable();
+ table.column("Version");
+ table.column("Repository");
+ table.column("Repository URL");
+ table.emptyTableText("No versions available for features '" + feature + "'");
+
+ for (Repository r : Arrays.asList(admin.listRepositories())) {
+ for (Feature f : r.getFeatures()) {
+
+ if (f.getName().equals(feature)) {
+ table.addRow().addContent(f.getVersion(), r.getName(), r.getURI());
+ }
+ }
+ }
+
+ table.print(System.out, !noFormat);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
new file mode 100644
index 0000000..e86ff64
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
@@ -0,0 +1,106 @@
+/*
+ * 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.features.command;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "feature", name = "list", description = "Lists all existing features available from the defined repositories.")
+@Service
+public class ListFeaturesCommand extends FeaturesCommandSupport {
+
+ @Option(name = "-i", aliases = {"--installed"}, description = "Display a list of all installed features only", required = false, multiValued = false)
+ boolean onlyInstalled;
+
+ @Option(name = "-r", aliases = {"--required"}, description = "Display a list of all required features only", required = false, multiValued = false)
+ boolean onlyRequired;
+
+ @Option(name = "-o", aliases = {"--ordered"}, description = "Display a list using alphabetical order ", required = false, multiValued = false)
+ boolean ordered;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected void doExecute(FeaturesService featuresService) throws Exception {
+ boolean needsLegend = false;
+
+ ShellTable table = new ShellTable();
+ table.column("Name");
+ table.column("Version");
+ table.column("Required");
+ table.column("Installed");
+ table.column("Repository");
+ table.column("Description").maxSize(50);
+ table.emptyTableText(onlyInstalled ? "No features installed" : "No features available");
+
+ List<Repository> repos = Arrays.asList(featuresService.listRepositories());
+ for (Repository r : repos) {
+ List<Feature> features = Arrays.asList(r.getFeatures());
+ if (ordered) {
+ Collections.sort(features, new FeatureComparator());
+ }
+ for (Feature f : features) {
+ if (onlyInstalled && !featuresService.isInstalled(f)) {
+ // Filter out not installed features if we only want to see the installed ones
+ continue;
+ }
+ if (onlyRequired && !featuresService.isRequired(f)) {
+ // Filter out not installed features if we only want to see the installed ones
+ continue;
+ }
+ table.addRow().addContent(
+ f.getName(),
+ f.getVersion(),
+ featuresService.isRequired(f) ? "x" : "",
+ featuresService.isInstalled(f) ? "x" : "",
+ r.getName(),
+ f.getDescription());
+ if (isInstalledViaDeployDir(r.getName())) {
+ needsLegend = true;
+ }
+ }
+ }
+
+ table.print(System.out, !noFormat);
+
+ if (needsLegend) {
+ System.out.println("* Installed via deploy directory");
+ }
+
+ }
+
+ private boolean isInstalledViaDeployDir(String st) {
+ return (st == null || st.length() <= 1) ? false : (st.charAt(st.length() - 1) == '*');
+ }
+
+ class FeatureComparator implements Comparator<Feature> {
+ public int compare(Feature o1, Feature o2) {
+ return o1.getName().toLowerCase().compareTo( o2.getName().toLowerCase() );
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
new file mode 100644
index 0000000..16faf42
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
@@ -0,0 +1,54 @@
+/*
+ * 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.features.command;
+
+import java.net.URI;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.command.completers.AvailableRepoNameCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "repo-add", description = "Add a features repository")
+@Service
+public class RepoAddCommand extends FeaturesCommandSupport {
+
+ @Argument(index = 0, name = "name/url", description = "Shortcut name of the features repository or the full URL", required = true, multiValued = false)
+ @Completion(AvailableRepoNameCompleter.class)
+ private String nameOrUrl;
+
+ @Argument(index = 1, name = "version", description = "The version of the features repository if using features repository name as first argument. It should be empty if using the URL", required = false, multiValued = false)
+ private String version;
+
+ @Option(name = "-i", aliases = { "--install" }, description = "Install all features contained in the features repository", required = false, multiValued = false)
+ private boolean install;
+
+ @Override
+ protected void doExecute(FeaturesService featuresService) throws Exception {
+ String effectiveVersion = (version == null) ? "LATEST" : version;
+ URI uri = featuresService.getRepositoryUriFor(nameOrUrl, effectiveVersion);
+ if (uri == null) {
+ uri = new URI(nameOrUrl);
+ }
+ System.out.println("Adding feature url " + uri);
+ featuresService.addRepository(uri, install);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RepoListCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
new file mode 100644
index 0000000..55acf79
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
@@ -0,0 +1,73 @@
+/*
+ * 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.features.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.MultiException;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "feature", name = "repo-list", description = "Displays a list of all defined repositories.")
+@Service
+public class RepoListCommand extends FeaturesCommandSupport {
+
+ @Option(name="-r", description="Reload all feature urls", required = false, multiValued = false)
+ boolean reload;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected void doExecute(FeaturesService featuresService) throws Exception {
+ if (reload) {
+ reloadAllRepos(featuresService);
+ }
+
+ ShellTable table = new ShellTable();
+ table.column("Repository");
+ table.column("URL");
+ table.emptyTableText("No repositories available");
+
+ Repository[] repos = featuresService.listRepositories();
+ for (Repository repo : repos) {
+ if (repo != null) {
+ table.addRow().addContent(repo.getName(), repo.getURI().toString());
+ }
+ }
+ table.print(System.out, !noFormat);
+ }
+
+ private void reloadAllRepos(FeaturesService featuresService) throws Exception {
+ System.out.println("Reloading all repositories from their urls");
+ System.out.println();
+ List<Exception> exceptions = new ArrayList<Exception>();
+ for (Repository repo : featuresService.listRepositories()) {
+ try {
+ featuresService.addRepository(repo.getURI());
+ } catch (Exception e) {
+ exceptions.add(e);
+ }
+ }
+ MultiException.throwIf("Unable to reload repositories", exceptions);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
new file mode 100644
index 0000000..8c7ed79
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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.features.command;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.command.completers.InstalledRepoUriCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+
+@Command(scope = "feature", name = "repo-refresh", description = "Refresh a features repository")
+public class RepoRefreshCommand extends FeaturesCommandSupport {
+ @Argument(index = 0, name = "Feature name or uri", description = "Shortcut name of the feature repository or the full URI", required = false, multiValued = false)
+ @Completion(InstalledRepoUriCompleter.class)
+ private String nameOrUrl;
+
+ @Argument(index = 1, name = "Feature version", description = "The version of the feature if using the feature name. Should be empty if using the uri", required = false, multiValued = false)
+ private String version;
+
+ @Override
+ protected void doExecute(FeaturesService featuresService) throws Exception {
+ List<URI> uris = new ArrayList<URI>();
+ if (nameOrUrl != null) {
+ String effectiveVersion = (version == null) ? "LATEST" : version;
+ URI uri = featuresService.getRepositoryUriFor(nameOrUrl, effectiveVersion);
+ if (uri == null) {
+ uri = new URI(nameOrUrl);
+ }
+ uris.add(uri);
+ } else {
+ Repository[] repos = featuresService.listRepositories();
+ for (Repository repo : repos) {
+ uris.add(repo.getURI());
+ }
+ }
+ for (URI uri : uris) {
+ try {
+ System.out.println("Refreshing feature url " + uri);
+ featuresService.refreshRepository(uri);
+ } catch (Exception e) {
+ System.err.println("Error refreshing " + uri.toString() + ": " + e.getMessage());
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
new file mode 100644
index 0000000..0710b72
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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.features.command;
+
+import java.net.URI;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.command.completers.InstalledRepoNameCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "repo-remove", description = "Removes the specified repository features service.")
+@Service
+public class RepoRemoveCommand extends FeaturesCommandSupport {
+
+ @Argument(index = 0, name = "repository", description = "Name or url of the repository to remove.", required = true, multiValued = false)
+ @Completion(InstalledRepoNameCompleter.class)
+ private String repository;
+
+ @Option(name = "-u", aliases = { "--uninstall-all" }, description = "Uninstall all features from the repository", required = false, multiValued = false)
+ private boolean uninstall;
+
+ protected void doExecute(FeaturesService featuresService) throws Exception {
+ URI uri = null;
+ for (Repository r : featuresService.listRepositories()) {
+ if (r.getName() != null && r.getName().equals(repository)) {
+ uri = r.getURI();
+ break;
+ }
+ }
+
+ if (uri == null) {
+ uri = new URI(repository);
+ }
+
+ featuresService.removeRepository(uri, uninstall);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
new file mode 100644
index 0000000..e62f697
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
@@ -0,0 +1,62 @@
+/*
+ * 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.features.command;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.command.completers.RequiredFeatureCompleter;
+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;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "feature", name = "uninstall", description = "Uninstalls a feature with the specified name and version.")
+@Service
+public class UninstallFeatureCommand extends FeaturesCommandSupport {
+
+ @Argument(index = 0, name = "features", description = "The name and version of the features to uninstall. A feature id looks like name/version. The version is optional.", required = true, multiValued = true)
+ @Completion(RequiredFeatureCompleter.class)
+ List<String> features;
+
+ @Option(name = "-r", aliases = "--no-auto-refresh", description = "Do not automatically refresh bundles", required = false, multiValued = false)
+ boolean noRefresh;
+
+ @Option(name = "-v", aliases = "--verbose", description = "Explain what is being done", required = false, multiValued = false)
+ boolean verbose;
+
+ @Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only", required = false, multiValued = false)
+ boolean simulate;
+
+ protected void doExecute(FeaturesService admin) throws Exception {
+ // iterate in the provided feature
+ EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
+ if (simulate) {
+ options.add(FeaturesService.Option.Simulate);
+ }
+ if (noRefresh) {
+ options.add(FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (verbose) {
+ options.add(FeaturesService.Option.Verbose);
+ }
+ admin.uninstallFeatures(new HashSet<String>(features), options);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
new file mode 100644
index 0000000..7444b95
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.features.command.completers;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * {@link org.apache.karaf.shell.console.Completer} for available features.
+ */
+@Service
+public class AllFeatureCompleter extends FeatureCompleterSupport {
+
+ @Override
+ protected boolean acceptsFeature(Feature feature) {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
new file mode 100644
index 0000000..79cd280
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.features.command.completers;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * {@link org.apache.karaf.shell.console.Completer} for features not installed yet.
+ */
+@Service
+public class AvailableFeatureCompleter extends FeatureCompleterSupport {
+
+ @Override
+ protected boolean acceptsFeature(Feature feature) {
+ return !featuresService.isInstalled(feature);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
new file mode 100644
index 0000000..acefe77
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
@@ -0,0 +1,48 @@
+/*
+ * 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.features.command.completers;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+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;
+
+/**
+ * Shows the list of feature repos that can be installed with their short name
+ */
+@Service
+public class AvailableRepoNameCompleter implements Completer {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+ public int complete(Session session, CommandLine commandLine, final List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter(Arrays.asList(featuresService.getRepositoryNames()));
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
new file mode 100644
index 0000000..d01e5af
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
@@ -0,0 +1,65 @@
+/*
+ * 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.features.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+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;
+
+/**
+ * Base completer for feature commands.
+ */
+public abstract class FeatureCompleterSupport implements Completer {
+
+ /**
+ * Feature service.
+ */
+ @Reference
+ protected FeaturesService featuresService;
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+ public int complete(Session session, final CommandLine commandLine, final List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ for (Feature feature : featuresService.listFeatures()) {
+ if (acceptsFeature(feature)) {
+ delegate.getStrings().add(feature.getName());
+ }
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ /**
+ * Method for filtering features.
+ *
+ * @param feature The feature.
+ * @return True if feature should be available in completer.
+ */
+ protected abstract boolean acceptsFeature(Feature feature);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
new file mode 100644
index 0000000..94e4cf7
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.features.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+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;
+
+/**
+ * {@link Completer} for Feature Repository URLs.
+ *
+ * Displays a list of currently installed Feature repositories.
+ *
+ */
+@Service
+public class InstalledRepoNameCompleter implements Completer {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+ public int complete(Session session, final CommandLine commandLine, final List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ for (Repository repository : featuresService.listRepositories()) {
+ delegate.getStrings().add(repository.getName());
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
new file mode 100644
index 0000000..7a760c2
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
@@ -0,0 +1,59 @@
+/*
+ * 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.features.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+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;
+
+/**
+ * {@link Completer} for Feature Repository URLs.
+ *
+ * Displays a list of currently installed Feature repositories.
+ *
+ */
+
+@Service
+public class InstalledRepoUriCompleter implements Completer {
+
+ @Reference
+ private FeaturesService featuresService;
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+ public int complete(Session session, final CommandLine commandLine, final List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ for (Repository repository : featuresService.listRepositories()) {
+ delegate.getStrings().add(repository.getURI().toString());
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java b/features/command/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
new file mode 100644
index 0000000..a51f75f
--- /dev/null
+++ b/features/command/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.features.command.completers;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * {@link org.apache.karaf.shell.console.Completer} for installed features.
+ */
+@Service
+public class RequiredFeatureCompleter extends FeatureCompleterSupport {
+
+ @Override
+ protected boolean acceptsFeature(Feature feature) {
+ return featuresService.isRequired(feature);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/features/command/src/main/resources/OSGI-INF/bundle.info b/features/command/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..8f0598b
--- /dev/null
+++ b/features/command/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,30 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle provides the Karaf shell commands to manipulate features.
+
+The following commands are available:
+
+* features:addUrl - Adds a list of repository URLs to the features service.
+* features:info- Shows information about selected information.
+* features:install- Installs a feature with the specified name and version.
+* features:list - Lists all existing features available from the defined repositories.
+* features:listVersions- Lists all versions of a feature available from the currently available repositories.
+* features:listRepositories- Displays a list of all defined repositories.
+* features:listUrl- Displays a list of all defined repository URLs.
+* features:refreshUrl- Reloads the list of available features from the repositories.
+* features:removeRepository- Removes the specified repository features service.
+* features:removeUrl- Removes the given list of repository URLs from the features service.
+* features:uninstall- Uninstalls a feature with the specified name and version.
+
+h1. See also
+
+Commands- and Provisioning- sections of the Karaf User Guide.
http://git-wip-us.apache.org/repos/asf/karaf/blob/0c8e8a81/features/core/NOTICE
----------------------------------------------------------------------
diff --git a/features/core/NOTICE b/features/core/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/features/core/NOTICE
@@ -0,0 +1,71 @@
+Apache Karaf
+Copyright 2010-2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+OW2 (http://www.ow2.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+OPS4J (http://www.ops4j.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Eclipse Foundation (http://www.eclipse.org/).
+Licensed under the EPL.
+
+This product includes software written by
+Antony Lesuisse.
+Licensed under Public Domain.
+
+
+II. Used Software
+
+This product uses software developed at
+FUSE Source (http://www.fusesource.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+AOP Alliance (http://aopalliance.sourceforge.net/).
+Licensed under the Public Domain.
+
+This product uses software developed at
+Tanuki Software (http://www.tanukisoftware.com/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+Jasypt (http://jasypt.sourceforge.net/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JLine (http://jline.sourceforge.net).
+Licensed under the BSD License.
+
+This product uses software developed at
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product uses software developed at
+SpringSource (http://www.springsource.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software from http://www.json.org.
+Copyright (c) 2002 JSON.org
+
+
+III. License Summary
+- Apache License 2.0
+- BSD License
+- EPL License
+- MIT License