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/10 16:15:23 UTC
[01/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Repository: karaf
Updated Branches:
refs/heads/master 025a8ec93 -> 48ef3aa01
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
new file mode 100644
index 0000000..bed8104
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.internal.service;
+
+import org.apache.karaf.features.TestBase;
+
+public class BundleManagerTest extends TestBase {
+
+ /*
+ @Test
+ public void testfindBundlestoRefreshWithHostToRefresh() throws Exception {
+ Bundle hostBundle = createDummyBundle(12345l, "Host", headers());
+ Bundle fragmentBundle = createDummyBundle(54321l, "fragment", headers(Constants.FRAGMENT_HOST, "Host"));
+
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ BundleManager bundleManager = new BundleManager(bundleContext);
+
+ // Host was already installed, fragment is new
+ Set<Bundle> existing = new HashSet<Bundle>(Arrays.asList(hostBundle, fragmentBundle));
+ Set<Bundle> installed = new HashSet<Bundle>(Arrays.asList(fragmentBundle));
+
+ replay(bundleContext);
+ Set<Bundle> bundles = bundleManager.findBundlesWithFragmentsToRefresh(existing, installed);
+ EasyMock.verify(bundleContext);
+
+ Assert.assertEquals(1, bundles.size());
+ Assert.assertEquals(hostBundle, bundles.iterator().next());
+ }
+
+ @Test
+ public void testfindBundlestoRefreshWithOptionalPackages() throws Exception {
+ Bundle exporterBundle = createDummyBundle(12345l, "exporter", headers(Constants.EXPORT_PACKAGE, "org.my.package"));
+ Bundle importerBundle = createDummyBundle(54321l, "importer", headers(Constants.IMPORT_PACKAGE, "org.my.package;resolution:=optional"));
+
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ BundleManager bundleManager = new BundleManager(bundleContext);
+
+ // Importer was already installed, exporter is new
+ Set<Bundle> existing = new HashSet<Bundle>(Arrays.asList(importerBundle, exporterBundle));
+ Set<Bundle> installed = new HashSet<Bundle>(Arrays.asList(exporterBundle));
+
+ replay(bundleContext);
+ Set<Bundle> bundles = bundleManager.findBundlesWithOptionalPackagesToRefresh(existing, installed);
+ EasyMock.verify(bundleContext);
+
+ Assert.assertEquals(1, bundles.size());
+ Assert.assertEquals(importerBundle, bundles.iterator().next());
+ }
+ */
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
new file mode 100644
index 0000000..b8b5fc0
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.internal.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.TestBase;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link org.apache.karaf.features.internal.service.FeaturesServiceImpl}
+ */
+public class FeaturesServiceImplTest extends TestBase {
+
+ File dataFile;
+
+ @Before
+ public void setUp() throws IOException {
+ dataFile = File.createTempFile("features", null, null);
+ }
+
+ @Test
+ public void testGetFeature() throws Exception {
+ Feature transactionFeature = feature("transaction", "1.0.0");
+ final Map<String, Map<String, Feature>> features = features(transactionFeature);
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+ protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
+ return features;
+ }
+ };
+ assertNotNull(impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
+ assertSame(transactionFeature, impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
+ }
+
+ @Test
+ public void testGetFeatureStripVersion() throws Exception {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+ protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
+ return features(feature("transaction", "1.0.0"));
+ }
+ };
+ Feature feature = impl.getFeature("transaction", " 1.0.0 ");
+ assertNotNull(feature);
+ assertSame("transaction", feature.getName());
+ }
+
+ @Test
+ public void testGetFeatureNotAvailable() throws Exception {
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+ protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
+ return features(feature("transaction", "1.0.0"));
+ }
+ };
+ assertNull(impl.getFeature("activemq", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
+ }
+
+ @Test
+ public void testGetFeatureHighestAvailable() throws Exception {
+ final Map<String, Map<String, Feature>> features = features(
+ feature("transaction", "1.0.0"),
+ feature("transaction", "2.0.0")
+ );
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+ protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
+ return features;
+ }
+ };
+ assertNotNull(impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
+ assertSame("2.0.0", impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION).getVersion());
+ }
+
+ /**
+ * This test ensures that every feature get installed only once, even if it appears multiple times in the list
+ * of transitive feature dependencies (KARAF-1600)
+ */
+ /*
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testNoDuplicateFeaturesInstallation() throws Exception {
+ final List<Feature> installed = new LinkedList<Feature>();
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ expect(bundleManager.installBundleIfNeeded(EasyMock.anyObject(String.class), EasyMock.anyInt(), EasyMock.anyObject(String.class)))
+ .andReturn(new BundleInstallerResult(createDummyBundle(1l, "", headers()), true)).anyTimes();
+ bundleManager.refreshBundles(EasyMock.anyObject(Set.class), EasyMock.anyObject(Set.class), EasyMock.anyObject(EnumSet.class));
+ EasyMock.expectLastCall();
+ final FeaturesServiceImpl impl = new FeaturesServiceImpl(bundleManager, null) {
+ // override methods which refers to bundle context to avoid mocking everything
+ @Override
+ protected boolean loadState() {
+ return true;
+ }
+
+ @Override
+ protected void saveState() {
+
+ }
+
+ @Override
+ protected void doInstallFeature(InstallationState state, Feature feature, boolean verbose) throws Exception {
+ installed.add(feature);
+
+ super.doInstallFeature(state, feature, verbose);
+ }
+
+ };
+ replay(bundleManager);
+ impl.addRepository(getClass().getResource("repo2.xml").toURI());
+ impl.installFeature("all");
+
+ // copying the features to a set to filter out the duplicates
+ Set<Feature> noduplicates = new HashSet<Feature>();
+ noduplicates.addAll(installed);
+
+ assertEquals("Every feature should only have been installed once", installed.size(), noduplicates.size());
+ }
+
+ @Test
+ public void testGetOptionalImportsOnly() {
+ BundleManager bundleManager = new BundleManager(null, 0l);
+
+ List<Clause> result = bundleManager.getOptionalImports("org.apache.karaf,org.apache.karaf.optional;resolution:=optional");
+ assertEquals("One optional import expected", 1, result.size());
+ assertEquals("org.apache.karaf.optional", result.get(0).getName());
+
+ result = bundleManager.getOptionalImports(null);
+ assertNotNull(result);
+ assertEquals("No optional imports expected", 0, result.size());
+ }
+ */
+
+ static class Storage extends StateStorage {
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ return null;
+ }
+ @Override
+ protected OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java
new file mode 100644
index 0000000..f3ca2e6
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.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.internal.service;
+
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class FeaturesValidationTest {
+
+ @Test
+ public void testNoNs() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f01.xml").toURI());
+ }
+
+ @Test
+ public void testNs10() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f02.xml").toURI());
+ }
+
+ @Test
+ public void testNs10NoName() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f03.xml").toURI());
+ }
+
+ @Test
+ public void testNs11() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f04.xml").toURI());
+ }
+
+ @Test
+ public void testNs12() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f06.xml").toURI());
+ }
+
+ @Test
+ public void testNs11NoName() throws Exception {
+ try {
+ FeatureValidationUtil.validate(getClass().getResource("f05.xml").toURI());
+ fail("Validation should have failed");
+ } catch (Exception e) {
+ // ok
+ }
+ }
+
+ @Test
+ public void testNs13() throws Exception {
+ FeatureValidationUtil.validate(getClass().getResource("f07.xml").toURI());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
new file mode 100644
index 0000000..d9093d5
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.internal.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.internal.model.Bundle;
+import org.apache.karaf.features.internal.resolver.ResourceBuilder;
+import org.apache.karaf.features.internal.resolver.UriNamespace;
+import org.junit.Before;
+import org.junit.Test;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleException;
+import org.osgi.resource.Resource;
+
+import static org.apache.karaf.features.internal.resolver.UriNamespace.getUri;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class OverridesTest {
+
+ private String bsn = "bsn";
+ private Resource b100;
+ private Resource b101;
+ private Resource b102;
+ private Resource b110;
+ private Resource c100;
+ private Resource c101;
+ private Resource c110;
+
+ @Before
+ public void setUp() throws BundleException {
+ b100 = resource("karaf-100.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.0.0")
+ .build();
+
+ b101 = resource("karaf-101.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.0.1")
+ .build();
+
+ b102 = resource("karaf-102.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.0.2")
+ .build();
+
+ b110 = resource("karaf-110.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.1.0")
+ .build();
+
+ c100 = resource("karafc-100.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.0.0")
+ .set("Bundle-Vendor", "Apache")
+ .build();
+
+ c101 = resource("karafc-101.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.0.1")
+ .set("Bundle-Vendor", "NotApache")
+ .build();
+
+ c110 = resource("karafc-110.jar")
+ .set("Bundle-SymbolicName", bsn)
+ .set("Bundle-Version", "1.1.0")
+ .set("Bundle-Vendor", "NotApache")
+ .build();
+ }
+
+ @Test
+ public void testDifferentVendors() throws IOException {
+ Map<String, Resource> map = asResourceMap(c100, c101, c110);
+ assertEquals(c100, map.get(getUri(c100)));
+ Overrides.override(map, Arrays.asList(getUri(c101), getUri(c110)));
+ assertEquals(c101, map.get(getUri(c100)));
+ }
+
+ @Test
+ public void testMatching101() throws IOException {
+ Map<String, Resource> map = asResourceMap(b100, b101, b110);
+ assertEquals(b100, map.get(getUri(b100)));
+ Overrides.override(map, Arrays.asList(getUri(b101), getUri(b110)));
+ assertEquals(b101, map.get(getUri(b100)));
+ }
+
+ @Test
+ public void testMatching102() throws IOException {
+ Map<String, Resource> map = asResourceMap(b100, b101, b102, b110);
+ assertEquals(b100, map.get(getUri(b100)));
+ Overrides.override(map, Arrays.asList(getUri(b101), getUri(b102), getUri(b110)));
+ assertEquals(b102, map.get(getUri(b100)));
+ }
+
+ @Test
+ public void testMatchingRange() throws IOException {
+ Map<String, Resource> map = asResourceMap(b100, b101, b110);
+ assertEquals(b100, map.get(getUri(b100)));
+ Overrides.override(map, Arrays.asList(getUri(b101), getUri(b110) + ";range=\"[1.0, 2.0)\""));
+ assertEquals(b110, map.get(getUri(b100)));
+ }
+
+ @Test
+ public void testNotMatching() throws IOException {
+ Map<String, Resource> map = asResourceMap(b100, b110);
+ assertEquals(b100, map.get(getUri(b100)));
+ Overrides.override(map, Arrays.asList(getUri(b110)));
+ assertEquals(b100, map.get(getUri(b100)));
+ }
+
+ @Test
+ public void testLoadOverrides() {
+ Set<String> overrides = Overrides.loadOverrides(getClass().getResource("overrides.properties").toExternalForm());
+ assertEquals(2, overrides.size());
+
+ Clause karafAdminCommand = null;
+ Clause karafAdminCore = null;
+ for (Clause clause : Parser.parseClauses(overrides.toArray(new String[overrides.size()]))) {
+ if (clause.getName().equals("mvn:org.apache.karaf.admin/org.apache.karaf.admin.command/2.3.0.redhat-61033X")) {
+ karafAdminCommand = clause;
+ }
+ if (clause.getName().equals("mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/2.3.0.redhat-61033X")) {
+ karafAdminCore = clause;
+ }
+ }
+ assertNotNull("Missing admin.command bundle override", karafAdminCommand);
+ assertNotNull("Missing admin.core bundle override", karafAdminCore);
+ assertNotNull("Missing range on admin.core override", karafAdminCore.getAttribute(Overrides.OVERRIDE_RANGE));
+ }
+
+ /**
+ * Copies the content of {@link java.io.InputStream} to {@link java.io.OutputStream}.
+ *
+ * @param input
+ * @param output
+ * @throws java.io.IOException
+ */
+ private void copy(final InputStream input, final OutputStream output) throws IOException {
+ byte[] buffer = new byte[1024 * 16];
+ int n;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ output.flush();
+ }
+ input.close();
+ output.close();
+ }
+
+ static Builder resource(String uri) {
+ return new Builder(uri);
+ }
+
+ static Map<String, Resource> asResourceMap(Resource... resources) {
+ Map<String, Resource> map = new HashMap<String, Resource>();
+ for (Resource resource : resources) {
+ map.put(getUri(resource), resource);
+ }
+ return map;
+ }
+
+ static class Builder {
+ String uri;
+ Map<String,String> headers = new HashMap<String,String>();
+ Builder(String uri) {
+ this.uri = uri;
+ this.headers.put("Bundle-ManifestVersion", "2");
+ }
+ Builder set(String key, String value) {
+ this.headers.put(key, value);
+ return this;
+ }
+ Resource build() throws BundleException {
+ return ResourceBuilder.build(uri, headers);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f01.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
new file mode 100644
index 0000000..814c722
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="karaf-2.0.0">
+ <feature name="spring" version="3.0.3.RELEASE">
+ <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-asm/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-expression/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-beans/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-aop/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-context/3.0.3.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/3.0.3.RELEASE</bundle>
+ </feature>
+ <feature name="spring-dm" version="1.2.0">
+ <feature version="3.0.3.RELEASE">spring</feature>
+ <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/2.2.2_1</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-io/1.2.0</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-core/1.2.0</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-extender/1.2.0</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-annotation/1.2.0</bundle>
+ <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.spring/2.0.0</bundle>
+ </feature>
+ <feature name="wrapper" version="2.0.0">
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.wrapper/2.0.0</bundle>
+ </feature>
+ <feature name="obr" version="2.0.0">
+ <bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/1.6.4</bundle>
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.obr/2.0.0</bundle>
+ <bundle>mvn:org.apache.karaf.features/org.apache.karaf.features.obr/2.0.0</bundle>
+ </feature>
+ <feature name="http" version="2.0.0">
+ <config name="org.ops4j.pax.web">
+ org.osgi.service.http.port=8181
+ </config>
+ <bundle>mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2</bundle>
+ <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jetty-bundle/6.1.22_1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-api/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-spi/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-runtime/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-jetty/0.7.2</bundle>
+ </feature>
+ <feature name="war" version="2.0.0">
+ <feature version="2.0.0">http</feature>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-jsp/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-extender-war/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-extender-whiteboard/0.7.2</bundle>
+ <bundle>mvn:org.ops4j.pax.url/pax-url-war/1.1.3</bundle>
+ <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.war/2.0.0</bundle>
+ </feature>
+ <feature name="webconsole" version="2.0.0">
+ <feature version="2.0.0">http</feature>
+ <config name="org.apache.karaf.webconsole">
+ realm=karaf
+ </config>
+ <bundle>mvn:org.apache.felix/org.apache.felix.metatype/1.0.2</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/2.0.0</bundle>
+ <bundle>mvn:org.apache.felix/org.apache.felix.webconsole/3.1.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.0.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.0.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.0.0</bundle>
+ </feature>
+ <feature name="ssh" version="2.0.0">
+ <config name="org.apache.karaf.shell.ssh">
+ sshPort=8101
+ sshHost=0.0.0.0
+ sshRealm=karaf
+ </config>
+ <bundle>mvn:org.apache.mina/mina-core/2.0.0-RC1</bundle>
+ <bundle>mvn:org.apache.sshd/sshd-core/0.4.0</bundle>
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.ssh/2.0.0</bundle>
+ </feature>
+ <feature name="management" version="2.0.0">
+ <bundle>mvn:org.apache.karaf/org.apache.karaf.management/2.0.0</bundle>
+ <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.1-r964701</bundle>
+ <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.1-r964701</bundle>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f02.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
new file mode 100644
index 0000000..1578faa
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="karaf-2.2.0" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ </feature>
+ <feature name="spring-web" version="2.5.6.SEC02" resolver="(obr)">
+ <feature version="2.5.6.SEC02">spring</feature>
+ <feature version="2.2.0">http</feature>
+ <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-webmvc/2.5.6.SEC02</bundle>
+ </feature>
+ <feature name="spring" version="3.0.5.RELEASE" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-asm/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-expression/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-beans/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-aop/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-context/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/3.0.5.RELEASE</bundle>
+ </feature>
+ <feature name="spring-web" version="3.0.5.RELEASE" resolver="(obr)">
+ <feature version="3.0.5.RELEASE">spring</feature>
+ <feature version="2.2.0">http</feature>
+ <bundle>mvn:org.springframework/spring-web/3.0.5.RELEASE</bundle>
+ <bundle>mvn:org.springframework/spring-webmvc/3.0.5.RELEASE</bundle>
+ </feature>
+ <feature name="spring-dm" version="1.2.1" resolver="(obr)">
+ <feature version="[2.5.6,4)">spring</feature>
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/2.2.2_1</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-io/1.2.1</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-core/1.2.1</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-extender/1.2.1</bundle>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-annotation/1.2.1</bundle>
+ <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.spring/2.2.0</bundle>
+ </feature>
+ <feature name="spring-dm-web" version="1.2.1" resolver="(obr)">
+ <feature version="1.2.1">spring-dm</feature>
+ <feature version="[2.5.6,4)">spring-web</feature>
+ <feature version="2.2.0">http</feature>
+ <bundle>mvn:org.springframework.osgi/spring-osgi-web/1.2.1</bundle>
+ </feature>
+ <feature name="wrapper" version="2.2.0">
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.wrapper/2.2.0</bundle>
+ </feature>
+ <feature name="obr" version="2.2.0">
+ <bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/1.6.4</bundle>
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.obr/2.2.0</bundle>
+ <bundle>mvn:org.apache.karaf.features/org.apache.karaf.features.obr/2.2.0</bundle>
+ </feature>
+ <feature name="config" version="2.2.0">
+ <bundle start-level='30'>mvn:org.apache.karaf.shell/org.apache.karaf.shell.config/2.2.0</bundle>
+ </feature>
+ <feature name="jetty" version="7.2.2.v20101205" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2</bundle>
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.asm/3.3_1</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-util/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-io/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-http/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-continuation/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-server/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-security/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-servlet/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-xml/7.2.2.v20101205</bundle>
+ </feature>
+ <feature name="jetty-jaas" version="7.2.2.v20101205" resolver="(obr)">
+ <feature version="[7.0,8.0)">jetty</feature>
+ <bundle dependency='true'>mvn:javax.mail/mail/1.4.3</bundle>
+ <bundle dependency='true'>mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/1.1.1</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-webapp/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-jndi/7.2.2.v20101205</bundle>
+ <bundle>mvn:org.eclipse.jetty/jetty-plus/7.2.2.v20101205</bundle>
+ </feature>
+ <feature name="http" version="2.2.0" resolver="(obr)">
+ <configfile finalname="/etc/jetty.xml">mvn:org.apache.karaf/apache-karaf/2.2.0/xml/jettyconfig</configfile>
+ <config name="org.ops4j.pax.web">
+ org.osgi.service.http.port=8181
+ javax.servlet.context.tempdir=${karaf.data}/pax-web-jsp
+ org.ops4j.pax.web.config.file=${karaf.etc}/jetty.xml
+ </config>
+ <feature version="[7.0,8.0)">jetty</feature>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-api/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-spi/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-runtime/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-jetty/1.0.1</bundle>
+ </feature>
+ <feature name="war" version="2.2.0" resolver="(obr)">
+ <config name="org.ops4j.pax.url.war">
+ org.ops4j.pax.url.war.importPaxLoggingPackages=true
+ </config>
+ <feature>http</feature>
+ <bundle start-level='30'>mvn:org.apache.karaf.shell/org.apache.karaf.shell.web/2.2.0</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-jsp/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-extender-war/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-extender-whiteboard/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.web/pax-web-deployer/1.0.1</bundle>
+ <bundle>mvn:org.ops4j.pax.url/pax-url-war/1.2.5</bundle>
+ </feature>
+ <feature name="kar" version="2.2.0">
+ <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.kar/2.2.0</bundle>
+ </feature>
+ <feature name="webconsole-base" version="2.2.0">
+ <config name="org.apache.karaf.webconsole">
+ realm=karaf
+ </config>
+ <feature>http</feature>
+ <bundle>mvn:org.apache.felix/org.apache.felix.metatype/1.0.4</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/2.2.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.console/2.2.0</bundle>
+ </feature>
+ <feature name="webconsole" version="2.2.0">
+ <feature version="2.2.0">webconsole-base</feature>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.2.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.2.0</bundle>
+ <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.2.0</bundle>
+ <bundle>mvn:org.apache.felix/org.apache.felix.webconsole.plugins.event/1.0.2</bundle>
+ </feature>
+ <feature name="ssh" version="2.2.0">
+ <config name="org.apache.karaf.shell">
+ sshPort=8101
+ sshHost=0.0.0.0
+ sshRealm=karaf
+ hostKey=${karaf.etc}/host.key
+ </config>
+ <bundle dependency='true'>mvn:org.apache.mina/mina-core/2.0.1</bundle>
+ <bundle dependency='true'>mvn:org.apache.sshd/sshd-core/0.5.0</bundle>
+ <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.ssh/2.2.0</bundle>
+ </feature>
+ <feature name="management" version="2.2.0">
+ <bundle>mvn:org.apache.karaf/org.apache.karaf.management/2.2.0</bundle>
+ <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.3</bundle>
+ <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.3</bundle>
+ </feature>
+ <feature name="eventadmin" version="2.2.0">
+ <bundle start-level='30'>mvn:org.apache.felix/org.apache.felix.eventadmin/1.2.8</bundle>
+ </feature>
+ <feature name="jasypt-encryption" version="2.2.0" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-codec/1.3_3</bundle>
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-lang/2.4_4</bundle>
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.7_1</bundle>
+ <bundle>mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.jasypt/2.2.0</bundle>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f03.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
new file mode 100644
index 0000000..c058095
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f04.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
new file mode 100644
index 0000000..85f28ad
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ </feature>
+</features>
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f05.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
new file mode 100644
index 0000000..15d84e2
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ </feature>
+</features>
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f06.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
new file mode 100644
index 0000000..496cbdb
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_4</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ <conditional>
+ <condition>http</condition>
+ <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
+ </conditional>
+ </feature>
+</features>
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/f07.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
new file mode 100644
index 0000000..5b7dd90
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+ <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
+ <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_4</bundle>
+ <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
+ <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
+ <conditional>
+ <condition>http</condition>
+ <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
+ </conditional>
+ <capability>
+ service-reference;effective:=active;objectClass=org.apache.aries.proxy.ProxyManager
+ </capability>
+ </feature>
+</features>
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties b/features/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
new file mode 100644
index 0000000..d34fa7e
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
@@ -0,0 +1,23 @@
+
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Sample etc/overrides.properties file for testing purposes
+mvn:org.apache.karaf.admin/org.apache.karaf.admin.command/2.3.0.redhat-61033X
+mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/2.3.0.redhat-61033X;range=[2.3.0,2.5)
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml b/features/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
new file mode 100644
index 0000000..5fd51d0
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
@@ -0,0 +1,41 @@
+<!--
+
+ 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.
+-->
+<features name="repo2">
+ <feature name="common">
+ <bundle>b1</bundle>
+ </feature>
+ <feature name="f1">
+ <feature>common</feature>
+ <bundle>b2</bundle>
+ </feature>
+ <feature name="f2">
+ <feature>common</feature>
+ <feature>f1</feature>
+ <bundle>b3</bundle>
+ </feature>
+ <feature name="f3">
+ <feature>f1</feature>
+ <feature>f2</feature>
+ <bundle>b4</bundle>
+ </feature>
+ <feature name="all">
+ <feature>f1</feature>
+ <feature>f2</feature>
+ <feature>f3</feature>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/repo1.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/repo1.xml b/features/src/test/resources/org/apache/karaf/features/repo1.xml
new file mode 100644
index 0000000..641ef12
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/repo1.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
+ <repository>urn:r1</repository>
+ <feature name="f1" region="foo">
+ <config name="c1">
+ k=v
+ </config>
+ <bundle>b1</bundle>
+ <bundle>b2</bundle>
+ </feature>
+ <feature name="f2">
+ <feature>f1</feature>
+ <bundle>b3</bundle>
+ </feature>
+ <feature name="f3">
+ <configfile finalname="cf1" override="true">cfloc</configfile>
+ <bundle>b4</bundle>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/repo2.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/repo2.xml b/features/src/test/resources/org/apache/karaf/features/repo2.xml
new file mode 100644
index 0000000..f5e96ae
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/repo2.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+ <repository>
+ urn:r1
+ </repository>
+ <feature name="f1" region="foo">
+ <config name="c1">
+ k=v
+ </config>
+ <bundle>b1</bundle>
+ <bundle>b2</bundle>
+ </feature>
+ <feature name="f2">
+ <feature>f1</feature>
+ <bundle>b3</bundle>
+ </feature>
+ <feature name="f3">
+ <configfile finalname="cf1" override="true">cfloc</configfile>
+ <bundle>b4</bundle>
+ </feature>
+</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/resources/org/apache/karaf/features/repo3.xml
----------------------------------------------------------------------
diff --git a/features/src/test/resources/org/apache/karaf/features/repo3.xml b/features/src/test/resources/org/apache/karaf/features/repo3.xml
new file mode 100644
index 0000000..ffe08ed
--- /dev/null
+++ b/features/src/test/resources/org/apache/karaf/features/repo3.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+ <feature name="f1">
+ <capability>
+ cap
+ </capability>
+ <requirement>
+ req
+ </requirement>
+ </feature>
+</features>
[48/59] [abbrv] [KARAF-2852] Merge wrapper/core and wrapper/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper
deleted file mode 100755
index 5215c2e..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a
deleted file mode 100755
index 4bcc342..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper
deleted file mode 100755
index 6ba0351..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a
deleted file mode 100755
index b569e3f..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar
deleted file mode 100644
index 4db355b..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper
deleted file mode 100755
index ad883d7..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl
deleted file mode 100755
index 08adc52..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper
deleted file mode 100644
index 7e00645..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so
deleted file mode 100644
index 2cc4ab3..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper
deleted file mode 100644
index 3128b95..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so
deleted file mode 100644
index 24197bf..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper
deleted file mode 100644
index 0165db0..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib
deleted file mode 100644
index 6356705..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
deleted file mode 100644
index 1c18918..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
- -->
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>ProcessType</key>
- <string>Background</string>
- <key>KeepAlive</key>
- <false/>
- <key>Label</key>
- <string>org.apache.karaf.KARAF</string>
- <key>ProgramArguments</key>
- <array>
- <!-- path to your KARAF-service wrapper -->
- <string>${karaf.home}/bin/${name}-service</string>
- <string>console</string>
- </array>
- <key>RunAtLoad</key>
- <true/>
-</dict>
-</plist>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper
deleted file mode 100755
index 7cac208..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so
deleted file mode 100755
index 4093262..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper
deleted file mode 100755
index 91257c6..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so
deleted file mode 100755
index 008bef6..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper
deleted file mode 100755
index bdec254..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so
deleted file mode 100755
index 963ff49..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper
deleted file mode 100755
index 6bd165e..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so
deleted file mode 100755
index 0d52ffa..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
deleted file mode 100644
index a7ca8bb..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
+++ /dev/null
@@ -1,557 +0,0 @@
-#! /bin/sh
-
-# ------------------------------------------------------------------------
-# 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.
-# ------------------------------------------------------------------------
-
-# If require, set the JAVA_HOME to launch the wrapper
-#
-#JAVA_HOME=
-#
-
-# Application
-APP_NAME="${name}"
-APP_LONG_NAME="${displayName}"
-
-# Wrapper
-WRAPPER_CMD="${karaf.base}/bin/${APP_NAME}-wrapper"
-WRAPPER_CONF="${karaf.etc}/${APP_NAME}-wrapper.conf"
-
-# Priority at which to run the wrapper. See "man nice" for valid priorities.
-# nice is only used if a priority is specified.
-PRIORITY=
-
-# Location of the data folder.
-DATADIR="${karaf.data}"
-
-# Location of the pid file.
-PIDDIR="${karaf.data}"
-
-# If uncommented, causes the Wrapper to be shutdown using an anchor file.
-# When launched with the 'start' command, it will also ignore all INT and
-# TERM signals.
-#IGNORE_SIGNALS=true
-
-# If specified, the Wrapper will be run as the specified user.
-# IMPORTANT - Make sure that the user has the required privileges to write
-# the PID file and wrapper.log files. Failure to be able to write the log
-# file will cause the Wrapper to exit without any way to write out an error
-# message.
-# NOTE - This will set the user which is used to run the Wrapper as well as
-# the JVM and is not useful in situations where a privileged resource or
-# port needs to be allocated prior to the user being changed.
-#RUN_AS_USER=
-
-# The following two lines are used by the chkconfig command. Change as is
-# appropriate for your application. They should remain commented.
-# chkconfig: 2345 20 80
-# description: ${displayName}
-
-# Do not modify anything beyond this point
-#-----------------------------------------------------------------------------
-
-# Get the fully qualified path to the script
-case $0 in
- /*)
- SCRIPT="$0"
- ;;
- *)
- PWD=`pwd`
- SCRIPT="$PWD/$0"
- ;;
-esac
-
-# Resolve the true real path without any sym links.
-CHANGED=true
-while [ "X$CHANGED" != "X" ]
-do
- # Change spaces to ":" so the tokens can be parsed.
- SCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'`
- # Get the real path to this script, resolving any symbolic links
- TOKENS=`echo $SCRIPT | sed -e 's;/; ;g'`
- REALPATH=
- for C in $TOKENS; do
- REALPATH="$REALPATH/$C"
- while [ -h "$REALPATH" ] ; do
- LS="`ls -ld "$REALPATH"`"
- LINK="`expr "$LS" : '.*-> \(.*\)$'`"
- if expr "$LINK" : '/.*' > /dev/null; then
- REALPATH="$LINK"
- else
- REALPATH="`dirname "$REALPATH"`""/$LINK"
- fi
- done
- done
- # Change ":" chars back to spaces.
- REALPATH=`echo $REALPATH | sed -e 's;:; ;g'`
-
- if [ "$REALPATH" = "$SCRIPT" ]
- then
- CHANGED=""
- else
- SCRIPT="$REALPATH"
- fi
-done
-
-# Change the current directory to the location of the script
-cd "`dirname "$REALPATH"`"
-REALDIR=`pwd`
-
-# If the PIDDIR is relative, set its value relative to the full REALPATH to avoid problems if
-# the working directory is later changed.
-FIRST_CHAR=`echo $PIDDIR | cut -c1,1`
-if [ "$FIRST_CHAR" != "/" ]
-then
- PIDDIR=$REALDIR/$PIDDIR
-fi
-# Same test for WRAPPER_CMD
-FIRST_CHAR=`echo $WRAPPER_CMD | cut -c1,1`
-if [ "$FIRST_CHAR" != "/" ]
-then
- WRAPPER_CMD=$REALDIR/$WRAPPER_CMD
-fi
-# Same test for WRAPPER_CONF
-FIRST_CHAR=`echo $WRAPPER_CONF | cut -c1,1`
-if [ "$FIRST_CHAR" != "/" ]
-then
- WRAPPER_CONF=$REALDIR/$WRAPPER_CONF
-fi
-
-# Process ID
-ANCHORFILE="$PIDDIR/$APP_NAME.anchor"
-PIDFILE="$PIDDIR/$APP_NAME.pid"
-LOCKDIR="/var/lock/subsys"
-LOCKFILE="$LOCKDIR/$APP_NAME"
-pid=""
-
-# Resolve the location of the 'ps' command
-PSEXE="/usr/bin/ps"
-if [ ! -x $PSEXE ]
-then
- PSEXE="/bin/ps"
- if [ ! -x $PSEXE ]
- then
- echo "Unable to locate 'ps'."
- echo "Please report this message along with the location of the command on your system."
- exit 1
- fi
-fi
-
-# Resolve the os
-DIST_OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]`
-case "$DIST_OS" in
- 'sunos')
- DIST_OS="solaris"
- ;;
- 'hp-ux' | 'hp-ux64')
- DIST_OS="hpux"
- ;;
- 'darwin')
- DIST_OS="macosx"
- ;;
- 'unix_sv')
- DIST_OS="unixware"
- ;;
-esac
-
-# Resolve the architecture
-DIST_ARCH=`uname -p | tr [:upper:] [:lower:] | tr -d [:blank:]`
-if [ "$DIST_ARCH" = "unknown" ]
-then
- DIST_ARCH=`uname -m | tr [:upper:] [:lower:] | tr -d [:blank:]`
-fi
-case "$DIST_ARCH" in
- 'amd64' | 'ia32' | 'ia64' | 'i386' | 'i486' | 'i586' | 'i686' | 'x86_64')
- DIST_ARCH="x86"
- ;;
- 'ip27')
- DIST_ARCH="mips"
- ;;
- 'power' | 'powerpc' | 'power_pc' | 'ppc64')
- DIST_ARCH="ppc"
- ;;
- 'pa_risc' | 'pa-risc')
- DIST_ARCH="parisc"
- ;;
- 'sun4u' | 'sparcv9')
- DIST_ARCH="sparc"
- ;;
- '9000/800')
- DIST_ARCH="parisc"
- ;;
-esac
-
-# Decide on the wrapper binary to use.
-# If a 32-bit wrapper binary exists then it will work on 32 or 64 bit
-# platforms, if the 64-bit binary exists then the distribution most
-# likely wants to use long names. Otherwise, look for the default.
-# For macosx, we also want to look for universal binaries.
-WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
-if [ -x $WRAPPER_TEST_CMD ]
-then
- WRAPPER_CMD="$WRAPPER_TEST_CMD"
-else
- if [ "$DIST_OS" = "macosx" ]
- then
- WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-32"
- if [ -x $WRAPPER_TEST_CMD ]
- then
- WRAPPER_CMD="$WRAPPER_TEST_CMD"
- else
- WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
- if [ -x $WRAPPER_TEST_CMD ]
- then
- WRAPPER_CMD="$WRAPPER_TEST_CMD"
- else
- WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-64"
- if [ -x $WRAPPER_TEST_CMD ]
- then
- WRAPPER_CMD="$WRAPPER_TEST_CMD"
- else
- if [ ! -x $WRAPPER_CMD ]
- then
- echo "Unable to locate any of the following binaries:"
- echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
- echo " $WRAPPER_CMD-$DIST_OS-universal-32"
- echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
- echo " $WRAPPER_CMD-$DIST_OS-universal-64"
- echo " $WRAPPER_CMD"
- exit 1
- fi
- fi
- fi
- fi
- else
- WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
- if [ -x $WRAPPER_TEST_CMD ]
- then
- WRAPPER_CMD="$WRAPPER_TEST_CMD"
- else
- if [ ! -x $WRAPPER_CMD ]
- then
- echo "Unable to locate any of the following binaries:"
- echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
- echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
- echo " $WRAPPER_CMD"
- exit 1
- fi
- fi
- fi
-fi
-
-# Build the nice clause
-if [ "X$PRIORITY" = "X" ]
-then
- CMDNICE=""
-else
- CMDNICE="nice -$PRIORITY"
-fi
-
-# Build the anchor file clause.
-if [ "X$IGNORE_SIGNALS" = "X" ]
-then
- ANCHORPROP=
- IGNOREPROP=
-else
- ANCHORPROP=wrapper.anchorfile=$ANCHORFILE
- IGNOREPROP=wrapper.ignore_signals=TRUE
-fi
-
-# Build the lock file clause. Only create a lock file if the lock directory exists on this platform.
-if [ -d $LOCKDIR ]
-then
- LOCKPROP=wrapper.lockfile=$LOCKFILE
-else
- LOCKPROP=
-fi
-
-checkUser() {
- # Check the configured user. If necessary rerun this script as the desired user.
- if [ "X$RUN_AS_USER" != "X" ]
- then
- # Resolve the location of the 'id' command
- IDEXE="/usr/xpg4/bin/id"
- if [ ! -x $IDEXE ]
- then
- IDEXE="/usr/bin/id"
- if [ ! -x $IDEXE ]
- then
- echo "Unable to locate 'id'."
- echo "Please report this message along with the location of the command on your system."
- exit 1
- fi
- fi
-
- if [ "`$IDEXE -u -n`" = "$RUN_AS_USER" ]
- then
- # Already running as the configured user. Avoid password prompts by not calling su.
- RUN_AS_USER=""
- fi
- fi
- if [ "X$RUN_AS_USER" != "X" ]
- then
- # If LOCKPROP and $RUN_AS_USER are defined then the new user will most likely not be
- # able to create the lock file. The Wrapper will be able to update this file once it
- # is created but will not be able to delete it on shutdown. If $2 is defined then
- # the lock file should be created for the current command
- if [ "X$LOCKPROP" != "X" ]
- then
- if [ "X$2" != "X" ]
- then
- # Resolve the primary group
- RUN_AS_GROUP=`groups $RUN_AS_USER | awk '{print $3}' | tail -1`
- if [ "X$RUN_AS_GROUP" = "X" ]
- then
- RUN_AS_GROUP=$RUN_AS_USER
- fi
- touch $LOCKFILE
- chown $RUN_AS_USER:$RUN_AS_GROUP $LOCKFILE
- fi
- fi
-
- # Still want to change users, recurse. This means that the user will only be
- # prompted for a password once.
- su -m $RUN_AS_USER -s /bin/sh -c "$REALPATH $1"
- RETVAL=$?
-
- # Now that we are the original user again, we may need to clean up the lock file.
- if [ "X$LOCKPROP" != "X" ]
- then
- getpid
- if [ "X$pid" = "X" ]
- then
- # Wrapper is not running so make sure the lock file is deleted.
- if [ -f $LOCKFILE ]
- then
- rm $LOCKFILE
- fi
- fi
- fi
-
- exit $RETVAL
- fi
-}
-
-getpid() {
- if [ -f $PIDFILE ]
- then
- if [ -r $PIDFILE ]
- then
- pid=`cat $PIDFILE`
- if [ "X$pid" != "X" ]
- then
- # It is possible that 'a' process with the pid exists but that it is not the
- # correct process. This can happen in a number of cases, but the most
- # common is during system startup after an unclean shutdown.
- # The ps statement below looks for the specific wrapper command running as
- # the pid. If it is not found then the pid file is considered to be stale.
- if [ "$DIST_OS" = "solaris" ]
- then
- pidtest=`$PSEXE -p $pid -o comm | grep $WRAPPER_CMD | tail -1`
- else
- pidtest=`$PSEXE -p $pid -o command | grep $WRAPPER_CMD | tail -1`
- fi
- if [ "X$pidtest" = "X" ]
- then
- # This is a stale pid file.
- rm -f $PIDFILE
- echo "Removed stale pid file: $PIDFILE"
- pid=""
- fi
- fi
- else
- echo "Cannot read $PIDFILE."
- exit 1
- fi
- fi
-}
-
-testpid() {
- pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
- if [ "X$pid" = "X" ]
- then
- # Process is gone so remove the pid file.
- rm -f $PIDFILE
- pid=""
- fi
-}
-
-console() {
- echo "Running $APP_LONG_NAME..."
- getpid
- if [ "X$pid" = "X" ]
- then
- COMMAND_LINE="$CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.syslog.ident=$APP_NAME wrapper.pidfile=$PIDFILE $ANCHORPROP $LOCKPROP"
- exec $COMMAND_LINE
- else
- echo "$APP_LONG_NAME is already running."
- exit 1
- fi
-}
-
-start() {
- echo "Starting $APP_LONG_NAME..."
- getpid
- if [ "X$pid" = "X" ]
- then
- if [ ! -d $DATADIR ]; then
- mkdir $DATADIR
- fi
- if [ ! -d $DATADIR/log ]; then
- mkdir $DATADIR/log
- fi
- COMMAND_LINE="$CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.syslog.ident=$APP_NAME wrapper.pidfile=$PIDFILE wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $LOCKPROP"
- exec $COMMAND_LINE
- else
- echo "$APP_LONG_NAME is already running."
- exit 1
- fi
-}
-
-stopit() {
- echo "Stopping $APP_LONG_NAME..."
- getpid
- if [ "X$pid" = "X" ]
- then
- echo "$APP_LONG_NAME was not running."
- else
- if [ "X$IGNORE_SIGNALS" = "X" ]
- then
- # Running so try to stop it.
- kill $pid
- if [ $? -ne 0 ]
- then
- # An explanation for the failure should have been given
- echo "Unable to stop $APP_LONG_NAME."
- exit 1
- fi
- else
- rm -f $ANCHORFILE
- if [ -f $ANCHORFILE ]
- then
- # An explanation for the failure should have been given
- echo "Unable to stop $APP_LONG_NAME."
- exit 1
- fi
- fi
-
- # We can not predict how long it will take for the wrapper to
- # actually stop as it depends on settings in wrapper.conf.
- # Loop until it does.
- savepid=$pid
- CNT=0
- TOTCNT=0
- while [ "X$pid" != "X" ]
- do
- # Show a waiting message every 5 seconds.
- if [ "$CNT" -lt "5" ]
- then
- CNT=`expr $CNT + 1`
- else
- echo "Waiting for $APP_LONG_NAME to exit..."
- CNT=0
- fi
- TOTCNT=`expr $TOTCNT + 1`
-
- sleep 1
-
- testpid
- done
-
- pid=$savepid
- testpid
- if [ "X$pid" != "X" ]
- then
- echo "Failed to stop $APP_LONG_NAME."
- exit 1
- else
- echo "Stopped $APP_LONG_NAME."
- fi
- fi
-}
-
-status() {
- getpid
- if [ "X$pid" = "X" ]
- then
- echo "$APP_LONG_NAME is not running."
- exit 1
- else
- echo "$APP_LONG_NAME is running ($pid)."
- exit 0
- fi
-}
-
-dump() {
- echo "Dumping $APP_LONG_NAME..."
- getpid
- if [ "X$pid" = "X" ]
- then
- echo "$APP_LONG_NAME was not running."
-
- else
- kill -3 $pid
-
- if [ $? -ne 0 ]
- then
- echo "Failed to dump $APP_LONG_NAME."
- exit 1
- else
- echo "Dumped $APP_LONG_NAME."
- fi
- fi
-}
-
-case "$1" in
-
- 'console')
- checkUser $1 touchlock
- console
- ;;
-
- 'start')
- checkUser $1 touchlock
- start
- ;;
-
- 'stop')
- checkUser $1
- stopit
- ;;
-
- 'restart')
- checkUser $1 touchlock
- stopit
- start
- ;;
-
- 'status')
- checkUser $1
- status
- ;;
-
- 'dump')
- checkUser $1
- dump
- ;;
-
- *)
- echo "Usage: $0 { console | start | stop | restart | status | dump }"
- exit 1
- ;;
-esac
-
-exit 0
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
deleted file mode 100644
index a3f98a5..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
+++ /dev/null
@@ -1,135 +0,0 @@
-# ------------------------------------------------------------------------
-# 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.
-# ------------------------------------------------------------------------
-
-#********************************************************************
-# Wrapper Properties
-#********************************************************************
-set.default.JAVA_HOME=${java.home}
-set.default.KARAF_HOME=${karaf.home}
-set.default.KARAF_BASE=${karaf.base}
-set.default.KARAF_DATA=${karaf.data}
-set.default.KARAF_ETC=${karaf.etc}
-
-# Java Application
-wrapper.working.dir=%KARAF_BASE%
-wrapper.java.command=%JAVA_HOME%/bin/java
-wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
-wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
-wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
-wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
-wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
-wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
-wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
-wrapper.java.library.path.1=%KARAF_HOME%/lib/
-
-# Application Parameters. Add parameters as needed starting from 1
-#wrapper.app.parameter.1=
-
-# JVM Parameters
-# note that n is the parameter number starting from 1.
-wrapper.java.additional.1=-Dkaraf.home=%KARAF_HOME%
-wrapper.java.additional.2=-Dkaraf.base=%KARAF_BASE%
-wrapper.java.additional.3=-Dkaraf.data=%KARAF_DATA%
-wrapper.java.additional.4=-Dkaraf.etc=%KARAF_ETC%
-wrapper.java.additional.5=-Dcom.sun.management.jmxremote
-wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
-wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
-wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
-wrapper.java.additional.9=-Djava.endorsed.dirs=%JAVA_HOME%/jre/lib/endorsed:%JAVA_HOME%/lib/endorsed:%KARAF_HOME%/lib/endorsed
-wrapper.java.additional.10=-Djava.ext.dirs=%JAVA_HOME%/jre/lib/ext:%JAVA_HOME%/lib/ext:%KARAF_HOME%/lib/ext
-
-# Uncomment to enable jmx
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
-
-# Uncomment to enable YourKit profiling
-#wrapper.java.additional.n=-Xrunyjpagent
-
-# Uncomment to enable remote debugging
-#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
-#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
-
-# Initial Java Heap Size (in MB)
-#wrapper.java.initmemory=3
-
-# Maximum Java Heap Size (in MB)
-wrapper.java.maxmemory=512
-
-
-#********************************************************************
-# Wrapper Logging Properties
-#********************************************************************
-# Format of output for the console. (See docs for formats)
-wrapper.console.format=PM
-
-# Log Level for console output. (See docs for log levels)
-wrapper.console.loglevel=INFO
-
-# Log file to use for wrapper output logging.
-wrapper.logfile=%KARAF_DATA%/log/wrapper.log
-
-# Format of output for the log file. (See docs for formats)
-wrapper.logfile.format=LPTM
-
-# Log Level for log file output. (See docs for log levels)
-wrapper.logfile.loglevel=INFO
-
-# Maximum size that the log file will be allowed to grow to before
-# the log is rolled. Size is specified in bytes. The default value
-# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
-# 'm' (mb) suffix. For example: 10m = 10 megabytes.
-wrapper.logfile.maxsize=10m
-
-# Maximum number of rolled log files which will be allowed before old
-# files are deleted. The default value of 0 implies no limit.
-wrapper.logfile.maxfiles=5
-
-# Log Level for sys/event log output. (See docs for log levels)
-wrapper.syslog.loglevel=NONE
-
-#********************************************************************
-# Wrapper Windows Properties
-#********************************************************************
-# Title to use when running as a console
-wrapper.console.title=${name}
-
-#********************************************************************
-# Wrapper Windows NT/2000/XP Service Properties
-#********************************************************************
-# WARNING - Do not modify any of these properties when an application
-# using this configuration file has been installed as a service.
-# Please uninstall the service before modifying this section. The
-# service can then be reinstalled.
-
-# Name of the service
-wrapper.ntservice.name=${name}
-
-# Display name of the service
-wrapper.ntservice.displayname=${displayName}
-
-# Description of the service
-wrapper.ntservice.description=${description}
-
-# Service dependencies. Add dependencies as needed starting from 1
-wrapper.ntservice.dependency.1=
-
-# Mode in which the service is installed. AUTO_START or DEMAND_START
-wrapper.ntservice.starttype=${startType}
-
-# Allow the service to interact with the desktop.
-wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
deleted file mode 100644
index 0dd0474..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
+++ /dev/null
@@ -1,51 +0,0 @@
-@echo off
-
-REM ------------------------------------------------------------------------
-REM Licensed to the Apache Software Foundation (ASF) under one or more
-REM contributor license agreements. See the NOTICE file distributed with
-REM this work for additional information regarding copyright ownership.
-REM The ASF licenses this file to You under the Apache License, Version 2.0
-REM (the "License"); you may not use this file except in compliance with
-REM the License. You may obtain a copy of the License at
-REM
-REM http://www.apache.org/licenses/LICENSE-2.0
-REM
-REM Unless required by applicable law or agreed to in writing, software
-REM distributed under the License is distributed on an "AS IS" BASIS,
-REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-REM See the License for the specific language governing permissions and
-REM limitations under the License.
-REM ------------------------------------------------------------------------
-
-setlocal
-
-set APP_NAME=${name}
-set APP_LONG_NAME=${displayName}
-set APP_BASE=${karaf.base}
-set APP_ETC=${karaf.etc}
-
-if ""%1"" == ""run"" goto doRun
-if ""%1"" == ""install"" goto doInstall
-if ""%1"" == ""remove"" goto doRemove
-
-echo Usage: karaf-service ( commands ... )
-echo commands:
-echo run Start %APP_NAME% in the current console
-echo install Install %APP_NAME% as a Windows service
-echo remove Remove the %APP_NAME% Windows service
-goto end
-
-:doRun
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -c "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:doInstall
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -i "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:doRemove
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -r "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:end
-if not "%PAUSE%" == "" pause
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
deleted file mode 100644
index def40f7..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
+++ /dev/null
@@ -1,135 +0,0 @@
-# ------------------------------------------------------------------------
-# 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.
-# ------------------------------------------------------------------------
-
-#********************************************************************
-# Wrapper Properties
-#********************************************************************
-set.default.JAVA_HOME=${java.home}
-set.default.KARAF_HOME=${karaf.home}
-set.default.KARAF_BASE=${karaf.base}
-set.default.KARAF_DATA=${karaf.data}
-set.default.KARAF_ETC=${karaf.etc}
-
-# Java Application
-wrapper.working.dir=%KARAF_BASE%
-wrapper.java.command=%JAVA_HOME%/bin/java
-wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
-wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
-wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
-wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
-wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
-wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
-wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
-wrapper.java.library.path.1=%KARAF_HOME%/lib/
-
-# Application Parameters. Add parameters as needed starting from 1
-#wrapper.app.parameter.1=
-
-# JVM Parameters
-# note that n is the parameter number starting from 1.
-wrapper.java.additional.1=-Dkaraf.home="%KARAF_HOME%"
-wrapper.java.additional.2=-Dkaraf.base="%KARAF_BASE%"
-wrapper.java.additional.3=-Dkaraf.data="%KARAF_DATA%"
-wrapper.java.additional.4=-Dkaraf.etc="%KARAF_ETC%"
-wrapper.java.additional.5=-Dcom.sun.management.jmxremote
-wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
-wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
-wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
-wrapper.java.additional.9=-Djava.endorsed.dirs="%JAVA_HOME%/jre/lib/endorsed;%JAVA_HOME%/lib/endorsed;%KARAF_HOME%/lib/endorsed"
-wrapper.java.additional.10=-Djava.ext.dirs="%JAVA_HOME%/jre/lib/ext;%JAVA_HOME%/lib/ext;%KARAF_HOME%/lib/ext"
-
-# Uncomment to enable jmx
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
-
-# Uncomment to enable YourKit profiling
-#wrapper.java.additional.n=-Xrunyjpagent
-
-# Uncomment to enable remote debugging
-#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
-#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
-
-# Initial Java Heap Size (in MB)
-#wrapper.java.initmemory=3
-
-# Maximum Java Heap Size (in MB)
-wrapper.java.maxmemory=512
-
-
-#********************************************************************
-# Wrapper Logging Properties
-#********************************************************************
-# Format of output for the console. (See docs for formats)
-wrapper.console.format=PM
-
-# Log Level for console output. (See docs for log levels)
-wrapper.console.loglevel=INFO
-
-# Log file to use for wrapper output logging.
-wrapper.logfile=%KARAF_DATA%/log/wrapper.log
-
-# Format of output for the log file. (See docs for formats)
-wrapper.logfile.format=LPTM
-
-# Log Level for log file output. (See docs for log levels)
-wrapper.logfile.loglevel=INFO
-
-# Maximum size that the log file will be allowed to grow to before
-# the log is rolled. Size is specified in bytes. The default value
-# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
-# 'm' (mb) suffix. For example: 10m = 10 megabytes.
-wrapper.logfile.maxsize=10m
-
-# Maximum number of rolled log files which will be allowed before old
-# files are deleted. The default value of 0 implies no limit.
-wrapper.logfile.maxfiles=5
-
-# Log Level for sys/event log output. (See docs for log levels)
-wrapper.syslog.loglevel=NONE
-
-#********************************************************************
-# Wrapper Windows Properties
-#********************************************************************
-# Title to use when running as a console
-wrapper.console.title=${name}
-
-#********************************************************************
-# Wrapper Windows NT/2000/XP Service Properties
-#********************************************************************
-# WARNING - Do not modify any of these properties when an application
-# using this configuration file has been installed as a service.
-# Please uninstall the service before modifying this section. The
-# service can then be reinstalled.
-
-# Name of the service
-wrapper.ntservice.name=${name}
-
-# Display name of the service
-wrapper.ntservice.displayname=${displayName}
-
-# Description of the service
-wrapper.ntservice.description=${description}
-
-# Service dependencies. Add dependencies as needed starting from 1
-wrapper.ntservice.dependency.1=
-
-# Mode in which the service is installed. AUTO_START or DEMAND_START
-wrapper.ntservice.starttype=${startType}
-
-# Allow the service to interact with the desktop.
-wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe
deleted file mode 100644
index b4cfc55..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll
deleted file mode 100644
index cb553c1..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
deleted file mode 100644
index 0dd0474..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
+++ /dev/null
@@ -1,51 +0,0 @@
-@echo off
-
-REM ------------------------------------------------------------------------
-REM Licensed to the Apache Software Foundation (ASF) under one or more
-REM contributor license agreements. See the NOTICE file distributed with
-REM this work for additional information regarding copyright ownership.
-REM The ASF licenses this file to You under the Apache License, Version 2.0
-REM (the "License"); you may not use this file except in compliance with
-REM the License. You may obtain a copy of the License at
-REM
-REM http://www.apache.org/licenses/LICENSE-2.0
-REM
-REM Unless required by applicable law or agreed to in writing, software
-REM distributed under the License is distributed on an "AS IS" BASIS,
-REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-REM See the License for the specific language governing permissions and
-REM limitations under the License.
-REM ------------------------------------------------------------------------
-
-setlocal
-
-set APP_NAME=${name}
-set APP_LONG_NAME=${displayName}
-set APP_BASE=${karaf.base}
-set APP_ETC=${karaf.etc}
-
-if ""%1"" == ""run"" goto doRun
-if ""%1"" == ""install"" goto doInstall
-if ""%1"" == ""remove"" goto doRemove
-
-echo Usage: karaf-service ( commands ... )
-echo commands:
-echo run Start %APP_NAME% in the current console
-echo install Install %APP_NAME% as a Windows service
-echo remove Remove the %APP_NAME% Windows service
-goto end
-
-:doRun
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -c "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:doInstall
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -i "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:doRemove
-"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -r "%APP_ETC%\%APP_NAME%-wrapper.conf"
-goto end
-
-:end
-if not "%PAUSE%" == "" pause
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
deleted file mode 100644
index def40f7..0000000
--- a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
+++ /dev/null
@@ -1,135 +0,0 @@
-# ------------------------------------------------------------------------
-# 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.
-# ------------------------------------------------------------------------
-
-#********************************************************************
-# Wrapper Properties
-#********************************************************************
-set.default.JAVA_HOME=${java.home}
-set.default.KARAF_HOME=${karaf.home}
-set.default.KARAF_BASE=${karaf.base}
-set.default.KARAF_DATA=${karaf.data}
-set.default.KARAF_ETC=${karaf.etc}
-
-# Java Application
-wrapper.working.dir=%KARAF_BASE%
-wrapper.java.command=%JAVA_HOME%/bin/java
-wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
-wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
-wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
-wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
-wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
-wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
-wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
-wrapper.java.library.path.1=%KARAF_HOME%/lib/
-
-# Application Parameters. Add parameters as needed starting from 1
-#wrapper.app.parameter.1=
-
-# JVM Parameters
-# note that n is the parameter number starting from 1.
-wrapper.java.additional.1=-Dkaraf.home="%KARAF_HOME%"
-wrapper.java.additional.2=-Dkaraf.base="%KARAF_BASE%"
-wrapper.java.additional.3=-Dkaraf.data="%KARAF_DATA%"
-wrapper.java.additional.4=-Dkaraf.etc="%KARAF_ETC%"
-wrapper.java.additional.5=-Dcom.sun.management.jmxremote
-wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
-wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
-wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
-wrapper.java.additional.9=-Djava.endorsed.dirs="%JAVA_HOME%/jre/lib/endorsed;%JAVA_HOME%/lib/endorsed;%KARAF_HOME%/lib/endorsed"
-wrapper.java.additional.10=-Djava.ext.dirs="%JAVA_HOME%/jre/lib/ext;%JAVA_HOME%/lib/ext;%KARAF_HOME%/lib/ext"
-
-# Uncomment to enable jmx
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
-#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
-
-# Uncomment to enable YourKit profiling
-#wrapper.java.additional.n=-Xrunyjpagent
-
-# Uncomment to enable remote debugging
-#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
-#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
-
-# Initial Java Heap Size (in MB)
-#wrapper.java.initmemory=3
-
-# Maximum Java Heap Size (in MB)
-wrapper.java.maxmemory=512
-
-
-#********************************************************************
-# Wrapper Logging Properties
-#********************************************************************
-# Format of output for the console. (See docs for formats)
-wrapper.console.format=PM
-
-# Log Level for console output. (See docs for log levels)
-wrapper.console.loglevel=INFO
-
-# Log file to use for wrapper output logging.
-wrapper.logfile=%KARAF_DATA%/log/wrapper.log
-
-# Format of output for the log file. (See docs for formats)
-wrapper.logfile.format=LPTM
-
-# Log Level for log file output. (See docs for log levels)
-wrapper.logfile.loglevel=INFO
-
-# Maximum size that the log file will be allowed to grow to before
-# the log is rolled. Size is specified in bytes. The default value
-# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
-# 'm' (mb) suffix. For example: 10m = 10 megabytes.
-wrapper.logfile.maxsize=10m
-
-# Maximum number of rolled log files which will be allowed before old
-# files are deleted. The default value of 0 implies no limit.
-wrapper.logfile.maxfiles=5
-
-# Log Level for sys/event log output. (See docs for log levels)
-wrapper.syslog.loglevel=NONE
-
-#********************************************************************
-# Wrapper Windows Properties
-#********************************************************************
-# Title to use when running as a console
-wrapper.console.title=${name}
-
-#********************************************************************
-# Wrapper Windows NT/2000/XP Service Properties
-#********************************************************************
-# WARNING - Do not modify any of these properties when an application
-# using this configuration file has been installed as a service.
-# Please uninstall the service before modifying this section. The
-# service can then be reinstalled.
-
-# Name of the service
-wrapper.ntservice.name=${name}
-
-# Display name of the service
-wrapper.ntservice.displayname=${displayName}
-
-# Description of the service
-wrapper.ntservice.description=${description}
-
-# Service dependencies. Add dependencies as needed starting from 1
-wrapper.ntservice.dependency.1=
-
-# Mode in which the service is installed. AUTO_START or DEMAND_START
-wrapper.ntservice.starttype=${startType}
-
-# Allow the service to interact with the desktop.
-wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe
deleted file mode 100755
index db2ddda..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll b/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll
deleted file mode 100644
index f07fc9e..0000000
Binary files a/wrapper/core/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll and /dev/null differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/pom.xml
----------------------------------------------------------------------
diff --git a/wrapper/pom.xml b/wrapper/pom.xml
index 3c809b9..6f36786 100644
--- a/wrapper/pom.xml
+++ b/wrapper/pom.xml
@@ -10,7 +10,7 @@
(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
+ 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,
@@ -29,13 +29,105 @@
</parent>
<groupId>org.apache.karaf.wrapper</groupId>
- <artifactId>wrapper</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Wrapper</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.wrapper.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Wrapper :: Core</name>
+ <description>
+ Core implementation and integration of the Java Service Wrapper.
+ It provides a complete integration of Karaf with your Operating System.
+ </description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.main</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>tanukisoft</groupId>
+ <artifactId>wrapper</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </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.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>Main</mainClass>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.karaf.wrapper,
+ org.apache.karaf.wrapper.management
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.wrapper.commands,
+ org.apache.karaf.wrapper.internal,
+ org.apache.karaf.wrapper.internal.osgi,
+ org.apache.karaf.wrapper.management.internal,
+ org.tanukisoftware.wrapper*,
+ org.apache.karaf.main*,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Import-Package>
+ !org.apache.felix.utils.properties,
+ !org.apache.karaf.util.locks,
+ !org.apache.karaf.info,
+ *
+ </Import-Package>
+ <Bundle-Activator>
+ org.apache.karaf.wrapper.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>
+ org.apache.karaf.wrapper.commands
+ </Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/WrapperService.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/WrapperService.java b/wrapper/src/main/java/org/apache/karaf/wrapper/WrapperService.java
new file mode 100644
index 0000000..fb05a16
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/WrapperService.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.wrapper;
+
+import java.io.File;
+
+/**
+ * Interface describing the Wrapper service.
+ */
+public interface WrapperService {
+
+ /**
+ * Install the Karaf container as a system service in the OS.
+ */
+ public void install() throws Exception;
+
+ /**
+ * Install the Karaf container as a system service in the OS.
+ *
+ * @param name The service name that will be used when installing the service.
+ * @param displayName The display name of the service.
+ * @param description The description of the service.
+ * @param startType Mode in which the service is installed. AUTO_START or DEMAND_START.
+ * @return an array containing the wrapper configuration file (index 0) and the service file (index 1)
+ */
+ public File[] install(String name, String displayName, String description, String startType) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/commands/Install.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/commands/Install.java b/wrapper/src/main/java/org/apache/karaf/wrapper/commands/Install.java
new file mode 100644
index 0000000..346f6f1
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/commands/Install.java
@@ -0,0 +1,199 @@
+/*
+ * 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.wrapper.commands;
+
+import java.io.File;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.wrapper.WrapperService;
+
+import static org.apache.karaf.shell.support.ansi.SimpleAnsi.INTENSITY_BOLD;
+import static org.apache.karaf.shell.support.ansi.SimpleAnsi.INTENSITY_NORMAL;
+
+/**
+ * Installs the Karaf instance as a service in your operating system.
+ */
+@Command(scope = "wrapper", name = "install", description = "Install the container as a system service in the OS.")
+@Service
+public class Install implements Action {
+
+ @Option(name = "-n", aliases = { "--name" }, description = "The service name that will be used when installing the service. (Default: karaf)", required = false, multiValued = false)
+ private String name = "karaf";
+
+ @Option(name = "-d", aliases = { "--display" }, description = "The display name of the service.", required = false, multiValued = false)
+ private String displayName = "karaf";
+
+ @Option(name = "-D", aliases = { "--description" }, description = "The description of the service.", required = false, multiValued = false)
+ private String description = "";
+
+ @Option(name = "-s", aliases = { "--start-type" }, description = "Mode in which the service is installed. AUTO_START or DEMAND_START (Default: AUTO_START)", required = false, multiValued = false)
+ private String startType = "AUTO_START";
+
+ @Reference
+ private WrapperService wrapperService;
+
+ @Override
+ public Object execute() throws Exception {
+ File[] wrapperPaths = wrapperService.install(name, displayName, description, startType);
+
+ String os = System.getProperty("os.name", "Unknown");
+ File wrapperConf = wrapperPaths[0];
+ File serviceFile = wrapperPaths[1];
+
+ System.out.println("");
+ System.out.println("Setup complete. You may wish to tweak the JVM properties in the wrapper configuration file:");
+ System.out.println("\t" + wrapperConf.getPath());
+ System.out.println("before installing and starting the service.");
+ System.out.println("");
+ if (os.startsWith("Win")) {
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "MS Windows system detected:" + INTENSITY_NORMAL);
+ System.out.println("To install the service, run: ");
+ System.out.println(" C:> " + serviceFile.getPath() + " install");
+ System.out.println("");
+ System.out.println("Once installed, to start the service run: ");
+ System.out.println(" C:> net start \"" + name + "\"");
+ System.out.println("");
+ System.out.println("Once running, to stop the service run: ");
+ System.out.println(" C:> net stop \"" + name + "\"");
+ System.out.println("");
+ System.out.println("Once stopped, to remove the installed the service run: ");
+ System.out.println(" C:> " + serviceFile.getPath() + " remove");
+ System.out.println("");
+ } else if (os.startsWith("Mac OS X")) {
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "Mac OS X system detected:" + INTENSITY_NORMAL);
+ System.out.println("to add bin/org.apache.karaf.KARAF as user service move this file into ~/Library/LaunchAgents/");
+ System.out.println("> mv bin/org.apache.karaf.KARAF.plist ~/Library/LaunchAgents/");
+ System.out.println("");
+ System.out.println("to add org.apache.karaf.KARAF as system service move this into /Library/LaunchDaemons");
+ System.out.println("> sudo mv bin/org.apache.karaf.KARAF.plist /Library/LaunchDaemons/");
+ System.out.println("change owner and rights");
+ System.out.println("> sudo chown root:wheel /Library/LaunchDaemons/org.apache.karaf.KARAF.plist");
+ System.out.println("> sudo chmod u=rw,g=r,o=r /Library/LaunchDaemons/org.apache.karaf.KARAF.plist");
+ System.out.println("");
+ System.out.println("test your service");
+ System.out.println("> launchctl load ~/Library/LaunchAgents/org.apache.karaf.KARAF.plist");
+ System.out.println("> launchctl start org.apache.karaf.KARAF");
+ System.out.println("> launchctl stop org.apache.karaf.KARAF");
+ System.out.println("");
+ System.out.println("after restart your session or system");
+ System.out.println("you can use launchctl command to start and stop your service");
+ System.out.println("");
+ System.out.println("for removing the service call");
+ System.out.println("> launchctl remove org.apache.karaf.KARAF");
+ System.out.println("");
+ } else if (os.startsWith("Linux")) {
+
+ File debianVersion = new File("/etc/debian_version");
+ File redhatRelease = new File("/etc/redhat-release");
+
+ if (redhatRelease.exists()) {
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "RedHat/Fedora/CentOS Linux system detected:" + INTENSITY_NORMAL);
+ System.out.println(" To install the service:");
+ System.out.println(" $ ln -s " + serviceFile.getPath() + " /etc/init.d/");
+ System.out.println(" $ chkconfig " + serviceFile.getName() + " --add");
+ System.out.println("");
+ System.out.println(" To start the service when the machine is rebooted:");
+ System.out.println(" $ chkconfig " + serviceFile.getName() + " on");
+ System.out.println("");
+ System.out.println(" To disable starting the service when the machine is rebooted:");
+ System.out.println(" $ chkconfig " + serviceFile.getName() + " off");
+ System.out.println("");
+ System.out.println(" To start the service:");
+ System.out.println(" $ service " + serviceFile.getName() + " start");
+ System.out.println("");
+ System.out.println(" To stop the service:");
+ System.out.println(" $ service " + serviceFile.getName() + " stop");
+ System.out.println("");
+ System.out.println(" To uninstall the service :");
+ System.out.println(" $ chkconfig " + serviceFile.getName() + " --del");
+ System.out.println(" $ rm /etc/init.d/" + serviceFile.getPath());
+ } else if (debianVersion.exists()) {
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "Ubuntu/Debian Linux system detected:" + INTENSITY_NORMAL);
+ System.out.println(" To install the service:");
+ System.out.println(" $ ln -s " + serviceFile.getPath() + " /etc/init.d/");
+ System.out.println("");
+ System.out.println(" To start the service when the machine is rebooted:");
+ System.out.println(" $ update-rc.d " + serviceFile.getName() + " defaults");
+ System.out.println("");
+ System.out.println(" To disable starting the service when the machine is rebooted:");
+ System.out.println(" $ update-rc.d -f " + serviceFile.getName() + " remove");
+ System.out.println("");
+ System.out.println(" To start the service:");
+ System.out.println(" $ /etc/init.d/" + serviceFile.getName() + " start");
+ System.out.println("");
+ System.out.println(" To stop the service:");
+ System.out.println(" $ /etc/init.d/" + serviceFile.getName() + " stop");
+ System.out.println("");
+ System.out.println(" To uninstall the service :");
+ System.out.println(" $ rm /etc/init.d/" + serviceFile.getName());
+ } else {
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "On Redhat/Fedora/CentOS Systems:" + INTENSITY_NORMAL);
+ System.out.println(" To install the service:");
+ System.out.println(" $ ln -s "+serviceFile.getPath()+" /etc/init.d/");
+ System.out.println(" $ chkconfig "+serviceFile.getName()+" --add");
+ System.out.println("");
+ System.out.println(" To start the service when the machine is rebooted:");
+ System.out.println(" $ chkconfig "+serviceFile.getName()+" on");
+ System.out.println("");
+ System.out.println(" To disable starting the service when the machine is rebooted:");
+ System.out.println(" $ chkconfig "+serviceFile.getName()+" off");
+ System.out.println("");
+ System.out.println(" To start the service:");
+ System.out.println(" $ service "+serviceFile.getName()+" start");
+ System.out.println("");
+ System.out.println(" To stop the service:");
+ System.out.println(" $ service "+serviceFile.getName()+" stop");
+ System.out.println("");
+ System.out.println(" To uninstall the service :");
+ System.out.println(" $ chkconfig "+serviceFile.getName()+" --del");
+ System.out.println(" $ rm /etc/init.d/"+serviceFile.getName());
+
+ System.out.println("");
+ System.out.println(INTENSITY_BOLD + "On Ubuntu/Debian Systems:" + INTENSITY_NORMAL);
+ System.out.println(" To install the service:");
+ System.out.println(" $ ln -s "+serviceFile.getPath()+" /etc/init.d/");
+ System.out.println("");
+ System.out.println(" To start the service when the machine is rebooted:");
+ System.out.println(" $ update-rc.d "+serviceFile.getName()+" defaults");
+ System.out.println("");
+ System.out.println(" To disable starting the service when the machine is rebooted:");
+ System.out.println(" $ update-rc.d -f "+serviceFile.getName()+" remove");
+ System.out.println("");
+ System.out.println(" To start the service:");
+ System.out.println(" $ /etc/init.d/"+serviceFile.getName()+" start");
+ System.out.println("");
+ System.out.println(" To stop the service:");
+ System.out.println(" $ /etc/init.d/"+serviceFile.getName()+" stop");
+ System.out.println("");
+ System.out.println(" To uninstall the service :");
+ System.out.println(" $ rm /etc/init.d/"+serviceFile.getName());
+ }
+
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/internal/Main.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/internal/Main.java b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/Main.java
new file mode 100644
index 0000000..8f3060e
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/Main.java
@@ -0,0 +1,146 @@
+/*
+ * 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.wrapper.internal;
+
+import org.apache.karaf.main.ShutdownCallback;
+import org.tanukisoftware.wrapper.WrapperListener;
+import org.tanukisoftware.wrapper.WrapperManager;
+
+/**
+ * Java Service Wrapper Main class
+ */
+public class Main extends Thread implements WrapperListener, ShutdownCallback {
+
+ private org.apache.karaf.main.Main main;
+ private volatile boolean destroying;
+
+ /*---------------------------------------------------------------
+ * Constructors
+ *-------------------------------------------------------------*/
+ private Main() {
+ }
+
+ /*---------------------------------------------------------------
+ * WrapperListener Methods
+ *-------------------------------------------------------------*/
+
+ /**
+ * The start method is called when the WrapperManager is signaled by the
+ * native Wrapper code that it can start its application. This
+ * method call is expected to return, so a new thread should be launched
+ * if necessary.
+ *
+ * @param args List of arguments used to initialize the application.
+ * @return Any error code if the application should exit on completion
+ * of the start method. If there were no problems then this
+ * method should return null.
+ */
+ public Integer start(String[] args) {
+ main = new org.apache.karaf.main.Main(args);
+ try {
+ main.launch();
+ main.setShutdownCallback(this);
+ start();
+ return null;
+ } catch (Throwable ex) {
+ System.err.println("Could not create framework: " + ex);
+ ex.printStackTrace();
+ return -1;
+ }
+ }
+
+ public void run() {
+ try {
+ main.awaitShutdown();
+ if (!destroying) {
+ WrapperManager.stop(main.getExitCode());
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ /**
+ * Called when the application is shutting down. The Wrapper assumes that
+ * this method will return fairly quickly. If the shutdown code code
+ * could potentially take a long time, then WrapperManager.signalStopping()
+ * should be called to extend the timeout period. If for some reason,
+ * the stop method can not return, then it must call
+ * WrapperManager.stopped() to avoid warning messages from the Wrapper.
+ *
+ * @param exitCode The suggested exit code that will be returned to the OS
+ * when the JVM exits.
+ * @return The exit code to actually return to the OS. In most cases, this
+ * should just be the value of exitCode, however the user code has
+ * the option of changing the exit code if there are any problems
+ * during shutdown.
+ */
+ public int stop(int exitCode) {
+ try {
+ destroying = true;
+ if (!main.destroy()) {
+ System.err.println("Timeout waiting for Karaf to shutdown");
+ return -3;
+ }
+ } catch (Throwable ex) {
+ System.err.println("Error occured shutting down framework: " + ex);
+ ex.printStackTrace();
+ return -2;
+ }
+
+ return main.getExitCode();
+ }
+
+ /**
+ * Call-back method is called by the @{link org.apache.karaf.main.Main} for Signaling
+ * that the stopping process is in progress and the wrapper doesn't kill the JVM.
+ */
+ public void waitingForShutdown(int delay) {
+ WrapperManager.signalStopping(delay);
+ }
+
+ /**
+ * Called whenever the native Wrapper code traps a system control signal
+ * against the Java process. It is up to the callback to take any actions
+ * necessary. Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT,
+ * WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or
+ * WRAPPER_CTRL_SHUTDOWN_EVENT
+ *
+ * @param event The system control signal.
+ */
+ public void controlEvent(int event) {
+ if ((event == WrapperManager.WRAPPER_CTRL_LOGOFF_EVENT)
+ && (WrapperManager.isLaunchedAsService())) {
+ // Ignore
+ } else {
+ WrapperManager.stop(0);
+ // Will not get here.
+ }
+ }
+
+ /*---------------------------------------------------------------
+ * Main Method
+ *-------------------------------------------------------------*/
+ public static void main(String[] args) {
+ // Start the application. If the JVM was launched from the native
+ // Wrapper then the application will wait for the native Wrapper to
+ // call the application's start method. Otherwise the start method
+ // will be called immediately.
+ WrapperManager.start(new Main(), args);
+ }
+
+}
\ No newline at end of file
[44/59] [abbrv] [KARAF-2852] Merge obr/core and obr/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/core/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
----------------------------------------------------------------------
diff --git a/obr/core/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java b/obr/core/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
deleted file mode 100644
index c182165..0000000
--- a/obr/core/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.obr.core.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Resolver;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.obr.core.ObrMBean;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.Version;
-
-/**
- * Implementation of the OBR MBean.
- */
-public class ObrMBeanImpl extends StandardMBean implements ObrMBean {
-
- private static final char VERSION_DELIM = ',';
-
- private BundleContext bundleContext;
- private RepositoryAdmin repositoryAdmin;
-
- public ObrMBeanImpl(BundleContext bundleContext, RepositoryAdmin repositoryAdmin) throws NotCompliantMBeanException {
- super(ObrMBean.class);
- this.bundleContext = bundleContext;
- this.repositoryAdmin = repositoryAdmin;
- }
-
- public List<String> getUrls() {
- Repository[] repositories = repositoryAdmin.listRepositories();
- List<String> urls = new ArrayList<String>();
- for (int i = 0; i < repositories.length; i++) {
- urls.add(repositories[i].getURI());
- }
- return urls;
- }
-
- public TabularData getBundles() throws MBeanException {
- try {
- CompositeType bundleType = new CompositeType("OBR Resource", "Bundle available in the OBR",
- new String[]{"presentationname", "symbolicname", "version"},
- new String[]{"Presentation Name", "Symbolic Name", "Version"},
- new OpenType[]{SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
- TabularType tableType = new TabularType("OBR Resources", "Table of all resources/bundles available in the OBR",
- bundleType, new String[]{"symbolicname", "version"});
- TabularData table = new TabularDataSupport(tableType);
-
- Resource[] resources = repositoryAdmin.discoverResources("(|(presentationname=*)(symbolicname=*))");
- for (int i = 0; i < resources.length; i++) {
- try {
- CompositeData data = new CompositeDataSupport(bundleType,
- new String[]{"presentationname", "symbolicname", "version"},
- new Object[]{resources[i].getPresentationName(), resources[i].getSymbolicName(), resources[i].getVersion().toString()});
- table.put(data);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- return table;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void addUrl(String url) throws MBeanException {
- try {
- repositoryAdmin.addRepository(url);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void removeUrl(String url) {
- repositoryAdmin.removeRepository(url);
- }
-
- public void refreshUrl(String url) throws MBeanException {
- try {
- repositoryAdmin.addRepository(url);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void deployBundle(String bundle) throws MBeanException {
- try {
- deployBundle(bundle, false, false);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void deployBundle(String bundle, boolean start, boolean deployOptional) throws MBeanException {
- try {
- Resolver resolver = repositoryAdmin.resolver();
- String[] target = getTarget(bundle);
- Resource resource = selectNewestVersion(searchRepository(repositoryAdmin, target[0], target[1]));
- if (resource == null) {
- throw new IllegalArgumentException("Unknown bundle " + target[0]);
- }
- resolver.add(resource);
- if ((resolver.getAddedResources() != null) &&
- (resolver.getAddedResources().length > 0)) {
- if (resolver.resolve(deployOptional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
- try {
- resolver.deploy(start ? Resolver.START : 0);
- } catch (IllegalStateException ex) {
- throw new IllegalStateException("Can't deploy using OBR", ex);
- }
- }
- }
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- private Resource[] searchRepository(RepositoryAdmin admin, String targetId, String targetVersion) throws InvalidSyntaxException {
- // Try to see if the targetId is a bundle ID.
- try {
- Bundle bundle = bundleContext.getBundle(Long.parseLong(targetId));
- targetId = bundle.getSymbolicName();
- } catch (NumberFormatException ex) {
- // It was not a number, so ignore.
- }
-
- // The targetId may be a bundle name or a bundle symbolic name,
- // so create the appropriate LDAP query.
- StringBuffer sb = new StringBuffer("(|(presentationname=");
- sb.append(targetId);
- sb.append(")(symbolicname=");
- sb.append(targetId);
- sb.append("))");
- if (targetVersion != null) {
- sb.insert(0, "(&");
- sb.append("(version=");
- sb.append(targetVersion);
- sb.append("))");
- }
- return admin.discoverResources(sb.toString());
- }
-
- private Resource selectNewestVersion(Resource[] resources) {
- int idx = -1;
- Version v = null;
- for (int i = 0; (resources != null) && (i < resources.length); i++) {
- if (i == 0) {
- idx = 0;
- v = resources[i].getVersion();
- } else {
- Version vtmp = resources[i].getVersion();
- if (vtmp.compareTo(v) > 0) {
- idx = i;
- v = vtmp;
- }
- }
- }
- return (idx < 0) ? null : resources[idx];
- }
-
- private String[] getTarget(String bundle) {
- String[] target;
- int idx = bundle.indexOf(VERSION_DELIM);
- if (idx > 0) {
- target = new String[]{bundle.substring(0, idx), bundle.substring(idx + 1)};
- } else {
- target = new String[]{bundle, null};
- }
- return target;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/obr/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/obr/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
deleted file mode 100644
index 4fbe9fb..0000000
--- a/obr/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed 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.
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
- xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
-
- <ext:property-placeholder />
-
- <reference id="repositoryAdmin" interface="org.apache.felix.bundlerepository.RepositoryAdmin"/>
-
- <bean id="obrMBean" class="org.apache.karaf.obr.core.internal.ObrMBeanImpl">
- <argument ref="blueprintBundleContext"/>
- <argument ref="repositoryAdmin"/>
- </bean>
-
- <service ref="obrMBean" auto-export="interfaces">
- <service-properties>
- <entry key="jmx.objectname" value="org.apache.karaf:type=obr,name=${karaf.name}"/>
- </service-properties>
- </service>
-
-</blueprint>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/obr/core/src/main/resources/OSGI-INF/bundle.info b/obr/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index e14433c..0000000
--- a/obr/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,25 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-The obr mbean management bundle exposes an OBR MBean that can be used with any JMX client (for instance JConsole).
-
-The OBR MBean allows quite the same actions that can be performed using obr:* commands:
- * listUrls()
- * addUrl(url)
- * removeUrl(url)
- * refreshUrl(url)
- * list()
- * deploy(bundle)
- * deploy(bundle, start)
-
-h1. See also
-
- * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/pom.xml
----------------------------------------------------------------------
diff --git a/obr/pom.xml b/obr/pom.xml
index 28fbcdd..e0498c7 100644
--- a/obr/pom.xml
+++ b/obr/pom.xml
@@ -29,13 +29,67 @@
</parent>
<groupId>org.apache.karaf.obr</groupId>
- <artifactId>obr</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: OBR</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.obr.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: OBR :: Core</name>
+ <description>OBR core services and MBeans</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.apache.felix</groupId>
+ <artifactId>org.apache.felix.bundlerepository</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>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>
+ <Export-Package>
+ org.apache.karaf.obr.core
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.obr.command,
+ org.apache.karaf.obr.core.internal,
+ </Private-Package>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
new file mode 100644
index 0000000..5aaf13a
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.obr.command;
+
+import java.util.List;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "obr", name = "url-add", description = "Adds a list of repository URLs to the OBR service.")
+@Service
+public class AddUrlCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "urls", description = "Repository URLs to add to the OBR service separated by whitespaces", required = true, multiValued = true)
+ List<String> urls;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ for (String url : urls) {
+ admin.addRepository(url);
+ }
+ persistRepositoryList(admin);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/DeployCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
new file mode 100644
index 0000000..a852c70
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.obr.command;
+
+import java.util.List;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.shell.api.action.Argument;
+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;
+
+@Command(scope = "obr", name = "deploy", description = "Deploys a list of bundles using OBR service.")
+@Service
+public class DeployCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "bundles", description = "List of bundle names to deploy (separated by whitespaces)", required = true, multiValued = true)
+ protected List<String> bundles;
+
+ @Option(name = "-s", aliases = { "--start" }, description = "Start the deployed bundles", required = false, multiValued = false)
+ protected boolean start = false;
+
+ @Option(name = "-d", aliases = { "--deployOptional" }, description = "Deploy optional bundles", required = false, multiValued = false)
+ protected boolean deployOptional = false;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ doDeploy(admin, bundles, start, deployOptional);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/FindCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/FindCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/FindCommand.java
new file mode 100644
index 0000000..fad967b
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/FindCommand.java
@@ -0,0 +1,130 @@
+/*
+ * 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.obr.command;
+
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+@Command(scope = "obr", name = "find", description = "Find OBR bundles for a given filter.")
+@Service
+public class FindCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "requirements", description = "Requirement", required = true, multiValued = true)
+ List<String> requirements;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ Resource[] resources = admin.discoverResources(parseRequirements(admin, requirements));
+ if (resources == null)
+ {
+ System.err.println("No matching resources.");
+ }
+ else
+ {
+ for (int resIdx = 0; resIdx < resources.length; resIdx++)
+ {
+ if (resIdx > 0)
+ {
+ System.out.println("");
+ }
+ printResource(System.out, resources[resIdx]);
+ }
+ }
+ }
+
+ private void printResource(PrintStream out, Resource resource)
+ {
+ String name = resource.getPresentationName();
+ if (name == null) {
+ name = resource.getSymbolicName();
+ }
+
+ printUnderline(out, name.length());
+ out.println(name);
+ printUnderline(out, name .length());
+
+ Map map = resource.getProperties();
+ for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ if (entry.getValue().getClass().isArray())
+ {
+ out.println(entry.getKey() + ":");
+ for (int j = 0; j < Array.getLength(entry.getValue()); j++)
+ {
+ out.println(" " + Array.get(entry.getValue(), j));
+ }
+ }
+ else
+ {
+ out.println(entry.getKey() + ": " + entry.getValue());
+ }
+ }
+
+ Requirement[] reqs = resource.getRequirements();
+ if ((reqs != null) && (reqs.length > 0))
+ {
+ boolean hdr = false;
+ for (int i = 0; i < reqs.length; i++)
+ {
+ if (!reqs[i].isOptional())
+ {
+ if (!hdr)
+ {
+ hdr = true;
+ out.println("Requirements:");
+ }
+ out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
+ }
+ }
+ hdr = false;
+ for (int i = 0; i < reqs.length; i++)
+ {
+ if (reqs[i].isOptional())
+ {
+ if (!hdr)
+ {
+ hdr = true;
+ out.println("Optional Requirements:");
+ }
+ out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
+ }
+ }
+ }
+
+ Capability[] caps = resource.getCapabilities();
+ if ((caps != null) && (caps.length > 0))
+ {
+ out.println("Capabilities:");
+ for (int i = 0; i < caps.length; i++)
+ {
+ out.println(" " + caps[i].getName() + ":" + caps[i].getPropertiesAsMap());
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/InfoCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
new file mode 100644
index 0000000..bacc61b
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
@@ -0,0 +1,108 @@
+/*
+ * 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.obr.command;
+
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "obr", name = "info", description = "Prints information about OBR bundles.")
+@Service
+public class InfoCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "bundles", description = "Specify bundles to query for information (separated by whitespaces)", required = true, multiValued = true)
+ List<String> bundles;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ for (String bundle : bundles) {
+ String[] target = getTarget(bundle);
+ Resource[] resources = searchRepository(admin, target[0], target[1]);
+ if (resources == null)
+ {
+ System.err.println("Unknown bundle and/or version: "
+ + target[0]);
+ }
+ else
+ {
+ for (int resIdx = 0; resIdx < resources.length; resIdx++)
+ {
+ if (resIdx > 0)
+ {
+ System.out.println("");
+ }
+ printResource(System.out, resources[resIdx]);
+ }
+ }
+ }
+ }
+
+ private void printResource(PrintStream out, Resource resource)
+ {
+ printUnderline(out, resource.getPresentationName().length());
+ out.println(resource.getPresentationName());
+ printUnderline(out, resource.getPresentationName().length());
+
+ Map map = resource.getProperties();
+ for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ if (entry.getValue().getClass().isArray())
+ {
+ out.println(entry.getKey() + ":");
+ for (int j = 0; j < Array.getLength(entry.getValue()); j++)
+ {
+ out.println(" " + Array.get(entry.getValue(), j));
+ }
+ }
+ else
+ {
+ out.println(entry.getKey() + ": " + entry.getValue());
+ }
+ }
+
+ Requirement[] reqs = resource.getRequirements();
+ if ((reqs != null) && (reqs.length > 0))
+ {
+ out.println("Requires:");
+ for (int i = 0; i < reqs.length; i++)
+ {
+ out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
+ }
+ }
+
+ Capability[] caps = resource.getCapabilities();
+ if ((caps != null) && (caps.length > 0))
+ {
+ out.println("Capabilities:");
+ for (int i = 0; i < caps.length; i++)
+ {
+ out.println(" " + caps[i].getName() + ":" + caps[i].getPropertiesAsMap());
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/ListCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/ListCommand.java
new file mode 100644
index 0000000..45db82f
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/ListCommand.java
@@ -0,0 +1,85 @@
+/*
+ * 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.obr.command;
+
+import java.util.List;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.shell.api.action.Argument;
+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 = "obr", name = "list", description = "Lists OBR bundles, optionally providing the given packages.")
+@Service
+public class ListCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "packages", description = "A list of packages separated by whitespaces.", required = false, multiValued = true)
+ List<String> packages;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Override
+ void doExecute(RepositoryAdmin admin) throws Exception {
+ StringBuilder substr = new StringBuilder();
+
+ if (packages != null) {
+ for (String packageName : packages) {
+ substr.append(" ");
+ substr.append(packageName);
+ }
+ }
+
+ String query;
+ if ((substr == null) || (substr.length() == 0)) {
+ query = "(|(presentationname=*)(symbolicname=*))";
+ } else {
+ query = "(|(presentationname=*" + substr + "*)(symbolicname=*" + substr + "*))";
+ }
+ Resource[] resources = admin.discoverResources(query);
+ int maxPName = 4;
+ int maxSName = 13;
+ int maxVersion = 7;
+ for (Resource resource : resources) {
+ maxPName = Math.max(maxPName, emptyIfNull(resource.getPresentationName()).length());
+ maxSName = Math.max(maxSName, emptyIfNull(resource.getSymbolicName()).length());
+ maxVersion = Math.max(maxVersion, emptyIfNull(resource.getVersion()).length());
+ }
+
+ ShellTable table = new ShellTable();
+ table.column("Name");
+ table.column("Symbolic Name");
+ table.column("Version");
+ table.emptyTableText("No matching bundles");
+
+ for (Resource resource : resources) {
+ table.addRow().addContent(emptyIfNull(resource.getPresentationName()),
+ emptyIfNull(resource.getSymbolicName()),
+ emptyIfNull(resource.getVersion()));
+ }
+
+ table.print(System.out, !noFormat);
+ }
+
+ private String emptyIfNull(Object st) {
+ return st == null ? "" : st.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
new file mode 100644
index 0000000..1c07236
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.obr.command;
+
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+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 = "obr", name = "url-list", description = "Displays the repository URLs currently associated with the OBR service.")
+@Service
+public class ListUrlCommand extends ObrCommandSupport {
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected void doExecute(RepositoryAdmin admin) {
+
+ ShellTable table = new ShellTable();
+ table.column("Index");
+ table.column("OBR URL");
+ table.emptyTableText("No OBR repository URL");
+
+ Repository[] repos = admin.listRepositories();
+ if (repos != null) {
+ for (int i = 0; i < repos.length; i++) {
+ table.addRow().addContent(i, repos[i].getURI());
+ }
+ }
+
+ table.print(System.out, !noFormat);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java b/obr/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
new file mode 100644
index 0000000..5f038b4
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
@@ -0,0 +1,281 @@
+/*
+ * 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.obr.command;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.felix.bundlerepository.Reason;
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resolver;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+public abstract class ObrCommandSupport implements Action {
+
+ protected static final char VERSION_DELIM = ',';
+
+ @Reference
+ private RepositoryAdmin repositoryAdmin;
+
+ @Reference
+ BundleContext bundleContext;
+
+ public void setRepositoryAdmin(RepositoryAdmin repositoryAdmin) {
+ this.repositoryAdmin = repositoryAdmin;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ doExecute(repositoryAdmin);
+ return null;
+ }
+
+ abstract void doExecute(RepositoryAdmin admin) throws Exception;
+
+ protected Resource[] searchRepository(RepositoryAdmin admin, String targetId, String targetVersion) throws InvalidSyntaxException {
+ // Try to see if the targetId is a bundle ID.
+ try {
+ Bundle bundle = bundleContext.getBundle(Long.parseLong(targetId));
+ targetId = bundle.getSymbolicName();
+ } catch (NumberFormatException ex) {
+ // It was not a number, so ignore.
+ }
+
+ // The targetId may be a bundle name or a bundle symbolic name,
+ // so create the appropriate LDAP query.
+ StringBuffer sb = new StringBuffer("(|(presentationname=");
+ sb.append(targetId);
+ sb.append(")(symbolicname=");
+ sb.append(targetId);
+ sb.append("))");
+ if (targetVersion != null) {
+ sb.insert(0, "(&");
+ sb.append("(version=");
+ sb.append(targetVersion);
+ sb.append("))");
+ }
+ return admin.discoverResources(sb.toString());
+ }
+
+ public Resource selectNewestVersion(Resource[] resources) {
+ int idx = -1;
+ Version v = null;
+ for (int i = 0; (resources != null) && (i < resources.length); i++) {
+ if (i == 0) {
+ idx = 0;
+ v = resources[i].getVersion();
+ } else {
+ Version vtmp = resources[i].getVersion();
+ if (vtmp.compareTo(v) > 0) {
+ idx = i;
+ v = vtmp;
+ }
+ }
+ }
+ return (idx < 0) ? null : resources[idx];
+ }
+
+ protected String[] getTarget(String bundle) {
+ String[] target;
+ int idx = bundle.indexOf(VERSION_DELIM);
+ if (idx > 0) {
+ target = new String[]{bundle.substring(0, idx), bundle.substring(idx + 1)};
+ } else {
+ target = new String[]{bundle, null};
+ }
+ return target;
+ }
+
+ protected void printUnderline(PrintStream out, int length) {
+ for (int i = 0; i < length; i++) {
+ out.print('-');
+ }
+ out.println("");
+ }
+
+ protected void doDeploy(RepositoryAdmin admin, List<String> bundles, boolean start, boolean deployOptional) throws Exception {
+ Resolver resolver = admin.resolver();
+ for (String bundle : bundles) {
+ String[] target = getTarget(bundle);
+ Resource resource = selectNewestVersion(searchRepository(admin, target[0], target[1]));
+ if (resource != null) {
+ resolver.add(resource);
+ } else {
+ System.err.println("Unknown bundle - " + target[0]);
+ }
+ }
+ if ((resolver.getAddedResources() != null) &&
+ (resolver.getAddedResources().length > 0)) {
+ if (resolver.resolve(deployOptional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
+ System.out.println("Target resource(s):");
+ printUnderline(System.out, 19);
+ Resource[] resources = resolver.getAddedResources();
+ for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) {
+ System.out.println(" " + resources[resIdx].getPresentationName()
+ + " (" + resources[resIdx].getVersion() + ")");
+ }
+ resources = resolver.getRequiredResources();
+ if ((resources != null) && (resources.length > 0)) {
+ System.out.println("\nRequired resource(s):");
+ printUnderline(System.out, 21);
+ for (int resIdx = 0; resIdx < resources.length; resIdx++) {
+ System.out.println(" " + resources[resIdx].getPresentationName()
+ + " (" + resources[resIdx].getVersion() + ")");
+ }
+ }
+ if (deployOptional) {
+ resources = resolver.getOptionalResources();
+ if ((resources != null) && (resources.length > 0)) {
+ System.out.println("\nOptional resource(s):");
+ printUnderline(System.out, 21);
+ for (int resIdx = 0; resIdx < resources.length; resIdx++) {
+ System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")");
+ }
+ }
+ }
+
+ try {
+ System.out.print("\nDeploying...");
+ resolver.deploy(start ? Resolver.START : 0);
+ System.out.println("done.");
+ } catch (IllegalStateException ex) {
+ System.err.println(ex);
+ }
+ } else {
+ Reason[] reqs = resolver.getUnsatisfiedRequirements();
+ if ((reqs != null) && (reqs.length > 0)) {
+ System.out.println("Unsatisfied requirement(s):");
+ printUnderline(System.out, 27);
+ for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) {
+ System.out.println(" " + reqs[reqIdx].getRequirement().getFilter());
+ System.out.println(" " + reqs[reqIdx].getResource().getPresentationName());
+ }
+ } else {
+ System.out.println("Could not resolve targets.");
+ }
+ }
+ }
+
+ }
+
+
+ protected Requirement parseRequirement(RepositoryAdmin admin, String req) throws InvalidSyntaxException {
+ int p = req.indexOf(':');
+ String name;
+ String filter;
+ if (p > 0) {
+ name = req.substring(0, p);
+ filter = req.substring(p + 1);
+ } else {
+ if (req.contains("package")) {
+ name = "package";
+ } else if (req.contains("service")) {
+ name = "service";
+ } else {
+ name = "bundle";
+ }
+ filter = req;
+ }
+ if (!filter.startsWith("(")) {
+ filter = "(" + filter + ")";
+ }
+ return admin.getHelper().requirement(name, filter);
+ }
+
+ protected Requirement[] parseRequirements(RepositoryAdmin admin, List<String> requirements) throws InvalidSyntaxException {
+ Requirement[] reqs = new Requirement[requirements.size()];
+ for (int i = 0; i < reqs.length; i++) {
+ reqs[i] = parseRequirement(admin, requirements.get(i));
+ }
+ return reqs;
+ }
+
+ public static final String REPOSITORY_URL_PROP = "obr.repository.url";
+
+ protected void persistRepositoryList(RepositoryAdmin admin) {
+ try {
+ StringBuilder sb = new StringBuilder();
+ for (Repository repo : admin.listRepositories()) {
+ if (sb.length() > 0) {
+ sb.append(" ");
+ }
+ sb.append(repo.getURI());
+ }
+ File etc = new File(System.getProperty("karaf.etc"));
+ File sys = new File(etc, "config.properties");
+ File sysTmp = new File(etc, "config.properties.tmp");
+
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(sysTmp)));
+ boolean modified = false;
+ try {
+ if (sys.exists()) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(sys)));
+ try {
+ String line = reader.readLine();
+ while (line != null) {
+ if (line.matches("obr\\.repository\\.url[:= ].*")) {
+ modified = true;
+ line = "obr.repository.url = " + sb.toString();
+ }
+ writer.write(line);
+ writer.newLine();
+ line = reader.readLine();
+ }
+ } finally {
+ reader.close();
+ }
+ }
+ if (!modified) {
+ writer.newLine();
+ writer.write("# ");
+ writer.newLine();
+ writer.write("# OBR Repository list");
+ writer.newLine();
+ writer.write("# ");
+ writer.newLine();
+ writer.write("obr.repository.url = " + sb.toString());
+ writer.newLine();
+ writer.newLine();
+ }
+ } finally {
+ writer.close();
+ }
+
+ sys.delete();
+ sysTmp.renameTo(sys);
+
+ } catch (Exception e) {
+ System.err.println("Error while persisting repository list");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
new file mode 100644
index 0000000..20a65ed
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.obr.command;
+
+import java.util.List;
+
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.shell.api.action.Argument;
+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;
+
+@Command(scope = "obr", name = "url-refresh", description = "Reloads the repositories to obtain a fresh list of bundles.")
+@Service
+public class RefreshUrlCommand extends ObrCommandSupport {
+
+ @Option(name = "-i", aliases = { "--index" }, description = "Use index to identify URL", required = false, multiValued = false)
+ boolean useIndex;
+
+ @Argument(index = 0, name = "ids", description = "Repository URLs (or indexes if you use -i) to refresh (leave empty for all)", required = false, multiValued = true)
+ List<String> ids;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ if (ids != null && !ids.isEmpty()) {
+ for (String id : ids) {
+ if (useIndex) {
+ Repository[] repos = admin.listRepositories();
+ int index = Integer.parseInt(id);
+ if (index >= 0 && index < repos.length) {
+ admin.addRepository(repos[index].getURI());
+ } else {
+ System.err.println("Invalid index");
+ }
+ } else {
+ admin.addRepository(id);
+ }
+ }
+ } else {
+ Repository[] repos = admin.listRepositories();
+ if ((repos != null) && (repos.length > 0)) {
+ for (int i = 0; i < repos.length; i++) {
+ admin.addRepository(repos[i].getURI());
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java
new file mode 100644
index 0000000..2d41519
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.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.obr.command;
+
+import java.util.List;
+
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.shell.api.action.Argument;
+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;
+
+@Command(scope = "obr", name = "url-remove", description = "Removes a list of repository URLs from the OBR service.")
+@Service
+public class RemoveUrlCommand extends ObrCommandSupport {
+
+ @Option(name = "-i", aliases = { "--index" }, description = "Use index to identify URL", required = false, multiValued = false)
+ boolean useIndex;
+
+ @Argument(index = 0, name = "ids", description = "Repository URLs (or indexes if you use -i) to remove from OBR service", required = true, multiValued = true)
+ List<String> ids;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ for (String id : ids) {
+ if (useIndex) {
+ Repository[] repos = admin.listRepositories();
+ int index = Integer.parseInt(id);
+ if (index >= 0 && index < repos.length) {
+ admin.removeRepository(repos[index].getURI());
+ } else {
+ System.err.println("Invalid index");
+ }
+ } else {
+ admin.removeRepository(id);
+ }
+ }
+ persistRepositoryList(admin);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
new file mode 100644
index 0000000..ab1bd04
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
@@ -0,0 +1,145 @@
+/*
+ * 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.obr.command;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.bundlerepository.Reason;
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resolver;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.shell.api.action.Argument;
+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;
+
+@Command(scope = "obr", name = "resolve", description = "Shows the resolution output for a given set of requirements.")
+@Service
+public class ResolveCommand extends ObrCommandSupport {
+
+ @Option(name = "-w", aliases = "--why", description = "Display the reason of the inclusion of the resource")
+ boolean why;
+
+ @Option(name = "-l", aliases = "--no-local", description = "Ignore local resources during resolution")
+ boolean noLocal;
+
+ @Option(name = "--no-remote", description = "Ignore remote resources during resolution")
+ boolean noRemote;
+
+ @Option(name = "--deploy", description = "Deploy the selected bundles")
+ boolean deploy;
+
+ @Option(name = "--start", description = "Deploy and start the selected bundles")
+ boolean start;
+
+ @Option(name = "--optional", description = "Resolve optional dependencies")
+ boolean optional;
+
+ @Argument(index = 0, name = "requirements", description = "Requirements", required = true, multiValued = true)
+ List<String> requirements;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ List<Repository> repositories = new ArrayList<Repository>();
+ repositories.add(admin.getSystemRepository());
+ if (!noLocal) {
+ repositories.add(admin.getLocalRepository());
+ }
+ if (!noRemote) {
+ repositories.addAll(Arrays.asList(admin.listRepositories()));
+ }
+ Resolver resolver = admin.resolver(repositories.toArray(new Repository[repositories.size()]));
+ for (Requirement requirement : parseRequirements(admin, requirements)) {
+ resolver.add(requirement);
+ }
+ if (resolver.resolve(optional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
+ Resource[] resources;
+ resources = resolver.getRequiredResources();
+ if ((resources != null) && (resources.length > 0)) {
+ System.out.println("Required resource(s):");
+ printUnderline(System.out, 21);
+ for (int resIdx = 0; resIdx < resources.length; resIdx++) {
+ System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")");
+ if (why) {
+ Reason[] req = resolver.getReason(resources[resIdx]);
+ for (int reqIdx = 0; req != null && reqIdx < req.length; reqIdx++) {
+ if (!req[reqIdx].getRequirement().isOptional()) {
+ Resource r = req[reqIdx].getResource();
+ if (r != null) {
+ System.out.println(" - " + r.getPresentationName() + " / " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
+ } else {
+ System.out.println(" - " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
+ }
+ }
+ }
+ }
+ }
+ }
+ resources = resolver.getOptionalResources();
+ if ((resources != null) && (resources.length > 0)) {
+ System.out.println();
+ System.out.println("Optional resource(s):");
+ printUnderline(System.out, 21);
+ for (int resIdx = 0; resIdx < resources.length; resIdx++) {
+ System.out.println(" " + resources[resIdx].getPresentationName()
+ + " (" + resources[resIdx].getVersion() + ")");
+ if (why) {
+ Reason[] req = resolver.getReason(resources[resIdx]);
+ for (int reqIdx = 0; req != null && reqIdx < req.length; reqIdx++) {
+ if (!req[reqIdx].getRequirement().isOptional()) {
+ Resource r = req[reqIdx].getResource();
+ if (r != null) {
+ System.out.println(" - " + r.getPresentationName() + " / " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
+ } else {
+ System.out.println(" - " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
+ }
+ }
+ }
+ }
+ }
+ }
+ if (deploy || start) {
+ try
+ {
+ System.out.print("\nDeploying...");
+ resolver.deploy(start ? Resolver.START : 0);
+ System.out.println("done.");
+ }
+ catch (IllegalStateException ex)
+ {
+ System.err.println(ex);
+ }
+ }
+ } else {
+ Reason[] reqs = resolver.getUnsatisfiedRequirements();
+ if ((reqs != null) && (reqs.length > 0)) {
+ System.out.println("Unsatisfied requirement(s):");
+ printUnderline(System.out, 27);
+ for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) {
+ System.out.println(" " + reqs[reqIdx].getRequirement().getName() + ":" + reqs[reqIdx].getRequirement().getFilter());
+ System.out.println(" " +reqs[reqIdx].getResource().getPresentationName());
+ }
+ } else {
+ System.out.println("Could not resolve targets.");
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/SourceCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
new file mode 100644
index 0000000..161ba82
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.obr.command;
+
+import java.net.URI;
+import java.util.List;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.obr.command.util.FileUtil;
+import org.apache.karaf.shell.api.action.Argument;
+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;
+
+@Command(scope = "obr", name = "source", description = "Downloads the sources for an OBR bundle.")
+@Service
+public class SourceCommand extends ObrCommandSupport {
+
+ @Option(name = "-x", aliases = {}, description = "Extract the archive", required = false, multiValued = false)
+ boolean extract;
+
+ @Argument(index = 0, name = "folder", description = "Local folder for storing sources", required = true, multiValued = false)
+ String localDir;
+
+ @Argument(index = 1, name = "bundles", description = "List of bundles to download the sources for", required = true, multiValued = true)
+ List<String> bundles;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ for (String bundle : bundles) {
+ String[] target = getTarget(bundle);
+ Resource resource = selectNewestVersion(searchRepository(admin, target[0], target[1]));
+ if (resource == null)
+ {
+ System.err.println("Unknown bundle and/or version: " + target[0]);
+ }
+ else
+ {
+ URI srcURL = (URI) resource.getProperties().get(Resource.SOURCE_URI);
+ if (srcURL != null)
+ {
+ FileUtil.downloadSource(System.out, System.err, srcURL.toURL(), localDir, extract);
+ }
+ else
+ {
+ System.err.println("Missing source URL: " + target[0]);
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/StartCommand.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/StartCommand.java b/obr/src/main/java/org/apache/karaf/obr/command/StartCommand.java
new file mode 100644
index 0000000..0465bae
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/StartCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.obr.command;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.shell.api.action.Argument;
+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 java.util.List;
+
+@Command(scope = "obr", name = "start", description = "Deploys and starts a list of bundles using OBR.")
+@Service
+public class StartCommand extends ObrCommandSupport {
+
+ @Argument(index = 0, name = "bundles", description = "List of bundles to deploy (separated by whitespaces)", required = true, multiValued = true)
+ protected List<String> bundles;
+
+ @Option(name = "-d", aliases = { "--deployOptional" }, description = "Deploy optional bundles", required = false, multiValued = false)
+ protected boolean deployOptional = false;
+
+ protected void doExecute(RepositoryAdmin admin) throws Exception {
+ doDeploy(admin, bundles, true, deployOptional);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java b/obr/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
new file mode 100644
index 0000000..26aa0bd
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
@@ -0,0 +1,177 @@
+/*
+ * 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.obr.command.util;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+public class FileUtil
+{
+ public static void downloadSource(
+ PrintStream out, PrintStream err,
+ URL srcURL, String dirStr, boolean extract)
+ {
+ // Get the file name from the URL.
+ String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
+ ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
+ : srcURL.getFile();
+
+ try
+ {
+ out.println("Connecting...");
+
+ File dir = new File(dirStr);
+ if (!dir.exists())
+ {
+ err.println("Destination directory does not exist.");
+ }
+ File file = new File(dir, fileName);
+
+ OutputStream os = new FileOutputStream(file);
+ URLConnection conn = srcURL.openConnection();
+ int total = conn.getContentLength();
+ InputStream is = conn.getInputStream();
+
+ if (total > 0)
+ {
+ out.println("Downloading " + fileName
+ + " ( " + total + " bytes ).");
+ }
+ else
+ {
+ out.println("Downloading " + fileName + ".");
+ }
+ byte[] buffer = new byte[4096];
+ int count = 0;
+ for (int len = is.read(buffer); len > 0; len = is.read(buffer))
+ {
+ count += len;
+ os.write(buffer, 0, len);
+ }
+
+ os.close();
+ is.close();
+
+ if (extract)
+ {
+ is = new FileInputStream(file);
+ JarInputStream jis = new JarInputStream(is);
+ out.println("Extracting...");
+ unjar(jis, dir);
+ jis.close();
+ file.delete();
+ }
+ }
+ catch (Exception ex)
+ {
+ err.println(ex);
+ }
+ }
+
+ public static void unjar(JarInputStream jis, File dir)
+ throws IOException
+ {
+ // Reusable buffer.
+ byte[] buffer = new byte[4096];
+
+ // Loop through JAR entries.
+ for (JarEntry je = jis.getNextJarEntry();
+ je != null;
+ je = jis.getNextJarEntry())
+ {
+ if (je.getName().startsWith("/"))
+ {
+ throw new IOException("JAR resource cannot contain absolute paths.");
+ }
+
+ File target = new File(dir, je.getName());
+
+ // Check to see if the JAR entry is a directory.
+ if (je.isDirectory())
+ {
+ if (!target.exists())
+ {
+ if (!target.mkdirs())
+ {
+ throw new IOException("Unable to create target directory: "
+ + target);
+ }
+ }
+ // Just continue since directories do not have content to copy.
+ continue;
+ }
+
+ int lastIndex = je.getName().lastIndexOf('/');
+ String name = (lastIndex >= 0) ?
+ je.getName().substring(lastIndex + 1) : je.getName();
+ String destination = (lastIndex >= 0) ?
+ je.getName().substring(0, lastIndex) : "";
+
+ // JAR files use '/', so convert it to platform separator.
+ destination = destination.replace('/', File.separatorChar);
+ copy(jis, dir, name, destination, buffer);
+ }
+ }
+
+ public static void copy(
+ InputStream is, File dir, String destName, String destDir, byte[] buffer)
+ throws IOException
+ {
+ if (destDir == null)
+ {
+ destDir = "";
+ }
+
+ // Make sure the target directory exists and
+ // that is actually a directory.
+ File targetDir = new File(dir, destDir);
+ if (!targetDir.exists())
+ {
+ if (!targetDir.mkdirs())
+ {
+ throw new IOException("Unable to create target directory: "
+ + targetDir);
+ }
+ }
+ else if (!targetDir.isDirectory())
+ {
+ throw new IOException("Target is not a directory: "
+ + targetDir);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(new File(targetDir, destName)));
+ int count = 0;
+ while ((count = is.read(buffer)) > 0)
+ {
+ bos.write(buffer, 0, count);
+ }
+ bos.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/core/ObrMBean.java b/obr/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
new file mode 100644
index 0000000..bf5ebcb
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
@@ -0,0 +1,37 @@
+/*
+ * 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.obr.core;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+import java.util.List;
+
+/**
+ * OBR MBean.
+ */
+public interface ObrMBean {
+
+ List<String> getUrls();
+ TabularData getBundles() throws MBeanException;
+
+ void addUrl(String url) throws MBeanException;
+ void removeUrl(String url);
+ void refreshUrl(String url) throws MBeanException;
+
+ void deployBundle(String bundle) throws MBeanException;
+ void deployBundle(String bundle, boolean start, boolean deployOptional) throws MBeanException;
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java b/obr/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
new file mode 100644
index 0000000..c182165
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/core/internal/ObrMBeanImpl.java
@@ -0,0 +1,203 @@
+/*
+ * 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.obr.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Resolver;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.karaf.obr.core.ObrMBean;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+/**
+ * Implementation of the OBR MBean.
+ */
+public class ObrMBeanImpl extends StandardMBean implements ObrMBean {
+
+ private static final char VERSION_DELIM = ',';
+
+ private BundleContext bundleContext;
+ private RepositoryAdmin repositoryAdmin;
+
+ public ObrMBeanImpl(BundleContext bundleContext, RepositoryAdmin repositoryAdmin) throws NotCompliantMBeanException {
+ super(ObrMBean.class);
+ this.bundleContext = bundleContext;
+ this.repositoryAdmin = repositoryAdmin;
+ }
+
+ public List<String> getUrls() {
+ Repository[] repositories = repositoryAdmin.listRepositories();
+ List<String> urls = new ArrayList<String>();
+ for (int i = 0; i < repositories.length; i++) {
+ urls.add(repositories[i].getURI());
+ }
+ return urls;
+ }
+
+ public TabularData getBundles() throws MBeanException {
+ try {
+ CompositeType bundleType = new CompositeType("OBR Resource", "Bundle available in the OBR",
+ new String[]{"presentationname", "symbolicname", "version"},
+ new String[]{"Presentation Name", "Symbolic Name", "Version"},
+ new OpenType[]{SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
+ TabularType tableType = new TabularType("OBR Resources", "Table of all resources/bundles available in the OBR",
+ bundleType, new String[]{"symbolicname", "version"});
+ TabularData table = new TabularDataSupport(tableType);
+
+ Resource[] resources = repositoryAdmin.discoverResources("(|(presentationname=*)(symbolicname=*))");
+ for (int i = 0; i < resources.length; i++) {
+ try {
+ CompositeData data = new CompositeDataSupport(bundleType,
+ new String[]{"presentationname", "symbolicname", "version"},
+ new Object[]{resources[i].getPresentationName(), resources[i].getSymbolicName(), resources[i].getVersion().toString()});
+ table.put(data);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return table;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void addUrl(String url) throws MBeanException {
+ try {
+ repositoryAdmin.addRepository(url);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void removeUrl(String url) {
+ repositoryAdmin.removeRepository(url);
+ }
+
+ public void refreshUrl(String url) throws MBeanException {
+ try {
+ repositoryAdmin.addRepository(url);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void deployBundle(String bundle) throws MBeanException {
+ try {
+ deployBundle(bundle, false, false);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void deployBundle(String bundle, boolean start, boolean deployOptional) throws MBeanException {
+ try {
+ Resolver resolver = repositoryAdmin.resolver();
+ String[] target = getTarget(bundle);
+ Resource resource = selectNewestVersion(searchRepository(repositoryAdmin, target[0], target[1]));
+ if (resource == null) {
+ throw new IllegalArgumentException("Unknown bundle " + target[0]);
+ }
+ resolver.add(resource);
+ if ((resolver.getAddedResources() != null) &&
+ (resolver.getAddedResources().length > 0)) {
+ if (resolver.resolve(deployOptional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
+ try {
+ resolver.deploy(start ? Resolver.START : 0);
+ } catch (IllegalStateException ex) {
+ throw new IllegalStateException("Can't deploy using OBR", ex);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ private Resource[] searchRepository(RepositoryAdmin admin, String targetId, String targetVersion) throws InvalidSyntaxException {
+ // Try to see if the targetId is a bundle ID.
+ try {
+ Bundle bundle = bundleContext.getBundle(Long.parseLong(targetId));
+ targetId = bundle.getSymbolicName();
+ } catch (NumberFormatException ex) {
+ // It was not a number, so ignore.
+ }
+
+ // The targetId may be a bundle name or a bundle symbolic name,
+ // so create the appropriate LDAP query.
+ StringBuffer sb = new StringBuffer("(|(presentationname=");
+ sb.append(targetId);
+ sb.append(")(symbolicname=");
+ sb.append(targetId);
+ sb.append("))");
+ if (targetVersion != null) {
+ sb.insert(0, "(&");
+ sb.append("(version=");
+ sb.append(targetVersion);
+ sb.append("))");
+ }
+ return admin.discoverResources(sb.toString());
+ }
+
+ private Resource selectNewestVersion(Resource[] resources) {
+ int idx = -1;
+ Version v = null;
+ for (int i = 0; (resources != null) && (i < resources.length); i++) {
+ if (i == 0) {
+ idx = 0;
+ v = resources[i].getVersion();
+ } else {
+ Version vtmp = resources[i].getVersion();
+ if (vtmp.compareTo(v) > 0) {
+ idx = i;
+ v = vtmp;
+ }
+ }
+ }
+ return (idx < 0) ? null : resources[idx];
+ }
+
+ private String[] getTarget(String bundle) {
+ String[] target;
+ int idx = bundle.indexOf(VERSION_DELIM);
+ if (idx > 0) {
+ target = new String[]{bundle.substring(0, idx), bundle.substring(idx + 1)};
+ } else {
+ target = new String[]{bundle, null};
+ }
+ return target;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 0000000..4fbe9fb
--- /dev/null
+++ b/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+ xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
+
+ <ext:property-placeholder />
+
+ <reference id="repositoryAdmin" interface="org.apache.felix.bundlerepository.RepositoryAdmin"/>
+
+ <bean id="obrMBean" class="org.apache.karaf.obr.core.internal.ObrMBeanImpl">
+ <argument ref="blueprintBundleContext"/>
+ <argument ref="repositoryAdmin"/>
+ </bean>
+
+ <service ref="obrMBean" auto-export="interfaces">
+ <service-properties>
+ <entry key="jmx.objectname" value="org.apache.karaf:type=obr,name=${karaf.name}"/>
+ </service-properties>
+ </service>
+
+</blueprint>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/obr/src/main/resources/OSGI-INF/bundle.info b/obr/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..e14433c
--- /dev/null
+++ b/obr/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,25 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+The obr mbean management bundle exposes an OBR MBean that can be used with any JMX client (for instance JConsole).
+
+The OBR MBean allows quite the same actions that can be performed using obr:* commands:
+ * listUrls()
+ * addUrl(url)
+ * removeUrl(url)
+ * refreshUrl(url)
+ * list()
+ * deploy(bundle)
+ * deploy(bundle, start)
+
+h1. See also
+
+ * Monitoring and Administration using JMX - section of the Karaf User Guide
[28/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java b/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
deleted file mode 100644
index b95e4dc..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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.instance.core.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import javax.management.openmbean.TabularData;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.apache.karaf.instance.core.InstancesMBean;
-
-public class InstancesMBeanImpl extends StandardMBean implements InstancesMBean {
-
- static final String DEBUG_OPTS = " -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005";
- static final String DEFAULT_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote";
-
- private org.apache.karaf.instance.core.InstanceService instanceService;
-
- public InstancesMBeanImpl(org.apache.karaf.instance.core.InstanceService instanceService) throws NotCompliantMBeanException {
- super(InstancesMBean.class);
- this.instanceService = instanceService;
- }
-
- public int createInstance(String name, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, String features, String featureURLs)
- throws MBeanException {
- try {
- if ("".equals(location)) {
- location = null;
- }
- if ("".equals(javaOpts)) {
- javaOpts = null;
- }
-
- InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts,
- parseStringList(featureURLs), parseStringList(features));
-
- Instance inst = instanceService.createInstance(name, settings, false);
- if (inst != null) {
- return inst.getPid();
- } else {
- return -1;
- }
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void changeSshPort(String name, int port) throws MBeanException {
- try {
- getExistingInstance(name).changeSshPort(port);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void changeRmiRegistryPort(String name, int port) throws MBeanException {
- try {
- getExistingInstance(name).changeRmiRegistryPort(port);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void changeRmiServerPort(String name, int port) throws MBeanException {
- try {
- getExistingInstance(name).changeRmiServerPort(port);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void changeJavaOpts(String name, String javaOpts) throws MBeanException {
- try {
- getExistingInstance(name).changeJavaOpts(javaOpts);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void destroyInstance(String name) throws MBeanException {
- try {
- getExistingInstance(name).destroy();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void startInstance(String name) throws MBeanException {
- try {
- getExistingInstance(name).start(null);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void startInstance(String name, String opts) throws MBeanException {
- try {
- getExistingInstance(name).start(opts);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void startInstance(String name, String opts, boolean wait, boolean debug) throws MBeanException {
- try {
- Instance child = getExistingInstance(name);
- String options = opts;
- if (options == null) {
- options = child.getJavaOpts();
- }
- if (options == null) {
- options = DEFAULT_OPTS;
- }
- if (debug) {
- options += DEBUG_OPTS;
- }
- if (wait) {
- String state = child.getState();
- if (Instance.STOPPED.equals(state)) {
- child.start(opts);
- }
- if (!Instance.STARTED.equals(state)) {
- do {
- Thread.sleep(500);
- state = child.getState();
- } while (Instance.STARTING.equals(state));
- }
- } else {
- child.start(opts);
- }
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void stopInstance(String name) throws MBeanException {
- try {
- getExistingInstance(name).stop();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void renameInstance(String originalName, String newName) throws MBeanException {
- try {
- instanceService.renameInstance(originalName, newName, false);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void renameInstance(String originalName, String newName, boolean verbose) throws MBeanException {
- try {
- instanceService.renameInstance(originalName, newName, verbose);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void cloneInstance(String name, String cloneName, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts) throws MBeanException {
- try {
- if ("".equals(location)) {
- location = null;
- }
- if ("".equals(javaOpts)) {
- javaOpts = null;
- }
-
- InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, null, null);
-
- instanceService.cloneInstance(name, cloneName, settings, false);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public TabularData getInstances() throws MBeanException {
- List<Instance> instances = Arrays.asList(instanceService.getInstances());
- TabularData table = InstanceToTableMapper.tableFrom(instances);
- return table;
- }
-
- private Instance getExistingInstance(String name) {
- Instance i = instanceService.getInstance(name);
- if (i == null) {
- throw new IllegalArgumentException("Instance '" + name + "' does not exist");
- }
- return i;
- }
-
- private List<String> parseStringList(String value) {
- List<String> list = new ArrayList<String>();
- if (value != null) {
- for (String el : value.split(",")) {
- String trimmed = el.trim();
- if (trimmed.length() == 0) {
- continue;
- }
- list.add(trimmed);
- }
- }
- return list;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java b/instance/core/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
deleted file mode 100644
index a50db46..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.instance.core.internal.osgi;
-
-import org.apache.karaf.instance.core.InstanceService;
-import org.apache.karaf.instance.core.internal.InstanceServiceImpl;
-import org.apache.karaf.instance.core.internal.InstancesMBeanImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doStart() throws Exception {
- InstanceService instanceService = new InstanceServiceImpl();
- register(InstanceService.class, instanceService);
-
- InstancesMBeanImpl mbean = new InstancesMBeanImpl(instanceService);
- registerMBean(mbean, "type=instance");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/Process.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/Process.java b/instance/core/src/main/java/org/apache/karaf/jpm/Process.java
deleted file mode 100644
index 2bd3b36..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/Process.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.jpm;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-/**
- * Interface representing a process
- */
-public interface Process extends Serializable {
-
- /**
- * Retrieves the PID of the process
- * @return the pid
- */
- int getPid();
-
- /**
- * Check if this process is still running
- * @return <code>true</code> if the process is running
- * @throws IOException if an error occurs
- */
- boolean isRunning() throws IOException;
-
- /**
- * Destroy the process.
- *
- * @throws IOException
- */
- void destroy() throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java b/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java
deleted file mode 100644
index 2b6c612..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.jpm;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Interface used to create new processes.
- */
-public interface ProcessBuilder {
-
- /**
- * Specified the current directory to run the command from
- *
- * @param dir the directory to run the command from
- * @return the ProcessBuilder instance
- */
- ProcessBuilder directory(File dir);
-
- /**
- * Set the command to execute
- *
- * @param command the command to execute
- * @return the ProcessBuilder instance
- */
- ProcessBuilder command(String command);
-
- /**
- * Create and start the process
- *
- * @return the process that has been started
- * @throws IOException if the process can not be created
- */
- org.apache.karaf.jpm.Process start() throws IOException;
-
- /**
- * Attach to an existing process
- *
- * @return the process that has been attached
- * @throws IOException if the process can not be attached to
- */
- org.apache.karaf.jpm.Process attach(int pid) throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java b/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
deleted file mode 100644
index baa563b..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.jpm;
-
-
-/**
- * Factory for process builders.
- */
-public interface ProcessBuilderFactory {
- ProcessBuilder newBuilder();
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java b/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
deleted file mode 100644
index 12a6905..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.jpm.impl;
-
-import org.apache.karaf.jpm.ProcessBuilder;
-import org.apache.karaf.jpm.ProcessBuilderFactory;
-
-public class ProcessBuilderFactoryImpl implements ProcessBuilderFactory {
-
- public ProcessBuilder newBuilder() {
- return new ProcessBuilderImpl();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java b/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java
deleted file mode 100644
index 08f4407..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.jpm.impl;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.karaf.jpm.Process;
-import org.apache.karaf.jpm.ProcessBuilder;
-
-
-public class ProcessBuilderImpl implements ProcessBuilder {
-
- private File dir;
- private String command;
-
- public ProcessBuilder directory(File dir) {
- this.dir = dir;
- return this;
- }
-
- public ProcessBuilder command(String command) {
- this.command = command;
- return this;
- }
-
- public Process start() throws IOException {
- return ProcessImpl.create(dir, command);
- }
-
- public Process attach(int pid) throws IOException {
- return ProcessImpl.attach(pid);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java b/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
deleted file mode 100644
index d831fb7..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.jpm.impl;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.InterruptedIOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.karaf.jpm.Process;
-
-public class ProcessImpl implements Process {
-
- /**
- *
- */
- private static final long serialVersionUID = -8140632422386086507L;
-
- private int pid;
- //private File input;
- //private File output;
- //private File error;
-
- public ProcessImpl(int pid/*, File input, File output, File error*/) {
- this.pid = pid;
- //this.input = input;
- //this.output = output;
- //this.error = error;
- }
-
- public int getPid() {
- return pid;
- }
-
- public boolean isRunning() throws IOException {
- if (ScriptUtils.isWindows()) {
- Map<String, String> props = new HashMap<String, String>();
- props.put("${pid}", Integer.toString(pid));
- int ret = ScriptUtils.execute("running", props);
- return ret == 0;
- } else {
- try {
- java.lang.Process process = new java.lang.ProcessBuilder("ps", "-p", Integer.toString(pid)).start();
- BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
- r.readLine(); // skip headers
- String s = r.readLine();
- boolean running = s != null && s.length() > 0;
- process.waitFor();
- return running;
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
- }
- }
- }
-
- public void destroy() throws IOException {
- int ret;
- if (ScriptUtils.isWindows()) {
- Map<String, String> props = new HashMap<String, String>();
- props.put("${pid}", Integer.toString(pid));
- ret = ScriptUtils.execute("destroy", props);
- } else {
- ret = ScriptUtils.executeProcess(new java.lang.ProcessBuilder("kill", "-9", Integer.toString(pid)));
- }
- if (ret != 0) {
- throw new IOException("Unable to destroy process, it may already be terminated");
- }
- }
-
- /*
- public OutputStream getInputStream() throws FileNotFoundException {
- return new FileOutputStream(input);
- }
-
- public InputStream getOutputStream() throws FileNotFoundException {
- return new FileInputStream(output);
- }
-
- public InputStream getErrorStream() throws FileNotFoundException {
- return new FileInputStream(error);
- }
- */
-
- public int waitFor() throws InterruptedException {
- return 0;
- }
-
- public int exitValue() {
- return 0;
- }
-
- public static Process create(File dir, String command) throws IOException {
- //File input = File.createTempFile("jpm.", ".input");
- //File output = File.createTempFile("jpm.", ".output");
- //File error = File.createTempFile("jpm.", ".error");
- File pidFile = File.createTempFile("jpm.", ".pid");
- try {
- Map<String, String> props = new HashMap<String, String>();
- //props.put("${in.file}", input.getCanonicalPath());
- //props.put("${out.file}", output.getCanonicalPath());
- //props.put("${err.file}", error.getCanonicalPath());
- props.put("${pid.file}", pidFile.getCanonicalPath());
- props.put("${dir}", dir != null ? dir.getCanonicalPath() : "");
- if (ScriptUtils.isWindows()) {
- command = command.replaceAll("\"", "\"\"");
- }
- props.put("${command}", command);
- int ret = ScriptUtils.execute("start", props);
- if (ret != 0) {
- throw new IOException("Unable to create process (error code: " + ret + ")");
- }
- int pid = readPid(pidFile);
- return new ProcessImpl(pid/*, input, output, error*/);
- } finally {
- pidFile.delete();
- }
- }
-
- public static Process attach(int pid) throws IOException {
- return new ProcessImpl(pid);
- }
-
- private static int readPid(File pidFile) throws IOException {
- InputStream is = new FileInputStream(pidFile);
- try {
- BufferedReader r = new BufferedReader(new InputStreamReader(is));
- String pidString = r.readLine();
- return Integer.valueOf(pidString);
- } finally {
- try {
- is.close();
- } catch (IOException e) {}
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java b/instance/core/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
deleted file mode 100644
index a96e28e..0000000
--- a/instance/core/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.jpm.impl;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.Map;
-import java.util.Scanner;
-
-public class ScriptUtils {
-
- public static int execute(String name, Map<String, String> props) throws IOException {
- File script = File.createTempFile("jpm.", ".script");
- try {
- if (isWindows()) {
- String res = "windows/" + name + ".vbs";
- ScriptUtils.copyFilteredResource(res, script, props);
- return executeProcess(new java.lang.ProcessBuilder("cscript",
- "/NOLOGO",
- "//E:vbs",
- script.getCanonicalPath()));
- } else {
- String res = "unix/" + name + ".sh";
- ScriptUtils.copyFilteredResource(res, script, props);
- return executeProcess(new java.lang.ProcessBuilder("/bin/sh",
- script.getCanonicalPath()));
- }
- } finally {
- script.delete();
- }
- }
-
- public static int executeProcess(java.lang.ProcessBuilder builder) throws IOException {
- try {
- java.lang.Process process = builder.start();
- return process.waitFor();
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
- }
- }
-
- public static void copyFilteredResource(String resource, File outFile, Map<String, String> props) throws IOException {
- InputStream is = null;
- try {
- is = ScriptUtils.class.getResourceAsStream(resource);
- // Read it line at a time so that we can use the platform line ending when we write it out.
- PrintStream out = new PrintStream(new FileOutputStream(outFile));
- try {
- Scanner scanner = new Scanner(is);
- while (scanner.hasNextLine() ) {
- String line = scanner.nextLine();
- line = filter(line, props);
- out.println(line);
- }
- } finally {
- safeClose(out);
- }
- } finally {
- safeClose(is);
- }
- }
-
- private static void safeClose(InputStream is) throws IOException {
- if (is == null) {
- return;
- }
- try {
- is.close();
- } catch (Throwable ignore) {
- }
- }
-
- private static void safeClose(OutputStream is) throws IOException {
- if (is == null) {
- return;
- }
- try {
- is.close();
- } catch (Throwable ignore) {
- }
- }
-
- private static String filter(String line, Map<String, String> props) {
- for (Map.Entry<String, String> i : props.entrySet()) {
- int p1 = line.indexOf(i.getKey());
- if( p1 >= 0 ) {
- String l1 = line.substring(0, p1);
- String l2 = line.substring(p1+i.getKey().length());
- line = l1+i.getValue()+l2;
- }
- }
- return line;
- }
-
- private static final boolean windows;
-
- static {
- windows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
- }
-
- public static boolean isWindows() {
- return windows;
- }
-
- public static String getJavaCommandPath() throws IOException {
- return new File(System.getProperty("java.home"), isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/OSGI-INF/bundle.info b/instance/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 9d305c3..0000000
--- a/instance/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,36 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle is the core implementation of the Karaf instance feature.
-
-Karaf instance allows you to manage Karaf child instances.
-
-You can create new Karaf instances, configure attributes, rename instances, stop instances, etc.
-
-It also provides JMX MBeans related to the Karaf instance feature.
-
-In particular, an InstanceServiceMBean is provided that can be remotely administered using a JMX client (for instance
-JConsole).
-
-With this InstanceServiceMBean, you have the following operations available:
-* createInstance(name, sshPort, rmiPort, location, javaOpts, features, featureURLs) - Creates a new Karaf instance.
-* changeSshPort(name, port) - Changes the SSH port number of an existing Karaf instance.
-* changeRmiRegistryPort(name, port) - Changes the RMI registry port number of an existing Karaf instance.
-* changeRmiServerPort(name, port) - Changes the RMI server port number of an existing Karaf instance.
-* changeJavaOpts(name, javaopts) - Changes the Java options of an existing Karaf instance.
-* destroyInstance(name) - Destroys an existing Karaf instance.
-* startInstance(name) - Starts an existing Karaf instance.
-* stopInstance(name) - Stops an existing Karaf instance.
-* renameInstance(originalName, newName) - Renames an existing Karaf instance.
-
-h1. See also
-
-Managing child instances - of the Karaf User Guide.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
deleted file mode 100644
index 8967cea..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-KARAF_HOME=${SUBST-KARAF-HOME}
-KARAF_BASE=${SUBST-KARAF-BASE}
-
-export KARAF_BASE
-exec ${KARAF_HOME}/bin/karaf "$*"
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
deleted file mode 100644
index e054d83..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
+++ /dev/null
@@ -1,25 +0,0 @@
-@ECHO OFF
-REM =========================================================================
-REM
-REM Licensed to the Apache Software Foundation (ASF) under one or more
-REM contributor license agreements. See the NOTICE file distributed with
-REM this work for additional information regarding copyright ownership.
-REM The ASF licenses this file to You under the Apache License, Version 2.0
-REM (the "License"); you may not use this file except in compliance with
-REM the License. You may obtain a copy of the License at
-REM
-REM http://www.apache.org/licenses/LICENSE-2.0
-REM
-REM Unless required by applicable law or agreed to in writing, software
-REM distributed under the License is distributed on an "AS IS" BASIS,
-REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-REM See the License for the specific language governing permissions and
-REM limitations under the License.
-REM
-REM =========================================================================
-
-SETLOCAL
-SET KARAF_HOME=${SUBST-KARAF-HOME}
-SET KARAF_BASE=${SUBST-KARAF-BASE}
-
-"%KARAF_HOME%\bin\karaf.bat" %*
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start
deleted file mode 100644
index d45d749..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-KARAF_HOME=${SUBST-KARAF-HOME}
-KARAF_NAME=${SUBST-KARAF-NAME}
-
-exec ${KARAF_HOME}/bin/instance start ${KARAF_NAME} "$@"
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
deleted file mode 100644
index 0c530c8..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@ECHO OFF
-REM =========================================================================
-REM
-REM Licensed to the Apache Software Foundation (ASF) under one or more
-REM contributor license agreements. See the NOTICE file distributed with
-REM this work for additional information regarding copyright ownership.
-REM The ASF licenses this file to You under the Apache License, Version 2.0
-REM (the "License"); you may not use this file except in compliance with
-REM the License. You may obtain a copy of the License at
-REM
-REM http://www.apache.org/licenses/LICENSE-2.0
-REM
-REM Unless required by applicable law or agreed to in writing, software
-REM distributed under the License is distributed on an "AS IS" BASIS,
-REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-REM See the License for the specific language governing permissions and
-REM limitations under the License.
-REM
-REM =========================================================================
-
-SET KARAF_HOME=${SUBST-KARAF-HOME}
-SET KARAF_NAME=${SUBST-KARAF-NAME}
-
-"%KARAF_HOME%\bin\instance.bat" start %KARAF_NAME%
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop
deleted file mode 100644
index fb91985..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-KARAF_HOME=${SUBST-KARAF-HOME}
-KARAF_NAME=${SUBST-KARAF-NAME}
-
-exec ${KARAF_HOME}/bin/instance stop ${KARAF_NAME} "$@"
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat b/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
deleted file mode 100644
index 8520acb..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@ECHO OFF
-REM =========================================================================
-REM
-REM Licensed to the Apache Software Foundation (ASF) under one or more
-REM contributor license agreements. See the NOTICE file distributed with
-REM this work for additional information regarding copyright ownership.
-REM The ASF licenses this file to You under the Apache License, Version 2.0
-REM (the "License"); you may not use this file except in compliance with
-REM the License. You may obtain a copy of the License at
-REM
-REM http://www.apache.org/licenses/LICENSE-2.0
-REM
-REM Unless required by applicable law or agreed to in writing, software
-REM distributed under the License is distributed on an "AS IS" BASIS,
-REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-REM See the License for the specific language governing permissions and
-REM limitations under the License.
-REM
-REM =========================================================================
-
-SET KARAF_HOME=${SUBST-KARAF-HOME}
-SET KARAF_NAME=${SUBST-KARAF-NAME}
-
-"%KARAF_HOME%\bin\instance.bat" stop %KARAF_NAME%
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg b/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
deleted file mode 100644
index 57b2957..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
+++ /dev/null
@@ -1,63 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-#
-# The properties in this file define the configuration of Apache Karaf's JMX Management
-#
-
-#
-# Port number for RMI registry connection
-#
-rmiRegistryPort = ${SUBST-RMI-REGISTRY-PORT}
-
-#
-# Port number for RMI server connection
-#
-rmiServerPort = ${SUBST-RMI-SERVER-PORT}
-
-#
-# Name of the JAAS realm used for authentication
-#
-jmxRealm = karaf
-
-#
-# The service URL for the JMXConnectorServer
-#
-serviceUrl = service:jmx:rmi://0.0.0.0:${rmiServerPort}/jndi/rmi://0.0.0.0:${rmiRegistryPort}/karaf-${karaf.name}
-
-#
-# Whether any threads started for the JMXConnectorServer should be started as daemon threads
-#
-daemon = true
-
-#
-# Whether the JMXConnectorServer should be started in a separate thread
-#
-threaded = true
-
-#
-# The ObjectName used to register the JMXConnectorServer
-#
-objectName = connector:name=rmi
-
-#
-# Role name used for JMX access authorization
-# If not set, this defaults to the ${karaf.admin.role} configured in etc/system.properties
-#
-# jmxRole=admin
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg b/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
deleted file mode 100644
index 077f5da..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
+++ /dev/null
@@ -1,75 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-#
-# These properties are used to configure Karaf's ssh shell.
-#
-
-#
-# Via sshPort and sshHost you define the address you can login into Karaf.
-#
-sshPort = ${SUBST-SSH-PORT}
-sshHost = 0.0.0.0
-
-#
-# The sshIdleTimeout defines the inactivity timeout to logout the SSH session.
-# The sshIdleTimeout is in milliseconds, and the default is set to 30 minutes.
-#
-sshIdleTimeout = 1800000
-
-#
-# sshRealm defines which JAAS domain to use for password authentication.
-#
-sshRealm = karaf
-
-#
-# The location of the hostKey file defines where the private/public key of the server
-# is located. If no file is at the defined location it will be ignored.
-#
-hostKey = ${karaf.etc}/host.key
-
-#
-# Role name used for SSH access authorization
-# If not set, this defaults to the ${karaf.admin.role} configured in etc/system.properties
-#
-# sshRole = admin
-
-#
-# Self defined key size in 1024, 2048, 3072, or 4096
-# If not set, this defaults to 1024.
-#
-# keySize = 1024
-
-#
-# Specify host key algorithm, defaults to DSA
-#
-# algorithm = DSA
-
-#
-# Defines the completion mode on the Karaf shell console. The possible values are:
-# - GLOBAL: it's the same behavior as in previous Karaf releases. The completion displays all commands and all aliases
-# ignoring if you are in a subshell or not.
-# - FIRST: the completion displays all commands and all aliases only when you are not in a subshell. When you are
-# in a subshell, the completion displays only the commands local to the subshell.
-# - SUBSHELL: the completion displays only the subshells on the root level. When you are in a subshell, the completion
-# displays only the commands local to the subshell.
-# This property define the default value when you use the Karaf shell console.
-# You can change the completion mode directly in the shell console, using shell:completion command.
-#
-completionMode = GLOBAL
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties b/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
deleted file mode 100644
index a683a34..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
+++ /dev/null
@@ -1,120 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-#
-# The properties defined in this file will be made available through system
-# properties at the very beginning of the Karaf's boot process.
-#
-
-
-# Log level when the pax-logging service is not available
-# This level will only be used while the pax-logging service bundle
-# is not fully available.
-# To change log levels, please refer to the org.ops4j.pax.logging.cfg file
-# instead.
-org.ops4j.pax.logging.DefaultServiceLog.level = ERROR
-
-#
-# Name of this Karaf instance.
-#
-karaf.name = ${SUBST-KARAF-NAME}
-
-#
-# Default repository where bundles will be loaded from before using
-# other Maven repositories. For the full Maven configuration, see
-# the org.ops4j.pax.url.mvn.cfg file.
-#
-karaf.default.repository = system
-
-#
-# Location of a shell script that will be run when starting a shell
-# session. This script can be used to create aliases and define
-# additional commands.
-#
-karaf.shell.init.script = ${karaf.etc}/shell.init.script
-
-#
-# Sets the maximum size of the shell command history. If not set,
-# defaults to 500 entries. Setting to 0 will disable history.
-#
-# karaf.shell.history.maxSize = 0
-
-#
-# Deletes the entire karaf.data directory at every start
-#
-karaf.clean.all = false
-
-#
-# Deletes the karaf.data/cache directory at every start
-#
-karaf.clean.cache = false
-
-#
-# Roles to use when logging into a local Karaf console.
-#
-# The syntax is the following:
-# [classname:]principal
-# where classname is the class name of the principal object
-# (defaults to org.apache.karaf.jaas.modules.RolePrincipal)
-# and principal is the name of the principal of that class
-# (defaults to instance).
-#
-karaf.local.roles = admin,manager,viewer
-
-#
-# Set this empty property to avoid errors when validating xml documents.
-#
-xml.catalog.files =
-
-#
-# Suppress the bell in the console when hitting backspace too many times
-# for example
-#
-jline.nobell = true
-
-#
-# ServiceMix specs options
-#
-org.apache.servicemix.specs.debug = false
-org.apache.servicemix.specs.timeout = 100
-
-#
-# Settings for the OSGi 4.3 Weaving
-# By default, we will not weave any classes. Change this setting to include classes
-# that you application needs to have woven.
-#
-org.apache.aries.proxy.weaving.enabled = none
-# Classes not to weave - Aries default + Xerces which is known to have issues.
-org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.*
-
-#
-# By default, only Karaf shell commands are secured, but additional services can be
-# secured by expanding this filter
-#
-karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*))
-
-#
-# Security properties
-#
-# To enable OSGi security, uncomment the properties below,
-# install the framework-security feature and restart.
-#
-#java.security.policy=${karaf.etc}/all.policy
-#org.osgi.framework.security=osgi
-#org.osgi.framework.trust.repositories=${karaf.etc}/trustStore.ks
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh b/instance/core/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
deleted file mode 100644
index 1d1d720..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-#exec 1>${out.file}
-#exec 2>${err.file}
-exec 1>/dev/null
-exec 2>/dev/null
-if [ "x${dir}" != "x" ]; then
- cd ${dir}
-fi
-nohup ${command} &
-echo $! > ${pid.file}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs b/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
deleted file mode 100644
index abd60eb..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
+++ /dev/null
@@ -1,27 +0,0 @@
-'===============================================================================
-'
-' 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.
-'
-'===============================================================================
-
-Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
-Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
-intRetVal = 1
-For Each objProcess in colProcessList
- objProcess.Terminate()
- intRetVal = 0
-Next
-WScript.Quit(intRetVal)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs b/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
deleted file mode 100644
index 32c65c5..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
+++ /dev/null
@@ -1,26 +0,0 @@
-'===============================================================================
-'
-' 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.
-'
-'===============================================================================
-
-Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
-Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
-intRetVal = 1
-For Each objProcess in colProcessList
- intRetVal = 0
-Next
-WScript.Quit(intRetVal)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
----------------------------------------------------------------------
diff --git a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs b/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
deleted file mode 100644
index 6004c86..0000000
--- a/instance/core/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
+++ /dev/null
@@ -1,34 +0,0 @@
-'===============================================================================
-'
-' 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.
-'
-'===============================================================================
-
-Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
-Set objConfig = objWMIService.Get("Win32_ProcessStartup").SpawnInstance_
-objConfig.ShowWindow = SW_HIDE
-objConfig.CreateFlags = 8
-If Len("${dir}") > 0 Then
- intReturn = objWMIService.Get("Win32_Process").Create("${command}", "${dir}", objConfig, intProcessID)
-Else
- intReturn = objWMIService.Get("Win32_Process").Create("${command}", Null, objConfig, intProcessID)
-End If
-If intReturn = 0 Then
- Set objOutputFile = CreateObject("Scripting.fileSystemObject").CreateTextFile("${pid.file}", TRUE)
- objOutputFile.WriteLine(intProcessID)
- objOutputFile.Close
-End If
-WScript.Quit(intReturn)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java b/instance/core/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java
deleted file mode 100644
index 264176b..0000000
--- a/instance/core/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.instance.core;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.junit.Assert;
-
-public class InstanceSettingsTest extends TestCase {
- public void testInstanceSettings() {
- InstanceSettings is =
- new InstanceSettings(1, 1, 1, null, null, Collections.<String>emptyList(), Arrays.asList("hi"));
- assertEquals(1, is.getSshPort());
- assertEquals(1, is.getRmiRegistryPort());
- assertEquals(1, is.getRmiServerPort());
- Assert.assertNull(is.getLocation());
- assertEquals(Arrays.asList("hi"), is.getFeatures());
- assertEquals(0, is.getFeatureURLs().size());
- }
-
- public void testEqualsHashCode() {
- testEqualsHashCode(1, 1, 1, "top", "foo", Collections.<String>emptyList(), Arrays.asList("hi"));
- testEqualsHashCode(0, 0, 0, null, null, null, null);
- }
-
- private void testEqualsHashCode(int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, List<String> featureURLs, List<String> features) {
- InstanceSettings is = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
- InstanceSettings is2 = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
- assertEquals(is, is2);
- assertEquals(is.hashCode(), is2.hashCode());
- }
-
- public void testEqualsHashCode2() {
- InstanceSettings is = new InstanceSettings(1, 1, 1, "top", "foo", Collections.<String>emptyList(), Arrays.asList("hi"));
- Assert.assertFalse(is.equals(null));
- Assert.assertFalse(is.equals(new Object()));
- assertEquals(is, is);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java b/instance/core/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
deleted file mode 100644
index 9c77934..0000000
--- a/instance/core/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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.instance.core.internal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Properties;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class InstanceServiceImplTest {
-
- @Rule
- public TestName name = new TestName();
-
- @Rule
- public TemporaryFolder tempFolder = new TemporaryFolder();
-
- @BeforeClass
- public static void setUpClass() throws Exception {
- String buildDirectory = ClassLoader.getSystemResource("etc/startup.properties").getFile()
- .replace("startup.properties", "");
- System.setProperty("karaf.etc", buildDirectory);
- }
-
- @Test
- public void testHandleFeatures() throws Exception {
- InstanceServiceImpl as = new InstanceServiceImpl();
-
- File f = tempFolder.newFile(getName() + ".test");
- Properties p = new Properties();
- p.put("featuresBoot", "abc,def ");
- p.put("featuresRepositories", "somescheme://xyz");
- OutputStream os = new FileOutputStream(f);
- try {
- p.store(os, "Test comment");
- } finally {
- os.close();
- }
-
- InstanceSettings s = new InstanceSettings(8122, 1122, 44444, null, null, null, Arrays.asList("test"));
- as.addFeaturesFromSettings(f, s);
-
- Properties p2 = new Properties();
- InputStream is = new FileInputStream(f);
- try {
- p2.load(is);
- } finally {
- is.close();
- }
- assertEquals(2, p2.size());
- assertEquals("abc,def,test", p2.get("featuresBoot"));
- assertEquals("somescheme://xyz", p2.get("featuresRepositories"));
- }
-
- @Test
- public void testConfigurationFiles() throws Exception {
- InstanceServiceImpl service = new InstanceServiceImpl();
- service.setStorageLocation(tempFolder.newFolder("instances"));
-
- InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
- Instance instance = service.createInstance(getName(), settings, true);
-
- assertFileExists(instance.getLocation(), "etc/config.properties");
- assertFileExists(instance.getLocation(), "etc/users.properties");
- assertFileExists(instance.getLocation(), "etc/startup.properties");
-
- assertFileExists(instance.getLocation(), "etc/java.util.logging.properties");
- assertFileExists(instance.getLocation(), "etc/org.apache.karaf.features.cfg");
- assertFileExists(instance.getLocation(), "etc/org.apache.felix.fileinstall-deploy.cfg");
- assertFileExists(instance.getLocation(), "etc/org.apache.karaf.log.cfg");
- assertFileExists(instance.getLocation(), "etc/org.apache.karaf.management.cfg");
- assertFileExists(instance.getLocation(), "etc/org.ops4j.pax.logging.cfg");
- assertFileExists(instance.getLocation(), "etc/org.ops4j.pax.url.mvn.cfg");
- }
-
- /**
- * <p>
- * Test the renaming of an existing instance.
- * </p>
- */
- @Test
- public void testRenameInstance() throws Exception {
- InstanceServiceImpl service = new InstanceServiceImpl();
- service.setStorageLocation(tempFolder.newFolder("instances"));
-
- InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
- service.createInstance(getName(), settings, true);
-
- service.renameInstance(getName(), getName() + "b", true);
- assertNotNull(service.getInstance(getName() + "b"));
- }
-
- /**
- * <p>
- * Test the renaming of an existing instance.
- * </p>
- */
- @Test
- public void testToSimulateRenameInstanceByExternalProcess() throws Exception {
- InstanceServiceImpl service = new InstanceServiceImpl();
- File storageLocation = tempFolder.newFolder("instances");
- service.setStorageLocation(storageLocation);
-
- InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
- service.createInstance(getName(), settings, true);
-
- //to simulate the scenario that the instance name get changed by
- //external process, likely the admin command CLI tool, which cause
- //the instance storage file get updated, the AdminService should be
- //able to reload the storage file before check any status for the
- //instance
-
- File storageFile = new File(storageLocation, InstanceServiceImpl.STORAGE_FILE);
- assertTrue(storageFile.isFile());
- Properties storage = loadStorage(storageFile);
- storage.setProperty("item.0.name", getName() + "b");
- saveStorage(storage, storageFile, "testToSimulateRenameInstanceByExternalProcess");
-
- assertNotNull(service.getInstance(getName() + "b"));
- }
-
- private String getName() {
- return name.getMethodName();
- }
-
- private void saveStorage(Properties props, File location, String comment) throws IOException {
- OutputStream os = null;
- try {
- os = new FileOutputStream(location);
- props.store(os, comment);
- } finally {
- if (os != null) {
- os.close();
- }
- }
- }
-
- private Properties loadStorage(File location) throws IOException {
- InputStream is = null;
- try {
- is = new FileInputStream(location);
- Properties props = new Properties();
- props.load(is);
- return props;
- } finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- private void assertFileExists(String path, String name) throws IOException {
- File file = new File(path, name);
- assertTrue("Expected " + file.getCanonicalPath() + " to exist",
- file.exists());
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java b/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
deleted file mode 100644
index bb67041..0000000
--- a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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.instance.core.management.internal;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceService;
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.apache.karaf.instance.core.InstancesMBean;
-import org.apache.karaf.instance.core.internal.InstancesMBeanImpl;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-
-public class InstanceServiceMBeanImplTest extends TestCase {
-
- public void testCreateInstance() throws Exception {
- final InstanceSettings instanceSettings = new InstanceSettings(123, 456,789, "somewhere", "someopts",
- Collections.<String>emptyList(), Arrays.asList("webconsole", "funfeat"));
-
- final Instance inst = EasyMock.createMock(Instance.class);
- EasyMock.expect(inst.getPid()).andReturn(42);
- EasyMock.replay(inst);
-
- org.apache.karaf.instance.core.InstanceService instanceService = EasyMock.createMock(org.apache.karaf.instance.core.InstanceService.class);
- EasyMock.expect(instanceService.createInstance("t1", instanceSettings, false)).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBeanImpl ab = new InstancesMBeanImpl(instanceService);
- assertEquals(42, ab.createInstance("t1", 123, 456, 789, "somewhere", "someopts", " webconsole, funfeat", ""));
- }
-
- public void testCreateInstance2() throws Exception {
- final InstanceSettings instanceSettings = new InstanceSettings(0, 0, 0, null, null,
- Collections.<String>emptyList(), Collections.<String>emptyList());
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.createInstance("t1", instanceSettings, false)).andReturn(null);
- EasyMock.replay(instanceService);
-
- InstancesMBean ab = new InstancesMBeanImpl(instanceService);
- assertEquals(-1, ab.createInstance("t1", 0, 0, 0, "", "", "", ""));
- }
-
- public void testGetInstances() throws Exception {
- Instance i1 = EasyMock.createMock(Instance.class);
- EasyMock.expect(i1.getPid()).andReturn(1234);
- EasyMock.expect(i1.getSshPort()).andReturn(8818);
- EasyMock.expect(i1.getRmiRegistryPort()).andReturn(1122);
- EasyMock.expect(i1.getRmiServerPort()).andReturn(44444);
- EasyMock.expect(i1.getName()).andReturn("i1");
- EasyMock.expect(i1.isRoot()).andReturn(true);
- EasyMock.expect(i1.getLocation()).andReturn("somewhere");
- EasyMock.expect(i1.getJavaOpts()).andReturn("someopts");
- EasyMock.expect(i1.getState()).andReturn("Stopped");
- EasyMock.replay(i1);
- Instance i2 = EasyMock.createNiceMock(Instance.class);
- EasyMock.expect(i2.getName()).andReturn("i2");
- EasyMock.replay(i2);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstances()).andReturn(new Instance[]{i1, i2});
- EasyMock.replay(instanceService);
-
- InstancesMBeanImpl instanceServiceMBean = new InstancesMBeanImpl(instanceService);
- TabularData tabularData = instanceServiceMBean.getInstances();
- Assert.assertEquals(2, tabularData.size());
- CompositeData cd1 = tabularData.get(new Object[]{"i1"});
- Assert.assertTrue(cd1.containsValue("i1"));
- Assert.assertTrue(cd1.containsValue(true));
- Assert.assertTrue(cd1.containsValue(1234));
- Assert.assertTrue(cd1.containsValue(8818));
- Assert.assertTrue(cd1.containsValue(1122));
- Assert.assertTrue(cd1.containsValue(44444));
- Assert.assertTrue(cd1.containsValue("somewhere"));
- Assert.assertTrue(cd1.containsValue("someopts"));
- Assert.assertTrue(cd1.containsValue("Stopped"));
-
- CompositeData cd2 = tabularData.get(new Object [] {"i2"});
- Assert.assertTrue(cd2.containsValue("i2"));
- }
-
- public void testStartInstanceWithJavaOpts() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.start("-x -y -z");
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.startInstance("test instance", "-x -y -z");
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testStartInstanceWithNoJavaOpts() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.start(null);
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.startInstance("test instance", null);
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testStopInstance() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.stop();
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.stopInstance("test instance");
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testDestroyInstance() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.destroy();
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.destroyInstance("test instance");
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testSshChangePort() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.changeSshPort(7788);
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.changeSshPort("test instance", 7788);
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testRmiRegistryChangePort() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.changeRmiRegistryPort(1123);
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.changeRmiRegistryPort("test instance", 1123);
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testRmiServerChangePort() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.changeRmiServerPort(44444);
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.changeRmiServerPort("test instance", 44444);
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
- public void testChangeOptions() throws Exception {
- Instance inst = EasyMock.createMock(Instance.class);
- inst.changeJavaOpts("new opts");
- EasyMock.expectLastCall();
- EasyMock.replay(inst);
-
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
- EasyMock.replay(instanceService);
-
- InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
-
- instanceServiceMBean.changeJavaOpts("test instance", "new opts");
- EasyMock.verify(instanceService);
- EasyMock.verify(inst);
- }
-
-}
[49/59] [abbrv] git commit: [KARAF-2852] Merge wrapper/core and
wrapper/command
Posted by gn...@apache.org.
[KARAF-2852] Merge wrapper/core and wrapper/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/4182735c
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/4182735c
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/4182735c
Branch: refs/heads/master
Commit: 4182735c7979c461b5be733cbe9db06b0d83239b
Parents: b0a20b8
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 09:31:03 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:49 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
wrapper/NOTICE | 71 +++
wrapper/command/NOTICE | 71 ---
wrapper/command/pom.xml | 100 ----
.../apache/karaf/wrapper/commands/Install.java | 199 -------
.../services/org/apache/karaf/shell/commands | 18 -
.../src/main/resources/OSGI-INF/bundle.info | 19 -
wrapper/core/NOTICE | 71 ---
wrapper/core/pom.xml | 128 -----
.../apache/karaf/wrapper/WrapperService.java | 42 --
.../org/apache/karaf/wrapper/internal/Main.java | 146 -----
.../wrapper/internal/PumpStreamHandler.java | 246 --------
.../karaf/wrapper/internal/StreamPumper.java | 195 -------
.../wrapper/internal/WrapperServiceImpl.java | 450 ---------------
.../karaf/wrapper/internal/osgi/Activator.java | 36 --
.../karaf/wrapper/management/WrapperMBean.java | 46 --
.../management/internal/WrapperMBeanImpl.java | 62 ---
.../src/main/resources/OSGI-INF/bundle.info | 16 -
.../wrapper/internal/aix/ppc32/karaf-wrapper | Bin 281540 -> 0 bytes
.../wrapper/internal/aix/ppc32/libwrapper.a | Bin 22948 -> 0 bytes
.../wrapper/internal/aix/ppc64/karaf-wrapper | Bin 319397 -> 0 bytes
.../wrapper/internal/aix/ppc64/libwrapper.a | Bin 24499 -> 0 bytes
.../wrapper/internal/all/karaf-wrapper.jar | Bin 83820 -> 0 bytes
.../internal/hpux/parisc64/karaf-wrapper | Bin 253808 -> 0 bytes
.../internal/hpux/parisc64/libwrapper.sl | Bin 74520 -> 0 bytes
.../karaf/wrapper/internal/linux/karaf-wrapper | Bin 99401 -> 0 bytes
.../karaf/wrapper/internal/linux/libwrapper.so | Bin 11887 -> 0 bytes
.../wrapper/internal/linux64/karaf-wrapper | Bin 111027 -> 0 bytes
.../wrapper/internal/linux64/libwrapper.so | Bin 15248 -> 0 bytes
.../karaf/wrapper/internal/macosx/karaf-wrapper | Bin 378976 -> 0 bytes
.../wrapper/internal/macosx/libwrapper.jnilib | Bin 43840 -> 0 bytes
.../macosx/org.apache.karaf.KARAF.plist | 36 --
.../internal/solaris/sparc32/karaf-wrapper | Bin 112536 -> 0 bytes
.../internal/solaris/sparc32/libwrapper.so | Bin 13760 -> 0 bytes
.../internal/solaris/sparc64/karaf-wrapper | Bin 148512 -> 0 bytes
.../internal/solaris/sparc64/libwrapper.so | Bin 21032 -> 0 bytes
.../wrapper/internal/solaris/x86/karaf-wrapper | Bin 110992 -> 0 bytes
.../wrapper/internal/solaris/x86/libwrapper.so | Bin 12572 -> 0 bytes
.../internal/solaris/x86_64/karaf-wrapper | Bin 160000 -> 0 bytes
.../internal/solaris/x86_64/libwrapper.so | Bin 19072 -> 0 bytes
.../karaf/wrapper/internal/unix/karaf-service | 557 -------------------
.../wrapper/internal/unix/karaf-wrapper.conf | 135 -----
.../wrapper/internal/windows/karaf-service.bat | 51 --
.../wrapper/internal/windows/karaf-wrapper.conf | 135 -----
.../wrapper/internal/windows/karaf-wrapper.exe | Bin 204800 -> 0 bytes
.../karaf/wrapper/internal/windows/wrapper.dll | Bin 81920 -> 0 bytes
.../internal/windows64/karaf-service.bat | 51 --
.../internal/windows64/karaf-wrapper.conf | 135 -----
.../internal/windows64/karaf-wrapper.exe | Bin 220672 -> 0 bytes
.../wrapper/internal/windows64/wrapper.dll | Bin 76800 -> 0 bytes
wrapper/pom.xml | 110 +++-
.../apache/karaf/wrapper/WrapperService.java | 42 ++
.../apache/karaf/wrapper/commands/Install.java | 199 +++++++
.../org/apache/karaf/wrapper/internal/Main.java | 146 +++++
.../wrapper/internal/PumpStreamHandler.java | 246 ++++++++
.../karaf/wrapper/internal/StreamPumper.java | 195 +++++++
.../wrapper/internal/WrapperServiceImpl.java | 450 +++++++++++++++
.../karaf/wrapper/internal/osgi/Activator.java | 36 ++
.../karaf/wrapper/management/WrapperMBean.java | 46 ++
.../management/internal/WrapperMBeanImpl.java | 62 +++
.../services/org/apache/karaf/shell/commands | 18 +
wrapper/src/main/resources/OSGI-INF/bundle.info | 16 +
.../wrapper/internal/aix/ppc32/karaf-wrapper | Bin 0 -> 281540 bytes
.../wrapper/internal/aix/ppc32/libwrapper.a | Bin 0 -> 22948 bytes
.../wrapper/internal/aix/ppc64/karaf-wrapper | Bin 0 -> 319397 bytes
.../wrapper/internal/aix/ppc64/libwrapper.a | Bin 0 -> 24499 bytes
.../wrapper/internal/all/karaf-wrapper.jar | Bin 0 -> 83820 bytes
.../internal/hpux/parisc64/karaf-wrapper | Bin 0 -> 253808 bytes
.../internal/hpux/parisc64/libwrapper.sl | Bin 0 -> 74520 bytes
.../karaf/wrapper/internal/linux/karaf-wrapper | Bin 0 -> 99401 bytes
.../karaf/wrapper/internal/linux/libwrapper.so | Bin 0 -> 11887 bytes
.../wrapper/internal/linux64/karaf-wrapper | Bin 0 -> 111027 bytes
.../wrapper/internal/linux64/libwrapper.so | Bin 0 -> 15248 bytes
.../karaf/wrapper/internal/macosx/karaf-wrapper | Bin 0 -> 378976 bytes
.../wrapper/internal/macosx/libwrapper.jnilib | Bin 0 -> 43840 bytes
.../macosx/org.apache.karaf.KARAF.plist | 36 ++
.../internal/solaris/sparc32/karaf-wrapper | Bin 0 -> 112536 bytes
.../internal/solaris/sparc32/libwrapper.so | Bin 0 -> 13760 bytes
.../internal/solaris/sparc64/karaf-wrapper | Bin 0 -> 148512 bytes
.../internal/solaris/sparc64/libwrapper.so | Bin 0 -> 21032 bytes
.../wrapper/internal/solaris/x86/karaf-wrapper | Bin 0 -> 110992 bytes
.../wrapper/internal/solaris/x86/libwrapper.so | Bin 0 -> 12572 bytes
.../internal/solaris/x86_64/karaf-wrapper | Bin 0 -> 160000 bytes
.../internal/solaris/x86_64/libwrapper.so | Bin 0 -> 19072 bytes
.../karaf/wrapper/internal/unix/karaf-service | 557 +++++++++++++++++++
.../wrapper/internal/unix/karaf-wrapper.conf | 135 +++++
.../wrapper/internal/windows/karaf-service.bat | 51 ++
.../wrapper/internal/windows/karaf-wrapper.conf | 135 +++++
.../wrapper/internal/windows/karaf-wrapper.exe | Bin 0 -> 204800 bytes
.../karaf/wrapper/internal/windows/wrapper.dll | Bin 0 -> 81920 bytes
.../internal/windows64/karaf-service.bat | 51 ++
.../internal/windows64/karaf-wrapper.conf | 135 +++++
.../internal/windows64/karaf-wrapper.exe | Bin 0 -> 220672 bytes
.../wrapper/internal/windows64/wrapper.dll | Bin 0 -> 76800 bytes
94 files changed, 2728 insertions(+), 2955 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/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 e596a84..6813d27 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -103,7 +103,6 @@
<feature name="wrapper" description="Provide OS integration" version="${project.version}">
<bundle start-level="30">mvn:org.apache.karaf.wrapper/org.apache.karaf.wrapper.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.wrapper/org.apache.karaf.wrapper.command/${project.version}</bundle>
</feature>
<feature name="service-wrapper" description="Provide OS integration (alias to wrapper feature)" version="${project.version}">
<feature>wrapper</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/NOTICE
----------------------------------------------------------------------
diff --git a/wrapper/NOTICE b/wrapper/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/wrapper/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/4182735c/wrapper/command/NOTICE
----------------------------------------------------------------------
diff --git a/wrapper/command/NOTICE b/wrapper/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/wrapper/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/4182735c/wrapper/command/pom.xml
----------------------------------------------------------------------
diff --git a/wrapper/command/pom.xml b/wrapper/command/pom.xml
deleted file mode 100644
index 5e29b84..0000000
--- a/wrapper/command/pom.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?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.wrapper</groupId>
- <artifactId>wrapper</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.wrapper.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Wrapper :: Shell Commands</name>
- <description>
- This bundle provides Karaf shell commands to manipulate the OS service wrapper.
- </description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.wrapper</groupId>
- <artifactId>org.apache.karaf.wrapper.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.console</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.gogo.runtime</artifactId>
- <scope>provided</scope>
- </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>
- <Import-Package>
- !org.apache.karaf.main,
- !org.tanukisoftware*,
- org.apache.karaf.wrapper,
- javax.management,
- javax.management.loading,
- *
- </Import-Package>
- <Karaf-Commands>
- org.apache.karaf.wrapper.commands
- </Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/command/src/main/java/org/apache/karaf/wrapper/commands/Install.java
----------------------------------------------------------------------
diff --git a/wrapper/command/src/main/java/org/apache/karaf/wrapper/commands/Install.java b/wrapper/command/src/main/java/org/apache/karaf/wrapper/commands/Install.java
deleted file mode 100644
index 346f6f1..0000000
--- a/wrapper/command/src/main/java/org/apache/karaf/wrapper/commands/Install.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.wrapper.commands;
-
-import java.io.File;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.wrapper.WrapperService;
-
-import static org.apache.karaf.shell.support.ansi.SimpleAnsi.INTENSITY_BOLD;
-import static org.apache.karaf.shell.support.ansi.SimpleAnsi.INTENSITY_NORMAL;
-
-/**
- * Installs the Karaf instance as a service in your operating system.
- */
-@Command(scope = "wrapper", name = "install", description = "Install the container as a system service in the OS.")
-@Service
-public class Install implements Action {
-
- @Option(name = "-n", aliases = { "--name" }, description = "The service name that will be used when installing the service. (Default: karaf)", required = false, multiValued = false)
- private String name = "karaf";
-
- @Option(name = "-d", aliases = { "--display" }, description = "The display name of the service.", required = false, multiValued = false)
- private String displayName = "karaf";
-
- @Option(name = "-D", aliases = { "--description" }, description = "The description of the service.", required = false, multiValued = false)
- private String description = "";
-
- @Option(name = "-s", aliases = { "--start-type" }, description = "Mode in which the service is installed. AUTO_START or DEMAND_START (Default: AUTO_START)", required = false, multiValued = false)
- private String startType = "AUTO_START";
-
- @Reference
- private WrapperService wrapperService;
-
- @Override
- public Object execute() throws Exception {
- File[] wrapperPaths = wrapperService.install(name, displayName, description, startType);
-
- String os = System.getProperty("os.name", "Unknown");
- File wrapperConf = wrapperPaths[0];
- File serviceFile = wrapperPaths[1];
-
- System.out.println("");
- System.out.println("Setup complete. You may wish to tweak the JVM properties in the wrapper configuration file:");
- System.out.println("\t" + wrapperConf.getPath());
- System.out.println("before installing and starting the service.");
- System.out.println("");
- if (os.startsWith("Win")) {
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "MS Windows system detected:" + INTENSITY_NORMAL);
- System.out.println("To install the service, run: ");
- System.out.println(" C:> " + serviceFile.getPath() + " install");
- System.out.println("");
- System.out.println("Once installed, to start the service run: ");
- System.out.println(" C:> net start \"" + name + "\"");
- System.out.println("");
- System.out.println("Once running, to stop the service run: ");
- System.out.println(" C:> net stop \"" + name + "\"");
- System.out.println("");
- System.out.println("Once stopped, to remove the installed the service run: ");
- System.out.println(" C:> " + serviceFile.getPath() + " remove");
- System.out.println("");
- } else if (os.startsWith("Mac OS X")) {
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "Mac OS X system detected:" + INTENSITY_NORMAL);
- System.out.println("to add bin/org.apache.karaf.KARAF as user service move this file into ~/Library/LaunchAgents/");
- System.out.println("> mv bin/org.apache.karaf.KARAF.plist ~/Library/LaunchAgents/");
- System.out.println("");
- System.out.println("to add org.apache.karaf.KARAF as system service move this into /Library/LaunchDaemons");
- System.out.println("> sudo mv bin/org.apache.karaf.KARAF.plist /Library/LaunchDaemons/");
- System.out.println("change owner and rights");
- System.out.println("> sudo chown root:wheel /Library/LaunchDaemons/org.apache.karaf.KARAF.plist");
- System.out.println("> sudo chmod u=rw,g=r,o=r /Library/LaunchDaemons/org.apache.karaf.KARAF.plist");
- System.out.println("");
- System.out.println("test your service");
- System.out.println("> launchctl load ~/Library/LaunchAgents/org.apache.karaf.KARAF.plist");
- System.out.println("> launchctl start org.apache.karaf.KARAF");
- System.out.println("> launchctl stop org.apache.karaf.KARAF");
- System.out.println("");
- System.out.println("after restart your session or system");
- System.out.println("you can use launchctl command to start and stop your service");
- System.out.println("");
- System.out.println("for removing the service call");
- System.out.println("> launchctl remove org.apache.karaf.KARAF");
- System.out.println("");
- } else if (os.startsWith("Linux")) {
-
- File debianVersion = new File("/etc/debian_version");
- File redhatRelease = new File("/etc/redhat-release");
-
- if (redhatRelease.exists()) {
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "RedHat/Fedora/CentOS Linux system detected:" + INTENSITY_NORMAL);
- System.out.println(" To install the service:");
- System.out.println(" $ ln -s " + serviceFile.getPath() + " /etc/init.d/");
- System.out.println(" $ chkconfig " + serviceFile.getName() + " --add");
- System.out.println("");
- System.out.println(" To start the service when the machine is rebooted:");
- System.out.println(" $ chkconfig " + serviceFile.getName() + " on");
- System.out.println("");
- System.out.println(" To disable starting the service when the machine is rebooted:");
- System.out.println(" $ chkconfig " + serviceFile.getName() + " off");
- System.out.println("");
- System.out.println(" To start the service:");
- System.out.println(" $ service " + serviceFile.getName() + " start");
- System.out.println("");
- System.out.println(" To stop the service:");
- System.out.println(" $ service " + serviceFile.getName() + " stop");
- System.out.println("");
- System.out.println(" To uninstall the service :");
- System.out.println(" $ chkconfig " + serviceFile.getName() + " --del");
- System.out.println(" $ rm /etc/init.d/" + serviceFile.getPath());
- } else if (debianVersion.exists()) {
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "Ubuntu/Debian Linux system detected:" + INTENSITY_NORMAL);
- System.out.println(" To install the service:");
- System.out.println(" $ ln -s " + serviceFile.getPath() + " /etc/init.d/");
- System.out.println("");
- System.out.println(" To start the service when the machine is rebooted:");
- System.out.println(" $ update-rc.d " + serviceFile.getName() + " defaults");
- System.out.println("");
- System.out.println(" To disable starting the service when the machine is rebooted:");
- System.out.println(" $ update-rc.d -f " + serviceFile.getName() + " remove");
- System.out.println("");
- System.out.println(" To start the service:");
- System.out.println(" $ /etc/init.d/" + serviceFile.getName() + " start");
- System.out.println("");
- System.out.println(" To stop the service:");
- System.out.println(" $ /etc/init.d/" + serviceFile.getName() + " stop");
- System.out.println("");
- System.out.println(" To uninstall the service :");
- System.out.println(" $ rm /etc/init.d/" + serviceFile.getName());
- } else {
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "On Redhat/Fedora/CentOS Systems:" + INTENSITY_NORMAL);
- System.out.println(" To install the service:");
- System.out.println(" $ ln -s "+serviceFile.getPath()+" /etc/init.d/");
- System.out.println(" $ chkconfig "+serviceFile.getName()+" --add");
- System.out.println("");
- System.out.println(" To start the service when the machine is rebooted:");
- System.out.println(" $ chkconfig "+serviceFile.getName()+" on");
- System.out.println("");
- System.out.println(" To disable starting the service when the machine is rebooted:");
- System.out.println(" $ chkconfig "+serviceFile.getName()+" off");
- System.out.println("");
- System.out.println(" To start the service:");
- System.out.println(" $ service "+serviceFile.getName()+" start");
- System.out.println("");
- System.out.println(" To stop the service:");
- System.out.println(" $ service "+serviceFile.getName()+" stop");
- System.out.println("");
- System.out.println(" To uninstall the service :");
- System.out.println(" $ chkconfig "+serviceFile.getName()+" --del");
- System.out.println(" $ rm /etc/init.d/"+serviceFile.getName());
-
- System.out.println("");
- System.out.println(INTENSITY_BOLD + "On Ubuntu/Debian Systems:" + INTENSITY_NORMAL);
- System.out.println(" To install the service:");
- System.out.println(" $ ln -s "+serviceFile.getPath()+" /etc/init.d/");
- System.out.println("");
- System.out.println(" To start the service when the machine is rebooted:");
- System.out.println(" $ update-rc.d "+serviceFile.getName()+" defaults");
- System.out.println("");
- System.out.println(" To disable starting the service when the machine is rebooted:");
- System.out.println(" $ update-rc.d -f "+serviceFile.getName()+" remove");
- System.out.println("");
- System.out.println(" To start the service:");
- System.out.println(" $ /etc/init.d/"+serviceFile.getName()+" start");
- System.out.println("");
- System.out.println(" To stop the service:");
- System.out.println(" $ /etc/init.d/"+serviceFile.getName()+" stop");
- System.out.println("");
- System.out.println(" To uninstall the service :");
- System.out.println(" $ rm /etc/init.d/"+serviceFile.getName());
- }
-
- }
-
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
----------------------------------------------------------------------
diff --git a/wrapper/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands b/wrapper/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
deleted file mode 100644
index 73b329d..0000000
--- a/wrapper/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
+++ /dev/null
@@ -1,18 +0,0 @@
-##---------------------------------------------------------------------------
-## 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.
-##---------------------------------------------------------------------------
-org.apache.karaf.wrapper.internal.WrapperServiceImpl
-org.apache.karaf.wrapper.commands.Install
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/wrapper/command/src/main/resources/OSGI-INF/bundle.info b/wrapper/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index c5d6ba0..0000000
--- a/wrapper/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,19 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle contains all Karaf shell commands related to the wrapper.
-
-The following commands are available:
-* wrapper:install - Install this Karaf instance as a service in your operating system.
-
-h1. See also
-
-Wrapper - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/NOTICE
----------------------------------------------------------------------
diff --git a/wrapper/core/NOTICE b/wrapper/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/wrapper/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/4182735c/wrapper/core/pom.xml
----------------------------------------------------------------------
diff --git a/wrapper/core/pom.xml b/wrapper/core/pom.xml
deleted file mode 100644
index a097bfa..0000000
--- a/wrapper/core/pom.xml
+++ /dev/null
@@ -1,128 +0,0 @@
-<?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.wrapper</groupId>
- <artifactId>wrapper</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.wrapper.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Wrapper :: Core</name>
- <description>
- Core implementation and integration of the Java Service Wrapper.
- It provides a complete integration of Karaf with your Operating System.
- </description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.main</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>tanukisoft</groupId>
- <artifactId>wrapper</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <configuration>
- <mainClass>Main</mainClass>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.karaf.wrapper,
- org.apache.karaf.wrapper.management
- </Export-Package>
- <Private-Package>
- org.apache.karaf.wrapper.internal,
- org.apache.karaf.wrapper.internal.osgi,
- org.apache.karaf.wrapper.management.internal,
- org.tanukisoftware.wrapper*,
- org.apache.karaf.main*,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Import-Package>
- !org.apache.felix.utils.properties,
- !org.apache.karaf.util.locks,
- !org.apache.karaf.info,
- *
- </Import-Package>
- <Bundle-Activator>
- org.apache.karaf.wrapper.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/WrapperService.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/WrapperService.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/WrapperService.java
deleted file mode 100644
index fb05a16..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/WrapperService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.wrapper;
-
-import java.io.File;
-
-/**
- * Interface describing the Wrapper service.
- */
-public interface WrapperService {
-
- /**
- * Install the Karaf container as a system service in the OS.
- */
- public void install() throws Exception;
-
- /**
- * Install the Karaf container as a system service in the OS.
- *
- * @param name The service name that will be used when installing the service.
- * @param displayName The display name of the service.
- * @param description The description of the service.
- * @param startType Mode in which the service is installed. AUTO_START or DEMAND_START.
- * @return an array containing the wrapper configuration file (index 0) and the service file (index 1)
- */
- public File[] install(String name, String displayName, String description, String startType) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/Main.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/Main.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/Main.java
deleted file mode 100644
index 8f3060e..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/Main.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.wrapper.internal;
-
-import org.apache.karaf.main.ShutdownCallback;
-import org.tanukisoftware.wrapper.WrapperListener;
-import org.tanukisoftware.wrapper.WrapperManager;
-
-/**
- * Java Service Wrapper Main class
- */
-public class Main extends Thread implements WrapperListener, ShutdownCallback {
-
- private org.apache.karaf.main.Main main;
- private volatile boolean destroying;
-
- /*---------------------------------------------------------------
- * Constructors
- *-------------------------------------------------------------*/
- private Main() {
- }
-
- /*---------------------------------------------------------------
- * WrapperListener Methods
- *-------------------------------------------------------------*/
-
- /**
- * The start method is called when the WrapperManager is signaled by the
- * native Wrapper code that it can start its application. This
- * method call is expected to return, so a new thread should be launched
- * if necessary.
- *
- * @param args List of arguments used to initialize the application.
- * @return Any error code if the application should exit on completion
- * of the start method. If there were no problems then this
- * method should return null.
- */
- public Integer start(String[] args) {
- main = new org.apache.karaf.main.Main(args);
- try {
- main.launch();
- main.setShutdownCallback(this);
- start();
- return null;
- } catch (Throwable ex) {
- System.err.println("Could not create framework: " + ex);
- ex.printStackTrace();
- return -1;
- }
- }
-
- public void run() {
- try {
- main.awaitShutdown();
- if (!destroying) {
- WrapperManager.stop(main.getExitCode());
- }
- } catch (Exception e) {
- // Ignore
- }
- }
-
- /**
- * Called when the application is shutting down. The Wrapper assumes that
- * this method will return fairly quickly. If the shutdown code code
- * could potentially take a long time, then WrapperManager.signalStopping()
- * should be called to extend the timeout period. If for some reason,
- * the stop method can not return, then it must call
- * WrapperManager.stopped() to avoid warning messages from the Wrapper.
- *
- * @param exitCode The suggested exit code that will be returned to the OS
- * when the JVM exits.
- * @return The exit code to actually return to the OS. In most cases, this
- * should just be the value of exitCode, however the user code has
- * the option of changing the exit code if there are any problems
- * during shutdown.
- */
- public int stop(int exitCode) {
- try {
- destroying = true;
- if (!main.destroy()) {
- System.err.println("Timeout waiting for Karaf to shutdown");
- return -3;
- }
- } catch (Throwable ex) {
- System.err.println("Error occured shutting down framework: " + ex);
- ex.printStackTrace();
- return -2;
- }
-
- return main.getExitCode();
- }
-
- /**
- * Call-back method is called by the @{link org.apache.karaf.main.Main} for Signaling
- * that the stopping process is in progress and the wrapper doesn't kill the JVM.
- */
- public void waitingForShutdown(int delay) {
- WrapperManager.signalStopping(delay);
- }
-
- /**
- * Called whenever the native Wrapper code traps a system control signal
- * against the Java process. It is up to the callback to take any actions
- * necessary. Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT,
- * WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or
- * WRAPPER_CTRL_SHUTDOWN_EVENT
- *
- * @param event The system control signal.
- */
- public void controlEvent(int event) {
- if ((event == WrapperManager.WRAPPER_CTRL_LOGOFF_EVENT)
- && (WrapperManager.isLaunchedAsService())) {
- // Ignore
- } else {
- WrapperManager.stop(0);
- // Will not get here.
- }
- }
-
- /*---------------------------------------------------------------
- * Main Method
- *-------------------------------------------------------------*/
- public static void main(String[] args) {
- // Start the application. If the JVM was launched from the native
- // Wrapper then the application will wait for the native Wrapper to
- // call the application's start method. Otherwise the start method
- // will be called immediately.
- WrapperManager.start(new Main(), args);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
deleted file mode 100644
index 8737547..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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.wrapper.internal;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-//
-// Based on Apache Ant 1.6.5
-//
-
-/**
- * Copies standard output and error of children streams to standard output and error of the parent.
- */
-public class PumpStreamHandler {
-
- private final InputStream in;
-
- private final OutputStream out;
-
- private final OutputStream err;
-
- private final String name;
-
- private StreamPumper outputPump;
-
- private StreamPumper errorPump;
-
- private StreamPumper inputPump;
-
- //
- // NOTE: May want to use a ThreadPool here, 3 threads per/pair seems kinda expensive :-(
- //
-
- public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err, String name) {
- assert in != null;
- assert out != null;
- assert err != null;
- assert name != null;
-
- this.in = in;
- this.out = out;
- this.err = err;
- this.name = name;
- }
-
- public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err) {
- this(in, out, err, "<unknown>");
- }
-
- public PumpStreamHandler(final OutputStream out, final OutputStream err) {
- this(null, out, err);
- }
-
- public PumpStreamHandler(final OutputStream outAndErr) {
- this(outAndErr, outAndErr);
- }
-
- /**
- * Set the input stream from which to read the standard output of the child.
- */
- public void setChildOutputStream(final InputStream in) {
- assert in != null;
-
- createChildOutputPump(in, out);
- }
-
- /**
- * Set the input stream from which to read the standard error of the child.
- */
- public void setChildErrorStream(final InputStream in) {
- assert in != null;
-
- if (err != null) {
- createChildErrorPump(in, err);
- }
- }
-
- /**
- * Set the output stream by means of which input can be sent to the child.
- */
- public void setChildInputStream(final OutputStream out) {
- assert out != null;
-
- if (in != null) {
- inputPump = createInputPump(in, out, true);
- } else {
- try {
- out.close();
- } catch (IOException e) {
- }
- }
- }
-
- /**
- * Attach to a child streams from the given process.
- *
- * @param p The process to attach to.
- */
- public void attach(final Process p) {
- assert p != null;
-
- setChildInputStream(p.getOutputStream());
- setChildOutputStream(p.getInputStream());
- setChildErrorStream(p.getErrorStream());
- }
-
- /**
- * Start pumping the streams.
- */
- public void start() {
- if (outputPump != null) {
- Thread thread = new Thread(outputPump);
- thread.setDaemon(true);
- thread.setName("Output pump for " + this.name);
- thread.start();
- }
-
- if (errorPump != null) {
- Thread thread = new Thread(errorPump);
- thread.setDaemon(true);
- thread.setName("Error pump for " + this.name);
- thread.start();
- }
-
- if (inputPump != null) {
- Thread thread = new Thread(inputPump);
- thread.setDaemon(true);
- thread.setName("Input pump for " + this.name);
- thread.start();
- }
- }
-
- /**
- * Stop pumping the streams.
- */
- public void stop() {
- if (outputPump != null) {
- try {
- outputPump.stop();
- outputPump.waitFor();
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- if (errorPump != null) {
- try {
- errorPump.stop();
- errorPump.waitFor();
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- if (inputPump != null) {
- inputPump.stop();
- }
-
- try {
- err.flush();
- } catch (IOException e) {
- }
- try {
- out.flush();
- } catch (IOException e) {
- }
- }
-
- /**
- * Create the pump to handle child output.
- */
- protected void createChildOutputPump(final InputStream in, final OutputStream out) {
- assert in != null;
- assert out != null;
-
- outputPump = createPump(in, out);
- }
-
- /**
- * Create the pump to handle error output.
- */
- protected void createChildErrorPump(final InputStream in, final OutputStream out) {
- assert in != null;
- assert out != null;
-
- errorPump = createPump(in, out);
- }
-
- /**
- * Creates a stream pumper to copy the given input stream to the given output stream.
- */
- protected StreamPumper createPump(final InputStream in, final OutputStream out) {
- assert in != null;
- assert out != null;
-
- return createPump(in, out, false);
- }
-
- /**
- * Creates a stream pumper to copy the given input stream to the
- * given output stream.
- *
- * @param in The input stream to copy from.
- * @param out The output stream to copy to.
- * @param closeWhenExhausted If true close the inputstream.
- * @return A thread object that does the pumping.
- */
- protected StreamPumper createPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
- assert in != null;
- assert out != null;
-
- StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
- return pumper;
- }
-
- /**
- * Creates a stream pumper to copy the given input stream to the
- * given output stream. Used for standard input.
- */
- protected StreamPumper createInputPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
- assert in != null;
- assert out != null;
-
- StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
- pumper.setAutoflush(true);
- return pumper;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
deleted file mode 100644
index 330d8fc..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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.wrapper.internal;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-//
-// Based on Apache Ant 1.6.5
-//
-
-/**
- * Copies all data from an input stream to an output stream.
- */
-public class StreamPumper implements Runnable {
-
- private InputStream in;
-
- private OutputStream out;
-
- private volatile boolean finish;
-
- private volatile boolean finished;
-
- private boolean closeWhenExhausted;
-
- private boolean autoflush;
-
- private Exception exception;
-
- private int bufferSize = 128;
-
- private boolean started;
-
- /**
- * Create a new stream pumper.
- *
- * @param in Input stream to read data from
- * @param out Output stream to write data to.
- * @param closeWhenExhausted If true, the output stream will be closed when
- * the input is exhausted.
- */
- public StreamPumper(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
- assert in != null;
- assert out != null;
-
- this.in = in;
- this.out = out;
- this.closeWhenExhausted = closeWhenExhausted;
- }
-
- /**
- * Create a new stream pumper.
- *
- * @param in Input stream to read data from
- * @param out Output stream to write data to.
- */
- public StreamPumper(final InputStream in, final OutputStream out) {
- this(in, out, false);
- }
-
- /**
- * Set whether data should be flushed through to the output stream.
- *
- * @param autoflush If true, push through data; if false, let it be buffered
- */
- public void setAutoflush(boolean autoflush) {
- this.autoflush = autoflush;
- }
-
- /**
- * Copies data from the input stream to the output stream.
- * <p/>
- * Terminates as soon as the input stream is closed or an error occurs.
- */
- public void run() {
- synchronized (this) {
- started = true;
- }
- finished = false;
- finish = false;
-
- final byte[] buf = new byte[bufferSize];
-
- int length;
- try {
- while ((length = in.read(buf)) > 0 && !finish) {
- out.write(buf, 0, length);
- if (autoflush) {
- out.flush();
- }
- }
- out.flush();
- } catch (Exception e) {
- synchronized (this) {
- exception = e;
- }
- } finally {
- if (closeWhenExhausted) {
- try {
- out.close();
- } catch (IOException e) {
- }
- }
- finished = true;
-
- synchronized (this) {
- notifyAll();
- }
- }
- }
-
- /**
- * Tells whether the end of the stream has been reached.
- *
- * @return true If the stream has been exhausted.
- */
- public boolean isFinished() {
- return finished;
- }
-
- /**
- * This method blocks until the stream pumper finishes.
- *
- * @see #isFinished()
- */
- public synchronized void waitFor() throws InterruptedException {
- while (!isFinished()) {
- wait();
- }
- }
-
- /**
- * Set the size in bytes of the read buffer.
- *
- * @param bufferSize the buffer size to use.
- * @throws IllegalStateException if the StreamPumper is already running.
- */
- public synchronized void setBufferSize(final int bufferSize) {
- if (started) {
- throw new IllegalStateException("Cannot set buffer size on a running StreamPumper");
- }
-
- this.bufferSize = bufferSize;
- }
-
- /**
- * Get the size in bytes of the read buffer.
- *
- * @return The size of the read buffer.
- */
- public synchronized int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Get the exception encountered, if any.
- *
- * @return The Exception encountered; or null if there was none.
- */
- public synchronized Exception getException() {
- return exception;
- }
-
- /**
- * Stop the pumper as soon as possible.
- * <p/>
- * Note that it may continue to block on the input stream
- * but it will really stop the thread as soon as it gets EOF
- * or any byte, and it will be marked as finished.
- */
- public synchronized void stop() {
- finish = true;
-
- notifyAll();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
deleted file mode 100644
index ad4aa4a..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * 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.wrapper.internal;
-
-import org.apache.karaf.wrapper.WrapperService;
-import org.fusesource.jansi.Ansi;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.*;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.jar.JarOutputStream;
-import java.util.zip.ZipEntry;
-
-/**
- * Default implementation of the wrapper service.
- */
-public class WrapperServiceImpl implements WrapperService {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(WrapperServiceImpl.class);
-
- public void install() throws Exception {
- install("karaf", "karaf", "", "AUTO_START");
- }
-
- public File[] install(String name, String displayName, String description, String startType) throws Exception {
-
- File base = new File(System.getProperty("karaf.base"));
- File etc = new File(System.getProperty("karaf.etc"));
- File bin = new File(base, "bin");
- File lib = new File(base, "lib");
-
- if (name == null) {
- name = base.getName();
- }
-
- HashMap<String, String> props = new HashMap<String, String>();
- props.put("${java.home}", System.getenv("JAVA_HOME"));
- props.put("${karaf.home}", System.getProperty("karaf.home"));
- props.put("${karaf.base}", base.getPath());
- props.put("${karaf.data}", System.getProperty("karaf.data"));
- props.put("${karaf.etc}", System.getProperty("karaf.etc"));
- props.put("${name}", name);
- props.put("${displayName}", displayName);
- props.put("${description}", description);
- props.put("${startType}", startType);
-
- String os = System.getProperty("os.name", "Unknown");
- File serviceFile = null;
- File wrapperConf = null;
- if (os.startsWith("Win")) {
- String arch = System.getProperty("os.arch");
- if (arch.equalsIgnoreCase("amd64") || arch.equalsIgnoreCase("x86_64")) {
- mkdir(bin);
-
- copyResourceTo(new File(bin, name + "-wrapper.exe"), "windows64/karaf-wrapper.exe", false);
-
- serviceFile = new File(bin, name + "-service.bat");
- wrapperConf = new File(etc, name + "-wrapper.conf");
-
- copyFilteredResourceTo(wrapperConf, "windows64/karaf-wrapper.conf", props);
- copyFilteredResourceTo(serviceFile, "windows64/karaf-service.bat", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "wrapper.dll"), "windows64/wrapper.dll", false);
- } else {
- mkdir(bin);
-
- copyResourceTo(new File(bin, name + "-wrapper.exe"), "windows/karaf-wrapper.exe", false);
-
- serviceFile = new File(bin, name + "-service.bat");
- wrapperConf = new File(etc, name + "-wrapper.conf");
-
- copyFilteredResourceTo(wrapperConf, "windows/karaf-wrapper.conf", props);
- copyFilteredResourceTo(serviceFile, "windows/karaf-service.bat", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "wrapper.dll"), "windows/wrapper.dll", false);
- }
- } else if (os.startsWith("Mac OS X")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "macosx/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- File plistConf = new File(bin, "org.apache.karaf."+ name + ".plist");
- copyFilteredResourceTo(plistConf, "macosx/org.apache.karaf.KARAF.plist", props);
-
- mkdir(lib);
-
- copyResourceTo(new File(lib, "libwrapper.jnilib"), "macosx/libwrapper.jnilib", false);
- } else if (os.startsWith("Linux")) {
- String arch = System.getProperty("os.arch");
- if (arch.equalsIgnoreCase("amd64") || arch.equalsIgnoreCase("x86_64")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "linux64/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "linux64/libwrapper.so", false);
- } else {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "linux/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "linux/libwrapper.so", false);
- }
- } else if (os.startsWith("AIX")) {
- String arch = System.getProperty("os.arch");
- if (arch.equalsIgnoreCase("ppc64")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "aix/ppc64/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.a"), "aix/ppc64/libwrapper.a", false);
- } else {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "aix/ppc32/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.a"), "aix/ppc32/libwrapper.a", false);
- }
- } else if (os.startsWith("Solaris") || os.startsWith("SunOS")) {
- String arch = System.getProperty("os.arch");
- if (arch.equalsIgnoreCase("sparc")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "solaris/sparc64/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "solaris/sparc64/libwrapper.so", false);
- } else if (arch.equalsIgnoreCase("x86")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "solaris/x86/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "solaris/x86/libwrapper.so", false);
- } else if (arch.equalsIgnoreCase("x86_64")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "solaris/x86_64/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "solaris/x86_64/libwrapper.so", false);
- } else {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "solaris/sparc32/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.so"), "solaris/sparc32/libwrapper.so", false);
- }
- } else if (os.startsWith("HP-UX") || os.startsWith("HPUX")) {
- mkdir(bin);
-
- File file = new File(bin, name + "-wrapper");
- copyResourceTo(file, "hpux/parisc64/karaf-wrapper", false);
- chmod(file, "a+x");
-
- serviceFile = new File(bin, name + "-service");
- copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
- chmod(serviceFile, "a+x");
-
- wrapperConf = new File(etc, name + "-wrapper.conf");
- copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
-
- mkdir(lib);
- copyResourceTo(new File(lib, "libwrapper.sl"), "hpux/parisc64/libwrapper.sl", false);
- } else {
- throw new IllegalStateException("Your operating system '" + os + "' is not currently supported.");
- }
-
- // install the wrapper jar to the lib directory
- mkdir(lib);
- copyResourceTo(new File(lib, "karaf-wrapper.jar"), "all/karaf-wrapper.jar", false);
- mkdir(etc);
-
- createJar(new File(lib, "karaf-wrapper-main.jar"), "org/apache/karaf/wrapper/internal/Main.class");
-
- File[] wrapperPaths = new File[2];
- wrapperPaths[0] = wrapperConf;
- wrapperPaths[1] = serviceFile;
-
- return wrapperPaths;
- }
-
- private void mkdir(File file) {
- if (!file.exists()) {
- LOGGER.info("Creating missing directory: {}", file.getPath());
- System.out.println(Ansi.ansi().a("Creating missing directory: ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(file.getPath()).a(Ansi.Attribute.RESET).toString());
- file.mkdirs();
- }
- }
-
- private void copyResourceTo(File outFile, String resource, boolean text) throws Exception {
- if (!outFile.exists()) {
- LOGGER.info("Creating file: {}", outFile.getPath());
- System.out.println(Ansi.ansi().a("Creating file: ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
- InputStream is = WrapperServiceImpl.class.getResourceAsStream(resource);
- if (is == null) {
- throw new IllegalArgumentException("Resource " + resource + " doesn't exist");
- }
- try {
- if (text) {
- // read it line at a time so what we can use the platform line ending when we write it out
- PrintStream out = new PrintStream(new FileOutputStream(outFile));
- try {
- Scanner scanner = new Scanner(is);
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- LOGGER.info("writing: {}", line);
- out.println(line);
- }
- } finally {
- safeClose(out);
- }
- } else {
- // binary resource so just write it out the way it came in
- FileOutputStream out = new FileOutputStream(outFile);
- try {
- int c = 0;
- while ((c = is.read()) >= 0) {
- out.write(c);
- }
- } finally {
- safeClose(out);
- }
- }
- } finally {
- safeClose(is);
- }
- } else {
- LOGGER.warn("File already exists. Move it out of the way if you wish to recreate it: {}", outFile.getPath());
- System.out.println(Ansi.ansi()
- .fg(Ansi.Color.RED).a("File already exists").a(Ansi.Attribute.RESET)
- .a(". Move it out of the way if you wish to recreate it: ").a(outFile.getPath()).toString());
- }
- }
-
- private void copyFilteredResourceTo(File outFile, String resource, HashMap<String, String> props) throws Exception {
- if (!outFile.exists()) {
- LOGGER.info("Creating file: {}", outFile.getPath());
- System.out.println(Ansi.ansi().a("Creating file: ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
- InputStream is = WrapperServiceImpl.class.getResourceAsStream(resource);
- if (is == null) {
- throw new IllegalArgumentException("Resource " + resource + " doesn't exist");
- }
- try {
- // read it line at a time so that we can use the platform line ending when we write it out
- PrintStream out = new PrintStream(new FileOutputStream(outFile));
- try {
- Scanner scanner = new Scanner(is);
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- line = filter(line, props);
- out.println(line);
- }
- } finally {
- safeClose(out);
- }
- } finally {
- safeClose(is);
- }
- } else {
- LOGGER.warn("File already exists. Move it out of the way if you wish to recreate it: {}", outFile.getPath());
- System.out.println(Ansi.ansi()
- .fg(Ansi.Color.RED).a("File already exists").a(Ansi.Attribute.RESET)
- .a(". Move it out of the way if you wish to recreate it: ").a(outFile.getPath()).toString());
- }
- }
-
- private void safeClose(InputStream is) throws IOException {
- if (is == null)
- return;
- try {
- is.close();
- } catch (Throwable ignore) {
- // nothing to do
- }
- }
-
- private void safeClose(OutputStream is) throws IOException {
- if (is == null)
- return;
- try {
- is.close();
- } catch (Throwable ignore) {
- // nothing to do
- }
- }
-
- private String filter(String line, HashMap<String, String> props) {
- for (Map.Entry<String, String> i : props.entrySet()) {
- int p1 = line.indexOf(i.getKey());
- if (p1 >= 0) {
- String l1 = line.substring(0, p1);
- String l2 = line.substring(p1 + i.getKey().length());
- line = l1 + i.getValue() + l2;
- }
- }
- return line;
- }
-
- private int chmod(File serviceFile, String mode) throws Exception {
- ProcessBuilder builder = new ProcessBuilder();
- builder.command("chmod", mode, serviceFile.getCanonicalPath());
- Process p = builder.start();
-
- PumpStreamHandler handler = new PumpStreamHandler(System.in, System.out, System.err);
- handler.attach(p);
- handler.start();
- int status = p.waitFor();
- handler.stop();
- return status;
- }
-
- private void createJar(File outFile, String resource) throws Exception {
- if (!outFile.exists()) {
- LOGGER.info("Creating file: {}", outFile.getPath());
- System.out.println(Ansi.ansi().a("Creating file: ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
- InputStream is = getClass().getClassLoader().getResourceAsStream(resource);
- if (is == null) {
- throw new IllegalStateException("Resource " + resource + " not found!");
- }
- try {
- JarOutputStream jar = new JarOutputStream(new FileOutputStream(outFile));
- int idx = resource.indexOf('/');
- while (idx > 0) {
- jar.putNextEntry(new ZipEntry(resource.substring(0, idx)));
- jar.closeEntry();
- idx = resource.indexOf('/', idx + 1);
- }
- jar.putNextEntry(new ZipEntry(resource));
- int c;
- while ((c = is.read()) >= 0) {
- jar.write(c);
- }
- jar.closeEntry();
- jar.close();
- } finally {
- safeClose(is);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
deleted file mode 100644
index 0cb8242..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.wrapper.internal.osgi;
-
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.apache.karaf.wrapper.WrapperService;
-import org.apache.karaf.wrapper.internal.WrapperServiceImpl;
-import org.apache.karaf.wrapper.management.internal.WrapperMBeanImpl;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doStart() throws Exception {
- WrapperService wrapperService = new WrapperServiceImpl();
- register(WrapperService.class, wrapperService);
-
- WrapperMBeanImpl wrapperMBean = new WrapperMBeanImpl();
- wrapperMBean.setWrapperService(wrapperService);
- registerMBean(wrapperMBean, "type=wrapper");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
deleted file mode 100644
index 937bfe2..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.wrapper.management;
-
-import javax.management.MBeanException;
-import java.io.File;
-
-/**
- * Describe the WrapperMBean.
- */
-public interface WrapperMBean {
-
- /**
- * Install the service wrapper.
- *
- * @throws MBeanException in case of installation failure.
- */
- void install() throws MBeanException;
-
- /**
- * Install the service wrapper.
- *
- * @param name the service name.
- * @param displayName the service display name.
- * @param description the service description.
- * @param startType the start type.
- * @return the wrapper configuration (index 0) and service files (index 1).
- * @throws MBeanException in case of installation failure.
- */
- File[] install(String name, String displayName, String description, String startType) throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java b/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java
deleted file mode 100644
index 1523015..0000000
--- a/wrapper/core/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.wrapper.management.internal;
-
-import org.apache.karaf.wrapper.WrapperService;
-import org.apache.karaf.wrapper.management.WrapperMBean;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import java.io.File;
-
-/**
- * Implementation of the wrapper MBean.
- */
-public class WrapperMBeanImpl extends StandardMBean implements WrapperMBean {
-
- private WrapperService wrapperService;
-
- public WrapperMBeanImpl() throws NotCompliantMBeanException {
- super(WrapperMBean.class);
- }
-
- public void setWrapperService(WrapperService wrapperService) {
- this.wrapperService = wrapperService;
- }
-
- public WrapperService getWrapperService() {
- return this.wrapperService;
- }
-
- public void install() throws MBeanException {
- try {
- wrapperService.install();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public File[] install(String name, String displayName, String description, String startType) throws MBeanException {
- try {
- return wrapperService.install(name, displayName, description, startType);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/wrapper/core/src/main/resources/OSGI-INF/bundle.info b/wrapper/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 8462cc5..0000000
--- a/wrapper/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,16 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides support of the service wrapper, which allows for starting/stopping Karaf as a system service.
-
-h1. See also
-
-Service Wrapper - section of the Karaf User Guide
[53/59] [abbrv] [KARAF-2852] Merge region/core and region/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java b/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
new file mode 100644
index 0000000..410121c
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
@@ -0,0 +1,661 @@
+/*
+ * 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.region.persist.internal.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Constants;
+
+public class ManifestHeaderProcessor
+{
+ public static final String NESTED_FILTER_ATTRIBUTE = "org.apache.aries.application.filter.attribute";
+ private static final Pattern FILTER_ATTR = Pattern.compile("(\\(!)?\\((.*?)([<>]?=)(.*?)\\)\\)?");
+ private static final String LESS_EQ_OP = "<=";
+ private static final String GREATER_EQ_OP = ">=";
+
+ /**
+ * A simple class to associate two types.
+ *
+ */
+ public static class NameValuePair {
+ private String name;
+ private Map<String,String> attributes;
+
+ public NameValuePair(String name, Map<String,String> value)
+ {
+ this.name = name;
+ this.attributes = value;
+ }
+ public String getName()
+ {
+ return name;
+ }
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public Map<String,String> getAttributes()
+ {
+ return attributes;
+ }
+ public void setAttributes(Map<String,String> value)
+ {
+ this.attributes = value;
+ }
+
+ @Override
+ public String toString(){
+ return "{"+name.toString()+"::"+attributes.toString()+"}";
+ }
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final NameValuePair other = (NameValuePair) obj;
+ if (name == null) {
+ if (other.name != null) return false;
+ } else if (!name.equals(other.name)) return false;
+ if (attributes == null) {
+ if (other.attributes != null) return false;
+ } else if (!attributes.equals(other.attributes)) return false;
+ return true;
+ }
+ }
+
+ /**
+ * Intended to provide a standard way to add Name/Value's to
+ * aggregations of Name/Value's.
+ *
+ */
+ public static interface NameValueCollection {
+ /**
+ * Add this Name & Value to the collection.
+ * @param n
+ * @param v
+ */
+ public void addToCollection(String n, Map<String,String> v);
+ }
+
+ /**
+ * Map of Name -> Value.
+ *
+ */
+ public static class NameValueMap extends HashMap<String, Map<String,String>> implements NameValueCollection, Map<String, Map<String,String>>{
+ private static final long serialVersionUID = -6446338858542599141L;
+
+ public void addToCollection(String n, Map<String,String> v){
+ this.put(n,v);
+ }
+
+ @Override
+ public String toString(){
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ boolean first=true;
+ for(Map.Entry<String, Map<String,String>> entry : this.entrySet()){
+ if(!first)sb.append(",");
+ first=false;
+ sb.append(entry.getKey()+"->"+entry.getValue());
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+ }
+
+ /**
+ * List of Name/Value
+ *
+ */
+ public static class NameValueList extends ArrayList<NameValuePair> implements NameValueCollection, List<NameValuePair> {
+ private static final long serialVersionUID = 1808636823825029983L;
+
+ public void addToCollection(String n, Map<String,String> v){
+ this.add(new NameValuePair(n,v));
+ }
+ @Override
+ public String toString(){
+ StringBuffer sb = new StringBuffer();
+ sb.append("{");
+ boolean first = true;
+ for(NameValuePair nvp : this){
+ if(!first)sb.append(",");
+ first=false;
+ sb.append(nvp.toString());
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+ }
+
+ /**
+ *
+ * Splits a delimiter separated string, tolerating presence of non separator commas
+ * within double quoted segments.
+ *
+ * Eg.
+ * com.ibm.ws.eba.helloWorldService;version="[1.0.0, 1.0.0]" &
+ * com.ibm.ws.eba.helloWorldService;version="1.0.0"
+ * com.ibm.ws.eba.helloWorld;version="2";bundle-version="[2,30)"
+ * com.acme.foo;weirdAttr="one;two;three";weirdDir:="1;2;3"
+ * @param value the value to be split
+ * @param delimiter the delimiter string such as ',' etc.
+ * @return List<String> the components of the split String in a list
+ */
+ public static List<String> split(String value, String delimiter)
+ {
+ return ManifestHeaderUtils.split(value, delimiter);
+ }
+
+
+ /**
+ * Internal method to parse headers with the format<p>
+ * [Name](;[Name])*(;[attribute-name]=[attribute-value])*<br>
+ * Eg.<br>
+ * rumplestiltskin;thing=value;other=something<br>
+ * littleredridinghood
+ * bundle1;bundle2;other=things
+ * bundle1;bundle2
+ *
+ * @param s data to parse
+ * @return a list of NameValuePair, with the Name being the name component,
+ * and the Value being a NameValueMap of key->value mappings.
+ */
+ private static List<NameValuePair> genericNameWithNameValuePairProcess(String s){
+ String name;
+ Map<String,String> params = null;
+ List<NameValuePair> nameValues = new ArrayList<NameValuePair>();
+ List<String> pkgs = new ArrayList<String>();
+ int index = s.indexOf(";");
+ if(index==-1){
+ name = s;
+ params = new HashMap<String, String>();
+ pkgs.add(name);
+ }else{
+ name = s.substring(0,index).trim();
+ String tail = s.substring(index+1).trim();
+
+ pkgs.add(name); // add the first package
+ StringBuilder parameters = new StringBuilder();
+
+
+ // take into consideration of multiple packages separated by ';'
+ // while they share the same attributes or directives
+ List<String> tailParts = split(tail, ";");
+ boolean firstParameter =false;
+
+ for (String part : tailParts) {
+ // if it is not a parameter and no parameter appears in front of it, it must a package
+ if (!!!(part.contains("="))) {
+ // Need to make sure no parameter appears before the package, otherwise ignore this string
+ // as this syntax is invalid
+ if (!!!(firstParameter))
+ pkgs.add(part);
+ } else {
+ if (!!!(firstParameter))
+ firstParameter = true;
+
+ parameters.append(part + ";");
+ }
+ }
+
+ if (parameters.length() != 0) {
+ //remove the final ';' if there is one
+ if (parameters.toString().endsWith(";")) {
+
+ parameters = parameters.deleteCharAt(parameters.length() -1);
+ }
+
+ params = genericNameValueProcess(parameters.toString());
+ }
+
+ }
+ for (String pkg : pkgs) {
+ nameValues.add(new NameValuePair(pkg,params));
+ }
+
+ return nameValues;
+
+ }
+
+ /**
+ * Internal method to parse headers with the format<p>
+ * [attribute-name]=[attribute-value](;[attribute-name]=[attribute-value])*<br>
+ * Eg.<br>
+ * thing=value;other=something<br>
+ * <p>
+ * Note. Directives (name:=value) are represented in the map with name suffixed by ':'
+ *
+ * @param s data to parse
+ * @return a NameValueMap, with attribute-name -> attribute-value.
+ */
+ private static Map<String,String> genericNameValueProcess(String s){
+ Map<String,String> params = new HashMap<String,String>();
+ List<String> parameters = split(s, ";");
+ for(String parameter : parameters) {
+ List<String> parts = split(parameter,"=");
+ // do a check, otherwise we might get NPE
+ if (parts.size() ==2) {
+ String second = parts.get(1).trim();
+ if (second.startsWith("\"") && second.endsWith("\""))
+ second = second.substring(1,second.length()-1);
+
+ String first = parts.get(0).trim();
+
+ // make sure for directives we clear out any space as in "directive :=value"
+ if (first.endsWith(":")) {
+ first = first.substring(0, first.length()-1).trim()+":";
+ }
+
+ params.put(first, second);
+ }
+ }
+
+ return params;
+ }
+
+ /**
+ * Processes an import/export style header.. <p>
+ * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
+ *
+ * @param out The collection to add each package name + attrib map to.
+ * @param s The data to parse
+ */
+ private static void genericImportExportProcess(NameValueCollection out, String s){
+ List<String> packages = split(s, ",");
+ for(String pkg : packages){
+ List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
+ for (NameValuePair p : ps) {
+ out.addToCollection(p.getName(), p.getAttributes());
+ }
+ }
+ }
+
+ /**
+ * Parse an export style header.<p>
+ * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value2
+ * <p>
+ * Result is returned as a list, as export does allow duplicate package exports.
+ *
+ * @param s The data to parse.
+ * @return List of NameValuePairs, where each Name in the list is an exported package,
+ * with its associated Value being a NameValueMap of any attributes declared.
+ */
+ public static List<NameValuePair> parseExportString(String s){
+ NameValueList retval = new NameValueList();
+ genericImportExportProcess(retval, s);
+ return retval;
+ }
+
+ /**
+ * Parse an export style header in a list.<p>
+ * pkg1;attrib=value;attrib=value
+ * pkg2;attrib=value
+ * pkg3;attrib=value2
+ * <p>
+ * Result is returned as a list, as export does allow duplicate package exports.
+ *
+ * @param list The data to parse.
+ * @return List of NameValuePairs, where each Name in the list is an exported package,
+ * with its associated Value being a NameValueMap of any attributes declared.
+ */
+ public static List<NameValuePair> parseExportList(List<String> list){
+ NameValueList retval = new NameValueList();
+ for(String pkg : list){
+ List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
+ for (NameValuePair p : ps) {
+ retval.addToCollection(p.getName(), p.getAttributes());
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * Parse an import style header.<p>
+ * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
+ * <p>
+ * Result is returned as a set, as import does not allow duplicate package imports.
+ *
+ * @param s The data to parse.
+ * @return Map of NameValuePairs, where each Key in the Map is an imported package,
+ * with its associated Value being a NameValueMap of any attributes declared.
+ */
+ public static Map<String, Map<String, String>> parseImportString(String s){
+ NameValueMap retval = new NameValueMap();
+ genericImportExportProcess(retval, s);
+ return retval;
+ }
+
+ /**
+ * Parse a bundle symbolic name.<p>
+ * bundlesymbolicname;attrib=value;attrib=value
+ * <p>
+ *
+ * @param s The data to parse.
+ * @return NameValuePair with Name being the BundleSymbolicName,
+ * and Value being any attribs declared for the name.
+ */
+ public static NameValuePair parseBundleSymbolicName(String s){
+ return genericNameWithNameValuePairProcess(s).get(0); // should just return the first one
+ }
+
+ /**
+ * Parse a version range..
+ *
+ * @param s
+ * @return VersionRange object.
+ * @throws IllegalArgumentException if the String could not be parsed as a VersionRange
+ */
+ public static VersionRange parseVersionRange(String s) throws IllegalArgumentException{
+ return new VersionRange(s);
+ }
+
+ /**
+ * Parse a version range and indicate if the version is an exact version
+ *
+ * @param s
+ * @param exactVersion
+ * @return VersionRange object.
+ * @throws IllegalArgumentException if the String could not be parsed as a VersionRange
+ */
+ public static VersionRange parseVersionRange(String s, boolean exactVersion) throws IllegalArgumentException{
+ return new VersionRange(s, exactVersion);
+ }
+
+ /**
+ * Generate a filter from a set of attributes. This filter will be suitable
+ * for presentation to OBR This means that, due to the way OBR works, it
+ * will include a stanza of the form, (mandatory:<*mandatoryAttribute)
+ * Filter strings generated by this method will therefore tend to break the
+ * standard OSGi Filter class. The OBR stanza can be stripped out later if
+ * required.
+ *
+ * @param attribs
+ * @return filter string
+ */
+ public static String generateFilter(Map<String, Object> attribs) {
+ StringBuilder filter = new StringBuilder("(&");
+ boolean realAttrib = false;
+ StringBuffer realAttribs = new StringBuffer();
+
+ if (attribs == null) {
+ attribs = new HashMap<String, Object>();
+ }
+
+ for (Map.Entry<String, Object> attrib : attribs.entrySet()) {
+ String attribName = attrib.getKey();
+
+ if (attribName.endsWith(":")) {
+ // skip all directives. It is used to affect the attribs on the
+ // filter xml.
+ } else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
+ || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
+ // version and bundle-version attrib requires special
+ // conversion.
+ realAttrib = true;
+
+ VersionRange vr = ManifestHeaderProcessor
+ .parseVersionRange(attrib.getValue().toString());
+
+ filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
+
+ if (vr.getMaximumVersion() != null) {
+ filter.append(")(" + attribName + "<=");
+ filter.append(vr.getMaximumVersion());
+ }
+
+ if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
+ filter.append(")(!(" + attribName + "=");
+ filter.append(vr.getMinimumVersion());
+ filter.append(")");
+ }
+
+ if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
+ filter.append(")(!(" + attribName + "=");
+ filter.append(vr.getMaximumVersion());
+ filter.append(")");
+ }
+ filter.append(")");
+
+ } else if (NESTED_FILTER_ATTRIBUTE.equals(attribName)) {
+ // Filters go in whole, no formatting needed
+ realAttrib = true;
+ filter.append(attrib.getValue());
+
+ } else if (Constants.OBJECTCLASS.equals(attribName)) {
+ realAttrib = true;
+ // objectClass has a "," separated list of interfaces
+ String[] values = attrib.getValue().toString().split(",");
+ for (String s : values)
+ filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
+
+ } else {
+ // attribName was not version..
+ realAttrib = true;
+
+ filter.append("(" + attribName + "=" + attrib.getValue() + ")");
+ // store all attributes in order to build up the mandatory
+ // filter and separate them with ", "
+ // skip bundle-symbolic-name in the mandatory directive query
+ if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
+ .equals(attribName)) {
+ realAttribs.append(attribName);
+ realAttribs.append(", ");
+ }
+ }
+ }
+// /*
+// * The following is how OBR makes mandatory attributes work, we require
+// * that the set of mandatory attributes on the export is a subset of (or
+// * equal to) the set of the attributes we supply.
+// */
+//
+// if (realAttribs.length() > 0) {
+// String attribStr = (realAttribs.toString()).trim();
+// // remove the final ,
+// if ((attribStr.length() > 0) && (attribStr.endsWith(","))) {
+// attribStr = attribStr.substring(0, attribStr.length() - 1);
+// }
+// // build the mandatory filter, e.g.(mandatory:<*company, local)
+// filter.append("(" + Constants.MANDATORY_DIRECTIVE + ":" + "<*"
+// + attribStr + ")");
+// }
+
+ // Prune (& off the front and ) off end
+ String filterString = filter.toString();
+ int openBraces = 0;
+ for (int i = 0; openBraces < 3; i++) {
+ i = filterString.indexOf('(', i);
+ if (i == -1) {
+ break;
+ } else {
+ openBraces++;
+ }
+ }
+ if (openBraces < 3 && filterString.length() > 2) {
+ filter.delete(0, 2);
+ } else {
+ filter.append(")");
+ }
+
+ String result = "";
+ if (realAttrib != false) {
+ result = filter.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Generate a filter from a set of attributes. This filter will be suitable
+ * for presentation to OBR. This means that, due to the way OBR works, it will
+ * include a stanza of the form, (mandatory:<*mandatoryAttribute) Filter
+ * strings generated by this method will therefore tend to break the standard
+ * OSGi Filter class. The OBR stanza can be stripped out later if required.
+ *
+ * We may wish to consider relocating this method since VersionRange has its
+ * own top level class.
+ *
+ * @param type
+ * @param name
+ * @param attribs
+ * @return filter string
+ */
+ public static String generateFilter(String type, String name,
+ Map<String, Object> attribs) {
+ StringBuffer filter = new StringBuffer();
+ String result;
+ // shortcut for the simple case with no attribs.
+
+ if (attribs == null || attribs.isEmpty())
+ filter.append("(" + type + "=" + name + ")");
+ else {
+ // process all the attribs passed.
+ // find out whether there are attributes on the filter
+
+ filter.append("(&(" + type + "=" + name + ")");
+
+ String filterString = generateFilter(attribs);
+
+ int start = 0;
+ int end = filterString.length();
+ if (filterString.startsWith("(&")) {
+ start = 2;
+ end--;
+ }
+
+ if ("".equals(filterString)) {
+ filter.delete(0, 2);
+ } else {
+ filter.append(filterString, start, end);
+ filter.append(")");
+ }
+ }
+
+ result = filter.toString();
+
+ return result;
+ }
+
+ private static Map<String, String> parseFilterList(String filter) {
+
+ Map<String, String> result = new HashMap<String, String>();
+ Set<String> negatedVersions = new HashSet<String>();
+ Set<String> negatedBundleVersions = new HashSet<String>();
+
+ String lowerVersion = null;
+ String upperVersion = null;
+ String lowerBundleVersion = null;
+ String upperBundleVersion = null;
+
+ Matcher m = FILTER_ATTR.matcher(filter);
+ while (m.find()) {
+ boolean negation = m.group(1) != null;
+ String attr = m.group(2);
+ String op = m.group(3);
+ String value = m.group(4);
+
+ if (Constants.VERSION_ATTRIBUTE.equals(attr)) {
+ if (negation) {
+ negatedVersions.add(value);
+ } else {
+ if (GREATER_EQ_OP.equals(op))
+ lowerVersion = value;
+ else if (LESS_EQ_OP.equals(op))
+ upperVersion = value;
+ else
+ throw new IllegalArgumentException();
+ }
+ } else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attr)) {
+ // bundle-version is like version, but may be specified at the
+ // same time
+ // therefore we have similar code with separate variables
+ if (negation) {
+ negatedBundleVersions.add(value);
+ } else {
+ if (GREATER_EQ_OP.equals(op))
+ lowerBundleVersion = value;
+ else if (LESS_EQ_OP.equals(op))
+ upperBundleVersion = value;
+ else
+ throw new IllegalArgumentException();
+ }
+ } else {
+ result.put(attr, value);
+ }
+ }
+
+ if (lowerVersion != null) {
+ StringBuilder versionAttr = new StringBuilder(lowerVersion);
+ if (upperVersion != null) {
+ versionAttr.append(",").append(upperVersion).insert(0,
+ negatedVersions.contains(lowerVersion) ? '(' : '[').append(
+ negatedVersions.contains(upperVersion) ? ')' : ']');
+ }
+
+ result.put(Constants.VERSION_ATTRIBUTE, versionAttr.toString());
+ }
+ // Do it again for bundle-version
+ if (lowerBundleVersion != null) {
+ StringBuilder versionAttr = new StringBuilder(lowerBundleVersion);
+ if (upperBundleVersion != null) {
+ versionAttr.append(",").append(upperBundleVersion).insert(0,
+ negatedBundleVersions.contains(lowerBundleVersion) ? '(' : '[')
+ .append(
+ negatedBundleVersions.contains(upperBundleVersion) ? ')' : ']');
+ }
+
+ result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, versionAttr.toString());
+ }
+
+ return result;
+ }
+
+ public static Map<String,String> parseFilter(String filter)
+ {
+ Map<String,String> result;
+ if (filter.startsWith("(&")) {
+ result = parseFilterList(filter.substring(2, filter.length()-1));
+ } else {
+ result = parseFilterList(filter);
+ }
+ return result;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java b/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
new file mode 100644
index 0000000..8c87616
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
@@ -0,0 +1,85 @@
+/*
+ * 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.region.persist.internal.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ManifestHeaderUtils {
+
+ /**
+ *
+ * Splits a delimiter separated string, tolerating presence of non separator commas
+ * within double quoted segments.
+ *
+ * Eg.
+ * com.ibm.ws.eba.helloWorldService;version="[1.0.0, 1.0.0]" &
+ * com.ibm.ws.eba.helloWorldService;version="1.0.0"
+ * com.ibm.ws.eba.helloWorld;version="2";bundle-version="[2,30)"
+ * com.acme.foo;weirdAttr="one;two;three";weirdDir:="1;2;3"
+ * @param value the value to be split
+ * @param delimiter the delimiter string such as ',' etc.
+ * @return List<String> the components of the split String in a list
+ */
+ public static List<String> split(String value, String delimiter)
+ {
+ List<String> result = new ArrayList<String>();
+ if (value != null) {
+ String[] packages = value.split(delimiter);
+
+ for (int i = 0; i < packages.length; ) {
+ String tmp = packages[i++].trim();
+ // if there is a odd number of " in a string, we need to append
+ while (count(tmp, "\"") % 2 != 0) {
+ // check to see if we need to append the next package[i++]
+ if (i<packages.length)
+ tmp = tmp + delimiter + packages[i++].trim();
+ else
+ // oops. The double quotes are not paired up. We have reached to the end of the string.
+ throw new IllegalArgumentException("Unmatched double quotes: " + tmp);
+ }
+
+ result.add(tmp);
+
+ }
+ }
+ return result;
+ }
+
+ /**
+ * count the number of characters in a string
+ * @param parent The string to be searched
+ * @param subString The substring to be found
+ * @return the number of occurrence of the subString
+ */
+ private static int count(String parent, String subString) {
+
+ int count = 0 ;
+ int i = parent.indexOf(subString);
+ while (i > -1) {
+ if (parent.length() >= i+1)
+ parent = parent.substring(i+1);
+ count ++;
+ i = parent.indexOf(subString);
+ }
+ return count;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java b/region/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
new file mode 100644
index 0000000..19bbc77
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
@@ -0,0 +1,456 @@
+/*
+ * 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.region.persist.internal.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Version;
+
+public final class VersionRange {
+
+ /** A string representation of the version. */
+ private String version;
+
+ /** The minimum desired version for the bundle */
+ private Version minimumVersion;
+
+ /** The maximum desired version for the bundle */
+ private Version maximumVersion;
+
+ /** True if the match is exclusive of the minimum version */
+ private boolean minimumExclusive;
+
+ /** True if the match is exclusive of the maximum version */
+ private boolean maximumExclusive;
+
+ /** A regexp to select the version */
+ private static final Pattern versionCapture = Pattern.compile("\"?(.*?)\"?$");
+
+ /**
+ *
+ * @param version
+ * version for the verioninfo
+ */
+ public VersionRange(String version) {
+ this.version = version;
+ processVersionAttribute(version);
+ }
+
+ /**
+ * This method should be used to create a version range from a single
+ * version string.
+ * @param version
+ * version for the versioninfo
+ * @param exactVersion
+ * whether this is an exact version {@code true} or goes to infinity
+ * {@code false}
+ */
+ public VersionRange(String version, boolean exactVersion) {
+
+ if (exactVersion) {
+ // Do not store this string as it might be just a version, or a range!
+ processExactVersionAttribute(version);
+ } else {
+ this.version = version;
+ processVersionAttribute(this.version);
+ }
+
+ assertInvariants();
+ }
+
+ /**
+ * Constructor designed for internal use only.
+ *
+ * @param maximumVersion
+ * @param maximumExclusive
+ * @param minimumVersion
+ * @param minimumExclusive
+ * @throws IllegalArgumentException
+ * if parameters are not valid.
+ */
+ private VersionRange(Version maximumVersion,
+ boolean maximumExclusive,
+ Version minimumVersion,
+ boolean minimumExclusive) {
+ this.maximumVersion = maximumVersion;
+ this.maximumExclusive = maximumExclusive;
+ this.minimumVersion = minimumVersion;
+ this.minimumExclusive = minimumExclusive;
+
+ assertInvariants();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.aries.application.impl.VersionRange#toString()
+ */
+ @Override
+ public String toString() {
+ // Some constructors don't take in a string that we can return directly,
+ // so construct one if needed
+ if (version == null) {
+ if (maximumVersion == null) {
+ version = minimumVersion.toString();
+ } else {
+ version = (minimumExclusive ? "(" : "[") + minimumVersion + "," + maximumVersion
+ + (maximumExclusive ? ")" : "]");
+ }
+ }
+ return this.version;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + minimumVersion.hashCode();
+ result = 31 * result + (minimumExclusive ? 1 : 0);
+ result = 31 * result + (maximumVersion != null ? maximumVersion.hashCode() : 0);
+ result = 31 * result + (maximumExclusive ? 1 : 0);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ boolean result = false;
+ if (this == other) {
+ result = true;
+ } else if (other instanceof VersionRange) {
+ VersionRange vr = (VersionRange) other;
+ result = minimumVersion.equals(vr.minimumVersion)
+ && minimumExclusive == vr.minimumExclusive
+ && (maximumVersion == null ? vr.maximumVersion == null : maximumVersion
+ .equals(vr.maximumVersion)) && maximumExclusive == vr.maximumExclusive;
+ }
+
+ return result;
+ }
+
+ /**
+ * this method returns the exact version from the versionInfo obj.
+ * this is used for DeploymentContent only to return a valid exact version
+ * otherwise, null is returned.
+ * @return the exact version
+ */
+ public Version getExactVersion() {
+ Version v = null;
+ if (isExactVersion()) {
+ v = getMinimumVersion();
+ }
+ return v;
+ }
+
+ /**
+ * get the maximum version
+ * @return the maximum version
+ */
+ public Version getMaximumVersion() {
+ return maximumVersion;
+ }
+
+ /**
+ * get the minimum version
+ * @return the minimum version
+ */
+ public Version getMinimumVersion() {
+ return minimumVersion;
+ }
+
+ /**
+ * is the maximum version exclusive
+ * @return is the max version in the range.
+ */
+ public boolean isMaximumExclusive() {
+ return maximumExclusive;
+ }
+
+ /**
+ * is the maximum version unbounded
+ * @return true if no upper bound was specified.
+ */
+ public boolean isMaximumUnbounded() {
+ boolean unbounded = maximumVersion == null;
+ return unbounded;
+ }
+
+ /**
+ * is the minimum version exclusive
+ * @return true if the min version is in range.
+ */
+ public boolean isMinimumExclusive() {
+ return minimumExclusive;
+ }
+
+ /**
+ * this is designed for deployed-version as that is the exact version.
+ *
+ * @param version
+ * @return
+ * @throws IllegalArgumentException
+ */
+ private boolean processExactVersionAttribute(String version) throws IllegalArgumentException {
+ boolean success = processVersionAttribute(version);
+
+ if (maximumVersion == null) {
+ maximumVersion = minimumVersion;
+ }
+
+ if (!minimumVersion.equals(maximumVersion)) {
+ throw new IllegalArgumentException("Version is not exact: " + version);
+ }
+
+ if (!!!isExactVersion()) {
+ throw new IllegalArgumentException("Version is not exact: " + version);
+ }
+
+ return success;
+ }
+
+ /**
+ * process the version attribute,
+ *
+ * @param version
+ * the value to be processed
+ * @return
+ * @throws IllegalArgumentException
+ */
+ private boolean processVersionAttribute(String version) throws IllegalArgumentException {
+ boolean success = false;
+
+ if (version == null) {
+ throw new IllegalArgumentException("Version is null");
+ }
+
+ Matcher matches = versionCapture.matcher(version);
+
+ if (matches.matches()) {
+ String versions = matches.group(1);
+
+ if ((versions.startsWith("[") || versions.startsWith("("))
+ && (versions.endsWith("]") || versions.endsWith(")"))) {
+ if (versions.startsWith("["))
+ minimumExclusive = false;
+ else if (versions.startsWith("("))
+ minimumExclusive = true;
+
+ if (versions.endsWith("]"))
+ maximumExclusive = false;
+ else if (versions.endsWith(")"))
+ maximumExclusive = true;
+
+ int index = versions.indexOf(',');
+ String minVersion = versions.substring(1, index);
+ String maxVersion = versions.substring(index + 1, versions.length() - 1);
+
+ try {
+ minimumVersion = new Version(minVersion.trim());
+ maximumVersion = new Version(maxVersion.trim());
+ success = true;
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException("Version cannot be decoded: " + version, nfe);
+ }
+ } else {
+ try {
+ if (versions.trim().length() == 0)
+ minimumVersion = new Version(0, 0, 0);
+ else
+ minimumVersion = new Version(versions.trim());
+ success = true;
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException("Version cannot be decoded: " + version, nfe);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Version cannot be decoded: " + version);
+ }
+
+ return success;
+ }
+
+ /**
+ * Assert object invariants. Called by constructors to verify that arguments
+ * were valid.
+ *
+ * @throws IllegalArgumentException
+ * if invariants are violated.
+ */
+ private void assertInvariants() {
+ if (minimumVersion == null
+ || !isRangeValid(minimumVersion, minimumExclusive, maximumVersion, maximumExclusive)) {
+ IllegalArgumentException e = new IllegalArgumentException();
+ throw e;
+ }
+ }
+
+ /**
+ * Check if the supplied parameters describe a valid version range.
+ *
+ * @param min
+ * the minimum version.
+ * @param minExclusive
+ * whether the minimum version is exclusive.
+ * @param max
+ * the maximum version.
+ * @param maxExclusive
+ * whether the maximum version is exclusive.
+ * @return true is the range is valid; otherwise false.
+ */
+ private boolean isRangeValid(Version min,
+ boolean minExclusive,
+ Version max,
+ boolean maxExclusive) {
+ boolean result;
+
+ // A null maximum version is unbounded so means that minimum is smaller
+ // than
+ // maximum.
+ int minMaxCompare = (max == null ? -1 : min.compareTo(max));
+ if (minMaxCompare > 0) {
+ // Minimum larger than maximum is invalid.
+ result = false;
+ } else if (minMaxCompare == 0 && (minExclusive || maxExclusive)) {
+ // If min and max are the same, and either are exclusive, no valid
+ // range
+ // exists.
+ result = false;
+ } else {
+ // Range is valid.
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ * This method checks that the provided version matches the desired version.
+ *
+ * @param version
+ * the version.
+ * @return true if the version matches, false otherwise.
+ */
+ public boolean matches(Version version) {
+ boolean result;
+ if (this.getMaximumVersion() == null) {
+ result = this.getMinimumVersion().compareTo(version) <= 0;
+ } else {
+ int minN = this.isMinimumExclusive() ? 0 : 1;
+ int maxN = this.isMaximumExclusive() ? 0 : 1;
+
+ result = (this.getMinimumVersion().compareTo(version) < minN)
+ && (version.compareTo(this.getMaximumVersion()) < maxN);
+ }
+ return result;
+ }
+
+ /**
+ * check if the versioninfo is the exact version
+ * @return true if the range will match 1 exact version.
+ */
+ public boolean isExactVersion() {
+ return minimumVersion.equals(maximumVersion) && minimumExclusive == maximumExclusive
+ && !!!minimumExclusive;
+ }
+
+ /**
+ * Create a new version range that is the intersection of {@code this} and the argument.
+ * In other words, the largest version range that lies within both {@code this} and
+ * the parameter.
+ * @param r a version range to be intersected with {@code this}.
+ * @return a new version range, or {@code null} if no intersection is possible.
+ */
+ public VersionRange intersect(VersionRange r) {
+ // Use the highest minimum version.
+ final Version newMinimumVersion;
+ final boolean newMinimumExclusive;
+ int minCompare = minimumVersion.compareTo(r.getMinimumVersion());
+ if (minCompare > 0) {
+ newMinimumVersion = minimumVersion;
+ newMinimumExclusive = minimumExclusive;
+ } else if (minCompare < 0) {
+ newMinimumVersion = r.getMinimumVersion();
+ newMinimumExclusive = r.isMinimumExclusive();
+ } else {
+ newMinimumVersion = minimumVersion;
+ newMinimumExclusive = (minimumExclusive || r.isMinimumExclusive());
+ }
+
+ // Use the lowest maximum version.
+ final Version newMaximumVersion;
+ final boolean newMaximumExclusive;
+ // null maximum version means unbounded, so the highest possible value.
+ if (maximumVersion == null) {
+ newMaximumVersion = r.getMaximumVersion();
+ newMaximumExclusive = r.isMaximumExclusive();
+ } else if (r.getMaximumVersion() == null) {
+ newMaximumVersion = maximumVersion;
+ newMaximumExclusive = maximumExclusive;
+ } else {
+ int maxCompare = maximumVersion.compareTo(r.getMaximumVersion());
+ if (maxCompare < 0) {
+ newMaximumVersion = maximumVersion;
+ newMaximumExclusive = maximumExclusive;
+ } else if (maxCompare > 0) {
+ newMaximumVersion = r.getMaximumVersion();
+ newMaximumExclusive = r.isMaximumExclusive();
+ } else {
+ newMaximumVersion = maximumVersion;
+ newMaximumExclusive = (maximumExclusive || r.isMaximumExclusive());
+ }
+ }
+
+ VersionRange result;
+ if (isRangeValid(newMinimumVersion, newMinimumExclusive, newMaximumVersion,
+ newMaximumExclusive)) {
+ result = new VersionRange(newMaximumVersion, newMaximumExclusive, newMinimumVersion,
+ newMinimumExclusive);
+ } else {
+ result = null;
+ }
+ return result;
+ }
+
+ /**
+ * Parse a version range..
+ *
+ * @param s
+ * @return VersionRange object.
+ * @throws IllegalArgumentException
+ * if the String could not be parsed as a VersionRange
+ */
+ public static VersionRange parseVersionRange(String s) throws IllegalArgumentException {
+ return new VersionRange(s);
+ }
+
+ /**
+ * Parse a version range and indicate if the version is an exact version
+ *
+ * @param s
+ * @param exactVersion
+ * @return VersionRange object.
+ * @throws IllegalArgumentException
+ * if the String could not be parsed as a VersionRange
+ */
+ public static VersionRange parseVersionRange(String s, boolean exactVersion)
+ throws IllegalArgumentException {
+ return new VersionRange(s, exactVersion);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/resources/org/apache/karaf/region/persist/region.xsd
----------------------------------------------------------------------
diff --git a/region/src/main/resources/org/apache/karaf/region/persist/region.xsd b/region/src/main/resources/org/apache/karaf/region/persist/region.xsd
new file mode 100644
index 0000000..8ca26e7
--- /dev/null
+++ b/region/src/main/resources/org/apache/karaf/region/persist/region.xsd
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<xsd:schema xmlns="http://karaf.apache.org/xmlns/region/v1.0.0"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://karaf.apache.org/xmlns/region/v1.0.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines the configuration elements for Apache Karaf region xml configuration.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="regions" type="regionsType"/>
+
+
+ <xsd:complexType name="regionsType">
+ <xsd:annotation>
+ <xsd:documentation>
+ Regions element
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="region" type="regionType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="filter" type="filterType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="regionType">
+ <xsd:annotation>
+ <xsd:documentation>
+ Region element
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="bundle" type="regionBundleType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="regionBundleType">
+ <xsd:sequence/>
+ <xsd:attribute name="id" type="xsd:long"/>
+ <xsd:attribute name="location" type="xsd:string"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="filterBundleType">
+ <xsd:sequence>
+ <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:long"/>
+ <xsd:attribute name="symbolic-name" type="xsd:string"/>
+ <xsd:attribute name="version" type="xsd:string"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="filterType">
+ <xsd:sequence>
+ <xsd:element name="bundle" type="filterBundleType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="package" type="filterPackageType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="namespace" type="filterNamespaceType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="from" type="xsd:string" use="required"/>
+ <xsd:attribute name="to" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="filterPackageType">
+ <xsd:sequence>
+ <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="version" type="xsd:string"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="filterAttributeType">
+ <xsd:sequence/>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="value" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="filterNamespaceType">
+ <xsd:sequence>
+ <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+</xsd:schema>
[30/59] [abbrv] git commit: [KARAF-2852] Merge instance/core and
instance/command
Posted by gn...@apache.org.
[KARAF-2852] Merge instance/core and instance/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/7c2db062
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/7c2db062
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/7c2db062
Branch: refs/heads/master
Commit: 7c2db062584b2b15afc5bf1727e2f477feac2877
Parents: d33e095
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 22:17:39 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:00:16 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
instance/NOTICE | 71 ++
instance/command/NOTICE | 71 --
instance/command/pom.xml | 129 --
.../instance/command/ChangeOptsCommand.java | 41 -
.../command/ChangeRmiRegistryPortCommand.java | 41 -
.../command/ChangeRmiServerPortCommand.java | 41 -
.../instance/command/ChangeSshPortCommand.java | 41 -
.../karaf/instance/command/CloneCommand.java | 66 -
.../karaf/instance/command/ConnectCommand.java | 78 --
.../karaf/instance/command/CreateCommand.java | 74 --
.../karaf/instance/command/DestroyCommand.java | 41 -
.../command/InstanceCommandSupport.java | 51 -
.../karaf/instance/command/ListCommand.java | 81 --
.../karaf/instance/command/RenameCommand.java | 45 -
.../karaf/instance/command/StartCommand.java | 76 --
.../karaf/instance/command/StatusCommand.java | 40 -
.../karaf/instance/command/StopCommand.java | 38 -
.../command/completers/InstanceCompleter.java | 52 -
.../org/apache/karaf/instance/main/Execute.java | 171 ---
.../services/org/apache/karaf/shell/commands | 30 -
.../src/main/resources/OSGI-INF/bundle.info | 29 -
.../instance/command/CreateCommandTest.java | 57 -
.../apache/karaf/instance/main/ExecuteTest.java | 126 --
instance/core/NOTICE | 71 --
instance/core/pom.xml | 181 ---
.../apache/karaf/instance/core/Instance.java | 66 -
.../karaf/instance/core/InstanceService.java | 33 -
.../karaf/instance/core/InstanceSettings.java | 97 --
.../karaf/instance/core/InstancesMBean.java | 55 -
.../instance/core/internal/InstanceImpl.java | 110 --
.../core/internal/InstanceServiceImpl.java | 1166 ------------------
.../core/internal/InstanceToTableMapper.java | 83 --
.../core/internal/InstancesMBeanImpl.java | 224 ----
.../instance/core/internal/osgi/Activator.java | 35 -
.../main/java/org/apache/karaf/jpm/Process.java | 47 -
.../org/apache/karaf/jpm/ProcessBuilder.java | 59 -
.../apache/karaf/jpm/ProcessBuilderFactory.java | 25 -
.../jpm/impl/ProcessBuilderFactoryImpl.java | 27 -
.../karaf/jpm/impl/ProcessBuilderImpl.java | 48 -
.../org/apache/karaf/jpm/impl/ProcessImpl.java | 155 ---
.../org/apache/karaf/jpm/impl/ScriptUtils.java | 128 --
.../src/main/resources/OSGI-INF/bundle.info | 36 -
.../apache/karaf/instance/resources/bin/karaf | 25 -
.../karaf/instance/resources/bin/karaf.bat | 25 -
.../apache/karaf/instance/resources/bin/start | 25 -
.../karaf/instance/resources/bin/start.bat | 24 -
.../apache/karaf/instance/resources/bin/stop | 25 -
.../karaf/instance/resources/bin/stop.bat | 24 -
.../etc/org.apache.karaf.management.cfg | 63 -
.../resources/etc/org.apache.karaf.shell.cfg | 75 --
.../instance/resources/etc/system.properties | 120 --
.../org/apache/karaf/jpm/impl/unix/start.sh | 29 -
.../apache/karaf/jpm/impl/windows/destroy.vbs | 27 -
.../apache/karaf/jpm/impl/windows/running.vbs | 26 -
.../org/apache/karaf/jpm/impl/windows/start.vbs | 34 -
.../instance/core/InstanceSettingsTest.java | 58 -
.../core/internal/InstanceServiceImplTest.java | 187 ---
.../internal/InstanceServiceMBeanImplTest.java | 239 ----
.../internal/InstanceToTableMapperTest.java | 90 --
.../java/org/apache/karaf/jpm/MainTest.java | 24 -
.../java/org/apache/karaf/jpm/ProcessTest.java | 69 --
.../src/test/resources/etc/startup.properties | 20 -
instance/pom.xml | 175 ++-
.../instance/command/ChangeOptsCommand.java | 41 +
.../command/ChangeRmiRegistryPortCommand.java | 41 +
.../command/ChangeRmiServerPortCommand.java | 41 +
.../instance/command/ChangeSshPortCommand.java | 41 +
.../karaf/instance/command/CloneCommand.java | 66 +
.../karaf/instance/command/ConnectCommand.java | 78 ++
.../karaf/instance/command/CreateCommand.java | 74 ++
.../karaf/instance/command/DestroyCommand.java | 41 +
.../command/InstanceCommandSupport.java | 51 +
.../karaf/instance/command/ListCommand.java | 81 ++
.../karaf/instance/command/RenameCommand.java | 45 +
.../karaf/instance/command/StartCommand.java | 76 ++
.../karaf/instance/command/StatusCommand.java | 40 +
.../karaf/instance/command/StopCommand.java | 38 +
.../command/completers/InstanceCompleter.java | 52 +
.../apache/karaf/instance/core/Instance.java | 66 +
.../karaf/instance/core/InstanceService.java | 33 +
.../karaf/instance/core/InstanceSettings.java | 97 ++
.../karaf/instance/core/InstancesMBean.java | 55 +
.../instance/core/internal/InstanceImpl.java | 110 ++
.../core/internal/InstanceServiceImpl.java | 1166 ++++++++++++++++++
.../core/internal/InstanceToTableMapper.java | 83 ++
.../core/internal/InstancesMBeanImpl.java | 224 ++++
.../instance/core/internal/osgi/Activator.java | 35 +
.../org/apache/karaf/instance/main/Execute.java | 171 +++
.../main/java/org/apache/karaf/jpm/Process.java | 47 +
.../org/apache/karaf/jpm/ProcessBuilder.java | 59 +
.../apache/karaf/jpm/ProcessBuilderFactory.java | 25 +
.../jpm/impl/ProcessBuilderFactoryImpl.java | 27 +
.../karaf/jpm/impl/ProcessBuilderImpl.java | 48 +
.../org/apache/karaf/jpm/impl/ProcessImpl.java | 155 +++
.../org/apache/karaf/jpm/impl/ScriptUtils.java | 128 ++
.../services/org/apache/karaf/shell/commands | 30 +
.../src/main/resources/OSGI-INF/bundle.info | 36 +
.../apache/karaf/instance/resources/bin/karaf | 25 +
.../karaf/instance/resources/bin/karaf.bat | 25 +
.../apache/karaf/instance/resources/bin/start | 25 +
.../karaf/instance/resources/bin/start.bat | 24 +
.../apache/karaf/instance/resources/bin/stop | 25 +
.../karaf/instance/resources/bin/stop.bat | 24 +
.../etc/org.apache.karaf.management.cfg | 63 +
.../resources/etc/org.apache.karaf.shell.cfg | 75 ++
.../instance/resources/etc/system.properties | 120 ++
.../org/apache/karaf/jpm/impl/unix/start.sh | 29 +
.../apache/karaf/jpm/impl/windows/destroy.vbs | 27 +
.../apache/karaf/jpm/impl/windows/running.vbs | 26 +
.../org/apache/karaf/jpm/impl/windows/start.vbs | 34 +
.../instance/command/CreateCommandTest.java | 57 +
.../instance/core/InstanceSettingsTest.java | 58 +
.../core/internal/InstanceServiceImplTest.java | 187 +++
.../internal/InstanceServiceMBeanImplTest.java | 239 ++++
.../internal/InstanceToTableMapperTest.java | 90 ++
.../apache/karaf/instance/main/ExecuteTest.java | 126 ++
.../java/org/apache/karaf/jpm/MainTest.java | 24 +
.../java/org/apache/karaf/jpm/ProcessTest.java | 69 ++
.../src/test/resources/etc/startup.properties | 20 +
120 files changed, 5031 insertions(+), 5283 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/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 1c67ca7..830ba9d 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -134,7 +134,6 @@
<feature name="instance" description="Provide Instance support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.instance/org.apache.karaf.instance.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.instance/org.apache.karaf.instance.command/${project.version}</bundle>
</feature>
<feature name="jaas" description="Provide JAAS support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/NOTICE
----------------------------------------------------------------------
diff --git a/instance/NOTICE b/instance/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/instance/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/7c2db062/instance/command/NOTICE
----------------------------------------------------------------------
diff --git a/instance/command/NOTICE b/instance/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/instance/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/7c2db062/instance/command/pom.xml
----------------------------------------------------------------------
diff --git a/instance/command/pom.xml b/instance/command/pom.xml
deleted file mode 100644
index d9741ca..0000000
--- a/instance/command/pom.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?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.instance</groupId>
- <artifactId>instance</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.instance.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Instance :: Command</name>
- <description>Instance shell commands to manipulate Karaf child instances.</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.instance</groupId>
- <artifactId>org.apache.karaf.instance.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.command</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymockclassextension</artifactId>
- <version>${easymock.version}</version>
- <scope>test</scope>
- </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>
- <Export-Package>
- !*
- </Export-Package>
- <!-- We have to avoid importing instance.core.internal and jansi
- as Execute.java accesses the InstanceServiceImpl and jansi
- (but only outside OSGi) -->
- <Import-Package>
- !org.apache.karaf.shell.impl.action.command,
- !org.apache.karaf.instance.core.internal,
- !org.fusesource.jansi,
- *
- </Import-Package>
- <Private-Package>
- org.apache.karaf.instance.main,
- org.apache.karaf.instance.command,
- org.apache.karaf.instance.command.completers
- </Private-Package>
- <Karaf-Commands>org.apache.karaf.instance.command.*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
deleted file mode 100644
index c526c07..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "opts-change", description = "Changes the Java options of an existing container instance.")
-@Service
-public class ChangeOptsCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- @Argument(index = 1, name = "javaOpts", description = "The new Java options to set", required = true, multiValued = false)
- private String javaOpts;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).changeJavaOpts(javaOpts);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
deleted file mode 100644
index de5bfaf..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "rmi-registry-port-change", description = "Changes the RMI registry port (used by management layer) of an existing container instance.")
-@Service
-public class ChangeRmiRegistryPortCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- @Argument(index = 1, name = "port", description = "The new RMI registry port to set", required = true, multiValued = false)
- private int port = 0;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).changeRmiRegistryPort(port);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
deleted file mode 100644
index 0ac2cf7..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "rmi-server-port-change", description = "Changes the RMI server port (used by management layer) of an existing instance.")
-@Service
-public class ChangeRmiServerPortCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- @Argument(index = 1, name = "port", description = "The new RMI server port to set", required = true, multiValued = false)
- private int port = 0;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).changeRmiServerPort(port);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
deleted file mode 100644
index 17ad26c..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "ssh-port-change", description = "Changes the secure shell port of an existing container instance.")
-@Service
-public class ChangeSshPortCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- @Argument(index = 1, name = "port", description = "The new secure shell port to set", required = true, multiValued = false)
- private int port = 0;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).changeSshPort(port);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/CloneCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
deleted file mode 100644
index e4f28c5..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-import org.apache.karaf.instance.core.InstanceSettings;
-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;
-
-/**
- * Clone an existing instance.
- */
-@Command(scope = "instance", name = "clone", description = "Clones an existing container instance.")
-@Service
-public class CloneCommand extends InstanceCommandSupport {
-
- @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
- int sshPort = 0;
-
- @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
- int rmiRegistryPort = 0;
-
- @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
- int rmiServerPort = 0;
-
- @Option(name = "-l", aliases = {"--location"}, description = "Location of the cloned container instance in the file system", required = false, multiValued = false)
- String location;
-
- @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the cloned instance", required = false, multiValued = false)
- String javaOpts;
-
- @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
- boolean verbose = false;
-
- @Argument(index = 0, name = "name", description = "The name of the source container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- String name;
-
- @Argument(index = 1, name = "cloneName", description = "The name of the cloned container instance", required = true, multiValued = false)
- String cloneName;
-
-
- protected Object doExecute() throws Exception {
- InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, null, null);
- getInstanceService().cloneInstance(name, cloneName, settings, verbose);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
deleted file mode 100644
index c81a3eb..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.instance.command;
-
-import java.util.List;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.Session;
-
-@Command(scope = "instance", name = "connect", description = "Connects to an existing container instance.")
-@Service
-public class ConnectCommand extends InstanceCommandSupport {
-
- @Option(name="-u", aliases={"--username"}, description="Remote user name", required = false, multiValued = false)
- private String username;
-
- @Option(name = "-p", aliases = {"--password"}, description = "Remote password", required = false, multiValued = false)
- private String password;
-
- @Argument(index = 0, name="name", description="The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- @Argument(index = 1, name = "command", description = "Optional command to execute", required = false, multiValued = true)
- private List<String> command;
-
- @Reference
- Session session;
-
- protected Object doExecute() throws Exception {
- String cmdStr = "";
- if (command != null) {
- StringBuilder sb = new StringBuilder();
- for (String cmd : command) {
- if (sb.length() > 0) {
- sb.append(' ');
- }
- sb.append(cmd);
- }
- cmdStr = "'" + sb.toString().replaceAll("'", "\\'") + "'";
- }
-
- int port = getExistingInstance(instance).getSshPort();
- if (username != null) {
- if (password == null) {
- session.execute("ssh:ssh -q -l " + username + " -p " + port + " localhost " + cmdStr);
- } else {
- session.execute("ssh:ssh -q -l " + username + " -P " + password + " -p " + port + " localhost " + cmdStr);
- }
- } else {
- session.execute("ssh:ssh -q -p " + port + " localhost " + cmdStr);
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/CreateCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
deleted file mode 100644
index 0dcc3ac..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.instance.command;
-
-import java.util.List;
-
-import org.apache.karaf.features.command.completers.AllFeatureCompleter;
-import org.apache.karaf.features.command.completers.InstalledRepoUriCompleter;
-import org.apache.karaf.instance.core.InstanceSettings;
-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;
-
-/**
- * Creates a new instance.
- */
-@Command(scope = "instance", name = "create", description = "Creates a new container instance.")
-@Service
-public class CreateCommand extends InstanceCommandSupport
-{
- @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
- int sshPort = 0;
-
- @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
- int rmiRegistryPort = 0;
-
- @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
- int rmiServerPort = 0;
-
- @Option(name = "-l", aliases = {"--location"}, description = "Location of the new container instance in the file system", required = false, multiValued = false)
- String location;
-
- @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the instance", required = false, multiValued = false)
- String javaOpts;
-
- @Option(name = "-f", aliases = {"--feature"},
- description = "Initial features. This option can be specified multiple times to enable multiple initial features", required = false, multiValued = true)
- @Completion(AllFeatureCompleter.class)
- List<String> features;
-
- @Option(name = "-furl", aliases = {"--featureURL"},
- description = "Additional feature descriptor URLs. This option can be specified multiple times to add multiple URLs", required = false, multiValued = true)
- @Completion(InstalledRepoUriCompleter.class)
- List<String> featureURLs;
-
- @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
- boolean verbose = false;
-
- @Argument(index = 0, name = "name", description="The name of the new container instance", required = true, multiValued = false)
- String instance = null;
-
- protected Object doExecute() throws Exception {
- InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
- getInstanceService().createInstance(instance, settings, verbose);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
deleted file mode 100644
index fb2964f..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-/**
- * Destroy an existing instance.
- */
-@Command(scope = "instance", name = "destroy", description = "Destroys an existing container instance.")
-@Service
-public class DestroyCommand extends InstanceCommandSupport
-{
- @Argument(index = 0, name = "name", description= "The name of the container instance to destroy", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).destroy();
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java b/instance/command/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
deleted file mode 100644
index 3b0b535..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-
-public abstract class InstanceCommandSupport implements Action {
-
- @Reference
- private InstanceService instanceService;
-
- public InstanceService getInstanceService() {
- return instanceService;
- }
-
- public void setInstanceService(InstanceService instanceService) {
- this.instanceService = instanceService;
- }
-
- protected Instance getExistingInstance(String name) {
- Instance i = instanceService.getInstance(name);
- if (i == null) {
- throw new IllegalArgumentException("Instances '" + name + "' does not exist");
- }
- return i;
- }
-
- @Override
- public Object execute() throws Exception {
- return doExecute();
- }
-
- protected abstract Object doExecute() throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/ListCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/ListCommand.java
deleted file mode 100644
index fe571a8..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/ListCommand.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.core.Instance;
-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 = "instance", name = "list", description = "Lists all existing container instances.")
-@Service
-public class ListCommand extends InstanceCommandSupport {
-
- @Option(name = "-l", aliases = { "--location" }, description = "Displays the location of the container instances", required = false, multiValued = false)
- boolean location;
-
- @Option(name = "-o", aliases = { "--java-opts" }, description = "Displays the Java options used to launch the JVM", required = false, multiValued = false)
- boolean javaOpts;
-
- @Option(name = "--no-color", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- protected Object doExecute() throws Exception {
- getInstanceService().refreshInstance();
- Instance[] instances = getInstanceService().getInstances();
- ShellTable table = new ShellTable();
- table.column("SSH Port").alignRight();
- table.column("RMI Registry").alignRight();
- table.column("RMI Server").alignRight();
- table.column("State");
- table.column("PID");
- table.column(getRightColumnHeader());
- for (Instance instance : instances) {
- table.addRow().addContent(
- instance.getSshPort(),
- instance.getRmiRegistryPort(),
- instance.getRmiServerPort(),
- instance.getState(),
- instance.getPid(),
- getRightColumnValue(instance));
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
- private String getRightColumnHeader() {
- if (javaOpts) {
- return "JavaOpts";
- } else if (location) {
- return "Location";
- } else {
- return "Name";
- }
- }
-
- private String getRightColumnValue(Instance instance) {
- if (javaOpts) {
- return instance.getJavaOpts();
- } else if (location) {
- return instance.getLocation();
- } else {
- return instance.getName();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/RenameCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
deleted file mode 100644
index ef68400..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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 = "instance", name = "rename", description = "Rename an existing container instance.")
-@Service
-public class RenameCommand extends InstanceCommandSupport {
-
- @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
- boolean verbose = false;
-
- @Argument(index = 0, name = "name", description = "The name of the container instance to rename", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- String instance = null;
-
- @Argument(index = 1, name = "new-name", description = "The new name of the container instance", required = true, multiValued = false)
- String newName = null;
-
- protected Object doExecute() throws Exception {
- getInstanceService().renameInstance(instance, newName, verbose);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/StartCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/StartCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/StartCommand.java
deleted file mode 100644
index 8c52d5e..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/StartCommand.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-import org.apache.karaf.instance.core.Instance;
-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 = "instance", name = "start", description = "Start an existing container instance.")
-@Service
-public class StartCommand extends InstanceCommandSupport {
-
- @Option(name = "-d", aliases = { "--debug"}, description = "Start the instance in debug mode", required = false, multiValued = false)
- private boolean debug;
-
- @Option(name = "-o", aliases = { "--java-opts"}, description = "Java options when launching the instance", required = false, multiValued = false)
- private String javaOpts;
-
- @Option(name = "-w", aliases = { "--wait"}, description = "Wait for the instance to be fully started", required = false, multiValued = false)
- private boolean wait;
-
- @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- static final String DEBUG_OPTS = " -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005";
- static final String DEFAULT_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote";
-
- protected Object doExecute() throws Exception {
- Instance child = getExistingInstance(instance);
- String opts = javaOpts;
- if (opts == null) {
- opts = child.getJavaOpts();
- }
- if (opts == null) {
- opts = DEFAULT_OPTS;
- }
- if (debug) {
- opts += DEBUG_OPTS;
- }
- if (wait) {
- String state = child.getState();
- if (Instance.STOPPED.equals(state)) {
- child.start(opts);
- }
- if (!Instance.STARTED.equals(state)) {
- do {
- Thread.sleep(500);
- state = child.getState();
- } while (Instance.STARTING.equals(state));
- }
- } else {
- child.start(opts);
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/StatusCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
deleted file mode 100644
index 82100e1..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-import org.apache.karaf.instance.core.Instance;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "status", description = "Check the current status of an instance.")
-@Service
-public class StatusCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description = "The name of the instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String name;
-
- protected Object doExecute() throws Exception {
- Instance instance = getExistingInstance(name);
- System.out.println(instance.getState());
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/StopCommand.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/StopCommand.java b/instance/command/src/main/java/org/apache/karaf/instance/command/StopCommand.java
deleted file mode 100644
index 6c8de10..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/StopCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.instance.command;
-
-import org.apache.karaf.instance.command.completers.InstanceCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "instance", name = "stop", description = "Stop an existing container instance.")
-@Service
-public class StopCommand extends InstanceCommandSupport {
-
- @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
- @Completion(InstanceCompleter.class)
- private String instance = null;
-
- protected Object doExecute() throws Exception {
- getExistingInstance(instance).stop();
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java b/instance/command/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
deleted file mode 100644
index 4468374..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.instance.command.completers;
-
-import java.util.List;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceService;
-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;
-
-/**
- * Displays a list of configured server instances for the instance commands.
- *
- */
-@Service
-public class InstanceCompleter implements Completer {
-
- @Reference
- private InstanceService instanceService;
-
- public void setInstanceService(InstanceService instanceService) {
- this.instanceService = instanceService;
- }
-
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- for (Instance instance : instanceService.getInstances()) {
- delegate.getStrings().add(instance.getName());
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/java/org/apache/karaf/instance/main/Execute.java
----------------------------------------------------------------------
diff --git a/instance/command/src/main/java/org/apache/karaf/instance/main/Execute.java b/instance/command/src/main/java/org/apache/karaf/instance/main/Execute.java
deleted file mode 100644
index 591873e..0000000
--- a/instance/command/src/main/java/org/apache/karaf/instance/main/Execute.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.instance.main;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.karaf.instance.command.ChangeOptsCommand;
-import org.apache.karaf.instance.command.ChangeRmiRegistryPortCommand;
-import org.apache.karaf.instance.command.ChangeRmiServerPortCommand;
-import org.apache.karaf.instance.command.ChangeSshPortCommand;
-import org.apache.karaf.instance.command.CloneCommand;
-import org.apache.karaf.instance.command.CreateCommand;
-import org.apache.karaf.instance.command.DestroyCommand;
-import org.apache.karaf.instance.command.InstanceCommandSupport;
-import org.apache.karaf.instance.command.ListCommand;
-import org.apache.karaf.instance.command.RenameCommand;
-import org.apache.karaf.instance.command.StartCommand;
-import org.apache.karaf.instance.command.StatusCommand;
-import org.apache.karaf.instance.command.StopCommand;
-import org.apache.karaf.instance.core.internal.InstanceServiceImpl;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.impl.action.command.DefaultActionPreparator;
-import org.fusesource.jansi.AnsiConsole;
-
-public class Execute {
- static Class<? extends Action> x = CreateCommand.class;
- private static final Class<?>[] COMMAND_CLASSES = new Class[]{
- ChangeOptsCommand.class,
- ChangeRmiRegistryPortCommand.class,
- ChangeRmiServerPortCommand.class,
- ChangeSshPortCommand.class,
- CloneCommand.class,
- CreateCommand.class,
- DestroyCommand.class,
- ListCommand.class,
- RenameCommand.class,
- StartCommand.class,
- StatusCommand.class,
- StopCommand.class};
- private static final Map<String, Class<?>> COMMANDS = new TreeMap<String, Class<?>>();
-
- static {
- for (Class<?> c : COMMAND_CLASSES) {
- Command ann = c.getAnnotation(Command.class);
- if (ann == null) {
- continue;
- }
- COMMANDS.put(ann.name(), c);
- }
- }
-
- // For testing
- static boolean exitAllowed = true;
-
- /**
- * Environment variable for specifying extra options to the Karaf instance
- * process kicked off from this Java process.
- */
- private static final String ENV_KARAF_OPTS = "KARAF_OPTS";
-
- /**
- * System property for specifying extra options to the Karaf instance
- * process kicked off from this Java process.
- */
- private static final String PROP_KARAF_OPTS = "karaf.opts";
-
- public static void main(String[] args) throws Exception {
- AnsiConsole.systemInstall();
-
- if (args.length == 0) {
- listCommands();
- exit(0);
- }
- String commandName = args[0];
- Class<?> cls = COMMANDS.get(commandName);
- if (cls == null) {
- System.err.println("Command not found: " + commandName);
- exit(-1);
- }
-
- String storage = System.getProperty("karaf.instances");
- if (storage == null) {
- System.err.println("System property 'karaf.instances' is not set. \n" +
- "This property needs to be set to the full path of the instance.properties file.");
- exit(-2);
- }
- File storageFile = new File(storage);
- System.setProperty("user.dir", storageFile.getParentFile().getParentFile().getCanonicalPath());
-
- try {
- String karafOpts = System.getenv(ENV_KARAF_OPTS);
- if (karafOpts != null) {
- System.setProperty(PROP_KARAF_OPTS, karafOpts);
- }
- } catch (Exception e) {
- System.err.println("Could not read KARAF_OPTS environment variable: " + e.getMessage());
- if (System.getProperty("karaf.showStackTrace") != null) {
- throw e;
- }
- }
-
- Object command = cls.newInstance();
- if (command instanceof InstanceCommandSupport) {
- try {
- execute((InstanceCommandSupport) command, storageFile, args);
- } catch (Exception e) {
- System.err.println("Error execution command '" + commandName + "': " + e.getMessage());
- if (System.getProperty("karaf.showStackTrace") != null) {
- throw e;
- }
- }
- } else {
- System.err.println("Not an instance command: " + commandName);
- exit(-3);
- }
- }
-
- static void execute(InstanceCommandSupport command, File storageFile, String[] args) throws Exception {
- DefaultActionPreparator dap = new DefaultActionPreparator();
- List<Object> params = new ArrayList<Object>(Arrays.asList(args));
- params.remove(0); // this is the actual command name
-
- if (!dap.prepare(command, null, params)) {
- return;
- }
-
- InstanceServiceImpl instanceService = new InstanceServiceImpl();
- instanceService.setStorageLocation(storageFile);
- command.setInstanceService(instanceService);
- command.execute();
- }
-
- private static void listCommands() {
- System.out.println("Available commands:");
- for (Map.Entry<String, Class<?>> entry : COMMANDS.entrySet()) {
- Command ann = entry.getValue().getAnnotation(Command.class);
- System.out.printf(" %s - %s\n", entry.getKey(), ann.description());
- }
-
- System.out.println("Type 'command --help' for more help on the specified command.");
- }
-
- private static void exit(int rc) {
- if (exitAllowed) {
- System.exit(rc);
- } else {
- throw new RuntimeException("" + rc);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
----------------------------------------------------------------------
diff --git a/instance/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands b/instance/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
deleted file mode 100644
index 92245c7..0000000
--- a/instance/command/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
+++ /dev/null
@@ -1,30 +0,0 @@
-##---------------------------------------------------------------------------
-## 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.
-##---------------------------------------------------------------------------
-org.apache.karaf.instance.core.internal.InstanceServiceImpl
-org.apache.karaf.instance.command.ChangeOptsCommand
-org.apache.karaf.instance.command.ChangeRmiRegistryPortCommand
-org.apache.karaf.instance.command.ChangeRmiServerPortCommand
-org.apache.karaf.instance.command.ChangeSshPortCommand
-org.apache.karaf.instance.command.CloneCommand
-org.apache.karaf.instance.command.ConnectCommand
-org.apache.karaf.instance.command.CreateCommand
-org.apache.karaf.instance.command.DestroyCommand
-org.apache.karaf.instance.command.ListCommand
-org.apache.karaf.instance.command.RenameCommand
-org.apache.karaf.instance.command.StartCommand
-org.apache.karaf.instance.command.StatusCommand
-org.apache.karaf.instance.command.StopCommand
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/instance/command/src/main/resources/OSGI-INF/bundle.info b/instance/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index afeac5e..0000000
--- a/instance/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,29 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle contains all Karaf shell commands related to the instance feature.
-
-The following commands are available:
-* instance:create - Creates a new container instance.
-* instance:connect - Connects to an existing container instance.
-* instance:list - Lists all existing container instances.
-* instance:start - Starts an existing container instance.
-* instance:stop - Stops an existing container instance.
-* instance:destroy - Destroys an existing container instance.
-* instance:rename - Renames an existing container instance.
-* instance:change-ssh-port - Changes the secure shell port of an existing container instance.
-* instance:change-rmi-registry-port - Changes the RMI registry port (used by management layer) of an existing container instance.
-* instance:change-rmi-server-port - Changes the RMI server port (used by management layer) of an existing container instance.
-* instance:change-opts - Changes the java options of an existing container instance.
-
-h1. See also
-
-Commands - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
----------------------------------------------------------------------
diff --git a/instance/command/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java b/instance/command/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
deleted file mode 100644
index 359a183..0000000
--- a/instance/command/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.instance.command;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.instance.core.InstanceService;
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.easymock.EasyMock;
-
-public class CreateCommandTest extends TestCase {
-
- public void testCreateCommandExecute() throws Exception {
- InstanceService instanceService = EasyMock.createMock(InstanceService.class);
- EasyMock.replay(instanceService);
-
- CreateCommand cc = new CreateCommand();
- cc.setInstanceService(instanceService);
- cc.sshPort = 9941;
- cc.rmiRegistryPort = 1122;
- cc.rmiServerPort = 44444;
- cc.location = "top";
- cc.javaOpts = "foo";
- cc.features = Arrays.asList("abc", "def");
- cc.featureURLs = Collections.singletonList("http://something");
- cc.instance = "myInstance";
- cc.verbose = true;
-
- EasyMock.verify(instanceService); // check precondition
- EasyMock.reset(instanceService);
- InstanceSettings expectedIS =
- new InstanceSettings(9941, 1122, 44444, "top", "foo", Collections.singletonList("http://something"), Arrays.asList("abc", "def"));
- EasyMock.expect(instanceService.createInstance("myInstance", expectedIS, true)).andReturn(null);
- EasyMock.replay(instanceService);
-
- cc.doExecute();
- EasyMock.verify(instanceService);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/command/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
----------------------------------------------------------------------
diff --git a/instance/command/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java b/instance/command/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
deleted file mode 100644
index 1e49a88..0000000
--- a/instance/command/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.instance.main;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.io.IOException;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-
-public class ExecuteTest extends TestCase {
- private String userDir;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Execute.exitAllowed = false;
- userDir = System.getProperty("user.dir");
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- Execute.exitAllowed = true;
- System.setProperty("user.dir", userDir);
- }
-
- public void testListCommands() throws Exception {
- PrintStream oldOut = System.out;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream capturedOut = new PrintStream(baos);
- System.setOut(capturedOut);
-
- try {
- Execute.main(new String [] {});
- } catch (RuntimeException re) {
- assertEquals("0", re.getMessage());
-
- String s = new String(baos.toByteArray());
- assertTrue(s.contains("list"));
- assertTrue(s.contains("create"));
- assertTrue(s.contains("destroy"));
- } finally {
- System.setOut(oldOut);
- }
- }
-
- public void testNonexistingCommand() throws Exception {
- try {
- Execute.main(new String [] {"bheuaark"});
- } catch (RuntimeException re) {
- assertEquals("-1", re.getMessage());
- }
- }
-
- public void testNoStorageFile() throws Exception {
- PrintStream oldErr = System.err;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream capturedErr = new PrintStream(baos);
- System.setErr(capturedErr);
-
- try {
- Execute.main(new String [] {"create"});
- } catch (RuntimeException re) {
- assertEquals("-2", re.getMessage());
-
- String s = new String(baos.toByteArray());
- assertTrue(s.contains("karaf.instances"));
- assertTrue(s.contains("instance.properties"));
- } finally {
- System.setErr(oldErr);
- }
- }
-
- public void testSetDir() throws Exception {
- Properties oldProps = (Properties) System.getProperties().clone();
- final File tempFile = createTempDir(getName());
- assertFalse("Precondition failed",
- tempFile.getParentFile().getParentFile().getCanonicalPath().equals(System.getProperty("user.dir")));
-
- System.setProperty("karaf.instances", tempFile.getCanonicalPath());
- try {
- Execute.main(new String [] {"list"});
- assertTrue(tempFile.getParentFile().getParentFile().getCanonicalPath().equals(System.getProperty("user.dir")));
- } finally {
- System.setProperties(oldProps);
- assertNull("Postcondition failed", System.getProperty("karaf.instances"));
- delete(tempFile);
- }
- }
-
- private static File createTempDir(String name) throws IOException {
- final File tempFile = File.createTempFile(name, null);
- tempFile.delete();
- tempFile.mkdirs();
- return tempFile.getCanonicalFile();
- }
-
- private static void delete(File tmp) {
- if (tmp.isDirectory()) {
- for (File f : tmp.listFiles()) {
- delete(f);
- }
- }
- tmp.delete();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/NOTICE
----------------------------------------------------------------------
diff --git a/instance/core/NOTICE b/instance/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/instance/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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
[33/59] [abbrv] [KARAF-2852] Merge kar/core and kar/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java b/kar/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
new file mode 100644
index 0000000..506bdb3
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.kar.command;
+
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.kar.command.completers.KarCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "kar", name = "uninstall", description = "Uninstall a KAR file.")
+@Service
+public class UninstallKarCommand implements Action {
+
+ @Argument(index = 0, name = "name", description = "The name of the KAR file to uninstall.", required = true, multiValued = false)
+ @Completion(KarCompleter.class)
+ private String name;
+
+ @Reference
+ private KarService karService;
+
+ @Override
+ public Object execute() throws Exception {
+ karService.uninstall(name);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java b/kar/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
new file mode 100644
index 0000000..539cfaf
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.kar.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.kar.KarService;
+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;
+
+/**
+ * Completer on all installed KAR files.
+ */
+@Service
+public class KarCompleter implements Completer {
+
+ @Reference
+ private KarService karService;
+
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ for (String karName : karService.list()) {
+ delegate.getStrings().add(karName);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java b/kar/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
new file mode 100644
index 0000000..aca1f53
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
@@ -0,0 +1,87 @@
+/*
+ * 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.kar.internal;
+
+import java.io.File;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Simple helper to determine if a file is a feature repo
+ */
+class FeatureDetector {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FeatureDetector.class);
+
+ private DocumentBuilderFactory dbf;
+
+ FeatureDetector() {
+ dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ }
+ /**
+ * Check if a file is a features XML.
+ *
+ * @param artifact the file to check.
+ * @return true if the artifact is a features XML, false else.
+ */
+ boolean isFeaturesRepository(File artifact) {
+ try {
+ if (artifact.isFile() && artifact.getName().endsWith(".xml")) {
+ Document doc = parse(artifact);
+ String name = doc.getDocumentElement().getLocalName();
+ String uri = doc.getDocumentElement().getNamespaceURI();
+ if ("features".equals(name) && (uri == null || "".equals(uri) || uri.startsWith("http://karaf.apache.org/xmlns/features/v"))) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.debug("File '{}' is not a features file.", artifact.getName(), e);
+ }
+ return false;
+ }
+
+ /**
+ * Parse a features XML.
+ *
+ * @param artifact the features XML to parse.
+ * @return the parsed document.
+ * @throws Exception in case of parsing failure.
+ */
+ private Document parse(File artifact) throws Exception {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setErrorHandler(new ErrorHandler() {
+ public void warning(SAXParseException exception) throws SAXException {
+ }
+ public void error(SAXParseException exception) throws SAXException {
+ }
+ public void fatalError(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+ });
+ return db.parse(artifact);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/internal/Kar.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/Kar.java b/kar/src/main/java/org/apache/karaf/kar/internal/Kar.java
new file mode 100644
index 0000000..005cd17
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/Kar.java
@@ -0,0 +1,203 @@
+/*
+ * 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.kar.internal;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Representation of a Karaf Kar archive
+ *
+ * A Kar archive is a jar file with a special structure that can be used
+ * to deploy feature repositories, maven repo contents and resources for the
+ * karaf installation.
+ *
+ * meta-inf/Manifest:
+ * Karaf-Feature-Start: (true|false) Controls if the features in the feature repos should be started on deploy
+ * Karaf-Feature-Repos: (uri)* If present then only the given feature repo urls are added to karaf if it is not
+ * present then the karaf file is scanned for repo files
+ *
+ * repository/
+ * Everything below this directory is treated as a maven repository. On deploy the contents
+ * will be copied to a directory below data. This directory will then be added to the
+ * maven repos of pax url maven
+ *
+ * resource/
+ * Everything below this directory will be copied to the karaf base dir on deploy
+ *
+ */
+public class Kar {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(KarServiceImpl.class);
+ public static final String MANIFEST_ATTR_KARAF_FEATURE_START = "Karaf-Feature-Start";
+ public static final String MANIFEST_ATTR_KARAF_FEATURE_REPOS = "Karaf-Feature-Repos";
+ private final URI karUri;
+ private boolean shouldInstallFeatures;
+ private List<URI> featureRepos;
+
+ public Kar(URI karUri) {
+ this.karUri = karUri;
+ }
+
+ /**
+ * Extract a kar from a given URI into a repository dir and resource dir
+ * and populate shouldInstallFeatures and featureRepos
+ *
+ * @param repoDir directory to write the repository contents of the kar to
+ * @param resourceDir directory to write the resource contents of the kar to
+ */
+ public void extract(File repoDir, File resourceDir) {
+ InputStream is = null;
+ JarInputStream zipIs = null;
+ FeatureDetector featureDetector = new FeatureDetector();
+ this.featureRepos = new ArrayList<URI>();
+ this.shouldInstallFeatures = true;
+
+ try {
+ is = karUri.toURL().openStream();
+ repoDir.mkdirs();
+
+ if (!repoDir.isDirectory()) {
+ throw new RuntimeException("The KAR file " + karUri + " is already installed");
+ }
+
+ LOGGER.debug("Uncompress the KAR file {} into directory {}", karUri, repoDir);
+ zipIs = new JarInputStream(is);
+ boolean scanForRepos = true;
+
+ Manifest manifest = zipIs.getManifest();
+ if (manifest != null) {
+ Attributes attr = manifest.getMainAttributes();
+ String featureStartSt = (String)attr
+ .get(new Attributes.Name(MANIFEST_ATTR_KARAF_FEATURE_START));
+ if ("false".equals(featureStartSt)) {
+ shouldInstallFeatures = false;
+ }
+ String featureReposAttr = (String)attr
+ .get(new Attributes.Name(MANIFEST_ATTR_KARAF_FEATURE_REPOS));
+ if (featureReposAttr != null) {
+ featureRepos.add(new URI(featureReposAttr));
+ scanForRepos = false;
+ }
+ }
+
+ ZipEntry entry = zipIs.getNextEntry();
+ while (entry != null) {
+ if (entry.getName().startsWith("repository")) {
+ String path = entry.getName().substring("repository/".length());
+ File destFile = new File(repoDir, path);
+ extract(zipIs, entry, destFile);
+ if (scanForRepos && featureDetector.isFeaturesRepository(destFile)) {
+ featureRepos.add(destFile.toURI());
+ }
+ }
+
+ if (entry.getName().startsWith("resource")) {
+ String path = entry.getName().substring("resource/".length());
+ File destFile = new File(resourceDir, path);
+ extract(zipIs, entry, destFile);
+ }
+ entry = zipIs.getNextEntry();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error extracting kar file " + karUri + " into dir " + repoDir + ": " + e.getMessage(), e);
+ } finally {
+ closeStream(zipIs);
+ closeStream(is);
+ }
+ }
+
+ /**
+ * Extract an entry from a KAR file
+ *
+ * @param is
+ * @param zipEntry
+ * @param dest
+ * @return
+ * @throws Exception
+ */
+ private static File extract(InputStream is, ZipEntry zipEntry, File dest) throws Exception {
+ if (zipEntry.isDirectory()) {
+ LOGGER.debug("Creating directory {}", dest.getName());
+ dest.mkdirs();
+ } else {
+ dest.getParentFile().mkdirs();
+ FileOutputStream out = new FileOutputStream(dest);
+ copyStream(is, out);
+ out.close();
+ }
+ return dest;
+ }
+
+ private static void closeStream(InputStream is) {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ LOGGER.warn("Error closing stream", e);
+ }
+ }
+ }
+
+ static long copyStream(InputStream input, OutputStream output) throws IOException {
+ byte[] buffer = new byte[10000];
+ long count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ public String getKarName() {
+ try {
+ String karName = new File(karUri.toURL().getFile()).getName();
+ karName = karName.substring(0, karName.lastIndexOf("."));
+ return karName;
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("Invalid kar URI " + karUri, e);
+ }
+ }
+
+ public URI getKarUri() {
+ return karUri;
+ }
+
+ public boolean isShouldInstallFeatures() {
+ return shouldInstallFeatures;
+ }
+
+ public List<URI> getFeatureRepos() {
+ return featureRepos;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java b/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
new file mode 100644
index 0000000..0f86466
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
@@ -0,0 +1,382 @@
+/*
+ * 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.kar.internal;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+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.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+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;
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.util.maven.Parser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the KAR service.
+ */
+public class KarServiceImpl implements KarService {
+ private static final String FEATURE_CONFIG_FILE = "features.cfg";
+ private static final Logger LOGGER = LoggerFactory.getLogger(KarServiceImpl.class);
+
+ private File storage;
+ private File base;
+ private FeaturesService featuresService;
+
+ private boolean noAutoRefreshBundles;
+
+ public KarServiceImpl(String karafBase, FeaturesService featuresService) {
+ this.base = new File(karafBase);
+ this.storage = new File(this.base, "data" + File.separator + "kar");
+ this.featuresService = featuresService;
+ this.storage.mkdirs();
+ if (!storage.isDirectory()) {
+ throw new IllegalStateException("KAR storage " + storage + " is not a directory");
+ }
+ }
+
+ @Override
+ public void install(URI karUri) throws Exception {
+ String karName = new Kar(karUri).getKarName();
+ LOGGER.debug("Installing KAR {} from {}", karName, karUri);
+ File karDir = new File(storage, karName);
+ install(karUri, karDir, base);
+ }
+
+ @Override
+ public void install(URI karUri, File repoDir, File resourceDir) throws Exception {
+ Kar kar = new Kar(karUri);
+ kar.extract(repoDir, resourceDir);
+ writeToFile(kar.getFeatureRepos(), new File(repoDir, FEATURE_CONFIG_FILE));
+ for (URI uri : kar.getFeatureRepos()) {
+ addToFeaturesRepositories(uri);
+ }
+ if (kar.isShouldInstallFeatures()) {
+ installFeatures(kar.getFeatureRepos());
+ }
+
+ }
+
+
+ private List<URI> readFromFile(File repoListFile) {
+ ArrayList<URI> uriList = new ArrayList<URI>();
+ FileReader fr = null;
+ try {
+ fr = new FileReader(repoListFile);
+ BufferedReader br = new BufferedReader(fr);
+ String line;
+ while ((line = br.readLine()) != null) {
+ uriList.add(new URI(line));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error reading repo list from file " + repoListFile.getAbsolutePath(), e);
+ } finally {
+ try {
+ fr.close();
+ } catch (IOException e) {
+ LOGGER.warn("Error closing reader for file " + repoListFile, e);
+ }
+ }
+ return uriList;
+ }
+
+ private void writeToFile(List<URI> featuresRepositoriesInKar, File repoListFile) {
+ FileOutputStream fos = null;
+ PrintStream ps = null;
+ try {
+ fos = new FileOutputStream(repoListFile);
+ ps = new PrintStream(fos);
+ for (URI uri : featuresRepositoriesInKar) {
+ ps.println(uri);
+ }
+ ps.close();
+ fos.close();
+ } catch (Exception e) {
+ throw new RuntimeException("Error writing feature repo list to file " + repoListFile.getAbsolutePath(), e);
+ } finally {
+ closeStream(ps);
+ closeStream(fos);
+ }
+ }
+
+ private void deleteRecursively(File dir) {
+ if (dir.isDirectory()) {
+ File[] children = dir.listFiles();
+ for (File child : children) {
+ deleteRecursively(child);
+ }
+ }
+ dir.delete();
+ }
+
+ @Override
+ public void uninstall(String karName) throws Exception {
+ File karDir = new File(storage, karName);
+
+ if (!karDir.exists()) {
+ throw new IllegalArgumentException("The KAR " + karName + " is not installed");
+ }
+
+ List<URI> featuresRepositories = readFromFile(new File(karDir, FEATURE_CONFIG_FILE));
+ uninstallFeatures(featuresRepositories);
+ for (URI featuresRepository : featuresRepositories) {
+ featuresService.removeRepository(featuresRepository);
+ }
+
+ deleteRecursively(karDir);
+ }
+
+ @Override
+ public List<String> list() throws Exception {
+ List<String> kars = new ArrayList<String>();
+ for (File kar : storage.listFiles()) {
+ if (kar.isDirectory()) {
+ kars.add(kar.getName());
+ }
+ }
+ return kars;
+ }
+
+
+
+ /**
+ * Add an URI to the list of features repositories.
+ *
+ * @param uri the URI to add.
+ * @throws Exception in case of add failure.
+ */
+ private void addToFeaturesRepositories(URI uri) throws Exception {
+ try {
+ featuresService.removeRepository(uri);
+ featuresService.addRepository(uri);
+ LOGGER.info("Added feature repository '{}'", uri);
+ } catch (Exception e) {
+ LOGGER.warn("Unable to add repository '{}'", uri, e);
+ }
+ }
+
+ /**
+ * Install all features contained in the list of features XML.
+ *
+ * @param featuresRepositories the list of features XML.
+ */
+ private void installFeatures(List<URI> featuresRepositories) throws Exception {
+ for (Repository repository : featuresService.listRepositories()) {
+ for (URI karFeatureRepoUri : featuresRepositories) {
+ if (repository.getURI().equals(karFeatureRepoUri)) {
+ try {
+ for (Feature feature : repository.getFeatures()) {
+ try {
+ LOGGER.debug("noAutoRefreshBundles is " + isNoAutoRefreshBundles());
+ if (isNoAutoRefreshBundles()) {
+ featuresService.installFeature(feature, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
+ } else {
+ featuresService.installFeature(feature, EnumSet.noneOf(FeaturesService.Option.class));
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Unable to install Kar feature {}", feature.getName() + "/" + feature.getVersion(), e);
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Can't get features for KAR {}", karFeatureRepoUri, e);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void create(String repoName, List<String> features, PrintStream console) {
+ FileOutputStream fos = null;
+ JarOutputStream jos = null;
+ try {
+ 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);
+ Manifest manifest = createNonAutoStartManifest(repo.getURI());
+ jos = new JarOutputStream(new BufferedOutputStream(fos, 100000), manifest);
+
+ Map<URI, Integer> locationMap = new HashMap<URI, Integer>();
+ copyResourceToJar(jos, repo.getURI(), locationMap);
+
+ Map<String, Feature> featureMap = new HashMap<String, Feature>();
+ for (Feature feature : repo.getFeatures()) {
+ featureMap.put(feature.getName(), feature);
+ }
+
+ Set<Feature> featuresToCopy = getFeatures(featureMap, features, 1);
+
+ for (Feature feature : featuresToCopy) {
+ if (console != null)
+ console.println("Adding feature " + feature.getName());
+ copyFeatureToJar(jos, feature, locationMap);
+ }
+
+ if (console != null)
+ console.println("Kar file created : " + karPath);
+ } catch (Exception e) {
+ throw new RuntimeException("Error creating kar: " + e.getMessage(), e);
+ } finally {
+ 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 ++));
+ }
+ }
+ return featureSet;
+ }
+
+ private Manifest createNonAutoStartManifest(URI repoUri) throws UnsupportedEncodingException, IOException {
+ String manifestSt = "Manifest-Version: 1.0\n" +
+ Kar.MANIFEST_ATTR_KARAF_FEATURE_START +": false\n" +
+ Kar.MANIFEST_ATTR_KARAF_FEATURE_REPOS + ": " + repoUri.toString() + "\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)
+ throws URISyntaxException {
+ for (BundleInfo bundleInfo : feature.getBundles()) {
+ URI location = new URI(bundleInfo.getLocation());
+ copyResourceToJar(jos, location, locationMap);
+ }
+ for (ConfigFileInfo configFileInfo : feature.getConfigurationFiles()) {
+ URI location = new URI(configFileInfo.getLocation());
+ copyResourceToJar(jos, location, locationMap);
+ }
+ }
+
+ private void copyResourceToJar(JarOutputStream jos, URI location, Map<URI, Integer> locationMap) {
+ if (locationMap.containsKey(location)) {
+ return;
+ }
+ try {
+ String noPrefixLocation = location.toString().substring(location.toString().lastIndexOf(":") + 1);
+ Parser parser = new Parser(noPrefixLocation);
+ InputStream is = location.toURL().openStream();
+ String path = "repository/" + parser.getArtifactPath();
+ jos.putNextEntry(new JarEntry(path));
+ Kar.copyStream(is, jos);
+ is.close();
+ locationMap.put(location, 1);
+ } catch (Exception e) {
+ LOGGER.error("Error adding " + location, e);
+ }
+ }
+
+ /**
+ * Uninstall all features contained in the list of features XML.
+ *
+ * @param featuresRepositories the list of features XML.
+ */
+ private void uninstallFeatures(List<URI> featuresRepositories) throws Exception {
+ for (Repository repository : featuresService.listRepositories()) {
+ for (URI karFeatureRepoUri : featuresRepositories) {
+ if (repository.getURI().equals(karFeatureRepoUri)) {
+ try {
+ for (Feature feature : repository.getFeatures()) {
+ try {
+ featuresService.uninstallFeature(feature.getName(), feature.getVersion());
+ } catch (Exception e) {
+ LOGGER.warn("Unable to uninstall Kar feature {}", feature.getName() + "/" + feature.getVersion(), e);
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Can't get features for KAR {}", karFeatureRepoUri, e);
+ }
+ }
+ }
+ }
+ }
+
+ public boolean isNoAutoRefreshBundles() {
+ return noAutoRefreshBundles;
+ }
+
+ public void setNoAutoRefreshBundles(boolean noAutoRefreshBundles) {
+ this.noAutoRefreshBundles = noAutoRefreshBundles;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java b/kar/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
new file mode 100644
index 0000000..b274e21
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
@@ -0,0 +1,72 @@
+/*
+ * 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.kar.internal;
+
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.kar.KarsMBean;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import java.net.URI;
+import java.util.List;
+
+public class KarsMBeanImpl extends StandardMBean implements KarsMBean {
+
+ private KarService karService;
+
+ public KarsMBeanImpl() throws NotCompliantMBeanException {
+ super(KarsMBean.class);
+ }
+
+ public List<String> getKars() throws MBeanException {
+ try {
+ return karService.list();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void create(String repoName, List<String> features) {
+ karService.create(repoName, features, null);
+ }
+
+ public void install(String url) throws MBeanException {
+ try {
+ karService.install(new URI(url));
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void uninstall(String name) throws MBeanException {
+ try {
+ karService.uninstall(name);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public KarService getKarService() {
+ return karService;
+ }
+
+ public void setKarService(KarService karService) {
+ this.karService = karService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java b/kar/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java
new file mode 100644
index 0000000..05a1b59
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.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.kar.internal.osgi;
+
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.kar.internal.KarServiceImpl;
+import org.apache.karaf.kar.internal.KarsMBeanImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.osgi.service.cm.ManagedService;
+
+public class Activator extends BaseActivator implements ManagedService {
+
+ @Override
+ protected void doOpen() throws Exception {
+ manage("org.apache.karaf.kar");
+ trackService(FeaturesService.class);
+ }
+
+ protected void doStart() throws Exception {
+ FeaturesService featuresService = getTrackedService(FeaturesService.class);
+ if (featuresService == null) {
+ return;
+ }
+
+ boolean noAutoRefreshBundles = getBoolean("noAutoRefreshBundles", false);
+
+ KarServiceImpl karService = new KarServiceImpl(
+ System.getProperty("karaf.base"),
+ featuresService
+ );
+ karService.setNoAutoRefreshBundles(noAutoRefreshBundles);
+ register(KarService.class, karService);
+
+ KarsMBeanImpl mbean = new KarsMBeanImpl();
+ mbean.setKarService(karService);
+ registerMBean(mbean, "type=kar");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/kar/src/main/resources/OSGI-INF/bundle.info b/kar/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..7056453
--- /dev/null
+++ b/kar/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,19 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle is the core implementation of the Karaf kar support.
+
+Karaf Archives (KAR) is an artifact (zip file) shipping a features XML and the associated bundles or configuration
+files.
+
+h1. See also
+
+KAR - section of the Karaf User Guide
[32/59] [abbrv] git commit: [KARAF-2852] Merge diagnostic/core and
diagnostic/command
Posted by gn...@apache.org.
[KARAF-2852] Merge diagnostic/core and diagnostic/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/886863a2
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/886863a2
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/886863a2
Branch: refs/heads/master
Commit: 886863a28a3ed666a149d7566034f8826094037f
Parents: 7c2db06
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 23:01:24 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:00:59 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
diagnostic/NOTICE | 71 +++++
diagnostic/command/NOTICE | 71 -----
diagnostic/command/pom.xml | 90 ------
.../karaf/diagnostic/command/DumpCommand.java | 97 -------
.../src/main/resources/OSGI-INF/bundle.info | 19 --
diagnostic/core/NOTICE | 71 -----
diagnostic/core/pom.xml | 109 -------
.../diagnostic/core/DiagnosticDumpMBean.java | 42 ---
.../karaf/diagnostic/core/DumpDestination.java | 42 ---
.../karaf/diagnostic/core/DumpProvider.java | 29 --
.../common/ClosingEntryOutputStreamWrapper.java | 75 -----
.../core/common/DirectoryDumpDestination.java | 55 ----
.../core/common/TextDumpProvider.java | 66 -----
.../core/common/ZipDumpDestination.java | 79 -----
.../core/internal/BundleDumpProvider.java | 85 ------
.../core/internal/DiagnosticDumpMBeanImpl.java | 89 ------
.../core/internal/EnvironmentDumpProvider.java | 291 -------------------
.../core/internal/FeaturesDumpProvider.java | 79 -----
.../core/internal/HeapDumpProvider.java | 68 -----
.../core/internal/LogDumpProvider.java | 98 -------
.../core/internal/MemoryDumpProvider.java | 54 ----
.../core/internal/ThreadDumpProvider.java | 118 --------
.../core/internal/osgi/Activator.java | 131 ---------
.../src/main/resources/OSGI-INF/bundle.info | 18 --
diagnostic/pom.xml | 93 +++++-
.../karaf/diagnostic/command/DumpCommand.java | 97 +++++++
.../diagnostic/core/DiagnosticDumpMBean.java | 42 +++
.../karaf/diagnostic/core/DumpDestination.java | 42 +++
.../karaf/diagnostic/core/DumpProvider.java | 29 ++
.../common/ClosingEntryOutputStreamWrapper.java | 75 +++++
.../core/common/DirectoryDumpDestination.java | 55 ++++
.../core/common/TextDumpProvider.java | 66 +++++
.../core/common/ZipDumpDestination.java | 79 +++++
.../core/internal/BundleDumpProvider.java | 85 ++++++
.../core/internal/DiagnosticDumpMBeanImpl.java | 89 ++++++
.../core/internal/EnvironmentDumpProvider.java | 291 +++++++++++++++++++
.../core/internal/FeaturesDumpProvider.java | 79 +++++
.../core/internal/HeapDumpProvider.java | 68 +++++
.../core/internal/LogDumpProvider.java | 98 +++++++
.../core/internal/MemoryDumpProvider.java | 54 ++++
.../core/internal/ThreadDumpProvider.java | 118 ++++++++
.../core/internal/osgi/Activator.java | 131 +++++++++
.../src/main/resources/OSGI-INF/bundle.info | 18 ++
44 files changed, 1672 insertions(+), 1885 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/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 830ba9d..af81c40 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -129,7 +129,6 @@
<feature name="diagnostic" description="Provide Diagnostic support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.command/${project.version}</bundle>
</feature>
<feature name="instance" description="Provide Instance support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/NOTICE
----------------------------------------------------------------------
diff --git a/diagnostic/NOTICE b/diagnostic/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/diagnostic/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/886863a2/diagnostic/command/NOTICE
----------------------------------------------------------------------
diff --git a/diagnostic/command/NOTICE b/diagnostic/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/diagnostic/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/886863a2/diagnostic/command/pom.xml
----------------------------------------------------------------------
diff --git a/diagnostic/command/pom.xml b/diagnostic/command/pom.xml
deleted file mode 100644
index 28502f0..0000000
--- a/diagnostic/command/pom.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?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.diagnostic</groupId>
- <artifactId>diagnostic</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.diagnostic.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Diagnostic :: Command</name>
- <description>This bundle provides Karaf diagnostic shell commands.</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.diagnostic</groupId>
- <artifactId>org.apache.karaf.diagnostic.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>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/command/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
----------------------------------------------------------------------
diff --git a/diagnostic/command/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java b/diagnostic/command/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
deleted file mode 100644
index 3f6c607..0000000
--- a/diagnostic/command/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.diagnostic.command;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-import org.apache.karaf.diagnostic.core.common.DirectoryDumpDestination;
-import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-/**
- * Command to create dump from shell.
- */
-@Command(scope = "dev", name = "dump-create", description = "Creates zip archive with diagnostic info.")
-@Service
-public class DumpCommand implements Action {
-
- /**
- * Output format of the filename if not defined otherwise
- */
- private SimpleDateFormat dumpFormat = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
-
- /**
- * Directory switch.
- */
- @Option(name = "-d", aliases = "--directory", description = "Creates dump in a directory in place of a ZIP archive")
- boolean directory;
-
- /**
- * Name of created directory or archive.
- */
- @Argument(name = "name", description = "Name of created zip or directory", required = false)
- String fileName;
-
- @Reference
- List<DumpProvider> providers;
-
- @Override
- public Object execute() throws Exception {
- DumpDestination destination;
-
- if (providers.isEmpty()) {
- System.out.println("Unable to create dump. No providers were found");
- return null;
- }
-
- // create default file name if none provided
- if (fileName == null || fileName.trim().length() == 0) {
- fileName = dumpFormat.format(new Date());
- if (!directory) {
- fileName += ".zip";
- }
- }
- File target = new File(fileName);
-
- // if directory switch is on, create dump in directory
- if (directory) {
- destination = new DirectoryDumpDestination(target);
- } else {
- destination = new ZipDumpDestination(target);
- }
-
- for (DumpProvider provider : providers) {
- provider.createDump(destination);
- }
- destination.save();
- System.out.println("Diagnostic dump created at " + target.getAbsolutePath() + ".");
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/diagnostic/command/src/main/resources/OSGI-INF/bundle.info b/diagnostic/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 93d0674..0000000
--- a/diagnostic/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,19 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-This bundle provides the Karaf shell commands for the Karaf diagnostic.
-
-The current provided command is:
-
-* dev:create-dump -
-
-h1. See also
-
-Diagnostic - section of the Karaf User Guide.
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/NOTICE
----------------------------------------------------------------------
diff --git a/diagnostic/core/NOTICE b/diagnostic/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/diagnostic/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/886863a2/diagnostic/core/pom.xml
----------------------------------------------------------------------
diff --git a/diagnostic/core/pom.xml b/diagnostic/core/pom.xml
deleted file mode 100644
index 1dee9cd..0000000
--- a/diagnostic/core/pom.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?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.diagnostic</groupId>
- <artifactId>diagnostic</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.diagnostic.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Diagnostic :: Core</name>
- <description>Core implementation using Karaf diagnostic using the diagnostic common services</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</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.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>
- <Export-Package>
- ${project.artifactId},
- ${project.artifactId}.common
- </Export-Package>
- <Import-Package>
- com.sun.management*;resolution:=optional,
- *
- </Import-Package>
- <Private-Package>
- org.apache.karaf.diagnostic.core.internal,
- org.apache.karaf.diagnostic.core.internal.osgi,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.diagnostic.core.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java
deleted file mode 100644
index f59982a..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.diagnostic.core;
-
-import javax.management.MBeanException;
-
-/**
- * Diagnostic MBean which allows to create dumps over JMX.
- */
-public interface DiagnosticDumpMBean {
-
- /**
- * Creates dump over JMX.
- *
- * @param name Name of the dump.
- * @throws Exception In case of any problems.
- */
- void createDump(String name) throws MBeanException;
-
- /**
- * Create dump with directory switch and name.
- *
- * @param directory Should dump be created in directory.
- * @param name Name of the dump.
- * @throws Exception In case of any problems.
- */
- void createDump(boolean directory, String name) throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java
deleted file mode 100644
index 39c4edc..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.diagnostic.core;
-
-import java.io.OutputStream;
-
-/**
- * Destination for created dumps.
- */
-public interface DumpDestination {
-
- /**
- * Creates new entry in dump destination.
- *
- * Destination does not close returned output stream by default, dump
- * provider should do this after completing write operation.
- *
- * @param name Name of file in destination.
- * @return Output stream ready to write.
- * @throws Exception When entry cannot be added.
- */
- OutputStream add(String name) throws Exception;
-
- /**
- * Complete creation of the dump.
- */
- void save() throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
deleted file mode 100644
index ec7724c..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.diagnostic.core;
-
-/**
- * Interface which represents instance of tool which can provide dump
- * information.
- */
-public interface DumpProvider {
-
- /**
- * Creates dump in given entry.
- */
- void createDump(DumpDestination destination) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
deleted file mode 100644
index 0c4f9db..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.diagnostic.core.common;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.zip.ZipOutputStream;
-
-/**
- * Output stream which closes entry instead closing whole stream.
- */
-public class ClosingEntryOutputStreamWrapper extends OutputStream {
-
- /**
- * Wrapped ZIP output stream.
- */
- private ZipOutputStream outputStream;
-
- /**
- * Creates new OutputStream.
- *
- * @param outputStream Wrapped output stream.
- */
- public ClosingEntryOutputStreamWrapper(ZipOutputStream outputStream) {
- this.outputStream = outputStream;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void write(int b) throws IOException {
- outputStream.write(b);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void write(byte[] b) throws IOException {
- outputStream.write(b);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void write(byte[] b, int off, int len)
- throws IOException {
- outputStream.write(b, off, len);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() throws IOException {
- // close entry instead of closing zip stream.
- outputStream.closeEntry();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
deleted file mode 100644
index 37ae72e..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.diagnostic.core.common;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-
-import org.apache.karaf.diagnostic.core.DumpDestination;
-
-/**
- * Class which packages dumps to given directory.
- */
-public class DirectoryDumpDestination implements DumpDestination {
-
- /**
- * Directory where dump files will be created.
- */
- private File directory;
-
- public DirectoryDumpDestination(File file) {
- this.directory = file;
-
- if (!file.exists()) {
- file.mkdirs();
- }
- }
-
- public OutputStream add(String name) throws Exception {
- File destination = new File(directory, name);
- if (name.contains("/") || name.contains("\\")) {
- // if name contains slashes we need to create sub directory
- destination.getParentFile().mkdirs();
- }
- return new FileOutputStream(destination);
- }
-
- public void save() throws Exception {
- // do nothing, all should be written to output streams
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
deleted file mode 100644
index 0b97d6f..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.diagnostic.core.common;
-
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-
-import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-
-/**
- * Base class for dump providers which writes text to destination.
- */
-public abstract class TextDumpProvider implements DumpProvider {
-
- /**
- * Name of the file.
- */
- private final String name;
-
- /**
- * Creates new dump provider.
- *
- * @param name Name of the file.
- */
- protected TextDumpProvider(String name) {
- this.name = name;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final void createDump(DumpDestination destination) throws Exception {
- OutputStream outputStream = destination.add(name);
- OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
- try {
- writeDump(outputStreamWriter);
- } finally {
- outputStreamWriter.close();
- outputStream.close();
- }
- }
-
- /**
- * This method should create output.
- *
- * @param outputStreamWriter Stream which points to file specified in constructor.
- * @throws Exception If any problem occur.
- */
- protected abstract void writeDump(OutputStreamWriter outputStreamWriter) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
deleted file mode 100644
index bafd38d..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.diagnostic.core.common;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.apache.karaf.diagnostic.core.DumpDestination;
-
-/**
- * Class which packages dumps to ZIP archive.
- */
-public class ZipDumpDestination implements DumpDestination {
-
- /**
- * Destination streem.
- */
- private ZipOutputStream outputStream;
-
- /**
- * Creates new dump in given directory.
- *
- * @param directory Target directory.
- * @param name Name of the archive.
- */
- public ZipDumpDestination(File directory, String name) {
- this(new File(directory, name));
- }
-
- /**
- * Creates new dump in given file (zip archive).
- *
- * @param file Destination file.
- */
- public ZipDumpDestination(File file) {
- try {
- outputStream = new ZipOutputStream(new FileOutputStream(
- file));
- } catch (FileNotFoundException e) {
- // sometimes this can occur, but we simply re throw and let
- // caller handle exception
- throw new RuntimeException("Unable to create dump destination", e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public OutputStream add(String name) throws Exception {
- ZipEntry zipEntry = new ZipEntry(name);
- outputStream.putNextEntry(zipEntry);
- return new ClosingEntryOutputStreamWrapper(outputStream);
- }
-
- /**
- * Closes archive handle.
- */
- public void save() throws Exception {
- outputStream.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
deleted file mode 100644
index 774dc1f..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/**
- * Dump provider which produces file named bundles.txt with list of
- * installed bundles and it's state.
- */
-public class BundleDumpProvider extends TextDumpProvider {
-
- /**
- * Static map with state mask to string representation.
- */
- private static Map<Integer, String> stateMap = new HashMap<Integer, String>();
-
- /**
- * Map bundle states to string representation.
- */
- static {
- stateMap.put(0x00000001, "UNINSTALLED");
- stateMap.put(0x00000002, "INSTALLED");
- stateMap.put(0x00000004, "RESOLVED");
- stateMap.put(0x00000008, "STARTING");
- stateMap.put(0x00000010, "STOPPING");
- stateMap.put(0x00000020, "ACTIVE");
- }
-
- /**
- * Bundle context.
- */
- private BundleContext bundleContext;
-
- /**
- * Creates new bundle information file.
- *
- * @param context Bundle context to access framework state.
- */
- public BundleDumpProvider(BundleContext context) {
- super("bundles.txt");
- this.bundleContext = context;
- }
-
- /**
- * {@inheritDoc}
- */
- protected void writeDump(OutputStreamWriter writer) throws IOException {
- // get bundle states
- Bundle[] bundles = bundleContext.getBundles();
-
- writer.write("Number of installed bundles " + bundles.length + "\n");
-
- // create file header
- writer.write("Id\tSymbolic name\tVersion\tState\n");
- for (Bundle bundle : bundles) {
- // write row :)
- writer.write(bundle.getBundleId() + "\t" + bundle.getSymbolicName() + '\t' + bundle.getVersion()
- + "\t" + stateMap.get(bundle.getState()) + "\n");
- }
-
- writer.flush();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
deleted file mode 100644
index 22e09c9..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed 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.diagnostic.core.internal;
-
-import java.io.File;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-
-import org.apache.karaf.diagnostic.core.DiagnosticDumpMBean;
-import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-import org.apache.karaf.diagnostic.core.common.DirectoryDumpDestination;
-import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
-
-/**
- * Implementation of diagnostic MBean.
- */
-public class DiagnosticDumpMBeanImpl extends StandardMBean implements DiagnosticDumpMBean {
-
- /**
- * Dump providers.
- */
- private final List<DumpProvider> providers = new CopyOnWriteArrayList<DumpProvider>();
-
- /**
- * Creates new diagnostic mbean.
- *
- * @throws NotCompliantMBeanException
- */
- public DiagnosticDumpMBeanImpl() throws NotCompliantMBeanException {
- super(DiagnosticDumpMBean.class);
- }
-
- /**
- * Creates dump witch given name
- *
- * @param name Name of the dump.
- */
- public void createDump(String name) throws MBeanException {
- createDump(false, name);
- }
-
- /**
- * {@inheritDoc}
- */
- public void createDump(boolean directory, String name) throws MBeanException {
- try {
- File target = new File(name);
-
- DumpDestination destination;
- if (directory) {
- destination = new DirectoryDumpDestination(target);
- } else {
- destination = new ZipDumpDestination(target);
- }
-
- for (DumpProvider provider : providers) {
- provider.createDump(destination);
- }
-
- destination.save();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void registerProvider(DumpProvider provider) {
- providers.add(provider);
- }
-
- public void unregisterProvider(DumpProvider provider) {
- providers.add(provider);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
deleted file mode 100644
index 3328067..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.lang.management.ClassLoadingMXBean;
-import java.lang.management.CompilationMXBean;
-import java.lang.management.GarbageCollectorMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.management.MemoryUsage;
-import java.lang.management.OperatingSystemMXBean;
-import java.lang.management.RuntimeMXBean;
-import java.lang.management.ThreadMXBean;
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Version;
-
-/**
- * Provider which dumps runtime environment information to file named environment.txt.
- */
-public class EnvironmentDumpProvider extends TextDumpProvider {
-
- private static final String KEY_VALUE_FORMAT = "%1$s\t: %2$s";
- private static final String INDENT_KEY_VALUE_FORMAT = " "+KEY_VALUE_FORMAT;
- private final BundleContext bundleContext;
-
- /**
- * Creates new dump entry which contains information about the runtime environment.
- */
- public EnvironmentDumpProvider(final BundleContext context) {
- super("environment.txt");
- this.bundleContext = context;
- }
-
- @Override
- protected void writeDump(final OutputStreamWriter outputStream) throws Exception {
- if( null == outputStream) {
- return;
- }
- final PrintWriter outPW = new PrintWriter(outputStream);
- // current date/time
- final DateFormat dateTimeFormatInstance = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);
- outPW.printf(KEY_VALUE_FORMAT,"Dump timestamp", dateTimeFormatInstance.format(new Date(System.currentTimeMillis()))).println();
- outPW.println();
- // karaf information
- dumpKarafInformation(outPW);
- outPW.println();
- // OSGi information
- dumpOSGiInformation(outPW);
- outPW.println();
- // OS information
- dumpOSInformation(outPW);
- outPW.println();
- // general information about JVM
- dumpVMInformation(outPW, dateTimeFormatInstance);
- outPW.println();
- // threads
- dumpThreadsInformation(outPW);
- outPW.println();
- // classes
- dumpClassesInformation(outPW);
- outPW.println();
- // memory
- dumpMemoryInformation(outPW);
- outPW.println();
- // garbage collector
- dumpGCInformation(outPW);
- }
-
- private void dumpKarafInformation(final PrintWriter outPW) {
- outPW.printf(KEY_VALUE_FORMAT, "Karaf", System.getProperty("karaf.name", "root") + ' ' + System.getProperty("karaf.version", "")).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "home", System.getProperty("karaf.home", "")).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "base", System.getProperty("karaf.base", "")).println();
- }
-
- private void dumpOSGiInformation(final PrintWriter outPW) {
- if( null == bundleContext ) {
- return;
- }
- outPW.println("OSGi:");
- final Bundle[] bundles = bundleContext.getBundles();
- for (final Bundle bundle : bundles) {
- if( null == bundle || !!!"osgi.core".equals(bundle.getSymbolicName())) {
- continue;
- }
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", bundle.getVersion()).println();
- break;
- }
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "framework", bundleContext.getBundle(0).getSymbolicName() + " - " +
- bundleContext.getBundle(0).getVersion()).println();
- }
-
- private void dumpOSInformation(final PrintWriter outPW) {
- final OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
- if( null == mxBean) {
- return;
- }
- outPW.printf(KEY_VALUE_FORMAT, "Operating System", mxBean.getName() + ' ' + mxBean.getVersion()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "architecture", mxBean.getArch()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "processors", mxBean.getAvailableProcessors()).println();
-// outPW.printf(INDENT_KEY_VALUE_FORMAT, "current system load average", mxBean.getSystemLoadAverage()).println();
- }
-
- private void dumpVMInformation(final PrintWriter outPW,
- final DateFormat dateTimeFormatInstance) {
- final RuntimeMXBean mxBean = ManagementFactory.getRuntimeMXBean();
- if( mxBean == null ) {
- return;
- }
- outPW.printf(KEY_VALUE_FORMAT,"Instance name", mxBean.getName()).println();
- outPW.printf(KEY_VALUE_FORMAT,"Start time", dateTimeFormatInstance.format(new Date(mxBean.getStartTime()))).println();
- outPW.printf(KEY_VALUE_FORMAT,"Uptime", printDuration(mxBean.getUptime())).println();
- outPW.println();
- outPW.printf(KEY_VALUE_FORMAT, "Java VM", mxBean.getVmName() + " " + mxBean.getVmVersion()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "vendor", mxBean.getVmVendor()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", System.getProperty("java.version")).println();
- outPW.println();
- outPW.println("Input arguments:");
- final List<String> inputArguments = mxBean.getInputArguments();
- for (final String argument : inputArguments) {
- if( argument != null && argument.contains("=")) {
- final String[] split = argument.split("=");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, split[0], split[1]).println();
- } else {
- outPW.printf(INDENT_KEY_VALUE_FORMAT, argument,"").println();
- }
- }
- outPW.println("Classpath:");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "boot classpath", mxBean.getBootClassPath()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "library path", mxBean.getLibraryPath()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "classpath", mxBean.getClassPath()).println();
- outPW.println("System properties:");
- final Map<String, String> systemProperties = mxBean.getSystemProperties();
- for (final Entry<String, String> property : systemProperties.entrySet()) {
- outPW.printf(INDENT_KEY_VALUE_FORMAT, property.getKey(), property.getValue()).println();
- }
- outPW.println();
- // JIT information
- final CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
- if( compilationMXBean != null ) {
- outPW.printf(KEY_VALUE_FORMAT, "JIT compiler", compilationMXBean.getName()).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "total compile time", printDuration(compilationMXBean.getTotalCompilationTime())).println();
- }
- }
-
- private void dumpThreadsInformation(final PrintWriter outPW) {
- final ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
- if( null == mxBean) {
- return;
- }
- outPW.println("Threads:");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "live", formatLong(mxBean.getThreadCount())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "daemon", formatLong(mxBean.getDaemonThreadCount())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "peak", formatLong(mxBean.getPeakThreadCount())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", formatLong(mxBean.getTotalStartedThreadCount())).println();
- }
-
- private void dumpClassesInformation(final PrintWriter outPW) {
- final ClassLoadingMXBean mxBean = ManagementFactory.getClassLoadingMXBean();
- if( null == mxBean) {
- return;
- }
- outPW.println("Classes:");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "loaded", formatLong(mxBean.getLoadedClassCount())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", formatLong(mxBean.getTotalLoadedClassCount())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "unloaded", formatLong(mxBean.getUnloadedClassCount())).println();
- }
-
- private void dumpMemoryInformation(final PrintWriter outPW) {
- final MemoryMXBean mxBean = ManagementFactory.getMemoryMXBean();
- if( null == mxBean) {
- return;
- }
- final MemoryUsage heapMemoryUsage = mxBean.getHeapMemoryUsage();
- final MemoryUsage nonHeapMemoryUsage = mxBean.getNonHeapMemoryUsage();
- if( heapMemoryUsage != null ) {
- outPW.println("HEAP Memory:");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", printMemory(heapMemoryUsage.getCommitted())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", printMemory(heapMemoryUsage.getInit())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", printMemory(heapMemoryUsage.getUsed())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", printMemory(heapMemoryUsage.getMax())).println();
- }
- if( nonHeapMemoryUsage != null ) {
- outPW.println("NON-HEAP Memory:");
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", printMemory(nonHeapMemoryUsage.getCommitted())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", printMemory(nonHeapMemoryUsage.getInit())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", printMemory(nonHeapMemoryUsage.getUsed())).println();
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", printMemory(nonHeapMemoryUsage.getMax())).println();
- }
- }
-
- private void dumpGCInformation(final PrintWriter outPW) {
- final List<GarbageCollectorMXBean> mxBeans = ManagementFactory.getGarbageCollectorMXBeans();
- if( null == mxBeans || mxBeans.isEmpty()) {
- return;
- }
- final MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();
- if( memoryMxBean != null ) {
- outPW.printf(INDENT_KEY_VALUE_FORMAT, "pending objects", formatLong(memoryMxBean.getObjectPendingFinalizationCount())).println();
- }
- final String gcFormat ="'%1$s' collections: %2$s\ttime: %3$s";
- outPW.println();
- for (final GarbageCollectorMXBean mxBean : mxBeans) {
- if( null == mxBean) {
- continue;
- }
- outPW.printf(KEY_VALUE_FORMAT, "Garbage Collectors", String.format(gcFormat, mxBean.getName(), formatLong(mxBean.getCollectionCount()), printDuration(mxBean.getCollectionTime()))).println();
- }
- }
-
-
- private String formatLong(final long longValue) {
- final NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
- return fmtI.format(longValue);
- }
-
- private String printMemory(final long bytes) {
- if( bytes <= 1024) {
- return formatLong(bytes)+" bytes";
- }
- return formatLong(bytes/1024)+" kbytes";
- }
-
- /**
- * Prints the duration in a human readable format as X days Y hours Z minutes etc.
- *
- * @param uptime the uptime in millis
- * @return the time used for displaying on screen or in logs
- */
- private String printDuration(double uptime) {
- // Code based on code taken from Karaf
- // https://svn.apache.org/repos/asf/karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/InfoAction.java
-
- uptime /= 1000;
- if (uptime < 60) {
- final NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
- return fmtD.format(uptime) + " seconds";
- }
- uptime /= 60;
- if (uptime < 60) {
- final long minutes = (long) uptime;
- final String s = formatLong(minutes) + (minutes > 1 ? " minutes" : " minute");
- return s;
- }
- uptime /= 60;
- if (uptime < 24) {
- final long hours = (long) uptime;
- final long minutes = (long) ((uptime - hours) * 60);
- String s = formatLong(hours) + (hours > 1 ? " hours" : " hour");
- if (minutes != 0) {
- s += " " + formatLong(minutes) + (minutes > 1 ? " minutes" : " minute");
- }
- return s;
- }
- uptime /= 24;
- final long days = (long) uptime;
- final long hours = (long) ((uptime - days) * 24);
- String s = formatLong(days) + (days > 1 ? " days" : " day");
- if (hours != 0) {
- s += " " + formatLong(hours) + (hours > 1 ? " hours" : " hour");
- }
- return s;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
deleted file mode 100644
index e5fa55e..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import java.io.OutputStreamWriter;
-
-import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.features.Repository;
-
-/**
- * Dump provider which add file named features.txt with informations
- * about installed features and repositories.
- */
-public class FeaturesDumpProvider extends TextDumpProvider {
-
- /**
- * Feature service.
- */
- private final FeaturesService features;
-
- /**
- * Creates new dump entry witch contains information about
- * karaf features.
- *
- * @param features Feature service.
- */
- public FeaturesDumpProvider(FeaturesService features) {
- super("features.txt");
- this.features = features;
- }
-
- /**
- * {@inheritDoc}
- */
- protected void writeDump(OutputStreamWriter outputStreamWriter) throws Exception {
- // creates header
- outputStreamWriter.write("Repositories:\n");
-
- // list repositories
- for (Repository repo : features.listRepositories()) {
- outputStreamWriter.write(repo.getURI() + " (" + repo.getName() + ")\n");
- }
-
- // list features
- outputStreamWriter.write("\nfeatures:\n");
- for (Feature feature : features.listFeatures()) {
- outputStreamWriter.write(feature.getName() + " " + feature.getVersion());
- outputStreamWriter.write(" installed: " + features.isInstalled(feature));
- outputStreamWriter.write("\nBundles:\n");
- for (BundleInfo bundle : feature.getBundles()) {
- outputStreamWriter.write("\t" + bundle.getLocation());
- if (bundle.getStartLevel() != 0) {
- outputStreamWriter.write(" start level " + bundle.getStartLevel());
- }
- outputStreamWriter.write("\n\n");
- }
- }
-
- // flush & close stream
- outputStreamWriter.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
deleted file mode 100644
index b86f57b..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-
-import javax.management.MBeanServer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.OutputStream;
-import java.lang.management.ManagementFactory;
-
-/**
- * Create a heap dump.
- */
-public class HeapDumpProvider implements DumpProvider {
-
- @Override
- public void createDump(DumpDestination destination) throws Exception {
- FileInputStream in = null;
- OutputStream out = null;
- try {
- MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
- HotSpotDiagnosticMXBean diagnosticMXBean = ManagementFactory.newPlatformMXBeanProxy(mBeanServer,
- "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
- diagnosticMXBean.dumpHeap("heapdump.txt", false);
- // copy the dump in the destination
- File heapDumpFile = new File("heapdump.txt");
- in = new FileInputStream(heapDumpFile);
- out = destination.add("heapdump.txt");
- byte[] buffer = new byte[2048];
- while ((in.read(buffer) != -1)) {
- out.write(buffer);
- }
- // remove the original dump
- if (heapDumpFile.exists()) {
- heapDumpFile.delete();
- }
- } catch (Exception e) {
- // nothing to do
- } finally {
- if (in != null) {
- in.close();
- }
- if (out != null) {
- out.flush();
- out.close();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
deleted file mode 100644
index 64b45f1..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-/**
- * Dump provider which copies log files from data/log directory to
- * destination.
- */
-public class LogDumpProvider implements DumpProvider {
-
- private final BundleContext bundleContext;
-
- public LogDumpProvider(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- /**
- * Attach log entries from directory.
- */
- public void createDump(DumpDestination destination) throws Exception {
- // get the ConfigAdmin service
- ServiceReference ref = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
- if (ref == null) {
- return;
- }
-
- // get the PAX Logging configuration
- ConfigurationAdmin configurationAdmin = (ConfigurationAdmin) bundleContext.getService(ref);
- try {
- Configuration configuration = configurationAdmin.getConfiguration("org.ops4j.pax.logging");
-
- // get the ".file" Pax Logging properties
- Dictionary dictionary = configuration.getProperties();
- for (Enumeration e = dictionary.keys(); e.hasMoreElements(); ) {
- String property = (String) e.nextElement();
- if (property.endsWith(".file")) {
- // it's a file appender, get the file location
- String location = (String) dictionary.get(property);
- File file = new File(location);
- if (file.exists()) {
- FileInputStream inputStream = new FileInputStream(file);
- OutputStream outputStream = destination.add("log/" + file.getName());
- copy(inputStream, outputStream);
- }
- }
- }
- } catch (Exception e) {
- throw e;
- } finally {
- bundleContext.ungetService(ref);
- }
- }
-
- /**
- * Rewrites data from input stream to output stream. This code is very common
- * but we would avoid additional dependencies in diagnostic stuff.
- *
- * @param inputStream Source stream.
- * @param outputStream Destination stream.
- * @throws IOException When IO operation fails.
- */
- private void copy(InputStream inputStream, OutputStream outputStream) throws IOException {
- byte[] buffer = new byte[4096];
- int n = 0;
- while (-1 != (n = inputStream.read(buffer))) {
- outputStream.write(buffer, 0, n);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java
deleted file mode 100644
index ff23f9d..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
-
-import java.io.OutputStreamWriter;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-
-/**
- * Provider which dump the memory information in the memory.txt file.
- */
-public class MemoryDumpProvider extends TextDumpProvider {
-
- public MemoryDumpProvider() {
- super("memory.txt");
- }
-
- @Override
- protected void writeDump(OutputStreamWriter outputStream) throws Exception {
- MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
-
- outputStream.write("Number of objects waiting finalization: " + memoryMXBean.getObjectPendingFinalizationCount() + "\n\n");
-
- outputStream.write("Heap:\n");
- outputStream.write("\tInit: " + memoryMXBean.getHeapMemoryUsage().getInit() + "\n");
- outputStream.write("\tUser: " + memoryMXBean.getHeapMemoryUsage().getUsed() + "\n");
- outputStream.write("\tCommitted: " + memoryMXBean.getHeapMemoryUsage().getCommitted() + "\n");
- outputStream.write("\tMax: " + memoryMXBean.getHeapMemoryUsage().getMax() + "\n");
-
- outputStream.write("Non-Heap: \n");
- outputStream.write("\tInit: " + memoryMXBean.getNonHeapMemoryUsage().getInit() + "\n");
- outputStream.write("\tUser: " + memoryMXBean.getNonHeapMemoryUsage().getUsed() + "\n");
- outputStream.write("\tCommitted: " + memoryMXBean.getNonHeapMemoryUsage().getCommitted() + "\n");
- outputStream.write("\tMax: " + memoryMXBean.getNonHeapMemoryUsage().getMax() + "\n");
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
deleted file mode 100644
index 31edad6..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.diagnostic.core.internal;
-
-import java.io.OutputStreamWriter;
-import java.lang.management.LockInfo;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MonitorInfo;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-
-import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
-
-/**
- * Provider which dumps thread info to file named threads.txt.
- */
-public class ThreadDumpProvider extends TextDumpProvider {
-
- /**
- * Creates new dump entry which contains information about threads.
- */
- public ThreadDumpProvider() {
- super("threads.txt");
- }
-
- @Override
- protected void writeDump(OutputStreamWriter outputStream) throws Exception {
- ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-
- outputStream.write("Number of threads: " + threadMXBean.getThreadCount() + "\n");
-
- for (ThreadInfo threadInfo : threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), Integer.MAX_VALUE)) {
- outputStream.write(getDumpThreadString(threadInfo) + "\n\n");
- }
-
- }
-
- protected String getDumpThreadString(ThreadInfo threadInfo) {
- StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" + " Id=" + threadInfo.getThreadId() + " "
- + threadInfo.getThreadState());
- if (threadInfo.getLockName() != null) {
- sb.append(" on " + threadInfo.getLockName());
- }
- if (threadInfo.getLockOwnerName() != null) {
- sb.append(" owned by \"" + threadInfo.getLockOwnerName() + "\" Id=" + threadInfo.getLockOwnerId());
- }
- if (threadInfo.isSuspended()) {
- sb.append(" (suspended)");
- }
- if (threadInfo.isInNative()) {
- sb.append(" (in native)");
- }
- sb.append('\n');
- int i = 0;
- StackTraceElement[] stackTrace = threadInfo.getStackTrace();
- for (; i < stackTrace.length; i++) {
- StackTraceElement ste = stackTrace[i];
- sb.append("\tat " + ste.toString());
- sb.append('\n');
- if (i == 0 && threadInfo.getLockInfo() != null) {
- Thread.State ts = threadInfo.getThreadState();
- switch (ts) {
- case BLOCKED:
- sb.append("\t- blocked on " + threadInfo.getLockInfo());
- sb.append('\n');
- break;
- case WAITING:
- sb.append("\t- waiting on " + threadInfo.getLockInfo());
- sb.append('\n');
- break;
- case TIMED_WAITING:
- sb.append("\t- waiting on " + threadInfo.getLockInfo());
- sb.append('\n');
- break;
- default:
- }
- }
-
- for (MonitorInfo mi : threadInfo.getLockedMonitors()) {
- if (mi.getLockedStackDepth() == i) {
- sb.append("\t- locked " + mi);
- sb.append('\n');
- }
- }
- }
- if (i < stackTrace.length) {
- sb.append("\t...");
- sb.append('\n');
- }
-
- LockInfo[] locks = threadInfo.getLockedSynchronizers();
- if (locks.length > 0) {
- sb.append("\n\tNumber of locked synchronizers = " + locks.length);
- sb.append('\n');
- for (LockInfo li : locks) {
- sb.append("\t- " + li);
- sb.append('\n');
- }
- }
- sb.append('\n');
- return sb.toString();
- }
-
-
-}
[24/59] [abbrv] git commit: [KARAF-2852] Merge config/core and
config/command
Posted by gn...@apache.org.
[KARAF-2852] Merge config/core and config/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/d33e0955
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/d33e0955
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/d33e0955
Branch: refs/heads/master
Commit: d33e09557ba361f44b469e71959398472ef630b4
Parents: d018093
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 22:08:08 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 15:59:49 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
config/NOTICE | 71 +++++++
config/command/NOTICE | 71 -------
config/command/pom.xml | 106 -----------
.../karaf/config/command/CancelCommand.java | 32 ----
.../config/command/ConfigCommandSupport.java | 63 -------
.../command/ConfigPropertyCommandSupport.java | 85 ---------
.../karaf/config/command/DeleteCommand.java | 52 ------
.../karaf/config/command/EditCommand.java | 70 -------
.../karaf/config/command/ListCommand.java | 68 -------
.../karaf/config/command/PropAppendCommand.java | 50 -----
.../karaf/config/command/PropDelCommand.java | 38 ----
.../karaf/config/command/PropListCommand.java | 47 -----
.../karaf/config/command/PropSetCommand.java | 43 -----
.../karaf/config/command/UpdateCommand.java | 48 -----
.../completers/ConfigurationCompleter.java | 103 ----------
.../ConfigurationPropertyCompleter.java | 136 --------------
.../src/main/resources/OSGI-INF/bundle.info | 27 ---
.../org/apache/karaf/config/command/edit.txt | 13 --
.../karaf/config/command/EditCommandTest.java | 97 ----------
.../config/command/MockCommandSession.java | 99 ----------
.../karaf/config/command/UpdateCommandTest.java | 82 --------
config/core/NOTICE | 71 -------
config/core/pom.xml | 111 -----------
.../apache/karaf/config/core/ConfigMBean.java | 107 -----------
.../karaf/config/core/ConfigRepository.java | 51 -----
.../karaf/config/core/impl/ConfigMBeanImpl.java | 186 -------------------
.../config/core/impl/ConfigRepositoryImpl.java | 99 ----------
.../karaf/config/core/impl/osgi/Activator.java | 46 -----
.../src/main/resources/OSGI-INF/bundle.info | 27 ---
.../OSGI-INF/metatype/metatype.properties | 28 ---
.../resources/OSGI-INF/metatype/metatype.xml | 28 ---
config/pom.xml | 97 +++++++++-
.../karaf/config/command/CancelCommand.java | 32 ++++
.../config/command/ConfigCommandSupport.java | 63 +++++++
.../command/ConfigPropertyCommandSupport.java | 85 +++++++++
.../karaf/config/command/DeleteCommand.java | 52 ++++++
.../karaf/config/command/EditCommand.java | 70 +++++++
.../karaf/config/command/ListCommand.java | 68 +++++++
.../karaf/config/command/PropAppendCommand.java | 50 +++++
.../karaf/config/command/PropDelCommand.java | 38 ++++
.../karaf/config/command/PropListCommand.java | 47 +++++
.../karaf/config/command/PropSetCommand.java | 43 +++++
.../karaf/config/command/UpdateCommand.java | 48 +++++
.../completers/ConfigurationCompleter.java | 103 ++++++++++
.../ConfigurationPropertyCompleter.java | 136 ++++++++++++++
.../apache/karaf/config/core/ConfigMBean.java | 107 +++++++++++
.../karaf/config/core/ConfigRepository.java | 51 +++++
.../karaf/config/core/impl/ConfigMBeanImpl.java | 186 +++++++++++++++++++
.../config/core/impl/ConfigRepositoryImpl.java | 99 ++++++++++
.../karaf/config/core/impl/osgi/Activator.java | 46 +++++
config/src/main/resources/OSGI-INF/bundle.info | 27 +++
.../OSGI-INF/metatype/metatype.properties | 28 +++
.../resources/OSGI-INF/metatype/metatype.xml | 28 +++
.../org/apache/karaf/config/command/edit.txt | 13 ++
.../karaf/config/command/EditCommandTest.java | 97 ++++++++++
.../config/command/MockCommandSession.java | 99 ++++++++++
.../karaf/config/command/UpdateCommandTest.java | 82 ++++++++
58 files changed, 1857 insertions(+), 2094 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/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 2bc3ec4..1c67ca7 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -125,7 +125,6 @@
<feature name="config" description="Provide OSGi ConfigAdmin support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.config/org.apache.karaf.config.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.config/org.apache.karaf.config.command/${project.version}</bundle>
</feature>
<feature name="diagnostic" description="Provide Diagnostic support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/NOTICE
----------------------------------------------------------------------
diff --git a/config/NOTICE b/config/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/config/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/d33e0955/config/command/NOTICE
----------------------------------------------------------------------
diff --git a/config/command/NOTICE b/config/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/config/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/d33e0955/config/command/pom.xml
----------------------------------------------------------------------
diff --git a/config/command/pom.xml b/config/command/pom.xml
deleted file mode 100644
index de81567..0000000
--- a/config/command/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?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.config</groupId>
- <artifactId>config</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.config.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: ConfigAdmin :: Commands</name>
- <description>This bundle provides Karaf shell commands to manipulate the ConfigAdmin service.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.config</groupId>
- <artifactId>org.apache.karaf.config.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
-
- <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.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <Private-Package>
- org.apache.felix.utils.properties
- </Private-Package>
- <Karaf-Commands>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/CancelCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/CancelCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/CancelCommand.java
deleted file mode 100644
index dff43fa..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/CancelCommand.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "config", name = "cancel", description = "Cancels the changes to the configuration being edited.")
-@Service
-public class CancelCommand extends ConfigCommandSupport {
-
- protected Object doExecute() throws Exception {
- session.put(PROPERTY_CONFIG_PID, null);
- session.put(PROPERTY_CONFIG_PROPS, null);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java b/config/command/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
deleted file mode 100644
index fe0ca93..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.config.core.ConfigRepository;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.console.Session;
-
-/**
- * Abstract class from which all commands related to the ConfigurationAdmin
- * service should derive.
- * This command retrieves a reference to the ConfigurationAdmin service before
- * calling another method to actually process the command.
- */
-public abstract class ConfigCommandSupport implements Action {
-
- public static final String PROPERTY_CONFIG_PID = "ConfigCommand.PID";
- public static final String PROPERTY_CONFIG_PROPS = "ConfigCommand.Props";
- public static final String PROPERTY_FACTORY = "ConfigCommand.Factory";
-
- @Reference
- protected ConfigRepository configRepository;
-
- @Reference
- protected Session session;
-
- @Override
- public Object execute() throws Exception {
- return doExecute();
- }
-
- protected abstract Object doExecute() throws Exception;
-
- @SuppressWarnings("rawtypes")
- protected Dictionary getEditedProps() throws Exception {
- return (Dictionary) this.session.get(PROPERTY_CONFIG_PROPS);
- }
-
- public void setConfigRepository(ConfigRepository configRepository) {
- this.configRepository = configRepository;
- }
-
- public void setSession(Session session) {
- this.session = session;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java b/config/command/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
deleted file mode 100644
index 619c224..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-import java.util.Properties;
-
-import org.apache.karaf.config.command.completers.ConfigurationCompleter;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.Option;
-
-/**
- * Abstract class which commands that are related to property processing should extend.
- */
-public abstract class ConfigPropertyCommandSupport extends ConfigCommandSupport {
-
- @Option(name = "-p", aliases = "--pid", description = "The configuration pid", required = false, multiValued = false)
- @Completion(ConfigurationCompleter.class)
- protected String pid;
-
- @SuppressWarnings("rawtypes")
- protected Object doExecute() throws Exception {
- Dictionary props = getEditedProps();
- if (props == null && pid == null) {
- System.err.println("No configuration is being edited--run the edit command first");
- } else {
- if (props == null) {
- props = new Properties();
- }
- propertyAction(props);
- if(requiresUpdate(pid)) {
- this.configRepository.update(pid, props);
- }
- }
- return null;
- }
-
- /**
- * Perform an action on the properties.
- * @param props
- */
- @SuppressWarnings("rawtypes")
- protected abstract void propertyAction(Dictionary props);
-
- /**
- * Checks if the configuration requires to be updated.
- * The default behavior is to update if a valid pid has been passed to the method.
- * @param pid
- * @return
- */
- protected boolean requiresUpdate(String pid) {
- if (pid != null) {
- return true;
- } else {
- return false;
- }
- }
-
-
- /**
- * Retrieves confguration from the pid, if used or delegates to session from getting the configuration.
- * @return
- * @throws Exception
- */
- @SuppressWarnings("rawtypes")
- @Override
- protected Dictionary getEditedProps() throws Exception {
- Dictionary props = this.configRepository.getConfigProperties(pid);
- return (props != null) ? props : super.getEditedProps();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/DeleteCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
deleted file mode 100644
index 6953ef0..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import org.apache.karaf.config.command.completers.ConfigurationCompleter;
-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 = "config", name = "delete", description = "Delete a configuration.")
-@Service
-public class DeleteCommand extends ConfigCommandSupport {
-
- @Argument(index = 0, name = "pid", description = "PID of the configuration", required = true, multiValued = false)
- @Completion(ConfigurationCompleter.class)
- String pid;
-
- @Option(name = "--force", aliases = {}, description = "Force the edition of this config, even if another one was under edition", required = false, multiValued = false)
- boolean force;
-
- protected Object doExecute() throws Exception {
- String oldPid = (String) this.session.get(PROPERTY_CONFIG_PID);
- if (oldPid != null && oldPid.equals(pid) && !force) {
- System.err.println("This config is being edited. Cancel / update first, or use the --force option");
- return null;
- }
-
- this.configRepository.delete(pid);
- if (oldPid != null && oldPid.equals(pid) && !force) {
- this.session.put(PROPERTY_CONFIG_PID, null);
- this.session.put(PROPERTY_CONFIG_PROPS, null);
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/EditCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/EditCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/EditCommand.java
deleted file mode 100644
index 8c48b83..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/EditCommand.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.config.command.completers.ConfigurationCompleter;
-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.osgi.service.cm.Configuration;
-
-@Command(scope = "config", name = "edit", description = "Creates or edits a configuration.", detailedDescription="classpath:edit.txt")
-@Service
-public class EditCommand extends ConfigCommandSupport {
-
- @Argument(index = 0, name = "pid", description = "PID of the configuration or of the factory if --factory is given. Pid can also be specified as ldap query", required = true, multiValued = false)
- @Completion(ConfigurationCompleter.class)
- String pid;
-
- @Option(name = "--force", aliases = {}, description = "Force the edition of this config, even if another one was under edition", required = false, multiValued = false)
- boolean force;
-
- @Option(name = "--factory", aliases = {}, description = "Define this config as a factory config. Will be crearted on calling update", required = false, multiValued = false)
- boolean factory;
-
- @SuppressWarnings("rawtypes")
- protected Object doExecute() throws Exception {
- String oldPid = (String) this.session.get(PROPERTY_CONFIG_PID);
- if (oldPid != null && !oldPid.equals(pid) && !force) {
- System.err.println("Another config is being edited. Cancel / update first, or use the --force option");
- return null;
- }
-
- if (pid.startsWith("(")) {
- Configuration[] configs = this.configRepository.getConfigAdmin().listConfigurations(pid);
- if (configs.length == 0) {
- throw new RuntimeException("Filter matches no config");
- }
- if (configs.length > 1) {
- throw new RuntimeException("Filter matches more than one config");
- }
- pid = configs[0].getPid();
- System.out.println("Editing config " + pid);
- }
-
- Dictionary props = this.configRepository.getConfigProperties(pid);
- this.session.put(PROPERTY_CONFIG_PID, pid);
- this.session.put(PROPERTY_FACTORY, factory);
- this.session.put(PROPERTY_CONFIG_PROPS, props);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/ListCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/ListCommand.java
deleted file mode 100644
index bce8410..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/ListCommand.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.service.cm.Configuration;
-
-@Command(scope = "config", name = "list", description = "Lists existing configurations.")
-@Service
-public class ListCommand extends ConfigCommandSupport {
-
- @Argument(index = 0, name = "query", description = "Query in LDAP syntax. Example: \"(service.pid=org.apache.karaf.log)\"", required = false, multiValued = false)
- String query;
-
- @SuppressWarnings("rawtypes")
- protected Object doExecute() throws Exception {
- Configuration[] configs = configRepository.getConfigAdmin().listConfigurations(query);
- if (configs != null) {
- Map<String, Configuration> sortedConfigs = new TreeMap<String, Configuration>();
- for (Configuration config : configs) {
- sortedConfigs.put(config.getPid(), config);
- }
- for (String pid : sortedConfigs.keySet()) {
- Configuration config = sortedConfigs.get(pid);
- System.out.println("----------------------------------------------------------------");
- System.out.println("Pid: " + config.getPid());
- if (config.getFactoryPid() != null) {
- System.out.println("FactoryPid: " + config.getFactoryPid());
- }
- System.out.println("BundleLocation: " + config.getBundleLocation());
- if (config.getProperties() != null) {
- System.out.println("Properties:");
- Dictionary props = config.getProperties();
- Map<String, Object> sortedProps = new TreeMap<String, Object>();
- for (Enumeration e = props.keys(); e.hasMoreElements();) {
- Object key = e.nextElement();
- sortedProps.put(key.toString(), props.get(key));
- }
- for (String key : sortedProps.keySet()) {
- System.out.println(" " + key + " = " + sortedProps.get(key));
- }
- }
- }
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
deleted file mode 100644
index f021146..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.config.command.completers.ConfigurationPropertyCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "config", name = "property-append", description = "Appends the given value to an existing property or creates the property with the specified name and value.")
-@Service
-public class PropAppendCommand extends ConfigPropertyCommandSupport {
-
- @Argument(index = 0, name = "name", description = "The name of the property", required = true, multiValued = false)
- @Completion(ConfigurationPropertyCompleter.class)
- String prop;
-
- @Argument(index = 1, name = "value", description = "The value to append to the property", required = true, multiValued = false)
- String value;
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- @Override
- public void propertyAction(Dictionary props) {
- final Object currentValue = props.get(prop);
- if (currentValue == null) {
- props.put(prop, value);
- } else if (currentValue instanceof String) {
- props.put(prop, currentValue + value);
- } else {
- System.err.println("Append Failed: current value is not a String.");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/PropDelCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
deleted file mode 100644
index e416cf6..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-
-@Command(scope = "config", name = "property-delete", description = "Deletes a property from the configuration being edited.")
-@Service
-public class PropDelCommand extends ConfigPropertyCommandSupport {
-
- @Argument(index = 0, name = "property", description = "The name of the property to delete", required = true, multiValued = false)
- String prop;
-
- @SuppressWarnings("rawtypes")
- @Override
- public void propertyAction(Dictionary props) {
- props.remove(prop);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/PropListCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/PropListCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/PropListCommand.java
deleted file mode 100644
index a0d3a61..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/PropListCommand.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "config", name = "property-list", description = "Lists properties from the currently edited configuration.")
-@Service
-public class PropListCommand extends ConfigPropertyCommandSupport {
-
- @SuppressWarnings("rawtypes")
- @Override
- public void propertyAction(Dictionary props) {
- for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
- Object key = e.nextElement();
- System.out.println(" " + key + " = " + props.get(key));
- }
- }
-
- /**
- * List commands never requires an update, so it always returns false.
- * @param pid
- * @return
- */
- @Override
- protected boolean requiresUpdate(String pid) {
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/PropSetCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
deleted file mode 100644
index 8337f6a..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.config.command.completers.ConfigurationPropertyCompleter;
-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.lifecycle.Service;
-
-@Command(scope = "config", name = "property-set", description = "Sets a property in the currently edited configuration.")
-@Service
-public class PropSetCommand extends ConfigPropertyCommandSupport {
-
- @Argument(index = 0, name = "property", description = "The name of the property to set", required = true, multiValued = false)
- @Completion(ConfigurationPropertyCompleter.class)
- String prop;
-
- @Argument(index = 1, name = "value", description = "The value of the property", required = true, multiValued = false)
- String value;
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- @Override
- public void propertyAction(Dictionary props) {
- props.put(prop, value);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/UpdateCommand.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/UpdateCommand.java b/config/command/src/main/java/org/apache/karaf/config/command/UpdateCommand.java
deleted file mode 100644
index cc368b8..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/UpdateCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "config", name = "update", description = "Saves and propagates changes from the configuration being edited.")
-@Service
-public class UpdateCommand extends ConfigCommandSupport {
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected Object doExecute() throws Exception {
- Dictionary props = getEditedProps();
- if (props == null) {
- System.err.println("No configuration is being edited--run the edit command first");
- return null;
- }
-
- String pid = (String) this.session.get(PROPERTY_CONFIG_PID);
- boolean isFactory = this.session.get(PROPERTY_FACTORY) != null && (Boolean) this.session.get(PROPERTY_FACTORY);
- if (isFactory) {
- this.configRepository.createFactoryConfiguration(pid, props);
- } else {
- this.configRepository.update(pid, props);
- }
- this.session.put(PROPERTY_CONFIG_PID, null);
- this.session.put(PROPERTY_FACTORY, null);
- this.session.put(PROPERTY_CONFIG_PROPS, null);
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java b/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
deleted file mode 100644
index fe60c56..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.karaf.config.command.completers;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.lifecycle.Destroy;
-import org.apache.karaf.shell.api.action.lifecycle.Init;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ConfigurationEvent;
-import org.osgi.service.cm.ConfigurationListener;
-
-/**
- * {@link Completer} for Configuration Admin configurations.
- *
- * Displays a list of existing config instance configurations for completion.
- *
- */
-@Service
-public class ConfigurationCompleter implements Completer, ConfigurationListener {
-
- private final StringsCompleter delegate = new StringsCompleter();
-
- @Reference
- private ConfigurationAdmin admin;
-
- @Reference
- private BundleContext bundleContext;
-
- private ServiceRegistration<ConfigurationListener> registration;
-
- public void setAdmin(ConfigurationAdmin admin) {
- this.admin = admin;
- }
-
- @Init
- public void init() {
- registration = bundleContext.registerService(ConfigurationListener.class, this, null);
-
- Configuration[] configs;
- try {
- configs = admin.listConfigurations(null);
- if (configs == null) {
- return;
- }
- } catch (Exception e) {
- return;
- }
-
- Collection<String> pids = new ArrayList<String>();
- for (Configuration config : configs) {
- pids.add(config.getPid());
- }
-
- delegate.getStrings().addAll(pids);
- }
-
- @Destroy
- public void destroy() {
- registration.unregister();
- }
-
- public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
- return delegate.complete(session, commandLine, candidates);
- }
-
- public void configurationEvent(ConfigurationEvent configurationEvent) {
- String pid = configurationEvent.getPid();
- if (configurationEvent.getType() == ConfigurationEvent.CM_DELETED) {
- delegate.getStrings().remove(pid);
- } else if (configurationEvent.getType() == ConfigurationEvent.CM_UPDATED) {
- delegate.getStrings().add(pid);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
----------------------------------------------------------------------
diff --git a/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java b/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
deleted file mode 100644
index 2b43fec..0000000
--- a/config/command/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.karaf.config.command.completers;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.karaf.config.command.ConfigCommandSupport;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-/**
- * {@link Completer} for Configuration Admin properties.
- *
- * Displays a list of existing properties based on the current configuration being edited.
- *
- */
-@Service
-public class ConfigurationPropertyCompleter implements Completer {
-
- private final StringsCompleter delegate = new StringsCompleter();
-
- private static final String OPTION = "-p";
- private static final String ALIAS = "--pid";
-
- @Reference
- private ConfigurationAdmin configAdmin;
-
- @SuppressWarnings("rawtypes")
- public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
- if (session != null) {
- String pid = getPid(session, commandLine);
- Set<String> propertyNames = getPropertyNames(pid);
- delegate.getStrings().clear();
- if (propertyNames != null && !propertyNames.isEmpty()) {
- delegate.getStrings().addAll(propertyNames);
- }
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
- /**
- * Retrieves the pid stored in the {@link Session} or passed as an argument.
- * Argument takes precedence from pid stored in the {@link Session}.
- */
- private String getPid(Session session, CommandLine commandLine) {
- String pid = (String) session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID);
- if (commandLine.getArguments().length > 0) {
- List<String> arguments = Arrays.asList(commandLine.getArguments());
- if (arguments.contains(OPTION)) {
- int index = arguments.indexOf(OPTION);
- if (arguments.size() > index) {
- return arguments.get(index + 1);
- }
- }
-
- if (arguments.contains(ALIAS)) {
- int index = arguments.indexOf(ALIAS);
- if (arguments.size() > index) {
- return arguments.get(index + 1);
- }
- }
- }
- return pid;
- }
-
- /**
- * Returns the property names for the given pid.
- * @param pid
- * @return
- */
- @SuppressWarnings("rawtypes")
- private Set<String> getPropertyNames(String pid) {
- Set<String> propertyNames = new HashSet<String>();
- if (pid != null) {
- Configuration configuration = null;
- try {
- Configuration[] configs = configAdmin.listConfigurations("(service.pid="+pid+")");
- if (configs != null && configs.length > 0) {
- configuration = configs[0];
- if (configuration != null) {
- Dictionary properties = configuration.getProperties();
- if (properties != null) {
- Enumeration keys = properties.keys();
- while (keys.hasMoreElements()) {
- propertyNames.add(String.valueOf(keys.nextElement()));
- }
- }
- }
- }
- } catch (IOException e) {
- //Ignore
- } catch (InvalidSyntaxException e) {
- //Ignore
- }
- }
- return propertyNames;
- }
-
- public ConfigurationAdmin getConfigAdmin() {
- return configAdmin;
- }
-
- public void setConfigAdmin(ConfigurationAdmin configAdmin) {
- this.configAdmin = configAdmin;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/config/command/src/main/resources/OSGI-INF/bundle.info b/config/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 3cd35da..0000000
--- a/config/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,27 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to manipulate the ConfigAdmin OSGi service.
-
-The following commands are available:
-* config:cancel - Cancels the changes to the configuration being edited.
-* config:edit - Creates or edits a configuration.
-* config:list - Lists existing configurations.
-* config:propappend - Appends the given value to an existing property or creates
- the property with the specified name and value.
-* config:propdel - Deletes a property from the edited configuration.
-* config:proplist - Lists properties from the currently edited configuration.
-* config:propset - Sets a property in the currently edited configuration.
-* config:update - Saves and propagates changes from the configuration being edited.
-
-h1. See also
-
-Commands - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/main/resources/org/apache/karaf/config/command/edit.txt
----------------------------------------------------------------------
diff --git a/config/command/src/main/resources/org/apache/karaf/config/command/edit.txt b/config/command/src/main/resources/org/apache/karaf/config/command/edit.txt
deleted file mode 100644
index 88fa6d5..0000000
--- a/config/command/src/main/resources/org/apache/karaf/config/command/edit.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-The edit command can be used to create or edit a configuration in three ways.
-
-Edit or create a config by pid:
- > config:edit org.apache.karaf.sample.pid
-The command above will also create a file etc/org.apache.karaf.sample.pid which corresponds to a configuration object with pid org.apache.karaf.sample.pid.
-
-Create a factory config by factory pid:
- > config:edit --factory myfactorypid
-In this case the config is created with a pid like myfactorypid.<generated id>. This config is not written to a file.
-
-Edit a config specified by an ldap query
- > config:edit '(myattribute=myvalue)'
-This executes an ldap query like in config:list. If the result is exactly one config then it is edited.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
----------------------------------------------------------------------
diff --git a/config/command/src/test/java/org/apache/karaf/config/command/EditCommandTest.java b/config/command/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
deleted file mode 100644
index 09dc000..0000000
--- a/config/command/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.util.Dictionary;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-import org.apache.karaf.config.core.impl.ConfigRepositoryImpl;
-import org.apache.karaf.shell.api.console.Session;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-/**
- * Test cases for {@link EditCommand}
- */
-public class EditCommandTest extends TestCase {
-
- private static final String PID = "my.test.persistent.id";
-
- private EditCommand command;
- private BundleContext context;
- private ConfigurationAdmin admin;
- private Session session;
-
- @Override
- protected void setUp() throws Exception {
- command = new EditCommand();
-
- admin = createMock(ConfigurationAdmin.class);
- command.setConfigRepository(new ConfigRepositoryImpl(admin));
-
- session = new MockCommandSession();
- command.setSession(session);
- }
-
- public void testExecuteOnExistingPid() throws Exception {
- Configuration config = createMock(Configuration.class);
- expect(admin.getConfiguration(PID)).andReturn(config);
- replay(admin);
-
- // the ConfigAdmin service returns a Dictionary for an existing PID
- Dictionary props = new Properties();
- expect(config.getProperties()).andReturn(props);
- replay(config);
-
- command.pid = PID;
- command.execute();
-
- // the PID and Dictionary should have been set on the session
- assertEquals("The PID should be set on the session",
- PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
- assertSame("The Dictionary returned by the ConfigAdmin service should be set on the session",
- props, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS));
- }
-
- @SuppressWarnings("rawtypes")
- public void testExecuteOnNewPid() throws Exception {
- Configuration config = createMock(Configuration.class);
- expect(admin.getConfiguration(PID)).andReturn(config);
- replay(admin);
-
- // the ConfigAdmin service does not return a Dictionary for a new PID
- expect(config.getProperties()).andReturn(null);
- replay(config);
-
- command.pid = PID;
- command.execute();
-
- // the PID and an empty Dictionary should have been set on the session
- assertEquals("The PID should be set on the session",
- PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
- Dictionary props = (Dictionary) session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS);
- assertNotNull("Should have a Dictionary on the session", props);
- assertTrue("Should have an empty Dictionary on the session", props.isEmpty());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
----------------------------------------------------------------------
diff --git a/config/command/src/test/java/org/apache/karaf/config/command/MockCommandSession.java b/config/command/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
deleted file mode 100644
index 7fa430b..0000000
--- a/config/command/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.karaf.shell.api.console.History;
-import org.apache.karaf.shell.api.console.Registry;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.api.console.SessionFactory;
-import org.apache.karaf.shell.api.console.Terminal;
-
-/*
- * A mock CommandSession implementation that only cares about the properties set on the session
- */
-class MockCommandSession implements Session {
-
- private Map<String, Object> properties = new HashMap<String, Object>();
-
- public void close() {
- // not implemented
- }
-
- public Object execute(CharSequence commandline) throws Exception {
- // not implemented
- return null;
- }
-
- public Object get(String name) {
- return properties.get(name);
- }
-
- public PrintStream getConsole() {
- // not implemented
- return null;
- }
-
- public InputStream getKeyboard() {
- // not implemented
- return null;
- }
-
- public void put(String name, Object value) {
- properties.put(name, value);
- }
-
- @Override
- public String readLine(String prompt, Character mask) throws IOException {
- return null;
- }
-
- @Override
- public Terminal getTerminal() {
- return null;
- }
-
- @Override
- public History getHistory() {
- return null;
- }
-
- @Override
- public Registry getRegistry() {
- return null;
- }
-
- @Override
- public SessionFactory getFactory() {
- return null;
- }
-
- @Override
- public String resolveCommand(String name) {
- return null;
- }
-
- @Override
- public void run() {
-
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/command/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
----------------------------------------------------------------------
diff --git a/config/command/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java b/config/command/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
deleted file mode 100644
index e3f58b5..0000000
--- a/config/command/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.command;
-
-
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.config.core.ConfigRepository;
-import org.easymock.EasyMock;
-
-/**
- * Test cases for {@link EditCommand}
- */
-public class UpdateCommandTest extends TestCase {
-
- private static final String FACTORY_PID = "myFactoryPid";
- private static final String PID = "myPid";
-
- public void testupdateRegularConfig() throws Exception {
- Dictionary<String, Object> props = new Hashtable<String, Object>();
-
- UpdateCommand command = new UpdateCommand();
- ConfigRepository configRepo = EasyMock.createMock(ConfigRepository.class);
- configRepo.update(EasyMock.eq(PID), EasyMock.eq(props));
- EasyMock.expectLastCall();
- command.setConfigRepository(configRepo);
-
- MockCommandSession session = createMockSessionForFactoryEdit(PID, false, props);
- command.setSession(session);
- replay(configRepo);
-
- command.execute();
- EasyMock.verify(configRepo);
- }
-
- public void testupdateOnNewFactoryPid() throws Exception {
- Dictionary<String, Object> props = new Hashtable<String, Object>();
-
- UpdateCommand command = new UpdateCommand();
- ConfigRepository configRepo = EasyMock.createMock(ConfigRepository.class);
- expect(configRepo.createFactoryConfiguration(EasyMock.eq(FACTORY_PID), EasyMock.eq(props)))
- .andReturn(PID + ".35326647");
- command.setConfigRepository(configRepo);
-
- MockCommandSession session = createMockSessionForFactoryEdit(FACTORY_PID, true, props);
- command.setSession(session);
- replay(configRepo);
-
- command.execute();
- EasyMock.verify(configRepo);
- }
-
- private MockCommandSession createMockSessionForFactoryEdit(String pid, boolean isFactory,
- Dictionary<String, Object> props) {
- MockCommandSession session = new MockCommandSession();
- session.put(ConfigCommandSupport.PROPERTY_CONFIG_PID, pid);
- session.put(ConfigCommandSupport.PROPERTY_FACTORY, isFactory);
- session.put(ConfigCommandSupport.PROPERTY_CONFIG_PROPS, props);
- return session;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/NOTICE
----------------------------------------------------------------------
diff --git a/config/core/NOTICE b/config/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/config/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/d33e0955/config/core/pom.xml
----------------------------------------------------------------------
diff --git a/config/core/pom.xml b/config/core/pom.xml
deleted file mode 100644
index a1a646b..0000000
--- a/config/core/pom.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?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.config</groupId>
- <artifactId>config</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.config.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: ConfigAdmin :: Core</name>
- <description>This bundle provides Karaf services</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <Export-Package>
- org.apache.karaf.config.core
- </Export-Package>
- <Import-Package>
- *
- </Import-Package>
- <Private-Package>
- org.apache.karaf.config.core.impl,
- org.apache.karaf.config.core.impl.osgi,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.config.core.impl.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
----------------------------------------------------------------------
diff --git a/config/core/src/main/java/org/apache/karaf/config/core/ConfigMBean.java b/config/core/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
deleted file mode 100644
index 9cb9f7f..0000000
--- a/config/core/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.core;
-
-import javax.management.MBeanException;
-import java.util.List;
-import java.util.Map;
-
-/**
- * MBean to manipulate the Config layer.
- */
-public interface ConfigMBean {
-
- /**
- * Get the list of all configuration PIDs.
- *
- * @return the list of all configuration PIDs.
- * @throws Exception
- */
- List<String> getConfigs() throws MBeanException;
-
- /**
- * Create a new configuration for the given PID.
- *
- * @param pid the configuration PID.
- * @throws Exception
- */
- void create(String pid) throws MBeanException;
-
- /**
- * Delete a configuration identified by the given PID.
- *
- * @param pid the configuration PID to delete.
- * @throws Exception
- */
- void delete(String pid) throws MBeanException;
-
- /**
- * Get the list of properties for a configuration PID.
- *
- * @param pid the configuration PID.
- * @return the list of properties.
- * @throws Exception
- */
- Map<String, String> listProperties(String pid) throws MBeanException;
-
- /**
- * Remove the configuration property identified by the given key.
- *
- * @param pid the configuration PID.
- * @param key the property key.
- * @throws Exception
- */
- void deleteProperty(String pid, String key) throws MBeanException;
-
- /**
- * Append (or add) a value for the given configuration key.
- *
- * @param pid the configuration PID.
- * @param key the property key.
- * @param value the value to append to the current property value.
- * @throws Exception
- */
- void appendProperty(String pid, String key, String value) throws MBeanException;
-
- /**
- * Set a configuration property.
- *
- * @param pid the configuration PID.
- * @param key the property key.
- * @param value the property value.
- * @throws Exception
- */
- void setProperty(String pid, String key, String value) throws MBeanException;
-
- /**
- * Update a complete configuration.
- *
- * @param pid the configuration PID.
- * @param properties the new properties to set in the configuration.
- * @throws MBeanException
- */
- void update(String pid, Map<String, String> properties) throws MBeanException;
-
- /**
- * Create a factory based configuration.
- *
- * @param factoryPid
- * @param properties the new properties to set in the configuration.
- * @return created pid
- * @throws MBeanException
- */
- String createFactoryConfiguration(String factoryPid, Map<String, String> properties) throws MBeanException;
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
----------------------------------------------------------------------
diff --git a/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java b/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
deleted file mode 100644
index 8121679..0000000
--- a/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.core;
-
-import java.io.IOException;
-import java.util.Dictionary;
-
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-public interface ConfigRepository {
-
- /**
- * Saves config to storage or ConfigurationAdmin.
- * @param pid
- * @param props
- * @throws IOException
- */
- @SuppressWarnings("rawtypes")
- void update(String pid, Dictionary props) throws IOException;
-
- void delete(String pid) throws Exception;
-
- @SuppressWarnings("rawtypes")
- Dictionary getConfigProperties(String pid) throws IOException, InvalidSyntaxException;
-
- ConfigurationAdmin getConfigAdmin();
-
- /**
- * Create a factory based configuration.
- *
- * @param factoryPid
- * @param properties the new properties to set in the configuration.
- * @return created pid
- */
- String createFactoryConfiguration(String factoryPid, Dictionary<String, ?> properties);
-}
[26/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
new file mode 100644
index 0000000..535c2a0
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
@@ -0,0 +1,1166 @@
+/*
+ * 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.instance.core.internal;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.apache.karaf.jpm.Process;
+import org.apache.karaf.jpm.impl.ProcessBuilderFactoryImpl;
+import org.apache.karaf.jpm.impl.ScriptUtils;
+import org.apache.karaf.util.locks.FileLockUtils;
+import org.fusesource.jansi.Ansi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.Socket;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Scanner;
+
+public class InstanceServiceImpl implements InstanceService {
+
+ public static final String STORAGE_FILE = "instance.properties";
+ public static final String BACKUP_EXTENSION = ".bak";
+ private static final String FEATURES_CFG = "etc/org.apache.karaf.features.cfg";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(InstanceServiceImpl.class);
+
+ private static final String CONFIG_PROPERTIES_FILE_NAME = "config.properties";
+
+ private static final String KARAF_SHUTDOWN_PORT = "karaf.shutdown.port";
+
+ private static final String KARAF_SHUTDOWN_HOST = "karaf.shutdown.host";
+
+ private static final String KARAF_SHUTDOWN_PORT_FILE = "karaf.shutdown.port.file";
+
+ private static final String KARAF_SHUTDOWN_COMMAND = "karaf.shutdown.command";
+
+ private static final String KARAF_SHUTDOWN_PID_FILE = "karaf.shutdown.pid.file";
+
+ private static final String DEFAULT_SHUTDOWN_COMMAND = "SHUTDOWN";
+
+ public static final String DEFAULT_JAVA_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass";
+
+ private LinkedHashMap<String, InstanceImpl> proxies = new LinkedHashMap<String, InstanceImpl>();
+
+ private File storageLocation;
+
+ private long stopTimeout = 30000;
+
+ static class InstanceState {
+ String name;
+ String loc;
+ String opts;
+ int pid;
+ boolean root;
+ }
+
+ static class State {
+ int defaultSshPortStart = 8101;
+ int defaultRmiRegistryPortStart = 1099;
+ int defaultRmiServerPortStart = 44444;
+ Map<String, InstanceState> instances;
+ }
+
+ public InstanceServiceImpl() {
+ String prop = System.getProperty("karaf.instances");
+ if (prop != null) {
+ storageLocation = new File(prop);
+ }
+ }
+
+ public File getStorageLocation() {
+ return storageLocation;
+ }
+
+ public void setStorageLocation(File storage) {
+ this.storageLocation = storage;
+ }
+
+ public long getStopTimeout() {
+ return stopTimeout;
+ }
+
+ public void setStopTimeout(long stopTimeout) {
+ this.stopTimeout = stopTimeout;
+ }
+
+ private State loadData(org.apache.felix.utils.properties.Properties storage) {
+ State state = new State();
+ int count = getInt(storage, "count", 0);
+ state.defaultSshPortStart = getInt(storage, "ssh.port", state.defaultSshPortStart);
+ state.defaultRmiRegistryPortStart = getInt(storage, "rmi.registry.port", state.defaultRmiRegistryPortStart);
+ state.defaultRmiServerPortStart = getInt(storage, "rmi.server.port", state.defaultRmiServerPortStart);
+ state.instances = new LinkedHashMap<String, InstanceState>();
+
+ for (int i = 0; i < count; i++) {
+ InstanceState instance = new InstanceState();
+ instance.name = getString(storage, "item." + i + ".name", null);
+ instance.loc = getString(storage, "item." + i + ".loc", null);
+ instance.opts = getString(storage, "item." + i + ".opts", null);
+ instance.pid = getInt(storage, "item." + i + ".pid", 0);
+ instance.root = getBool(storage, "item." + i + ".root", false);
+ state.instances.put(instance.name, instance);
+ }
+ // Update proxies list
+ for (InstanceState instance : state.instances.values()) {
+ if (!this.proxies.containsKey(instance.name)) {
+ proxies.put(instance.name, new InstanceImpl(this, instance.name));
+ }
+ }
+ List<String> names = new ArrayList<String>(this.proxies.keySet());
+ for (String name : names) {
+ if (!state.instances.containsKey(name)) {
+ this.proxies.remove(name);
+ }
+ }
+ return state;
+ }
+
+ private void saveData(State state, org.apache.felix.utils.properties.Properties storage) {
+ storage.put("ssh.port", Integer.toString(state.defaultSshPortStart));
+ storage.put("rmi.registry.port", Integer.toString(state.defaultRmiRegistryPortStart));
+ storage.put("rmi.server.port", Integer.toString(state.defaultRmiServerPortStart));
+ storage.put("count", Integer.toString(state.instances.size()));
+ int i = 0;
+ for (InstanceState instance : state.instances.values()) {
+ storage.put("item." + i + ".name", instance.name);
+ storage.put("item." + i + ".root", Boolean.toString(instance.root));
+ storage.put("item." + i + ".loc", instance.loc);
+ storage.put("item." + i + ".pid", Integer.toString(instance.pid));
+ storage.put("item." + i + ".opts", instance.opts != null ? instance.opts : "");
+ i++;
+ }
+ while (storage.containsKey("item." + i + ".name")) {
+ storage.remove("item." + i + ".name");
+ storage.remove("item." + i + ".root");
+ storage.remove("item." + i + ".loc");
+ storage.remove("item." + i + ".pid");
+ storage.remove("item." + i + ".opts");
+ i++;
+ }
+ }
+
+ private boolean getBool(org.apache.felix.utils.properties.Properties storage, String name, boolean def) {
+ Object value = storage.get(name);
+ if (value != null) {
+ return Boolean.parseBoolean(value.toString());
+ } else {
+ return def;
+ }
+ }
+
+ private int getInt(org.apache.felix.utils.properties.Properties storage, String name, int def) {
+ Object value = storage.get(name);
+ if (value != null) {
+ return Integer.parseInt(value.toString());
+ } else {
+ return def;
+ }
+ }
+
+ private String getString(org.apache.felix.utils.properties.Properties storage, String name, String def) {
+ Object value = storage.get(name);
+ return value != null ? value.toString() : def;
+ }
+
+ interface Task<T> {
+ T call(State state) throws IOException;
+ }
+
+ synchronized <T> T execute(final Task<T> callback) {
+ final File storageFile = new File(storageLocation, STORAGE_FILE);
+ if (!storageFile.exists()) {
+ storageFile.getParentFile().mkdirs();
+ try {
+ storageFile.createNewFile();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ if (storageFile.exists()) {
+ if (!storageFile.isFile()) {
+ throw new IllegalStateException("Instance storage location should be a file: " + storageFile);
+ }
+ try {
+ return FileLockUtils.execute(storageFile, new FileLockUtils.CallableWithProperties<T>() {
+ public T call(org.apache.felix.utils.properties.Properties properties) throws IOException {
+ State state = loadData(properties);
+ T t = callback.call(state);
+ saveData(state, properties);
+ return t;
+ }
+ });
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ throw new IllegalStateException("Instance storage location does not exist: " + storageFile);
+ }
+ }
+
+ public synchronized void refreshInstance() throws Exception {
+ }
+
+ private void logInfo(String message, boolean printOutput, Object... args) {
+ if (LOGGER.isInfoEnabled() || printOutput) {
+ String formatted = String.format(message, args);
+ LOGGER.info(formatted);
+ if (printOutput) {
+ println(formatted);
+ }
+ }
+ }
+
+ public synchronized Instance createInstance(final String name, final InstanceSettings settings, final boolean printOutput) throws Exception {
+ return execute(new Task<Instance>() {
+ public Instance call(State state) throws IOException {
+ if (state.instances.get(name) != null) {
+ throw new IllegalArgumentException("Instance '" + name + "' already exists");
+ }
+ String loc = settings.getLocation() != null ? settings.getLocation() : name;
+ File karafBase = new File(loc);
+ if (!karafBase.isAbsolute()) {
+ karafBase = new File(storageLocation, loc);
+ }
+ int sshPort = settings.getSshPort();
+ if (sshPort <= 0) {
+ sshPort = ++state.defaultSshPortStart;
+ }
+ int rmiRegistryPort = settings.getRmiRegistryPort();
+ if (rmiRegistryPort <= 0) {
+ rmiRegistryPort = ++state.defaultRmiRegistryPortStart;
+ }
+ int rmiServerPort = settings.getRmiServerPort();
+ if (rmiServerPort <= 0) {
+ rmiServerPort = ++state.defaultRmiServerPortStart;
+ }
+ logInfo("Creating new instance on SSH port %d and registry port %d / RMI server port %d at: %s",
+ printOutput, sshPort, rmiRegistryPort, rmiServerPort, karafBase);
+
+ mkdir(karafBase, "bin", printOutput);
+ mkdir(karafBase, "etc", printOutput);
+ mkdir(karafBase, "system", printOutput);
+ mkdir(karafBase, "deploy", printOutput);
+ mkdir(karafBase, "data", printOutput);
+
+ copyResourceToDir(karafBase, "etc/all.policy", printOutput);
+ copyResourceToDir(karafBase, "etc/config.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/custom.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/distribution.info", printOutput);
+ copyResourceToDir(karafBase, "etc/equinox-debug.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/java.util.logging.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.java.lang.Memory.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.bundle.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.config.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.security.jmx.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jmx.acl.osgi.compendium.cm.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/jre.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/keys.properties", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.felix.fileinstall-deploy.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.bundle.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.config.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.feature.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.jaas.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.kar.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.shell.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.system.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.features.obr.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.features.repos.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.jaas.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.kar.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.apache.karaf.log.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.ops4j.pax.logging.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/org.ops4j.pax.url.mvn.cfg", printOutput);
+ copyResourceToDir(karafBase, "etc/regions-config.xml", printOutput);
+ copyResourceToDir(karafBase, "etc/shell.init.script", printOutput);
+ copyResourceToDir(karafBase, "etc/users.properties", printOutput);
+
+ copyResourceToDir(karafBase, FEATURES_CFG, printOutput);
+ addFeaturesFromSettings(new File(karafBase, FEATURES_CFG), settings);
+
+ // The startup.properties is now generated by the karaf maven plugin, so
+ // we use the one from the root instance instead of embedding it
+ File rootEtc = new File(System.getProperty("karaf.etc"));
+ copy(new File(rootEtc, "startup.properties"), new File(karafBase, "etc/startup.properties"));
+
+ HashMap<String, String> props = new HashMap<String, String>();
+ props.put("${SUBST-KARAF-NAME}", name);
+ props.put("${SUBST-KARAF-HOME}", System.getProperty("karaf.home"));
+ props.put("${SUBST-KARAF-BASE}", karafBase.getPath());
+ props.put("${SUBST-SSH-PORT}", Integer.toString(sshPort));
+ props.put("${SUBST-RMI-REGISTRY-PORT}", Integer.toString(rmiRegistryPort));
+ props.put("${SUBST-RMI-SERVER-PORT}", Integer.toString(rmiServerPort));
+ copyFilteredResourceToDir(karafBase, "etc/system.properties", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "etc/org.apache.karaf.shell.cfg", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "etc/org.apache.karaf.management.cfg", props, printOutput);
+
+ copyFilteredResourceToDir(karafBase, "bin/karaf", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "bin/start", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "bin/stop", props, printOutput);
+
+ copyFilteredResourceToDir(karafBase, "bin/karaf.bat", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "bin/start.bat", props, printOutput);
+ copyFilteredResourceToDir(karafBase, "bin/stop.bat", props, printOutput);
+
+ try {
+ chmod(new File(karafBase, "bin/karaf"), "a+x");
+ chmod(new File(karafBase, "bin/start"), "a+x");
+ chmod(new File(karafBase, "bin/stop"), "a+x");
+ } catch (IOException e) {
+ LOGGER.debug("Could not set file mode on scripts.", e);
+ }
+
+ String javaOpts = settings.getJavaOpts();
+ if (javaOpts == null || javaOpts.length() == 0) {
+ javaOpts = DEFAULT_JAVA_OPTS;
+ }
+ InstanceState is = new InstanceState();
+ is.name = name;
+ is.loc = karafBase.toString();
+ is.opts = javaOpts;
+ state.instances.put(name, is);
+ InstanceImpl instance = new InstanceImpl(InstanceServiceImpl.this, name);
+ InstanceServiceImpl.this.proxies.put(name, instance);
+ return instance;
+ }
+ });
+ }
+
+ void addFeaturesFromSettings(File featuresCfg, final InstanceSettings settings) throws IOException {
+ FileLockUtils.execute(featuresCfg, new FileLockUtils.RunnableWithProperties() {
+ public void run(org.apache.felix.utils.properties.Properties properties) throws IOException {
+ appendToPropList(properties, "featuresBoot", settings.getFeatures());
+ appendToPropList(properties, "featuresRepositories", settings.getFeatureURLs());
+ }
+ });
+ }
+
+ private void appendToPropList(org.apache.felix.utils.properties.Properties p, String key, List<String> elements) {
+ if (elements == null) {
+ return;
+ }
+ StringBuilder sb = new StringBuilder(p.get(key).toString().trim());
+ for (String f : elements) {
+ if (sb.length() > 0) {
+ sb.append(',');
+ }
+ sb.append(f);
+ }
+ p.put(key, sb.toString());
+ }
+
+ public Instance[] getInstances() {
+ return execute(new Task<Instance[]>() {
+ public Instance[] call(State state) throws IOException {
+ return proxies.values().toArray(new Instance[proxies.size()]);
+ }
+ });
+ }
+
+ public Instance getInstance(final String name) {
+ return execute(new Task<Instance>() {
+ public Instance call(State state) throws IOException {
+ return proxies.get(name);
+ }
+ });
+ }
+
+ public void startInstance(final String name, final String javaOpts) {
+ execute(new Task<Object>() {
+ public Object call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ checkPid(instance);
+ if (instance.pid != 0) {
+ throw new IllegalStateException("Instance already started");
+ }
+ String opts = javaOpts;
+ if (opts == null || opts.length() == 0) {
+ opts = instance.opts;
+ }
+ if (opts == null || opts.length() == 0) {
+ opts = DEFAULT_JAVA_OPTS;
+ }
+
+ // fallback and read karafOpts from KARAF_OPTS environment if no System property present
+ String karafOptsEnv = System.getenv("KARAF_OPTS");
+ String karafOpts = System.getProperty("karaf.opts", karafOptsEnv != null ? karafOptsEnv : "");
+
+ String location = instance.loc;
+
+ File libDir = new File(System.getProperty("karaf.home"), "lib");
+ File childLibDir = new File(location, "lib");
+
+ StringBuilder classpath = classpathFromLibDir(libDir);
+ StringBuilder childClasspath = classpathFromLibDir(childLibDir);
+ if (childClasspath.length() > 0 && !libDir.equals(childLibDir)) {
+ classpath.append(System.getProperty("path.separator"));
+ classpath.append(childClasspath);
+ }
+
+ String command = "\""
+ + new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath()
+ + "\" " + opts
+ + " " + karafOpts
+ + " -Djava.util.logging.config.file=\"" + new File(location, "etc/java.util.logging.properties").getCanonicalPath() + "\""
+ + " -Djava.endorsed.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(libDir, "endorsed").getCanonicalPath() + "\""
+ + " -Djava.ext.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "ext") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "ext") + System.getProperty("path.separator") + new File(libDir, "ext").getCanonicalPath() + "\""
+ + " -Dkaraf.home=\"" + System.getProperty("karaf.home") + "\""
+ + " -Dkaraf.base=\"" + new File(location).getCanonicalPath() + "\""
+ + " -Dkaraf.data=\"" + new File(new File(location).getCanonicalPath(), "data") + "\""
+ + " -Dkaraf.etc=\"" + new File(new File(location).getCanonicalPath(), "etc") + "\""
+ + " -Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder"
+ + " -Dkaraf.startLocalConsole=false"
+ + " -Dkaraf.startRemoteShell=true"
+ + " -classpath \"" + classpath.toString() + "\""
+ + " org.apache.karaf.main.Main";
+ LOGGER.debug("Starting instance " + name + " with command: " + command);
+ org.apache.karaf.jpm.Process process = new ProcessBuilderFactoryImpl().newBuilder()
+ .directory(new File(location))
+ .command(command)
+ .start();
+ instance.pid = process.getPid();
+ return null;
+ }
+
+ private StringBuilder classpathFromLibDir(File libDir) throws IOException {
+ File[] jars = libDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+ StringBuilder classpath = new StringBuilder();
+ if (jars != null) {
+ for (File jar : jars) {
+ if (classpath.length() > 0) {
+ classpath.append(System.getProperty("path.separator"));
+ }
+ classpath.append(jar.getCanonicalPath());
+ }
+ }
+ return classpath;
+ }
+ });
+ }
+
+ public void stopInstance(final String name) {
+ execute(new Task<Object>() {
+ public Object call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ checkPid(instance);
+ if (instance.pid == 0) {
+ throw new IllegalStateException("Instance already stopped");
+ }
+ cleanShutdown(instance);
+ if (instance.pid > 0) {
+ Process process = new ProcessBuilderFactoryImpl().newBuilder().attach(instance.pid);
+ process.destroy();
+ }
+ return null;
+ }
+ });
+ }
+
+ public void destroyInstance(final String name) {
+ execute(new Task<Object>() {
+ public Object call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ checkPid(instance);
+ if (instance.pid != 0) {
+ throw new IllegalStateException("Instance not stopped");
+ }
+ deleteFile(new File(instance.loc));
+ state.instances.remove(name);
+ InstanceServiceImpl.this.proxies.remove(name);
+ return null;
+ }
+ });
+ }
+
+ public void renameInstance(final String oldName, final String newName, final boolean printOutput) throws Exception {
+ execute(new Task<Object>() {
+ public Object call(State state) throws IOException {
+ if (state.instances.get(newName) != null) {
+ throw new IllegalArgumentException("Instance " + newName + " already exists");
+ }
+ InstanceState instance = state.instances.get(oldName);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + oldName + " not found");
+ }
+ if (instance.root) {
+ throw new IllegalArgumentException("Root instance cannot be renamed");
+ }
+ checkPid(instance);
+ if (instance.pid != 0) {
+ throw new IllegalStateException("Instance not stopped");
+ }
+
+ println(Ansi.ansi().a("Renaming instance ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(oldName).a(Ansi.Attribute.RESET)
+ .a(" to ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(newName).a(Ansi.Attribute.RESET).toString());
+ // rename directory
+ String oldLocationPath = instance.loc;
+ File oldLocation = new File(oldLocationPath);
+ String basedir = oldLocation.getParent();
+ File newLocation = new File(basedir, newName);
+ oldLocation.renameTo(newLocation);
+ // create the properties map including the instance name and instance location
+ // TODO: replacing is bad, we should re-extract the needed files
+ HashMap<String, String> props = new HashMap<String, String>();
+ props.put(oldName, newName);
+ props.put(oldLocationPath, newLocation.getPath());
+ // replace all references to the "old" name by the new one in etc/system.properties
+ // NB: it's replacement to avoid to override the user's changes
+ filterResource(newLocation, "etc/system.properties", props);
+ // replace all references to the "old" name by the new one in bin/karaf
+ filterResource(newLocation, "bin/karaf", props);
+ filterResource(newLocation, "bin/start", props);
+ filterResource(newLocation, "bin/stop", props);
+ filterResource(newLocation, "bin/karaf.bat", props);
+ filterResource(newLocation, "bin/start.bat", props);
+ filterResource(newLocation, "bin/stop.bat", props);
+ // update instance
+ instance.name = newName;
+ instance.loc = newLocation.getPath();
+ state.instances.put(newName, instance);
+ state.instances.remove(oldName);
+ InstanceImpl proxy = InstanceServiceImpl.this.proxies.remove(oldName);
+ if (proxy == null) {
+ proxy = new InstanceImpl(InstanceServiceImpl.this, newName);
+ } else {
+ proxy.doSetName(newName);
+ }
+ InstanceServiceImpl.this.proxies.put(newName, proxy);
+ return null;
+ }
+ });
+ }
+
+ public synchronized Instance cloneInstance(final String name, final String cloneName, final InstanceSettings settings, final boolean printOutput) throws Exception {
+ final int instanceSshPort = getInstanceSshPort(name);
+ final int instanceRmiRegistryPort = getInstanceRmiRegistryPort(name);
+ final int instanceRmiServerPort = getInstanceRmiServerPort(name);
+
+ return execute(new Task<Instance>() {
+ public Instance call(State state) throws IOException {
+ if (state.instances.get(cloneName) != null) {
+ throw new IllegalArgumentException("Instance " + cloneName + " already exists");
+ }
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+
+ // define the clone instance location
+ String cloneLocationPath = settings.getLocation() != null ? settings.getLocation() : cloneName;
+ File cloneLocation = new File(cloneLocationPath);
+ if (!cloneLocation.isAbsolute()) {
+ cloneLocation = new File(storageLocation, cloneLocationPath);
+ }
+ // copy instance directory
+ String locationPath = instance.loc;
+ File location = new File(locationPath);
+ copy(location, cloneLocation);
+ // create the properties map including the instance name, location, ssh and rmi port numbers
+ // TODO: replacing stuff anywhere is not really good, we might end up replacing unwanted stuff
+ // TODO: if no ports are overriden, shouldn't we choose new ports ?
+ HashMap<String, String> props = new HashMap<String, String>();
+ props.put(name, cloneName);
+ props.put(locationPath, cloneLocationPath);
+ if (settings.getSshPort() > 0)
+ props.put(Integer.toString(instanceSshPort), Integer.toString(settings.getSshPort()));
+ if (settings.getRmiRegistryPort() > 0)
+ props.put(Integer.toString(instanceRmiRegistryPort), Integer.toString(settings.getRmiRegistryPort()));
+ if (settings.getRmiServerPort() > 0)
+ props.put(Integer.toString(instanceRmiServerPort), Integer.toString(settings.getRmiServerPort()));
+
+ // filtering clone files
+ filterResource(cloneLocation, "etc/custom.properties", props);
+ filterResource(cloneLocation, "etc/org.apache.karaf.management.cfg", props);
+ filterResource(cloneLocation, "etc/org.apache.karaf.shell.cfg", props);
+ filterResource(cloneLocation, "etc/system.properties", props);
+ filterResource(cloneLocation, "bin/karaf", props);
+ filterResource(cloneLocation, "bin/start", props);
+ filterResource(cloneLocation, "bin/stop", props);
+ filterResource(cloneLocation, "bin/karaf.bat", props);
+ filterResource(cloneLocation, "bin/start.bat", props);
+ filterResource(cloneLocation, "bin/stop.bat", props);
+ // create and add the clone instance in the registry
+ String javaOpts = settings.getJavaOpts();
+ if (javaOpts == null || javaOpts.length() == 0) {
+ javaOpts = DEFAULT_JAVA_OPTS;
+ }
+ InstanceState is = new InstanceState();
+ is.name = cloneName;
+ is.loc = cloneLocation.toString();
+ is.opts = javaOpts;
+ state.instances.put(cloneName, is);
+ InstanceImpl cloneInstance = new InstanceImpl(InstanceServiceImpl.this, cloneName);
+ InstanceServiceImpl.this.proxies.put(cloneName, cloneInstance);
+ return cloneInstance;
+ }
+ });
+ }
+
+ private void checkPid(InstanceState instance) throws IOException {
+ if (instance.pid != 0) {
+ Process process = new ProcessBuilderFactoryImpl().newBuilder().attach(instance.pid);
+ if (!process.isRunning()) {
+ instance.pid = 0;
+ }
+ }
+ }
+
+ protected void cleanShutdown(InstanceState instance) {
+ try {
+ File file = new File(new File(instance.loc, "etc"), CONFIG_PROPERTIES_FILE_NAME);
+ URL configPropURL = file.toURI().toURL();
+ Properties props = loadPropertiesFile(configPropURL);
+ props.put("karaf.base", new File(instance.loc).getCanonicalPath());
+ props.put("karaf.home", System.getProperty("karaf.home"));
+ props.put("karaf.data", new File(new File(instance.loc), "data").getCanonicalPath());
+ props.put("karaf.etc", new File(new File(instance.loc), "etc").getCanonicalPath());
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ props.setProperty(key,
+ substVars(props.getProperty(key), key, null, props));
+ }
+ int port = Integer.parseInt(props.getProperty(KARAF_SHUTDOWN_PORT, "0"));
+ String host = props.getProperty(KARAF_SHUTDOWN_HOST, "localhost");
+ String portFile = props.getProperty(KARAF_SHUTDOWN_PORT_FILE);
+ String shutdown = props.getProperty(KARAF_SHUTDOWN_COMMAND, DEFAULT_SHUTDOWN_COMMAND);
+ if (port == 0 && portFile != null) {
+ BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(portFile)));
+ String portStr = r.readLine();
+ port = Integer.parseInt(portStr);
+ r.close();
+ }
+ // We found the port, try to send the command
+ if (port > 0) {
+ Socket s = new Socket(host, port);
+ s.getOutputStream().write(shutdown.getBytes());
+ s.close();
+ long t = System.currentTimeMillis() + getStopTimeout();
+ do {
+ Thread.sleep(100);
+ checkPid(instance);
+ } while (System.currentTimeMillis() < t && instance.pid > 0);
+ }
+ } catch (Exception e) {
+ LOGGER.debug("Unable to cleanly shutdown instance " + instance.name, e);
+ }
+ }
+
+ int getInstanceSshPort(String name) {
+ return getKarafPort(name, "etc/org.apache.karaf.shell.cfg", "sshPort");
+ }
+
+ void changeInstanceSshPort(String name, final int port) throws Exception {
+ setKarafPort(name, "etc/org.apache.karaf.shell.cfg", "sshPort", port);
+ }
+
+ int getInstanceRmiRegistryPort(String name) {
+ return getKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiRegistryPort");
+ }
+
+ void changeInstanceRmiRegistryPort(String name, final int port) throws Exception {
+ setKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiRegistryPort", port);
+ }
+
+ int getInstanceRmiServerPort(String name) {
+ return getKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiServerPort");
+ }
+
+ void changeInstanceRmiServerPort(String name, int port) throws Exception {
+ setKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiServerPort", port);
+ }
+
+ private int getKarafPort(final String name, final String path, final String key) {
+ return execute(new Task<Integer>() {
+ public Integer call(State state) throws IOException {
+ return InstanceServiceImpl.this.getKarafPort(state, name, path, key);
+ }
+ });
+ }
+
+ private Integer getKarafPort(State state, String name, String path, final String key) {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ File f = new File(instance.loc, path);
+ try {
+ return FileLockUtils.execute(f, new FileLockUtils.CallableWithProperties<Integer>() {
+ public Integer call(org.apache.felix.utils.properties.Properties properties) throws IOException {
+ return Integer.parseInt(properties.get(key).toString());
+ }
+ });
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ private void setKarafPort(final String name, final String path, final String key, final int port) throws IOException {
+ execute(new Task<Object>() {
+ public Object call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ checkPid(instance);
+ if (instance.pid != 0) {
+ throw new IllegalStateException("Instance is not stopped");
+ }
+ File f = new File(instance.loc, path);
+ FileLockUtils.execute(f, new FileLockUtils.RunnableWithProperties() {
+ public void run(org.apache.felix.utils.properties.Properties properties) throws IOException {
+ properties.put(key, Integer.toString(port));
+ }
+ });
+ return null;
+ }
+ });
+ }
+
+ boolean isInstanceRoot(final String name) {
+ return execute(new Task<Boolean>() {
+ public Boolean call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ return instance.root;
+ }
+ });
+ }
+
+ String getInstanceLocation(final String name) {
+ return execute(new Task<String>() {
+ public String call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ return instance.loc;
+ }
+ });
+ }
+
+ int getInstancePid(final String name) {
+ return execute(new Task<Integer>() {
+ public Integer call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ checkPid(instance);
+ return instance.pid;
+ }
+ });
+ }
+
+ String getInstanceJavaOpts(final String name) {
+ return execute(new Task<String>() {
+ public String call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ return instance.opts;
+ }
+ });
+ }
+
+ void changeInstanceJavaOpts(final String name, final String opts) {
+ execute(new Task<String>() {
+ public String call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ instance.opts = opts;
+ return null;
+ }
+ });
+ }
+
+ String getInstanceState(final String name) {
+ return execute(new Task<String>() {
+ public String call(State state) throws IOException {
+ InstanceState instance = state.instances.get(name);
+ if (instance == null) {
+ throw new IllegalArgumentException("Instance " + name + " not found");
+ }
+ int port = getKarafPort(state, name, "etc/org.apache.karaf.shell.cfg", "sshPort");
+ if (!new File(instance.loc).isDirectory() || port <= 0) {
+ return Instance.ERROR;
+ }
+ checkPid(instance);
+ if (instance.pid == 0) {
+ return Instance.STOPPED;
+ } else {
+ try {
+ Socket s = new Socket("localhost", port);
+ s.close();
+ return Instance.STARTED;
+ } catch (Exception e) {
+ // ignore
+ }
+ return Instance.STARTING;
+ }
+ }
+ });
+ }
+
+ private boolean deleteFile(File fileToDelete) {
+ if (fileToDelete == null || !fileToDelete.exists()) {
+ return true;
+ }
+ boolean result = true;
+ if (fileToDelete.isDirectory()) {
+ File[] files = fileToDelete.listFiles();
+ if (files == null) {
+ result = false;
+ } else {
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ if (file.getName().equals(".") || file.getName().equals("..")) {
+ continue;
+ }
+ if (file.isDirectory()) {
+ result &= deleteFile(file);
+ } else {
+ result &= file.delete();
+ }
+ }
+ }
+ }
+ result &= fileToDelete.delete();
+ return result;
+ }
+
+ private void copyResourceToDir(File target, String resource, boolean printOutput) throws IOException {
+ File outFile = new File(target, resource);
+ if( !outFile.exists() ) {
+ logInfo("Creating file: %s", printOutput, outFile.getPath());
+ InputStream is = getClass().getClassLoader().getResourceAsStream("org/apache/karaf/instance/resources/" + resource);
+ try {
+ // Read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine() ) {
+ String line = scanner.nextLine();
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(is);
+ }
+ }
+ }
+
+ private void println(String st) {
+ System.out.println(st);
+ }
+
+ protected static Properties loadPropertiesFile(URL configPropURL) throws Exception {
+ // Read the properties file.
+ Properties configProps = new Properties();
+ InputStream is = null;
+ try {
+ is = configPropURL.openConnection().getInputStream();
+ configProps.load(is);
+ is.close();
+ }
+ catch (Exception ex) {
+ System.err.println(
+ "Error loading config properties from " + configPropURL);
+ System.err.println("Main: " + ex);
+ try {
+ if (is != null) is.close();
+ }
+ catch (IOException ex2) {
+ // Nothing we can do.
+ }
+ return null;
+ }
+ return configProps;
+ }
+
+ private void filterResource(File basedir, String path, HashMap<String, String> props) throws IOException {
+ File file = new File(basedir, path);
+ File bak = new File(basedir, path + BACKUP_EXTENSION);
+ if (!file.exists()) {
+ return;
+ }
+ // rename the file to the backup one
+ file.renameTo(bak);
+ // copy and filter the bak file back to the original name
+ copyAndFilterResource(new FileInputStream(bak), new FileOutputStream(file), props);
+ // remove the bak file
+ bak.delete();
+ }
+
+ private void copyFilteredResourceToDir(File target, String resource, HashMap<String, String> props, boolean printOutput) throws IOException {
+ File outFile = new File(target, resource);
+ if( !outFile.exists() ) {
+ logInfo("Creating file: %s", printOutput, outFile.getPath());
+ InputStream is = getClass().getClassLoader().getResourceAsStream("org/apache/karaf/instance/resources/" + resource);
+ copyAndFilterResource(is, new FileOutputStream(outFile), props);
+ }
+ }
+
+ private void copyAndFilterResource(InputStream source, OutputStream target, HashMap<String, String> props) throws IOException {
+ try {
+ // read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(target);
+ try {
+ Scanner scanner = new Scanner(source);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ line = filter(line, props);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(source);
+ }
+ }
+
+ private void safeClose(InputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private void safeClose(OutputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private String filter(String line, HashMap<String, String> props) {
+ for (Map.Entry<String, String> i : props.entrySet()) {
+ int p1 = line.indexOf(i.getKey());
+ if( p1 >= 0 ) {
+ String l1 = line.substring(0, p1);
+ String l2 = line.substring(p1+i.getKey().length());
+ line = l1+i.getValue()+l2;
+ }
+ }
+ return line;
+ }
+
+ private void mkdir(File karafBase, String path, boolean printOutput) {
+ File file = new File(karafBase, path);
+ if( !file.exists() ) {
+ logInfo("Creating dir: %s", printOutput, file.getPath());
+ file.mkdirs();
+ }
+ }
+
+ private int chmod(File serviceFile, String mode) throws IOException {
+ java.lang.ProcessBuilder builder = new java.lang.ProcessBuilder();
+ builder.command("chmod", mode, serviceFile.getCanonicalPath());
+ java.lang.Process p = builder.start();
+
+ // gnodet: Fix SMX4KNL-46: cpu goes to 100% after running the 'admin create' command
+ // Not sure exactly what happens, but commenting the process io redirection seems
+ // to work around the problem.
+ //
+ //PumpStreamHandler handler = new PumpStreamHandler(io.inputStream, io.outputStream, io.errorStream);
+ //handler.attach(p);
+ //handler.start();
+ try {
+ return p.waitFor();
+ } catch (InterruptedException e) {
+ throw (IOException) new InterruptedIOException().initCause(e);
+ }
+ //handler.stop();
+ }
+
+ private void copy(File source, File destination) throws IOException {
+ if (source.getName().equals("cache.lock")) {
+ // ignore cache.lock file
+ return;
+ }
+ if (source.getName().equals("lock")) {
+ // ignore lock file
+ return;
+ }
+ if (source.getName().matches("transaction_\\d+\\.log")) {
+ // ignore active txlog files
+ return;
+ }
+ if (source.isDirectory()) {
+ if (!destination.exists()) {
+ destination.mkdirs();
+ }
+ String[] children = source.list();
+ for (String child : children) {
+ if (!child.contains("instances") && !child.contains("lib"))
+ copy(new File(source, child), new File(destination, child));
+ }
+ } else {
+ InputStream in = new FileInputStream(source);
+ OutputStream out = new FileOutputStream(destination);
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = in.read(buffer)) > 0) {
+ out.write(buffer, 0, length);
+ }
+ in.close();
+ out.close();
+ }
+ }
+
+ private static final String DELIM_START = "${";
+ private static final String DELIM_STOP = "}";
+
+ protected static String substVars(String val, String currentKey,
+ Map<String, String> cycleMap, Properties configProps)
+ throws IllegalArgumentException {
+ // If there is currently no cycle map, then create
+ // one for detecting cycles for this invocation.
+ if (cycleMap == null) {
+ cycleMap = new HashMap<String, String>();
+ }
+
+ // Put the current key in the cycle map.
+ cycleMap.put(currentKey, currentKey);
+
+ // Assume we have a value that is something like:
+ // "leading ${foo.${bar}} middle ${baz} trailing"
+
+ // Find the first ending '}' variable delimiter, which
+ // will correspond to the first deepest nested variable
+ // placeholder.
+ int stopDelim = val.indexOf(DELIM_STOP);
+
+ // Find the matching starting "${" variable delimiter
+ // by looping until we find a start delimiter that is
+ // greater than the stop delimiter we have found.
+ int startDelim = val.indexOf(DELIM_START);
+ while (stopDelim >= 0) {
+ int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
+ if ((idx < 0) || (idx > stopDelim)) {
+ break;
+ } else if (idx < stopDelim) {
+ startDelim = idx;
+ }
+ }
+
+ // If we do not have a start or stop delimiter, then just
+ // return the existing value.
+ if ((startDelim < 0) && (stopDelim < 0)) {
+ return val;
+ }
+ // At this point, we found a stop delimiter without a start,
+ // so throw an exception.
+ else if (((startDelim < 0) || (startDelim > stopDelim))
+ && (stopDelim >= 0)) {
+ throw new IllegalArgumentException(
+ "stop delimiter with no start delimiter: "
+ + val);
+ }
+
+ // At this point, we have found a variable placeholder so
+ // we must perform a variable substitution on it.
+ // Using the start and stop delimiter indices, extract
+ // the first, deepest nested variable placeholder.
+ String variable =
+ val.substring(startDelim + DELIM_START.length(), stopDelim);
+
+ // Verify that this is not a recursive variable reference.
+ if (cycleMap.get(variable) != null) {
+ throw new IllegalArgumentException(
+ "recursive variable reference: " + variable);
+ }
+
+ // Get the value of the deepest nested variable placeholder.
+ // Try to configuration properties first.
+ String substValue = (configProps != null)
+ ? configProps.getProperty(variable, null)
+ : null;
+ if (substValue == null) {
+ // Ignore unknown property values.
+ substValue = System.getProperty(variable, "");
+ }
+
+ // Remove the found variable from the cycle map, since
+ // it may appear more than once in the value and we don't
+ // want such situations to appear as a recursive reference.
+ cycleMap.remove(variable);
+
+ // Append the leading characters, the substituted value of
+ // the variable, and the trailing characters to get the new
+ // value.
+ val = val.substring(0, startDelim)
+ + substValue
+ + val.substring(stopDelim + DELIM_STOP.length(), val.length());
+
+ // Now perform substitution again, since there could still
+ // be substitutions to make.
+ val = substVars(val, currentKey, cycleMap, configProps);
+
+ // Return the value.
+ return val;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
new file mode 100644
index 0000000..baaedaf
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
@@ -0,0 +1,83 @@
+/*
+ * 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.instance.core.internal;
+
+import java.util.List;
+
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstancesMBean;
+
+public class InstanceToTableMapper {
+
+ private InstanceToTableMapper() {
+ }
+
+ private static CompositeDataSupport mapInstance(Instance instance, CompositeType comp) throws OpenDataException {
+ String state;
+ try {
+ state = instance.getState();
+ } catch (Exception e) {
+ state = "Error";
+ }
+ Object[] itemValues = new Object[] {instance.getPid(), instance.getName(), instance.isRoot(),
+ instance.getSshPort(), instance.getRmiRegistryPort(),
+ instance.getRmiServerPort(), state, instance.getLocation(),
+ instance.getJavaOpts()};
+ return new CompositeDataSupport(comp, InstancesMBean.INSTANCE, itemValues);
+ }
+
+ private static CompositeType createRowType() throws OpenDataException {
+ String desc = "This type describes Karaf instance";
+ OpenType<?>[] itemTypes = new OpenType[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN,
+ SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.INTEGER,
+ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING};
+ String[] descriptions = new String[] {"The Process ID of the instance or 0 if not running",
+ "The name of the instance", "Whether the instance is root",
+ "The SSH port that can be used to connect to the instance",
+ "The RMI registry port that can be used to manage the instance",
+ "The RMI server port that can be used to manage the instance",
+ "The state of the instance", "The location of the instance",
+ "The Java options of the instance"};
+ CompositeType comp = new CompositeType("Instances", desc, InstancesMBean.INSTANCE, descriptions, itemTypes);
+ return comp;
+ }
+
+ public static TabularData tableFrom(List<Instance> instances) {
+ try {
+ CompositeType rowType = createRowType();
+ TabularType tableType = new TabularType("Instances", "Table of all Karaf instances", rowType,
+ new String[] {InstancesMBean.INSTANCE_NAME});
+ TabularDataSupport table = new TabularDataSupport(tableType);
+ for (Instance instance : instances) {
+ CompositeDataSupport row = mapInstance(instance, rowType);
+ table.put(row);
+ }
+ return table;
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Error building instance table", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
new file mode 100644
index 0000000..b95e4dc
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstancesMBeanImpl.java
@@ -0,0 +1,224 @@
+/*
+ * 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.instance.core.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import javax.management.openmbean.TabularData;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.apache.karaf.instance.core.InstancesMBean;
+
+public class InstancesMBeanImpl extends StandardMBean implements InstancesMBean {
+
+ static final String DEBUG_OPTS = " -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005";
+ static final String DEFAULT_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote";
+
+ private org.apache.karaf.instance.core.InstanceService instanceService;
+
+ public InstancesMBeanImpl(org.apache.karaf.instance.core.InstanceService instanceService) throws NotCompliantMBeanException {
+ super(InstancesMBean.class);
+ this.instanceService = instanceService;
+ }
+
+ public int createInstance(String name, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, String features, String featureURLs)
+ throws MBeanException {
+ try {
+ if ("".equals(location)) {
+ location = null;
+ }
+ if ("".equals(javaOpts)) {
+ javaOpts = null;
+ }
+
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts,
+ parseStringList(featureURLs), parseStringList(features));
+
+ Instance inst = instanceService.createInstance(name, settings, false);
+ if (inst != null) {
+ return inst.getPid();
+ } else {
+ return -1;
+ }
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void changeSshPort(String name, int port) throws MBeanException {
+ try {
+ getExistingInstance(name).changeSshPort(port);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void changeRmiRegistryPort(String name, int port) throws MBeanException {
+ try {
+ getExistingInstance(name).changeRmiRegistryPort(port);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void changeRmiServerPort(String name, int port) throws MBeanException {
+ try {
+ getExistingInstance(name).changeRmiServerPort(port);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void changeJavaOpts(String name, String javaOpts) throws MBeanException {
+ try {
+ getExistingInstance(name).changeJavaOpts(javaOpts);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void destroyInstance(String name) throws MBeanException {
+ try {
+ getExistingInstance(name).destroy();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void startInstance(String name) throws MBeanException {
+ try {
+ getExistingInstance(name).start(null);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void startInstance(String name, String opts) throws MBeanException {
+ try {
+ getExistingInstance(name).start(opts);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void startInstance(String name, String opts, boolean wait, boolean debug) throws MBeanException {
+ try {
+ Instance child = getExistingInstance(name);
+ String options = opts;
+ if (options == null) {
+ options = child.getJavaOpts();
+ }
+ if (options == null) {
+ options = DEFAULT_OPTS;
+ }
+ if (debug) {
+ options += DEBUG_OPTS;
+ }
+ if (wait) {
+ String state = child.getState();
+ if (Instance.STOPPED.equals(state)) {
+ child.start(opts);
+ }
+ if (!Instance.STARTED.equals(state)) {
+ do {
+ Thread.sleep(500);
+ state = child.getState();
+ } while (Instance.STARTING.equals(state));
+ }
+ } else {
+ child.start(opts);
+ }
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void stopInstance(String name) throws MBeanException {
+ try {
+ getExistingInstance(name).stop();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void renameInstance(String originalName, String newName) throws MBeanException {
+ try {
+ instanceService.renameInstance(originalName, newName, false);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void renameInstance(String originalName, String newName, boolean verbose) throws MBeanException {
+ try {
+ instanceService.renameInstance(originalName, newName, verbose);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void cloneInstance(String name, String cloneName, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts) throws MBeanException {
+ try {
+ if ("".equals(location)) {
+ location = null;
+ }
+ if ("".equals(javaOpts)) {
+ javaOpts = null;
+ }
+
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, null, null);
+
+ instanceService.cloneInstance(name, cloneName, settings, false);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public TabularData getInstances() throws MBeanException {
+ List<Instance> instances = Arrays.asList(instanceService.getInstances());
+ TabularData table = InstanceToTableMapper.tableFrom(instances);
+ return table;
+ }
+
+ private Instance getExistingInstance(String name) {
+ Instance i = instanceService.getInstance(name);
+ if (i == null) {
+ throw new IllegalArgumentException("Instance '" + name + "' does not exist");
+ }
+ return i;
+ }
+
+ private List<String> parseStringList(String value) {
+ List<String> list = new ArrayList<String>();
+ if (value != null) {
+ for (String el : value.split(",")) {
+ String trimmed = el.trim();
+ if (trimmed.length() == 0) {
+ continue;
+ }
+ list.add(trimmed);
+ }
+ }
+ return list;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..a50db46
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/osgi/Activator.java
@@ -0,0 +1,35 @@
+/*
+ * 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.instance.core.internal.osgi;
+
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.instance.core.internal.InstanceServiceImpl;
+import org.apache.karaf.instance.core.internal.InstancesMBeanImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doStart() throws Exception {
+ InstanceService instanceService = new InstanceServiceImpl();
+ register(InstanceService.class, instanceService);
+
+ InstancesMBeanImpl mbean = new InstancesMBeanImpl(instanceService);
+ registerMBean(mbean, "type=instance");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/main/Execute.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/main/Execute.java b/instance/src/main/java/org/apache/karaf/instance/main/Execute.java
new file mode 100644
index 0000000..591873e
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/main/Execute.java
@@ -0,0 +1,171 @@
+/*
+ * 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.instance.main;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.karaf.instance.command.ChangeOptsCommand;
+import org.apache.karaf.instance.command.ChangeRmiRegistryPortCommand;
+import org.apache.karaf.instance.command.ChangeRmiServerPortCommand;
+import org.apache.karaf.instance.command.ChangeSshPortCommand;
+import org.apache.karaf.instance.command.CloneCommand;
+import org.apache.karaf.instance.command.CreateCommand;
+import org.apache.karaf.instance.command.DestroyCommand;
+import org.apache.karaf.instance.command.InstanceCommandSupport;
+import org.apache.karaf.instance.command.ListCommand;
+import org.apache.karaf.instance.command.RenameCommand;
+import org.apache.karaf.instance.command.StartCommand;
+import org.apache.karaf.instance.command.StatusCommand;
+import org.apache.karaf.instance.command.StopCommand;
+import org.apache.karaf.instance.core.internal.InstanceServiceImpl;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.impl.action.command.DefaultActionPreparator;
+import org.fusesource.jansi.AnsiConsole;
+
+public class Execute {
+ static Class<? extends Action> x = CreateCommand.class;
+ private static final Class<?>[] COMMAND_CLASSES = new Class[]{
+ ChangeOptsCommand.class,
+ ChangeRmiRegistryPortCommand.class,
+ ChangeRmiServerPortCommand.class,
+ ChangeSshPortCommand.class,
+ CloneCommand.class,
+ CreateCommand.class,
+ DestroyCommand.class,
+ ListCommand.class,
+ RenameCommand.class,
+ StartCommand.class,
+ StatusCommand.class,
+ StopCommand.class};
+ private static final Map<String, Class<?>> COMMANDS = new TreeMap<String, Class<?>>();
+
+ static {
+ for (Class<?> c : COMMAND_CLASSES) {
+ Command ann = c.getAnnotation(Command.class);
+ if (ann == null) {
+ continue;
+ }
+ COMMANDS.put(ann.name(), c);
+ }
+ }
+
+ // For testing
+ static boolean exitAllowed = true;
+
+ /**
+ * Environment variable for specifying extra options to the Karaf instance
+ * process kicked off from this Java process.
+ */
+ private static final String ENV_KARAF_OPTS = "KARAF_OPTS";
+
+ /**
+ * System property for specifying extra options to the Karaf instance
+ * process kicked off from this Java process.
+ */
+ private static final String PROP_KARAF_OPTS = "karaf.opts";
+
+ public static void main(String[] args) throws Exception {
+ AnsiConsole.systemInstall();
+
+ if (args.length == 0) {
+ listCommands();
+ exit(0);
+ }
+ String commandName = args[0];
+ Class<?> cls = COMMANDS.get(commandName);
+ if (cls == null) {
+ System.err.println("Command not found: " + commandName);
+ exit(-1);
+ }
+
+ String storage = System.getProperty("karaf.instances");
+ if (storage == null) {
+ System.err.println("System property 'karaf.instances' is not set. \n" +
+ "This property needs to be set to the full path of the instance.properties file.");
+ exit(-2);
+ }
+ File storageFile = new File(storage);
+ System.setProperty("user.dir", storageFile.getParentFile().getParentFile().getCanonicalPath());
+
+ try {
+ String karafOpts = System.getenv(ENV_KARAF_OPTS);
+ if (karafOpts != null) {
+ System.setProperty(PROP_KARAF_OPTS, karafOpts);
+ }
+ } catch (Exception e) {
+ System.err.println("Could not read KARAF_OPTS environment variable: " + e.getMessage());
+ if (System.getProperty("karaf.showStackTrace") != null) {
+ throw e;
+ }
+ }
+
+ Object command = cls.newInstance();
+ if (command instanceof InstanceCommandSupport) {
+ try {
+ execute((InstanceCommandSupport) command, storageFile, args);
+ } catch (Exception e) {
+ System.err.println("Error execution command '" + commandName + "': " + e.getMessage());
+ if (System.getProperty("karaf.showStackTrace") != null) {
+ throw e;
+ }
+ }
+ } else {
+ System.err.println("Not an instance command: " + commandName);
+ exit(-3);
+ }
+ }
+
+ static void execute(InstanceCommandSupport command, File storageFile, String[] args) throws Exception {
+ DefaultActionPreparator dap = new DefaultActionPreparator();
+ List<Object> params = new ArrayList<Object>(Arrays.asList(args));
+ params.remove(0); // this is the actual command name
+
+ if (!dap.prepare(command, null, params)) {
+ return;
+ }
+
+ InstanceServiceImpl instanceService = new InstanceServiceImpl();
+ instanceService.setStorageLocation(storageFile);
+ command.setInstanceService(instanceService);
+ command.execute();
+ }
+
+ private static void listCommands() {
+ System.out.println("Available commands:");
+ for (Map.Entry<String, Class<?>> entry : COMMANDS.entrySet()) {
+ Command ann = entry.getValue().getAnnotation(Command.class);
+ System.out.printf(" %s - %s\n", entry.getKey(), ann.description());
+ }
+
+ System.out.println("Type 'command --help' for more help on the specified command.");
+ }
+
+ private static void exit(int rc) {
+ if (exitAllowed) {
+ System.exit(rc);
+ } else {
+ throw new RuntimeException("" + rc);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/Process.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/Process.java b/instance/src/main/java/org/apache/karaf/jpm/Process.java
new file mode 100644
index 0000000..2bd3b36
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/Process.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jpm;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * Interface representing a process
+ */
+public interface Process extends Serializable {
+
+ /**
+ * Retrieves the PID of the process
+ * @return the pid
+ */
+ int getPid();
+
+ /**
+ * Check if this process is still running
+ * @return <code>true</code> if the process is running
+ * @throws IOException if an error occurs
+ */
+ boolean isRunning() throws IOException;
+
+ /**
+ * Destroy the process.
+ *
+ * @throws IOException
+ */
+ void destroy() throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java b/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilder.java
new file mode 100644
index 0000000..2b6c612
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilder.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.jpm;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Interface used to create new processes.
+ */
+public interface ProcessBuilder {
+
+ /**
+ * Specified the current directory to run the command from
+ *
+ * @param dir the directory to run the command from
+ * @return the ProcessBuilder instance
+ */
+ ProcessBuilder directory(File dir);
+
+ /**
+ * Set the command to execute
+ *
+ * @param command the command to execute
+ * @return the ProcessBuilder instance
+ */
+ ProcessBuilder command(String command);
+
+ /**
+ * Create and start the process
+ *
+ * @return the process that has been started
+ * @throws IOException if the process can not be created
+ */
+ org.apache.karaf.jpm.Process start() throws IOException;
+
+ /**
+ * Attach to an existing process
+ *
+ * @return the process that has been attached
+ * @throws IOException if the process can not be attached to
+ */
+ org.apache.karaf.jpm.Process attach(int pid) throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java b/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
new file mode 100644
index 0000000..baa563b
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/ProcessBuilderFactory.java
@@ -0,0 +1,25 @@
+/*
+ * 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.jpm;
+
+
+/**
+ * Factory for process builders.
+ */
+public interface ProcessBuilderFactory {
+ ProcessBuilder newBuilder();
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
new file mode 100644
index 0000000..12a6905
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderFactoryImpl.java
@@ -0,0 +1,27 @@
+/*
+ * 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.jpm.impl;
+
+import org.apache.karaf.jpm.ProcessBuilder;
+import org.apache.karaf.jpm.ProcessBuilderFactory;
+
+public class ProcessBuilderFactoryImpl implements ProcessBuilderFactory {
+
+ public ProcessBuilder newBuilder() {
+ return new ProcessBuilderImpl();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.java
new file mode 100644
index 0000000..08f4407
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessBuilderImpl.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.jpm.impl;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.karaf.jpm.Process;
+import org.apache.karaf.jpm.ProcessBuilder;
+
+
+public class ProcessBuilderImpl implements ProcessBuilder {
+
+ private File dir;
+ private String command;
+
+ public ProcessBuilder directory(File dir) {
+ this.dir = dir;
+ return this;
+ }
+
+ public ProcessBuilder command(String command) {
+ this.command = command;
+ return this;
+ }
+
+ public Process start() throws IOException {
+ return ProcessImpl.create(dir, command);
+ }
+
+ public Process attach(int pid) throws IOException {
+ return ProcessImpl.attach(pid);
+ }
+}
[14/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
deleted file mode 100644
index ad4cc85..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.Comparator;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.BundleNamespace;
-import org.osgi.framework.namespace.PackageNamespace;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.resource.Capability;
-
-public class CandidateComparator implements Comparator<Capability>
-{
- public int compare(Capability cap1, Capability cap2)
- {
- int c = 0;
- // Always prefer system bundle
- if (cap1 instanceof BundleCapability && !(cap2 instanceof BundleCapability)) {
- c = -1;
- } else if (!(cap1 instanceof BundleCapability) && cap2 instanceof BundleCapability) {
- c = 1;
- }
- // Compare revision capabilities.
- if ((c == 0) && cap1.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE))
- {
- c = ((Comparable) cap1.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE))
- .compareTo(cap2.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE));
- if (c == 0)
- {
- Version v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
- Version v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
- // Compare these in reverse order, since we want
- // highest version to have priority.
- c = compareVersions(v2, v1);
- }
- }
- // Compare package capabilities.
- else if ((c == 0) && cap1.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
- {
- c = ((Comparable) cap1.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))
- .compareTo(cap2.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
- if (c == 0)
- {
- Version v1 = (!cap1.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap1.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- Version v2 = (!cap2.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap2.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- // Compare these in reverse order, since we want
- // highest version to have priority.
- c = compareVersions(v2, v1);
- // if same version, rather compare on the bundle version
- if (c == 0)
- {
- v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
- v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
- // Compare these in reverse order, since we want
- // highest version to have priority.
- c = compareVersions(v2, v1);
- }
- }
- }
- // Compare feature capabilities
- else if ((c == 0) && cap1.getNamespace().equals(FeatureNamespace.FEATURE_NAMESPACE))
- {
- c = ((Comparable) cap1.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE))
- .compareTo(cap2.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE));
- if (c == 0)
- {
- Version v1 = (!cap1.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap1.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- Version v2 = (!cap2.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE))
- ? Version.emptyVersion
- : (Version) cap2.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- // Compare these in reverse order, since we want
- // highest version to have priority.
- c = compareVersions(v2, v1);
- }
- }
- return c;
- }
-
- private int compareVersions(Version v1, Version v2) {
- int c = v1.getMajor() - v2.getMajor();
- if (c != 0) {
- return c;
- }
- c = v1.getMinor() - v2.getMinor();
- if (c != 0) {
- return c;
- }
- c = v1.getMicro() - v2.getMicro();
- if (c != 0) {
- return c;
- }
- String q1 = cleanQualifierForComparison(v1.getQualifier());
- String q2 = cleanQualifierForComparison(v2.getQualifier());
- return q1.compareTo(q2);
- }
-
- private String cleanQualifierForComparison(String qualifier) {
- return qualifier.replaceAll("(redhat-[0-9]{3})([0-9]{3})", "$1-$2");
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
deleted file mode 100644
index bfe9b40..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Resource;
-
-public class CapabilityImpl extends BaseClause implements Capability {
-
- private final Resource m_resource;
- private final String m_namespace;
- private final Map<String, String> m_dirs;
- private final Map<String, Object> m_attrs;
- private final List<String> m_uses;
- private final List<List<String>> m_includeFilter;
- private final List<List<String>> m_excludeFilter;
- private final Set<String> m_mandatory;
-
- public CapabilityImpl(Capability capability) {
- this(null, capability.getNamespace(), capability.getDirectives(), capability.getAttributes());
- }
-
- public CapabilityImpl(Resource resource, String namespace,
- Map<String, String> dirs, Map<String, Object> attrs) {
- m_namespace = namespace;
- m_resource = resource;
- m_dirs = dirs;
- m_attrs = attrs;
-
- // Find all export directives: uses, mandatory, include, and exclude.
-
- List<String> uses = Collections.emptyList();
- String value = m_dirs.get(Constants.USES_DIRECTIVE);
- if (value != null) {
- // Parse these uses directive.
- StringTokenizer tok = new StringTokenizer(value, ",");
- uses = new ArrayList<String>(tok.countTokens());
- while (tok.hasMoreTokens()) {
- uses.add(tok.nextToken().trim());
- }
- }
- m_uses = uses;
-
- value = m_dirs.get(Constants.INCLUDE_DIRECTIVE);
- if (value != null) {
- List<String> filters = ResourceBuilder.parseDelimitedString(value, ",");
- m_includeFilter = new ArrayList<List<String>>(filters.size());
- for (String filter : filters) {
- List<String> substrings = SimpleFilter.parseSubstring(filter);
- m_includeFilter.add(substrings);
- }
- } else {
- m_includeFilter = null;
- }
-
- value = m_dirs.get(Constants.EXCLUDE_DIRECTIVE);
- if (value != null) {
- List<String> filters = ResourceBuilder.parseDelimitedString(value, ",");
- m_excludeFilter = new ArrayList<List<String>>(filters.size());
- for (String filter : filters) {
- List<String> substrings = SimpleFilter.parseSubstring(filter);
- m_excludeFilter.add(substrings);
- }
- } else {
- m_excludeFilter = null;
- }
-
- Set<String> mandatory = Collections.emptySet();
- value = m_dirs.get(Constants.MANDATORY_DIRECTIVE);
- if (value != null) {
- List<String> names = ResourceBuilder.parseDelimitedString(value, ",");
- mandatory = new HashSet<String>(names.size());
- for (String name : names) {
- // If attribute exists, then record it as mandatory.
- if (m_attrs.containsKey(name)) {
- mandatory.add(name);
- }
- // Otherwise, report an error.
- else {
- throw new IllegalArgumentException("Mandatory attribute '" + name + "' does not exist.");
- }
- }
- }
- m_mandatory = mandatory;
- }
-
- public Resource getResource() {
- return m_resource;
- }
-
- public String getNamespace() {
- return m_namespace;
- }
-
- public Map<String, String> getDirectives() {
- return m_dirs;
- }
-
- public Map<String, Object> getAttributes() {
- return m_attrs;
- }
-
- public boolean isAttributeMandatory(String name) {
- return !m_mandatory.isEmpty() && m_mandatory.contains(name);
- }
-
- public List<String> getUses() {
- return m_uses;
- }
-
- public boolean isIncluded(String name) {
- if ((m_includeFilter == null) && (m_excludeFilter == null)) {
- return true;
- }
-
- // Get the class name portion of the target class.
- String className = getClassName(name);
-
- // If there are no include filters then all classes are included
- // by default, otherwise try to find one match.
- boolean included = (m_includeFilter == null);
- for (int i = 0; !included && m_includeFilter != null && i < m_includeFilter.size(); i++) {
- included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
- }
-
- // If there are no exclude filters then no classes are excluded
- // by default, otherwise try to find one match.
- boolean excluded = false;
- for (int i = 0; (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size()); i++) {
- excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
- }
- return included && !excluded;
- }
-
- private static String getClassName(String className) {
- if (className == null) {
- className = "";
- }
- return (className.lastIndexOf('.') < 0) ? "" : className.substring(className.lastIndexOf('.') + 1);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
deleted file mode 100644
index 4c5656d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-
-public class CapabilitySet
-{
- private final Map<String, Map<Object, Set<Capability>>> m_indices;
- private final Set<Capability> m_capSet = new HashSet<Capability>();
-
-public void dump()
-{
- for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
- {
- boolean header1 = false;
- for (Entry<Object, Set<Capability>> entry2 : entry.getValue().entrySet())
- {
- boolean header2 = false;
- for (Capability cap : entry2.getValue())
- {
- if (!header1)
- {
- System.out.println(entry.getKey() + ":");
- header1 = true;
- }
- if (!header2)
- {
- System.out.println(" " + entry2.getKey());
- header2 = true;
- }
- System.out.println(" " + cap);
- }
- }
- }
-}
-
- public CapabilitySet(List<String> indexProps)
- {
- m_indices = new TreeMap<String, Map<Object, Set<Capability>>>();
- for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
- {
- m_indices.put(
- indexProps.get(i), new HashMap<Object, Set<Capability>>());
- }
- }
-
- public void addCapability(Capability cap)
- {
- m_capSet.add(cap);
-
- // Index capability.
- for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
- {
- Object value = cap.getAttributes().get(entry.getKey());
- if (value != null)
- {
- if (value.getClass().isArray())
- {
- value = convertArrayToList(value);
- }
-
- Map<Object, Set<Capability>> index = entry.getValue();
-
- if (value instanceof Collection)
- {
- Collection c = (Collection) value;
- for (Object o : c)
- {
- indexCapability(index, cap, o);
- }
- }
- else
- {
- indexCapability(index, cap, value);
- }
- }
- }
- }
-
- private void indexCapability(
- Map<Object, Set<Capability>> index, Capability cap, Object capValue)
- {
- Set<Capability> caps = index.get(capValue);
- if (caps == null)
- {
- caps = new HashSet<Capability>();
- index.put(capValue, caps);
- }
- caps.add(cap);
- }
-
- public void removeCapability(Capability cap)
- {
- if (m_capSet.remove(cap))
- {
- for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
- {
- Object value = cap.getAttributes().get(entry.getKey());
- if (value != null)
- {
- if (value.getClass().isArray())
- {
- value = convertArrayToList(value);
- }
-
- Map<Object, Set<Capability>> index = entry.getValue();
-
- if (value instanceof Collection)
- {
- Collection c = (Collection) value;
- for (Object o : c)
- {
- deindexCapability(index, cap, o);
- }
- }
- else
- {
- deindexCapability(index, cap, value);
- }
- }
- }
- }
- }
-
- private void deindexCapability(
- Map<Object, Set<Capability>> index, Capability cap, Object value)
- {
- Set<Capability> caps = index.get(value);
- if (caps != null)
- {
- caps.remove(cap);
- if (caps.isEmpty())
- {
- index.remove(value);
- }
- }
- }
-
- public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
- {
- Set<Capability> matches = match(m_capSet, sf);
- return (obeyMandatory)
- ? matchMandatory(matches, sf)
- : matches;
- }
-
- private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
- {
- Set<Capability> matches = new HashSet<Capability>();
-
- if (sf.getOperation() == SimpleFilter.MATCH_ALL)
- {
- matches.addAll(caps);
- }
- else if (sf.getOperation() == SimpleFilter.AND)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For AND we calculate the intersection of each subfilter.
- // We can short-circuit the AND operation if there are no
- // remaining capabilities.
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
- {
- matches = match(caps, sfs.get(i));
- caps = matches;
- }
- }
- else if (sf.getOperation() == SimpleFilter.OR)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For OR we calculate the union of each subfilter.
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
- {
- matches.addAll(match(caps, sfs.get(i)));
- }
- }
- else if (sf.getOperation() == SimpleFilter.NOT)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For OR we calculate the union of each subfilter.
- matches.addAll(caps);
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
- {
- matches.removeAll(match(caps, sfs.get(i)));
- }
- }
- else
- {
- Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
- if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
- {
- Set<Capability> existingCaps = index.get(sf.getValue());
- if (existingCaps != null)
- {
- matches.addAll(existingCaps);
- matches.retainAll(caps);
- }
- }
- else
- {
- for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
- {
- Capability cap = it.next();
- Object lhs = cap.getAttributes().get(sf.getName());
- if (lhs != null)
- {
- if (compare(lhs, sf.getValue(), sf.getOperation()))
- {
- matches.add(cap);
- }
- }
- }
- }
- }
-
- return matches;
- }
-
- public static boolean matches(Capability cap, SimpleFilter sf)
- {
- return matchesInternal(cap, sf) && matchMandatory(cap, sf);
- }
-
- private static boolean matchesInternal(Capability cap, SimpleFilter sf)
- {
- boolean matched = true;
-
- if (sf.getOperation() == SimpleFilter.MATCH_ALL)
- {
- matched = true;
- }
- else if (sf.getOperation() == SimpleFilter.AND)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For AND we calculate the intersection of each subfilter.
- // We can short-circuit the AND operation if there are no
- // remaining capabilities.
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; matched && (i < sfs.size()); i++)
- {
- matched = matchesInternal(cap, sfs.get(i));
- }
- }
- else if (sf.getOperation() == SimpleFilter.OR)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For OR we calculate the union of each subfilter.
- matched = false;
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; !matched && (i < sfs.size()); i++)
- {
- matched = matchesInternal(cap, sfs.get(i));
- }
- }
- else if (sf.getOperation() == SimpleFilter.NOT)
- {
- // Evaluate each subfilter against the remaining capabilities.
- // For OR we calculate the union of each subfilter.
- List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
- {
- matched = !(matchesInternal(cap, sfs.get(i)));
- }
- }
- else
- {
- matched = false;
- Object lhs = cap.getAttributes().get(sf.getName());
- if (lhs != null)
- {
- matched = compare(lhs, sf.getValue(), sf.getOperation());
- }
- }
-
- return matched;
- }
-
- private static Set<Capability> matchMandatory(
- Set<Capability> caps, SimpleFilter sf)
- {
- for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
- {
- Capability cap = it.next();
- if (!matchMandatory(cap, sf))
- {
- it.remove();
- }
- }
- return caps;
- }
-
- private static boolean matchMandatory(Capability cap, SimpleFilter sf)
- {
- if (cap instanceof CapabilityImpl) {
- for (Entry<String, Object> entry : cap.getAttributes().entrySet())
- {
- if (((CapabilityImpl) cap).isAttributeMandatory(entry.getKey())
- && !matchMandatoryAttribute(entry.getKey(), sf))
- {
- return false;
- }
- }
- } else {
- String value = cap.getDirectives().get(Constants.MANDATORY_DIRECTIVE);
- if (value != null) {
- List<String> names = ResourceBuilder.parseDelimitedString(value, ",");
- for (Entry<String, Object> entry : cap.getAttributes().entrySet())
- {
- if (names.contains(entry.getKey())
- && !matchMandatoryAttribute(entry.getKey(), sf))
- {
- return false;
- }
- }
- }
-
- }
- return true;
- }
-
- private static boolean matchMandatoryAttribute(String attrName, SimpleFilter sf)
- {
- if ((sf.getName() != null) && sf.getName().equals(attrName))
- {
- return true;
- }
- else if (sf.getOperation() == SimpleFilter.AND)
- {
- List list = (List) sf.getValue();
- for (int i = 0; i < list.size(); i++)
- {
- SimpleFilter sf2 = (SimpleFilter) list.get(i);
- if ((sf2.getName() != null)
- && sf2.getName().equals(attrName))
- {
- return true;
- }
- }
- }
- return false;
- }
-
- private static final Class<?>[] STRING_CLASS = new Class[] { String.class };
-
- private static boolean compare(Object lhs, Object rhsUnknown, int op)
- {
- if (lhs == null)
- {
- return false;
- }
-
- // If this is a PRESENT operation, then just return true immediately
- // since we wouldn't be here if the attribute wasn't present.
- if (op == SimpleFilter.PRESENT)
- {
- return true;
- }
-
- // If the type is comparable, then we can just return the
- // result immediately.
- if (lhs instanceof Comparable)
- {
- // Spec says SUBSTRING is false for all types other than string.
- if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
- {
- return false;
- }
-
- Object rhs;
- if (op == SimpleFilter.SUBSTRING)
- {
- rhs = rhsUnknown;
- }
- else
- {
- try
- {
- rhs = coerceType(lhs, (String) rhsUnknown);
- }
- catch (Exception ex)
- {
- return false;
- }
- }
-
- switch (op)
- {
- case SimpleFilter.EQ :
- try
- {
- return (((Comparable) lhs).compareTo(rhs) == 0);
- }
- catch (Exception ex)
- {
- return false;
- }
- case SimpleFilter.GTE :
- try
- {
- return (((Comparable) lhs).compareTo(rhs) >= 0);
- }
- catch (Exception ex)
- {
- return false;
- }
- case SimpleFilter.LTE :
- try
- {
- return (((Comparable) lhs).compareTo(rhs) <= 0);
- }
- catch (Exception ex)
- {
- return false;
- }
- case SimpleFilter.APPROX :
- return compareApproximate(((Comparable) lhs), rhs);
- case SimpleFilter.SUBSTRING :
- return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
- default:
- throw new RuntimeException(
- "Unknown comparison operator: " + op);
- }
- }
- // Booleans do not implement comparable, so special case them.
- else if (lhs instanceof Boolean)
- {
- Object rhs;
- try
- {
- rhs = coerceType(lhs, (String) rhsUnknown);
- }
- catch (Exception ex)
- {
- return false;
- }
-
- switch (op)
- {
- case SimpleFilter.EQ :
- case SimpleFilter.GTE :
- case SimpleFilter.LTE :
- case SimpleFilter.APPROX :
- return (lhs.equals(rhs));
- default:
- throw new RuntimeException(
- "Unknown comparison operator: " + op);
- }
- }
-
- // If the LHS is not a comparable or boolean, check if it is an
- // array. If so, convert it to a list so we can treat it as a
- // collection.
- if (lhs.getClass().isArray())
- {
- lhs = convertArrayToList(lhs);
- }
-
- // If LHS is a collection, then call compare() on each element
- // of the collection until a match is found.
- if (lhs instanceof Collection)
- {
- for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); )
- {
- if (compare(iter.next(), rhsUnknown, op))
- {
- return true;
- }
- }
-
- return false;
- }
-
- // Spec says SUBSTRING is false for all types other than string.
- if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
- {
- return false;
- }
-
- // Since we cannot identify the LHS type, then we can only perform
- // equality comparison.
- try
- {
- return lhs.equals(coerceType(lhs, (String) rhsUnknown));
- }
- catch (Exception ex)
- {
- return false;
- }
- }
-
- private static boolean compareApproximate(Object lhs, Object rhs)
- {
- if (rhs instanceof String)
- {
- return removeWhitespace((String) lhs)
- .equalsIgnoreCase(removeWhitespace((String) rhs));
- }
- else if (rhs instanceof Character)
- {
- return Character.toLowerCase(((Character) lhs))
- == Character.toLowerCase(((Character) rhs));
- }
- return lhs.equals(rhs);
- }
-
- private static String removeWhitespace(String s)
- {
- StringBuffer sb = new StringBuffer(s.length());
- for (int i = 0; i < s.length(); i++)
- {
- if (!Character.isWhitespace(s.charAt(i)))
- {
- sb.append(s.charAt(i));
- }
- }
- return sb.toString();
- }
-
- private static Object coerceType(Object lhs, String rhsString) throws Exception
- {
- // If the LHS expects a string, then we can just return
- // the RHS since it is a string.
- if (lhs.getClass() == rhsString.getClass())
- {
- return rhsString;
- }
-
- // Try to convert the RHS type to the LHS type by using
- // the string constructor of the LHS class, if it has one.
- Object rhs = null;
- try
- {
- // The Character class is a special case, since its constructor
- // does not take a string, so handle it separately.
- if (lhs instanceof Character)
- {
- rhs = new Character(rhsString.charAt(0));
- }
- else
- {
- // Spec says we should trim number types.
- if ((lhs instanceof Number) || (lhs instanceof Boolean))
- {
- rhsString = rhsString.trim();
- }
- Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
- ctor.setAccessible(true);
- rhs = ctor.newInstance(new Object[] { rhsString });
- }
- }
- catch (Exception ex)
- {
- throw new Exception(
- "Could not instantiate class "
- + lhs.getClass().getName()
- + " from string constructor with argument '"
- + rhsString + "' because " + ex);
- }
-
- return rhs;
- }
-
- /**
- * This is an ugly utility method to convert an array of primitives
- * to an array of primitive wrapper objects. This method simplifies
- * processing LDAP filters since the special case of primitive arrays
- * can be ignored.
- * @param array An array of primitive types.
- * @return An corresponding array using pritive wrapper objects.
- **/
- private static List convertArrayToList(Object array)
- {
- int len = Array.getLength(array);
- List list = new ArrayList(len);
- for (int i = 0; i < len; i++)
- {
- list.add(Array.get(array, i));
- }
- return list;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
deleted file mode 100644
index e211618..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.List;
-
-import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Namespace;
-import org.osgi.resource.Resource;
-
-/**
- */
-public final class FeatureNamespace extends Namespace {
-
- public static final String FEATURE_NAMESPACE = "karaf.feature";
-
- public static final String CAPABILITY_VERSION_ATTRIBUTE = "version";
-
- /**
- * The attribute value identifying the resource
- * {@link org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi bundle.
- *
- * @see org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
- */
- public static final String TYPE_FEATURE = "karaf.feature";
-
- public static String getName(Resource resource)
- {
- List<Capability> caps = resource.getCapabilities(null);
- for (Capability cap : caps)
- {
- if (cap.getNamespace().equals(FEATURE_NAMESPACE))
- {
- return cap.getAttributes().get(FEATURE_NAMESPACE).toString();
- }
- }
- return null;
- }
-
- public static Version getVersion(Resource resource)
- {
- List<Capability> caps = resource.getCapabilities(null);
- for (Capability cap : caps)
- {
- if (cap.getNamespace().equals(FEATURE_NAMESPACE))
- {
- return (Version)
- cap.getAttributes().get(CAPABILITY_VERSION_ATTRIBUTE);
- }
- }
- return null;
- }
-
-
- private FeatureNamespace() {
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
deleted file mode 100644
index 88f08ae..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.Conditional;
-import org.apache.karaf.features.Dependency;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.internal.util.Macro;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-/**
-*/
-public class FeatureResource extends ResourceImpl {
-
- private final Feature feature;
-
- public static Resource build(Feature feature, Conditional conditional, String featureRange, Map<String, Resource> locToRes) throws BundleException {
- Feature fcond = conditional.asFeature(feature.getName(), feature.getVersion());
- FeatureResource resource = (FeatureResource) build(fcond, featureRange, locToRes);
- for (Dependency dep : conditional.getCondition()) {
- addDependency(resource, dep, featureRange);
- }
- org.apache.karaf.features.internal.model.Dependency dep = new org.apache.karaf.features.internal.model.Dependency();
- dep.setName(feature.getName());
- dep.setVersion(feature.getVersion());
- addDependency(resource, dep, featureRange);
- return resource;
- }
-
- public static Resource build(Feature feature, String featureRange, Map<String, Resource> locToRes) throws BundleException {
- FeatureResource resource = new FeatureResource(feature);
- Map<String, String> dirs = new HashMap<String, String>();
- Map<String, Object> attrs = new HashMap<String, Object>();
- attrs.put(FeatureNamespace.FEATURE_NAMESPACE, feature.getName());
- attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, VersionTable.getVersion(feature.getVersion()));
- resource.addCapability(new CapabilityImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
- for (BundleInfo info : feature.getBundles()) {
- if (!info.isDependency()) {
- Resource res = locToRes.get(info.getLocation());
- if (res == null) {
- throw new IllegalStateException("Resource not found for url " + info.getLocation());
- }
- List<Capability> caps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
- if (caps.size() != 1) {
- throw new IllegalStateException("Resource does not have a single " + IdentityNamespace.IDENTITY_NAMESPACE + " capability");
- }
- dirs = new HashMap<String, String>();
- attrs = new HashMap<String, Object>();
- attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, caps.get(0).getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
- attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
- attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((Version) caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE), true));
- resource.addRequirement(new RequirementImpl(resource, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs));
- }
- }
- for (Dependency dep : feature.getDependencies()) {
- addDependency(resource, dep, featureRange);
- }
- for (org.apache.karaf.features.Capability cap : feature.getCapabilities()) {
- resource.addCapabilities(ResourceBuilder.parseCapability(resource, cap.getValue()));
- }
- for (org.apache.karaf.features.Requirement req : feature.getRequirements()) {
- resource.addRequirements(ResourceBuilder.parseRequirement(resource, req.getValue()));
- }
- return resource;
- }
-
- protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange) {
- Map<String, String> dirs;
- Map<String, Object> attrs;
- String name = dep.getName();
- String version = dep.getVersion();
- if (version.equals("0.0.0")) {
- version = null;
- } else if (!version.startsWith("[") && !version.startsWith("(")) {
- version = Macro.transform(featureRange, version);
- }
- dirs = new HashMap<String, String>();
- attrs = new HashMap<String, Object>();
- attrs.put(FeatureNamespace.FEATURE_NAMESPACE, name);
- if (version != null) {
- attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(version));
- }
- resource.addRequirement(new RequirementImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
- }
-
- public FeatureResource(Feature feature) {
- super(feature.getName(), FeatureNamespace.TYPE_FEATURE, VersionTable.getVersion(feature.getVersion()));
- this.feature = feature;
- }
-
- public Feature getFeature() {
- return feature;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
deleted file mode 100644
index cdc00d1..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Resource;
-
-class IdentityCapability extends BaseClause implements Capability
-{
- private final Resource m_resource;
- private final Map<String, String> m_dirs;
- private final Map<String, Object> m_attrs;
-
- public IdentityCapability(Resource resource, String name, String type, Version version)
- {
- m_resource = resource;
- m_dirs = new HashMap<String, String>();
- m_attrs = new HashMap<String, Object>();
- m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
- m_attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type);
- m_attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version);
- }
-
- public String getNamespace()
- {
- return IdentityNamespace.IDENTITY_NAMESPACE;
- }
-
- public Map<String, String> getDirectives()
- {
- return m_dirs;
- }
-
- public Map<String, Object> getAttributes()
- {
- return m_attrs;
- }
-
- public Resource getResource()
- {
- return m_resource;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
deleted file mode 100644
index a4ef775..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.Map;
-
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-public class RequirementImpl extends BaseClause implements Requirement {
- private final Resource m_resource;
- private final String m_namespace;
- private final SimpleFilter m_filter;
- private final boolean m_optional;
- private final Map<String, String> m_dirs;
- private final Map<String, Object> m_attrs;
-
- public RequirementImpl(
- Resource resource, String namespace,
- Map<String, String> dirs, Map<String, Object> attrs, SimpleFilter filter) {
- m_resource = resource;
- m_namespace = namespace;
- m_dirs = dirs;
- m_attrs = attrs;
- m_filter = filter;
- // Find resolution import directives.
- m_optional = Constants.RESOLUTION_OPTIONAL.equals(m_dirs.get(Constants.RESOLUTION_DIRECTIVE));
- }
-
- public RequirementImpl(
- Resource resource, String namespace,
- Map<String, String> dirs, Map<String, Object> attrs) {
- this(resource, namespace, dirs, attrs, SimpleFilter.convert(attrs));
- }
-
- public String getNamespace() {
- return m_namespace;
- }
-
- public Map<String, String> getDirectives() {
- return m_dirs;
- }
-
- public Map<String, Object> getAttributes() {
- return m_attrs;
- }
-
- public Resource getResource() {
- return m_resource;
- }
-
- public boolean matches(Capability cap) {
- return CapabilitySet.matches(cap, getFilter());
- }
-
- public boolean isOptional() {
- return m_optional;
- }
-
- public SimpleFilter getFilter() {
- return m_filter;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
deleted file mode 100644
index e2ff793..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-import org.osgi.resource.Wiring;
-import org.osgi.service.repository.Repository;
-import org.osgi.service.resolver.HostedCapability;
-import org.osgi.service.resolver.ResolveContext;
-
-/**
-*/
-public class ResolveContextImpl extends ResolveContext {
-
- private final Set<Resource> mandatory;
- private final Set<Resource> optional;
- private final Repository repository;
- private final Map<Resource, Wiring> wirings;
- private final boolean resolveOptional;
-
- private final CandidateComparator candidateComparator = new CandidateComparator();
-
- public ResolveContextImpl(Set<Resource> mandatory,
- Set<Resource> optional,
- Repository repository,
- boolean resolveOptional) {
- this.mandatory = mandatory;
- this.optional = optional;
- this.repository = repository;
- this.wirings = new HashMap<Resource, Wiring>();
- this.resolveOptional = resolveOptional;
- }
-
- @Override
- public Collection<Resource> getMandatoryResources() {
- return mandatory;
- }
-
- @Override
- public Collection<Resource> getOptionalResources() {
- return optional;
- }
-
- @Override
- public List<Capability> findProviders(Requirement requirement) {
- List<Capability> caps = new ArrayList<Capability>();
- Map<Requirement, Collection<Capability>> resMap =
- repository.findProviders(Collections.singleton(requirement));
- Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
- if (res != null) {
- caps.addAll(res);
- }
- Collections.sort(caps, candidateComparator);
- return caps;
- }
- @Override
- public int insertHostedCapability(List capabilities, HostedCapability hostedCapability) {
- for (int i=0; i < capabilities.size(); i++) {
- Capability cap = (Capability) capabilities.get(i);
- if (candidateComparator.compare(hostedCapability, cap) <= 0) {
- capabilities.add(i, hostedCapability);
- return i;
- }
- }
- capabilities.add(hostedCapability);
- return capabilities.size() - 1;
- }
- @Override
- public boolean isEffective(Requirement requirement) {
- return resolveOptional ||
- !Constants.RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(Constants.RESOLUTION_DIRECTIVE));
- }
- @Override
- public Map<Resource, Wiring> getWirings() {
- return wirings;
- }
-}
[51/59] [abbrv] [KARAF-2852] Merge web/core and web/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java b/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
new file mode 100644
index 0000000..f1a81bb
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
@@ -0,0 +1,116 @@
+/*
+ * 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.web.management.internal;
+
+import org.apache.karaf.web.WebBundle;
+import org.apache.karaf.web.WebContainerService;
+import org.apache.karaf.web.management.WebMBean;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import javax.management.openmbean.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the Web MBean.
+ */
+public class WebMBeanImpl extends StandardMBean implements WebMBean {
+
+ private WebContainerService webContainerService;
+
+ public WebMBeanImpl() throws NotCompliantMBeanException {
+ super(WebMBean.class);
+ }
+
+ public void setWebContainerService(WebContainerService webContainerService) {
+ this.webContainerService = webContainerService;
+ }
+
+ public TabularData getWebBundles() throws MBeanException {
+ try {
+ CompositeType webType = new CompositeType("Web Bundle", "An OSGi Web bundle",
+ new String[]{"ID", "State", "Web-State", "Level", "Web-ContextPath", "Name"},
+ new String[]{"ID of the bundle",
+ "OSGi state of the bundle",
+ "Web state of the bundle",
+ "Start level of the bundle",
+ "Web context path",
+ "Name of the bundle"},
+ new OpenType[]{SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING});
+ TabularType tableType = new TabularType("Web Bundles", "Table of web bundles", webType,
+ new String[]{"ID"});
+ TabularData table = new TabularDataSupport(tableType);
+ for (WebBundle webBundle : webContainerService.list()) {
+ try {
+ CompositeData data = new CompositeDataSupport(webType,
+ new String[]{"ID", "State", "Web-State", "Level", "Web-ContextPath", "Name"},
+ new Object[]{webBundle.getBundleId(),
+ webBundle.getState(),
+ webBundle.getWebState(),
+ webBundle.getLevel(),
+ webBundle.getContextPath(),
+ webBundle.getName()});
+ table.put(data);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return table;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void start(Long bundleId) throws MBeanException {
+ try {
+ List<Long> list = new ArrayList<Long>();
+ list.add(bundleId);
+ webContainerService.start(list);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void start(List<Long> bundleIds) throws MBeanException {
+ try {
+ webContainerService.start(bundleIds);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void stop(Long bundleId) throws MBeanException {
+ try {
+ List<Long> list = new ArrayList<Long>();
+ list.add(bundleId);
+ webContainerService.stop(list);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void stop(List<Long> bundleIds) throws MBeanException {
+ try {
+ webContainerService.stop(bundleIds);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/web/src/main/resources/OSGI-INF/bundle.info b/web/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..650fee9
--- /dev/null
+++ b/web/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,16 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle provides support of the WebContainer service, which allows to manipulate the Karaf embedded web container.
+
+h1. See also
+
+Web Container - section of the Karaf User Guide
[02/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
----------------------------------------------------------------------
diff --git a/features/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
new file mode 100644
index 0000000..9536ba1
--- /dev/null
+++ b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="http://karaf.apache.org/xmlns/features/v1.0.0"
+ xmlns:tns="http://karaf.apache.org/xmlns/features/v1.0.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Karaf features mechanism. For documentation please visit the
+<a href="http://karaf.apache.org/">Karaf website</a>.
+ ]]></xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType name="features">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Root element of the Feature definition. It contains an optional attribute for
+designating the name of the repository of this feature. The Karaf shell will
+show the repository name when displaying information about the feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="repository" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional repositories where dependencies are stored.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="feature" type="tns:feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature definition.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="details" minOccurs="0" type="xs:string">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The help text shown for this feature when using the feature:info console command.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ </xs:choice>
+ <xs:attribute name="name" type="tns:featureName" use="required" />
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ <xs:attribute name="description" type="xs:string" />
+ <xs:attribute name="resolver" type="tns:resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Optional alternative resolver to use for determining the list of bundles to install for a given feature.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="install" type="tns:install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If true, marks that the feature should start automatically when placed in the deploy folder.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for the bundles in this feature different
+from the default start level defined in Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="region" type="xs:string"/>
+ </xs:complexType>
+
+ <xs:complexType name="bundle">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Deployable element to install.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this bundle different
+from the default start level defined in Karaf's config.properties.
+
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start" type="xs:boolean" default="true">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If false, leaves the bundle in resolved state rather than the default active state.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="dependency" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Mark this bundle as a dependency for the resolver.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="dependency">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Dependency of feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="tns:featureName">
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="config">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Configuration entries which should be created during feature installation. This
+configuration may be used with OSGi Configuration Admin. The element content is
+read in as a properties file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="configFile">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional configuration files which should be created during feature installation.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="finalname" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The final destination path and name for the configuration file (relative to the KARAF_BASE).
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="override" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If the configFile already exists at the finalname location, whether or not to replace it.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="featureName">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature name should be non empty string.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Resolver to use. Karaf will look for OSGi service which has following properties:
+objectClass: org.apache.karaf.features.Resolver
+name: the value
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
+dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
+command line or as part of the org.apache.karaf.features.cfg.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="features" type="tns:features" />
+
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
----------------------------------------------------------------------
diff --git a/features/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
new file mode 100644
index 0000000..7138573
--- /dev/null
+++ b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="http://karaf.apache.org/xmlns/features/v1.1.0"
+ xmlns:tns="http://karaf.apache.org/xmlns/features/v1.1.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Karaf features mechanism. For documentation please visit the
+<a href="http://karaf.apache.org/">Karaf website</a>.
+ ]]></xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType name="features">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Root element of Feature definition. It contains an required attribute for
+designating from which repository this feature should be loaded. The Karaf
+shell will show the repository name when displaying information about the feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="repository" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional repositories where dependencies are stored.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="feature" type="tns:feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature definition.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="details" minOccurs="0" type="xs:string">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The help text shown for this feature when using feature:info console command.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ </xs:choice>
+ <xs:attribute name="name" type="tns:featureName" use="required" />
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ <xs:attribute name="description" type="xs:string" />
+ <xs:attribute name="resolver" type="tns:resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Optional alternative resolver to use for determining the list of bundles to install for a given feature.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="install" type="tns:install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Marks if the feaute will be automatically started when thrown to the deploy folder.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this feature different
+from the default start level defined in Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="bundle">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Deployable element to install.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this bundle different
+from the default start level defined in the Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start" type="xs:boolean" default="true">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If false, leaves bundle in resolved state rather than the default active state.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="dependency" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Mark this bundle as a dependency for the resolver.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="dependency">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Dependency of feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="tns:featureName">
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="config">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Configuration entries which should be created during feature installation. This
+configuration may be used with OSGi Configuration Admin. The element content is
+read in as a properties file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="configFile">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional configuration files which should be created during feature installation.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="finalname" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The final destination path and name for the configuration file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="override" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If the configFile already exists at the finalname location, whether or not to replace it.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="featureName">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature name should be non empty string.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Resolver to use. Karaf will look for OSGi service which have following properties:
+objectClass: org.apache.karaf.features.Resolver
+name: the value
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
+dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
+command line or as part of the org.apache.karaf.features.cfg.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="features" type="tns:features" />
+
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
----------------------------------------------------------------------
diff --git a/features/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
new file mode 100644
index 0000000..dbc4bfa
--- /dev/null
+++ b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:tns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Karaf features mechanism. For documentation please visit the
+<a href="http://karaf.apache.org/">Karaf website</a>.
+ ]]></xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType name="features">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Root element of Feature definition. It contains an required attribute for
+designating from which repository this feature should be loaded. The Karaf
+shell will show the repository name when displaying information about the feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="repository" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional repositories where dependencies are stored.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="feature" type="tns:feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature definition.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="details" minOccurs="0" type="xs:string">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The help text shown for this feature when using feature:info console command.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ <xs:element name="conditional" type="tns:conditional" />
+ </xs:choice>
+ <xs:attribute name="name" type="tns:featureName" use="required" />
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ <xs:attribute name="description" type="xs:string" />
+ <xs:attribute name="resolver" type="tns:resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Optional alternative resolver to use for determining the list of bundles to install for a given feature.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="install" type="tns:install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Marks if the feaute will be automatically started when thrown to the deploy folder.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this feature different
+from the default start level defined in Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="conditional">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Conditional.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ <xs:element name="condition" type="tns:dependency" minOccurs="0" maxOccurs="1" />
+ </xs:choice>
+ </xs:complexType>
+
+
+ <xs:complexType name="bundle">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Deployable element to install.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this bundle different
+from the default start level defined in the Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start" type="xs:boolean" default="true">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If false, leaves bundle in resolved state rather than the default active state.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="dependency" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Mark this bundle as a dependency for the resolver.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="dependency">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Dependency of feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="tns:featureName">
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="config">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Configuration entries which should be created during feature installation. This
+configuration may be used with OSGi Configuration Admin. The element content is
+read in as a properties file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="configFile">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional configuration files which should be created during feature installation.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="finalname" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The final destination path and name for the configuration file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="override" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If the configFile already exists at the finalname location, whether or not to replace it.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="featureName">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature name should be non empty string.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Resolver to use. Karaf will look for OSGi service which have following properties:
+objectClass: org.apache.karaf.features.Resolver
+name: the value
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
+dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
+command line or as part of the org.apache.karaf.features.cfg.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="features" type="tns:features" />
+
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
----------------------------------------------------------------------
diff --git a/features/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
new file mode 100644
index 0000000..60ec8d2
--- /dev/null
+++ b/features/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="http://karaf.apache.org/xmlns/features/v1.3.0"
+ xmlns:tns="http://karaf.apache.org/xmlns/features/v1.3.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Karaf features mechanism. For documentation please visit the
+<a href="http://karaf.apache.org/">Karaf website</a>.
+ ]]></xs:documentation>
+ </xs:annotation>
+
+ <xs:complexType name="features">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Root element of Feature definition. It contains an required attribute for
+designating from which repository this feature should be loaded. The Karaf
+shell will show the repository name when displaying information about the feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="repository" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional repositories where dependencies are stored.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="feature" type="tns:feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature definition.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="feature">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="details" minOccurs="0" type="xs:string">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The help text shown for this feature when using feature:info console command.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ <xs:element name="conditional" type="tns:conditional" />
+ <xs:element name="requirement" type="tns:requirement" />
+ <xs:element name="capability" type="tns:capability" />
+ </xs:choice>
+ <xs:attribute name="name" type="tns:featureName" use="required" />
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ <xs:attribute name="description" type="xs:string" />
+ <xs:attribute name="resolver" type="tns:resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Optional alternative resolver to use for determining the list of bundles to install for a given feature.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="install" type="tns:install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Marks if the feaute will be automatically started when thrown to the deploy folder.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this feature different
+from the default start level defined in Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="conditional">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Definition of the Conditional.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="config" type="tns:config" />
+ <xs:element name="configfile" type="tns:configFile" />
+ <xs:element name="feature" type="tns:dependency" />
+ <xs:element name="bundle" type="tns:bundle" />
+ <xs:element name="condition" type="tns:dependency" minOccurs="0" maxOccurs="1" />
+ </xs:choice>
+ </xs:complexType>
+
+
+ <xs:complexType name="bundle">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Deployable element to install.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="start-level" type="xs:int">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this bundle different
+from the default start level defined in the Karaf's config.properties.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="start" type="xs:boolean" default="true">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If false, leaves bundle in resolved state rather than the default active state.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="dependency" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Mark this bundle as a dependency for the resolver.
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="dependency">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Dependency of feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="tns:featureName">
+ <xs:attribute name="version" type="xs:string" default="0.0.0" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="config">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Configuration entries which should be created during feature installation. This
+configuration may be used with OSGi Configuration Admin. The element content is
+read in as a properties file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="configFile">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional configuration files which should be created during feature installation.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="finalname" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+The final destination path and name for the configuration file.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="override" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+If the configFile already exists at the finalname location, whether or not to replace it.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="requirement">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional requirements of this feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="capability">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Additional capability of this feature.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="featureName">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Feature name should be non empty string.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="resolver">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Resolver to use. Karaf will look for OSGi service which have following properties:
+objectClass: org.apache.karaf.features.Resolver
+name: the value
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="install">
+ <xs:annotation>
+ <xs:documentation><![CDATA[
+Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
+dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
+command line or as part of the org.apache.karaf.features.cfg.
+ ]]></xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="features" type="tns:features" />
+
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/ConditionalTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/ConditionalTest.java b/features/src/test/java/org/apache/karaf/features/ConditionalTest.java
new file mode 100644
index 0000000..d5e7e46
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/ConditionalTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import junit.framework.TestCase;
+import org.apache.karaf.features.internal.service.RepositoryImpl;
+
+
+public class ConditionalTest extends TestCase {
+
+ public void testLoad() throws Exception {
+ RepositoryImpl r = new RepositoryImpl(getClass().getResource("internal/service/f06.xml").toURI());
+ // Check repo
+ Feature[] features = r.getFeatures();
+ assertNotNull(features);
+ assertEquals(1, features.length);
+ Feature feature = features[0];
+
+ assertNotNull(feature.getConditional());
+ assertEquals(1,feature.getConditional().size());
+
+ Conditional conditional = feature.getConditional().get(0);
+ assertNotNull(conditional.getCondition());
+ assertEquals(1,conditional.getCondition().size());
+ Dependency dependency = conditional.getCondition().get(0);
+ assertNotNull(dependency);
+ assertEquals(dependency.getName(),"http");
+ assertNotNull(conditional.getBundles());
+ assertEquals(1, feature.getConditional().get(0).getBundles().size());
+
+ String wrapperName = "my6/1.5.3-beta-3".replaceAll("[^A-Za-z0-9 ]", "_");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/FeatureTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/FeatureTest.java b/features/src/test/java/org/apache/karaf/features/FeatureTest.java
new file mode 100644
index 0000000..b7d4c27
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/FeatureTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+import junit.framework.TestCase;
+
+public class FeatureTest extends TestCase {
+
+ public void testValueOf() {
+ Feature feature = org.apache.karaf.features.internal.model.Feature.valueOf("name" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + "version");
+ assertEquals(feature.getName(), "name");
+ assertEquals(feature.getVersion(), "version");
+ feature = org.apache.karaf.features.internal.model.Feature.valueOf("name");
+ assertEquals(feature.getName(), "name");
+ assertEquals(feature.getVersion(), org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java b/features/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
new file mode 100644
index 0000000..a74e3d0
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
@@ -0,0 +1,429 @@
+/*
+ * 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;
+
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.apache.karaf.features.internal.service.FeaturesServiceImpl;
+import org.apache.karaf.features.internal.service.StateStorage;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class FeaturesServiceTest extends TestBase {
+ private static final String FEATURE_WITH_INVALID_BUNDLE = "<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1'><bundle>%s</bundle><bundle>zfs:unknown</bundle></feature>"
+ + " <feature name='f2'><bundle>%s</bundle></feature>"
+ + "</features>";
+
+ File dataFile;
+
+ @Before
+ public void setUp() throws IOException {
+ dataFile = File.createTempFile("features", null, null);
+ }
+
+ private URI createTempRepo(String repoContent, Object ... variables) throws IOException {
+ File tmp = File.createTempFile("karaf", ".feature");
+ PrintWriter pw = new PrintWriter(new FileWriter(tmp));
+ pw.printf(repoContent, variables);
+ pw.close();
+ return tmp.toURI();
+ }
+
+ /*
+ TODO: migrate those tests
+
+ @Test
+ public void testInstallFeature() throws Exception {
+ URI uri = createTempRepo(
+ "<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1'><bundle start='true'>bundle-f1</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ Bundle installedBundle = createDummyBundle(12345L, "bundle-f1", headers());
+ FeaturesServiceImpl svc = testAddRepository("bundle-f1", uri, bundleManager, installedBundle);
+
+ reset(bundleManager);
+
+ expect(bundleManager.installBundleIfNeeded(eq("bundle-f1"), eq(0), eq((String)null))).andReturn(new BundleInstallerResult(installedBundle, true));
+ expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile);
+ ignoreRefreshes(bundleManager);
+ replay(bundleManager);
+ svc.installFeature("f1", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
+ verify(bundleManager);
+
+ Feature[] installed = svc.listInstalledFeatures();
+ assertEquals(1, installed.length);
+ assertEquals("f1", installed[0].getName());
+ }
+
+ private FeaturesServiceImpl testAddRepository(String name, URI uri, BundleManager bundleManager,
+ Bundle installedBundle) throws IOException, BundleException, Exception {
+ expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile);
+ expect(bundleManager.installBundleIfNeeded(eq(name), eq(0), eq((String)null))).andReturn(new BundleInstallerResult(installedBundle, true)).anyTimes();
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+ Repository[] repositories = svc.listRepositories();
+ verify(bundleManager);
+
+ assertNotNull(repositories);
+ assertEquals(1, repositories.length);
+ assertNotNull(repositories[0]);
+ Feature[] features = repositories[0].getFeatures();
+ assertNotNull(features);
+ assertEquals(1, features.length);
+ assertNotNull(features[0]);
+ assertEquals("f1", features[0].getName());
+ assertNotNull(features[0].getDependencies());
+ assertEquals(0, features[0].getDependencies().size());
+ assertNotNull(features[0].getBundles());
+ assertEquals(1, features[0].getBundles().size());
+ assertEquals(name, features[0].getBundles().get(0).getLocation());
+ assertTrue(features[0].getBundles().get(0).isStart());
+ return svc;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testUninstallFeatureWithTwoVersions() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><bundle>bundle-0.1</bundle></feature>"
+ + " <feature name='f1' version='0.2'><bundle>bundle-0.1</bundle></feature>"
+ + "</features>");
+
+ Bundle bundlef101 = createDummyBundle(12345L, "bundle-0.1", headers());
+
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile).anyTimes();
+ expect(bundleManager.installBundleIfNeeded("bundle-0.1", 0, null)).andReturn(new BundleInstallerResult(bundlef101, true));
+ expect(bundleManager.installBundleIfNeeded("bundle-0.1", 0, null)).andReturn(new BundleInstallerResult(bundlef101, false));
+ expect(bundleManager.getBundleContext()).andReturn(bundleContext);
+ ignoreRefreshes(bundleManager);
+ bundleManager.uninstall(Collections.EMPTY_LIST, true);
+ EasyMock.expectLastCall().times(2);
+
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+
+ try {
+ svc.uninstallFeature("f1");
+ fail("Uninstall should have failed as feature is not installed");
+ } catch (Exception e) {
+ // ok
+ }
+
+ svc.installFeature("f1", "0.1", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
+ svc.installFeature("f1", "0.2", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
+
+ try {
+ svc.uninstallFeature("f1");
+ fail("Uninstall should have failed as feature is installed in multiple versions");
+ } catch (Exception e) {
+ // ok
+ }
+
+ svc.uninstallFeature("f1", "0.1");
+ svc.uninstallFeature("f1");
+ verify(bundleManager);
+ }
+
+ @Test
+ public void testAddAndRemoveRepository() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><bundle>bundle-f1-0.1</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ EasyMock.verify(bundleManager);
+
+ svc.addRepository(uri);
+ svc.removeRepository(uri);
+ verify(bundleManager);
+ }
+
+ // Tests install of a Repository that includes a feature
+ // with a feature dependency
+ // The dependant feature is in the same repository
+ // Tests uninstall of features
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInstallFeatureWithDependantFeatures() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><feature version='0.1'>f2</feature><bundle>bundle-f1-0.1</bundle></feature>"
+ + " <feature name='f2' version='0.1'><bundle>bundle-f2-0.1</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ Bundle bundlef101 = createDummyBundle(12345L, "bundle-f1-0.1", headers());
+ Bundle bundlef201 = createDummyBundle(54321L, "bundle-f2-0.1", headers());
+ expect(bundleManager.getDataFile(EasyMock.<String> anyObject())).andReturn(dataFile).anyTimes();
+ expect(bundleManager.installBundleIfNeeded("bundle-f1-0.1", 0, null))
+ .andReturn(new BundleInstallerResult(bundlef101, true));
+ expect(bundleManager.installBundleIfNeeded("bundle-f2-0.1", 0, null))
+ .andReturn(new BundleInstallerResult(bundlef201, true));
+ expect(bundleManager.getBundleContext()).andReturn(bundleContext).anyTimes();
+ expect(bundleContext.getBundle(12345)).andReturn(bundlef101).anyTimes();
+ ignoreRefreshes(bundleManager);
+ bundleManager.uninstall(Collections.EMPTY_LIST, true);
+
+ EasyMock.expectLastCall().anyTimes();
+ replay(bundleManager);
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+ svc.installFeature("f1", "0.1");
+ svc.uninstallFeature("f1", "0.1");
+ verify(bundleManager);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private BundleManager prepareBundleManagerForInstallUninstall(String bundleUri, String bundlename) throws Exception {
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ Bundle installedBundle = createDummyBundle(12345L, bundlename, headers());
+ expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
+ expect(bundleManager.installBundleIfNeeded(bundleUri, 0, null)).andReturn(new BundleInstallerResult(installedBundle, true));
+ expect(bundleManager.getBundleContext()).andReturn(bundleContext);
+ ignoreRefreshes(bundleManager);
+ bundleManager.uninstall(Collections.EMPTY_LIST, true);
+ EasyMock.expectLastCall().times(2);
+ return bundleManager;
+ }
+
+ @Test
+ public void testInstallFeatureWithDependantFeaturesAndVersionWithoutPreinstall() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><feature version='0.1'>f2</feature></feature>"
+ + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
+ + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = prepareBundleManagerForInstallUninstall("bundle-0.1", "bundle-0.1");
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+ svc.installFeature("f1", "0.1");
+ svc.uninstallFeature("f1", "0.1");
+ svc.uninstallFeature("f2", "0.1");
+ verify(bundleManager);
+ }
+
+ @Test
+ public void testInstallFeatureWithDependantFeaturesAndNoVersionWithoutPreinstall() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><feature>f2</feature></feature>"
+ + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
+ + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = prepareBundleManagerForInstallUninstall("bundle-0.2", "bundle-0.2");
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+ svc.installFeature("f1", "0.1");
+ svc.uninstallFeature("f1", "0.1");
+ svc.uninstallFeature("f2", "0.2");
+ verify(bundleManager);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInstallFeatureWithDependantFeaturesAndRangeWithoutPreinstall() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
+ + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
+ + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
+ + "</features>");
+
+ BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ Bundle bundleVer02 = createDummyBundle(54321L, "bundleVer02", headers());
+ expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
+ expect(bundleManager.installBundleIfNeeded("bundle-0.2", 0, null)).andReturn(new BundleInstallerResult(bundleVer02, true));
+ expect(bundleManager.getBundleContext()).andReturn(bundleContext);
+ ignoreRefreshes(bundleManager);
+ bundleManager.uninstall(Collections.EMPTY_LIST, true);
+
+ EasyMock.expectLastCall().times(2);
+
+ replay(bundleManager);
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+ svc.addRepository(uri);
+ svc.installFeature("f1", "0.1");
+ svc.uninstallFeature("f1", "0.1");
+ svc.uninstallFeature("f2", "0.2");
+ verify(bundleManager);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInstallFeatureWithDependantFeaturesAndRangeWithPreinstall() throws Exception {
+ String bundleVer01Uri = "bundle-0.1";
+ String bundleVer02Uri = "bundle-0.2";
+
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + "<feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
+ + " <feature name='f2' version='0.1'><bundle>%s</bundle></feature>"
+ + " <feature name='f2' version='0.2'><bundle>%s</bundle></feature>"
+ + "</features>", bundleVer01Uri, bundleVer02Uri);
+
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
+ replay(bundleContext);
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null);
+ svc.addRepository(uri);
+ svc.installFeature("f2", "0.1");
+ svc.installFeature("f1", "0.1");
+ svc.uninstallFeature("f1", "0.1");
+ svc.uninstallFeature("f2", "0.1");
+
+ verify(bundleContext);
+ }
+ */
+
+ @Test
+ public void testGetFeaturesShouldHandleDifferentVersionPatterns() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
+ + " <feature name='f2' version='0.1'><bundle>bundle1</bundle></feature>"
+ + " <feature name='f2' version='0.2'><bundle>bundle2</bundle></feature>"
+ + "</features>");
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
+ svc.addRepository(uri);
+
+ assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "[0.1,0.3)"));
+ assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "0.0.0"));
+ assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "0.2"));
+ assertNull(svc.getFeature("f2", "0.3"));
+ }
+
+ @Test
+ public void testInstallBatchFeatureWithFailure() throws Exception {
+ String bundle1Uri = "file:bundle1";
+ String bundle2Uri = "file:bundle2";
+
+ URI uri = createTempRepo(FEATURE_WITH_INVALID_BUNDLE, bundle1Uri, bundle2Uri);
+
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
+ replay(bundleContext);
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null, null, null, null);
+ svc.addRepository(uri);
+ try {
+ List<String> features = new ArrayList<String>();
+ for (Feature feature : svc.listFeatures()) {
+ features.add(feature.getId());
+ }
+ Collections.reverse(features);
+ svc.installFeatures(new CopyOnWriteArraySet<String>(features),
+ EnumSet.noneOf(FeaturesService.Option.class));
+ fail("Call should have thrown an exception");
+ } catch (MalformedURLException e) {
+ }
+ verify(bundleContext);
+ }
+
+ /**
+ * This test checks schema validation of submited uri.
+ */
+ @Test
+ public void testSchemaValidation() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <featur><bundle>somebundle</bundle></featur></features>");
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
+ try {
+ svc.addRepository(uri);
+ fail("exception expected");
+ } catch (Exception e) {
+ assertTrue(e.getMessage().contains("Unable to validate"));
+ }
+ }
+
+ /**
+ * This test checks feature service behavior with old, non namespaced descriptor.
+ */
+ @Test
+ public void testLoadOldFeatureFile() throws Exception {
+ URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
+ + " <feature name='f1'><bundle>file:bundle1</bundle><bundle>file:bundle2</bundle></feature>"
+ + "</features>");
+
+ FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
+ svc.addRepository(uri);
+ Feature feature = svc.getFeature("f1");
+ Assert.assertNotNull("No feature named fi found", feature);
+ List<BundleInfo> bundles = feature.getBundles();
+ Assert.assertEquals(2, bundles.size());
+ }
+
+ static class Storage extends StateStorage {
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ return null;
+ }
+ @Override
+ protected OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/RepositoryTest.java b/features/src/test/java/org/apache/karaf/features/RepositoryTest.java
new file mode 100644
index 0000000..164dc79
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/RepositoryTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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;
+
+import java.net.URI;
+
+import junit.framework.TestCase;
+import org.apache.karaf.features.internal.resolver.FeatureResource;
+import org.apache.karaf.features.internal.service.RepositoryImpl;
+import org.osgi.resource.Resource;
+
+
+public class RepositoryTest extends TestCase {
+
+ public void testLoad() throws Exception {
+ RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo1.xml").toURI());
+ // Check repo
+ URI[] repos = r.getRepositories();
+ assertNotNull(repos);
+ assertEquals(1, repos.length);
+ assertEquals(URI.create("urn:r1"), repos[0]);
+ // Check features
+ Feature[] features = r.getFeatures();
+ assertNotNull(features);
+ assertEquals(3, features.length);
+ assertNotNull(features[0]);
+ assertEquals("f1", features[0].getName());
+ assertNotNull(features[0].getConfigurations());
+ assertEquals(1, features[0].getConfigurations().size());
+ assertNotNull(features[0].getConfigurations().get("c1"));
+ assertEquals(1, features[0].getConfigurations().get("c1").size());
+ assertEquals("v", features[0].getConfigurations().get("c1").get("k"));
+ assertNotNull(features[0].getDependencies());
+ assertEquals(0, features[0].getDependencies().size());
+ assertNotNull(features[0].getBundles());
+ assertEquals(2, features[0].getBundles().size());
+ assertEquals("b1", features[0].getBundles().get(0).getLocation());
+ assertEquals("b2", features[0].getBundles().get(1).getLocation());
+ assertNotNull(features[1]);
+ assertEquals("f2", features[1].getName());
+ assertNotNull(features[1].getConfigurations());
+ assertEquals(0, features[1].getConfigurations().size());
+ assertNotNull(features[1].getDependencies());
+ assertEquals(1, features[1].getDependencies().size());
+ assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
+ assertNotNull(features[1].getBundles());
+ assertEquals(1, features[1].getBundles().size());
+ assertEquals("b3", features[1].getBundles().get(0).getLocation());
+ assertEquals("f3", features[2].getName());
+ assertNotNull(features[2].getConfigurationFiles());
+ assertEquals(1, features[2].getConfigurationFiles().size());
+ assertEquals("cf1", features[2].getConfigurationFiles().get(0).getFinalname());
+ assertEquals(true, features[2].getConfigurationFiles().get(0).isOverride());
+ assertEquals("cfloc", features[2].getConfigurationFiles().get(0).getLocation());
+ }
+
+ public void testLoadFormattedRepo() throws Exception {
+ RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo2.xml").toURI());
+ // Check repo
+ URI[] repos = r.getRepositories();
+ assertNotNull(repos);
+ assertEquals(1, repos.length);
+ assertEquals(URI.create("urn:r1"), repos[0]);
+ // Check features
+ Feature[] features = r.getFeatures();
+ assertNotNull(features);
+ assertEquals(3, features.length);
+ assertNotNull(features[0]);
+ assertEquals("f1", features[0].getName());
+ assertNotNull(features[0].getConfigurations());
+ assertEquals(1, features[0].getConfigurations().size());
+ assertNotNull(features[0].getConfigurations().get("c1"));
+ assertEquals(1, features[0].getConfigurations().get("c1").size());
+ assertEquals("v", features[0].getConfigurations().get("c1").get("k"));
+ assertNotNull(features[0].getDependencies());
+ assertEquals(0, features[0].getDependencies().size());
+ assertNotNull(features[0].getBundles());
+ assertEquals(2, features[0].getBundles().size());
+ assertEquals("b1", features[0].getBundles().get(0).getLocation());
+ assertEquals("b2", features[0].getBundles().get(1).getLocation());
+ assertNotNull(features[1]);
+ assertEquals("f2", features[1].getName());
+ assertNotNull(features[1].getConfigurations());
+ assertEquals(0, features[1].getConfigurations().size());
+ assertNotNull(features[1].getDependencies());
+ assertEquals(1, features[1].getDependencies().size());
+ assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
+ assertNotNull(features[1].getBundles());
+ assertEquals(1, features[1].getBundles().size());
+ assertEquals("b3", features[1].getBundles().get(0).getLocation());
+ assertEquals("f3", features[2].getName());
+ assertNotNull(features[2].getConfigurationFiles());
+ assertEquals(1, features[2].getConfigurationFiles().size());
+ assertEquals("cf1", features[2].getConfigurationFiles().get(0).getFinalname());
+ assertEquals(true, features[2].getConfigurationFiles().get(0).isOverride());
+ assertEquals("cfloc", features[2].getConfigurationFiles().get(0).getLocation());
+ }
+
+ public void testLoadRepoWithCapabilitiesAndRequirement() throws Exception {
+ RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo3.xml").toURI());
+ // Check features
+ Feature[] features = r.getFeatures();
+ assertNotNull(features);
+ assertEquals(1, features.length);
+ assertNotNull(features[0]);
+ assertEquals("f1", features[0].getName());
+ assertEquals(1, features[0].getCapabilities().size());
+ assertEquals("cap", features[0].getCapabilities().get(0).getValue().trim());
+ assertEquals(1, features[0].getRequirements().size());
+ assertEquals("req", features[0].getRequirements().get(0).getValue().trim());
+
+ Resource res = FeatureResource.build(features[0], null, null);
+ assertEquals(1, res.getCapabilities("cap").size());
+ assertEquals(1, res.getRequirements("req").size());
+ }
+
+ public void testShowWrongUriInException() throws Exception {
+ String uri = "src/test/resources/org/apache/karaf/shell/features/repo1.xml";
+ RepositoryImpl r = new RepositoryImpl(new URI(uri));
+ try {
+ r.load();
+ } catch (Exception e) {
+ assertTrue(e.getMessage().contains(uri));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/TestBase.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/TestBase.java b/features/src/test/java/org/apache/karaf/features/TestBase.java
new file mode 100644
index 0000000..ac8f3d9
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/TestBase.java
@@ -0,0 +1,105 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.easymock.EasyMock;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.startlevel.BundleStartLevel;
+
+import static java.util.Arrays.asList;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+public class TestBase {
+ public Bundle createDummyBundle(long id, final String symbolicName, Dictionary<String,String> headers) {
+ Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+
+ // Be aware that this means all bundles are treated as different
+ expect(bundle.compareTo(EasyMock.<Bundle>anyObject())).andReturn(1).anyTimes();
+
+ expect(bundle.getBundleId()).andReturn(id).anyTimes();
+ expect(bundle.getSymbolicName()).andReturn(symbolicName).anyTimes();
+ expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+ BundleStartLevel sl = EasyMock.createMock(BundleStartLevel.class);
+ expect(sl.isPersistentlyStarted()).andReturn(true).anyTimes();
+ expect(bundle.adapt(BundleStartLevel.class)).andReturn(sl).anyTimes();
+ replay(bundle, sl);
+ return bundle;
+ }
+
+ public Dictionary<String, String> headers(String ... keyAndHeader) {
+ Hashtable<String, String> headersTable = new Hashtable<String, String>();
+ int c=0;
+ while (c < keyAndHeader.length) {
+ String key = keyAndHeader[c++];
+ String value = keyAndHeader[c++];
+ headersTable.put(key, value);
+ }
+ return headersTable;
+ }
+
+ public Map<String, Map<String, Feature>> features(Feature ... features) {
+ final Map<String, Map<String, Feature>> featuresMap = new HashMap<String, Map<String,Feature>>();
+ for (Feature feature : features) {
+ Map<String, Feature> featureVersion = getOrCreate(featuresMap, feature);
+ featureVersion.put(feature.getVersion(), feature);
+ }
+ return featuresMap;
+ }
+
+ private Map<String, Feature> getOrCreate(final Map<String, Map<String, Feature>> featuresMap, Feature feature) {
+ Map<String, Feature> featureVersion = featuresMap.get(feature.getName());
+ if (featureVersion == null) {
+ featureVersion = new HashMap<String, Feature>();
+ featuresMap.put(feature.getName(), featureVersion);
+ }
+ return featureVersion;
+ }
+
+ public Feature feature(String name) {
+ return feature(name, null);
+ }
+
+ public Feature feature(String name, String version) {
+ return new org.apache.karaf.features.internal.model.Feature(name, version);
+ }
+
+ public Set<Bundle> setOf(Bundle ... elements) {
+ return new HashSet<Bundle>(Arrays.asList(elements));
+ }
+
+ public Set<Long> setOf(Long ... elements) {
+ return new HashSet<Long>(Arrays.asList(elements));
+ }
+
+ public Set<String> setOf(String ... elements) {
+ return new HashSet<String>(asList(elements));
+ }
+
+ public Set<Feature> setOf(Feature ... elements) {
+ return new HashSet<Feature>(Arrays.asList(elements));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
----------------------------------------------------------------------
diff --git a/features/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java b/features/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
new file mode 100644
index 0000000..31f4f29
--- /dev/null
+++ b/features/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.internal.service;
+
+import static java.util.Arrays.asList;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.EnumSet;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService.Option;
+import org.apache.karaf.features.TestBase;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BootFeaturesInstallerTest extends TestBase {
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testParser() {
+ BootFeaturesInstaller installer = new BootFeaturesInstaller(null, null, "", "", false);
+ Assert.assertEquals(asList(setOf("test1", "test2"),setOf("test3")), installer.parseBootFeatures("(test1, test2), test3"));
+ Assert.assertEquals(asList(setOf("test1", "test2", "test3")), installer.parseBootFeatures("test1, test2, test3"));
+ }
+
+ @Test
+ public void testDefaultBootFeatures() throws Exception {
+ FeaturesServiceImpl impl = EasyMock.createMock(FeaturesServiceImpl.class);
+
+ impl.installFeatures(setOf("config", "standard", "region"), EnumSet.of(Option.NoFailOnFeatureNotFound));
+ EasyMock.expectLastCall();
+
+ impl.bootDone();
+ EasyMock.expectLastCall();
+
+ replay(impl);
+ BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl, "", "config,standard,region", false);
+ bootFeatures.installBootFeatures();
+ EasyMock.verify(impl);
+ }
+
+ @Test
+ public void testStagedBoot() throws Exception {
+ FeaturesServiceImpl impl = EasyMock.createStrictMock(FeaturesServiceImpl.class);
+
+ impl.installFeatures(setOf("transaction"), EnumSet.of(Option.NoFailOnFeatureNotFound));
+ EasyMock.expectLastCall();
+ impl.installFeatures(setOf("ssh"), EnumSet.of(Option.NoFailOnFeatureNotFound));
+ EasyMock.expectLastCall();
+
+ impl.bootDone();
+ EasyMock.expectLastCall();
+
+ replay(impl);
+ BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl , "", "(transaction), ssh", false);
+ bootFeatures.installBootFeatures();
+ EasyMock.verify(impl);
+ }
+
+ @Test
+ public void testStartDoesNotFailWithOneInvalidUri() throws Exception {
+ FeaturesServiceImpl impl = EasyMock.createStrictMock(FeaturesServiceImpl.class);
+ impl.addRepository(URI.create("mvn:inexistent/features/1.0/xml/features"));
+ EasyMock.expectLastCall().andThrow(new IllegalArgumentException());
+
+ impl.bootDone();
+ EasyMock.expectLastCall();
+
+ replay(impl);
+ BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl, "mvn:inexistent/features/1.0/xml/features", "", false);
+ bootFeatures.installBootFeatures();
+ EasyMock.verify(impl);
+ }
+
+}
[04/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java b/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
new file mode 100644
index 0000000..eaa9ba0
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
@@ -0,0 +1,170 @@
+/*
+ * 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.internal.service;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.karaf.features.BootFinished;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BootFeaturesInstaller {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BootFeaturesInstaller.class);
+
+ public static String VERSION_PREFIX = "version=";
+
+ private final FeaturesServiceImpl featuresService;
+ private final BundleContext bundleContext;
+ private final String repositories;
+ private final String features;
+ private final boolean asynchronous;
+
+ /**
+ *
+ * @param features list of boot features separated by comma. Optionally contains ;version=x.x.x to specify a specific feature version
+ */
+ public BootFeaturesInstaller(BundleContext bundleContext,
+ FeaturesServiceImpl featuresService,
+ String repositories,
+ String features,
+ boolean asynchronous) {
+ this.bundleContext = bundleContext;
+ this.featuresService = featuresService;
+ this.repositories = repositories;
+ this.features = features;
+ this.asynchronous = asynchronous;
+ }
+
+ /**
+ * Install boot features
+ */
+ public void start() {
+ if (featuresService.isBootDone()) {
+ publishBootFinished();
+ return;
+ }
+ if (asynchronous) {
+ new Thread("Initial Features Provisioning") {
+ public void run() {
+ installBootFeatures();
+ }
+ }.start();
+ } else {
+ installBootFeatures();
+ }
+ }
+
+ protected void installBootFeatures() {
+ try {
+ for (String repo : repositories.split(",")) {
+ repo = repo.trim();
+ if (!repo.isEmpty()) {
+ try {
+ featuresService.addRepository(URI.create(repo));
+ } catch (Exception e) {
+ LOGGER.error("Error installing boot feature repository " + repo);
+ }
+ }
+ }
+
+ List<Set<String>> stagedFeatures = parseBootFeatures(features);
+ for (Set<String> features : stagedFeatures) {
+ featuresService.installFeatures(features, EnumSet.of(FeaturesService.Option.NoFailOnFeatureNotFound));
+ }
+ featuresService.bootDone();
+ publishBootFinished();
+ } catch (Exception e) {
+ // Special handling in case the bundle has been refreshed.
+ // In such a case, simply exits without logging any exception
+ // as the restart should cause the feature service to finish
+ // the work.
+ if (e instanceof IllegalStateException) {
+ try {
+ bundleContext.getBundle();
+ } catch (IllegalStateException ies) {
+ return;
+ }
+ }
+ LOGGER.error("Error installing boot features", e);
+ }
+ }
+
+ /**
+ *
+ * @param featureSt either feature name or <featurename>;version=<version>
+ * @return feature matching the feature string
+ * @throws Exception
+ */
+ private Feature getFeature(String featureSt) throws Exception {
+ String[] parts = featureSt.trim().split(";");
+ String featureName = parts[0];
+ String featureVersion = null;
+ for (String part : parts) {
+ // if the part starts with "version=" it contains the version info
+ if (part.startsWith(VERSION_PREFIX)) {
+ featureVersion = part.substring(VERSION_PREFIX.length());
+ }
+ }
+ if (featureVersion == null) {
+ // no version specified - use default version
+ featureVersion = org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION;
+ }
+ return featuresService.getFeature(featureName, featureVersion);
+ }
+
+ protected List<Set<String>> parseBootFeatures(String bootFeatures) {
+ Pattern pattern = Pattern.compile("(\\((.+))\\),|.+");
+ Matcher matcher = pattern.matcher(bootFeatures);
+ List<Set<String>> result = new ArrayList<Set<String>>();
+ while (matcher.find()) {
+ String group = matcher.group(2) != null ? matcher.group(2) : matcher.group();
+ result.add(parseFeatureList(group));
+ }
+ return result;
+ }
+
+ protected Set<String> parseFeatureList(String group) {
+ HashSet<String> features = new HashSet<String>();
+ for (String feature : Arrays.asList(group.trim().split("\\s*,\\s*"))) {
+ if (feature.length() > 0) {
+ features.add(feature);
+ }
+ }
+ return features;
+ }
+
+ private void publishBootFinished() {
+ if (bundleContext != null) {
+ BootFinished bootFinished = new BootFinished() {};
+ bundleContext.registerService(BootFinished.class, bootFinished, new Hashtable<String, String>());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java b/features/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
new file mode 100644
index 0000000..b6eaae5
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.features.internal.service;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.karaf.features.EventConstants;
+import org.apache.karaf.features.FeatureEvent;
+import org.apache.karaf.features.FeaturesListener;
+import org.apache.karaf.features.RepositoryEvent;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * A listener to publish events to EventAdmin
+ */
+public class EventAdminListener implements FeaturesListener {
+
+ private final ServiceTracker<EventAdmin, EventAdmin> tracker;
+
+ public EventAdminListener(BundleContext context) {
+ tracker = new ServiceTracker<EventAdmin, EventAdmin>(context, EventAdmin.class.getName(), null);
+ tracker.open();
+ }
+
+ public void featureEvent(FeatureEvent event) {
+ EventAdmin eventAdmin = tracker.getService();
+ if (eventAdmin == null) {
+ return;
+ }
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(EventConstants.TYPE, event.getType());
+ props.put(EventConstants.EVENT, event);
+ props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
+ props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
+ props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
+ String topic;
+ switch (event.getType()) {
+ case FeatureInstalled:
+ topic = EventConstants.TOPIC_FEATURES_INSTALLED;
+ break;
+ case FeatureUninstalled:
+ topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
+ break;
+ default:
+ throw new IllegalStateException("Unknown features event type: " + event.getType());
+ }
+ eventAdmin.postEvent(new Event(topic, props));
+ }
+
+ public void repositoryEvent(RepositoryEvent event) {
+ EventAdmin eventAdmin = tracker.getService();
+ if (eventAdmin == null) {
+ return;
+ }
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(EventConstants.TYPE, event.getType());
+ props.put(EventConstants.EVENT, event);
+ props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
+ props.put(EventConstants.REPOSITORY_URI, event.getRepository().getURI().toString());
+ String topic;
+ switch (event.getType()) {
+ case RepositoryAdded:
+ topic = EventConstants.TOPIC_REPOSITORY_ADDED;
+ break;
+ case RepositoryRemoved:
+ topic = EventConstants.TOPIC_REPOSITORY_REMOVED;
+ break;
+ default:
+ throw new IllegalStateException("Unknown repository event type: " + event.getType());
+ }
+ eventAdmin.postEvent(new Event(topic, props));
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
new file mode 100644
index 0000000..0e9038d
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
@@ -0,0 +1,167 @@
+/*
+ * 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.internal.service;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.karaf.features.ConfigFileInfo;
+import org.apache.karaf.features.Feature;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FeatureConfigInstaller {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
+ private static final String CONFIG_KEY = "org.apache.karaf.features.configKey";
+
+ private final ConfigurationAdmin configAdmin;
+
+ public FeatureConfigInstaller(ConfigurationAdmin configAdmin) {
+ this.configAdmin = configAdmin;
+ }
+
+ private String[] parsePid(String pid) {
+ int n = pid.indexOf('-');
+ if (n > 0) {
+ String factoryPid = pid.substring(n + 1);
+ pid = pid.substring(0, n);
+ return new String[]{pid, factoryPid};
+ } else {
+ return new String[]{pid, null};
+ }
+ }
+
+ private Configuration createConfiguration(ConfigurationAdmin configurationAdmin,
+ String pid, String factoryPid) throws IOException, InvalidSyntaxException {
+ if (factoryPid != null) {
+ return configurationAdmin.createFactoryConfiguration(factoryPid, null);
+ } else {
+ return configurationAdmin.getConfiguration(pid, null);
+ }
+ }
+
+ private Configuration findExistingConfiguration(ConfigurationAdmin configurationAdmin,
+ String pid, String factoryPid) throws IOException, InvalidSyntaxException {
+ String filter;
+ if (factoryPid == null) {
+ filter = "(" + Constants.SERVICE_PID + "=" + pid + ")";
+ } else {
+ String key = createConfigurationKey(pid, factoryPid);
+ filter = "(" + CONFIG_KEY + "=" + key + ")";
+ }
+ Configuration[] configurations = configurationAdmin.listConfigurations(filter);
+ if (configurations != null && configurations.length > 0) {
+ return configurations[0];
+ }
+ return null;
+ }
+
+ void installFeatureConfigs(Feature feature) throws IOException, InvalidSyntaxException {
+ for (String config : feature.getConfigurations().keySet()) {
+ Dictionary<String,String> props = new Hashtable<String, String>(feature.getConfigurations().get(config));
+ String[] pid = parsePid(config);
+ Configuration cfg = findExistingConfiguration(configAdmin, pid[0], pid[1]);
+ if (cfg == null) {
+ cfg = createConfiguration(configAdmin, pid[0], pid[1]);
+ String key = createConfigurationKey(pid[0], pid[1]);
+ props.put(CONFIG_KEY, key);
+ if (cfg.getBundleLocation() != null) {
+ cfg.setBundleLocation(null);
+ }
+ cfg.update(props);
+ }
+ }
+ for (ConfigFileInfo configFile : feature.getConfigurationFiles()) {
+ installConfigurationFile(configFile.getLocation(), configFile.getFinalname(), configFile.isOverride());
+ }
+ }
+
+ private String createConfigurationKey(String pid, String factoryPid) {
+ return factoryPid == null ? pid : pid + "-" + factoryPid;
+ }
+
+ private void installConfigurationFile(String fileLocation, String finalname, boolean override) throws IOException {
+ String basePath = System.getProperty("karaf.base");
+
+ if (finalname.contains("${")) {
+ //remove any placeholder or variable part, this is not valid.
+ int marker = finalname.indexOf("}");
+ finalname = finalname.substring(marker+1);
+ }
+
+ finalname = basePath + File.separator + finalname;
+
+ File file = new File(finalname);
+ if (file.exists()) {
+ if (!override) {
+ LOGGER.debug("Configuration file {} already exist, don't override it", finalname);
+ return;
+ } else {
+ LOGGER.info("Configuration file {} already exist, overriding it", finalname);
+ }
+ } else {
+ LOGGER.info("Creating configuration file {}", finalname);
+ }
+
+ InputStream is = null;
+ FileOutputStream fop = null;
+ try {
+ is = new BufferedInputStream(new URL(fileLocation).openStream());
+
+ if (!file.exists()) {
+ File parentFile = file.getParentFile();
+ if (parentFile != null)
+ parentFile.mkdirs();
+ file.createNewFile();
+ }
+
+ fop = new FileOutputStream(file);
+
+ int bytesRead;
+ byte[] buffer = new byte[1024];
+
+ while ((bytesRead = is.read(buffer)) != -1) {
+ fop.write(buffer, 0, bytesRead);
+ }
+ } catch (RuntimeException e) {
+ LOGGER.error(e.getMessage());
+ throw e;
+ } catch (MalformedURLException e) {
+ LOGGER.error(e.getMessage());
+ throw e;
+ } finally {
+ if (is != null)
+ is.close();
+ if (fop != null) {
+ fop.flush();
+ fop.close();
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
new file mode 100644
index 0000000..d6defe0
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
@@ -0,0 +1,68 @@
+/*
+ * 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.internal.service;
+
+import java.net.URI;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+public class FeatureFinder implements ManagedService {
+
+ final Map<String, String> nameToArtifactMap = new HashMap<String, String>();
+
+ public String[] getNames() {
+ synchronized (nameToArtifactMap) {
+ Set<String> strings = nameToArtifactMap.keySet();
+ return strings.toArray(new String[strings.size()]);
+ }
+ }
+
+ public URI getUriFor(String name, String version) {
+ String coords;
+ synchronized (nameToArtifactMap) {
+ coords = nameToArtifactMap.get(name);
+ }
+ if (coords == null) {
+ return null;
+ }
+ Artifact artifact = new Artifact(coords);
+ return artifact.getMavenUrl(version);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void updated(Dictionary properties) throws ConfigurationException {
+ synchronized (nameToArtifactMap) {
+ if (properties != null) {
+ nameToArtifactMap.clear();
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ if (!"felix.fileinstall.filename".equals(key) && !"service.pid".equals(key)) {
+ nameToArtifactMap.put(key, (String) properties.get(key));
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
new file mode 100644
index 0000000..8fb161e
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
@@ -0,0 +1,113 @@
+/*
+ * 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.internal.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URLConnection;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.apache.karaf.features.FeaturesNamespaces;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Utility class which fires XML Schema validation.
+ */
+public class FeatureValidationUtil {
+
+ public static final QName FEATURES_0_0 = new QName("features");
+ public static final QName FEATURES_1_0 = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features");
+ public static final QName FEATURES_1_1 = new QName("http://karaf.apache.org/xmlns/features/v1.1.0", "features");
+ public static final QName FEATURES_1_2 = new QName("http://karaf.apache.org/xmlns/features/v1.2.0", "features");
+ private static final Logger LOGGER = LoggerFactory.getLogger(FeatureValidationUtil.class);
+
+ /**
+ * Runs schema validation.
+ *
+ * @param uri Uri to validate.
+ * @throws Exception When validation fails.
+ */
+ public static void validate(URI uri) throws Exception {
+ Document doc = load(uri);
+
+ QName name = new QName(doc.getDocumentElement().getNamespaceURI(), doc.getDocumentElement().getLocalName());
+
+ if (FeaturesNamespaces.FEATURES_0_0_0.equals(name)) {
+ LOGGER.warn("Old style feature file without namespace found (URI: {}). This format is deprecated and support for it will soon be removed", uri);
+ return;
+ } else if (FeaturesNamespaces.FEATURES_1_0_0.equals(name)) {
+ validate(doc, "/org/apache/karaf/features/karaf-features-1.0.0.xsd");
+ } else if (FeaturesNamespaces.FEATURES_1_1_0.equals(name)) {
+ validate(doc, "/org/apache/karaf/features/karaf-features-1.1.0.xsd");
+ } else if (FeaturesNamespaces.FEATURES_1_2_0.equals(name)) {
+ validate(doc, "/org/apache/karaf/features/karaf-features-1.2.0.xsd");
+ } else if (FeaturesNamespaces.FEATURES_1_3_0.equals(name)) {
+ validate(doc, "/org/apache/karaf/features/karaf-features-1.3.0.xsd");
+ }
+ else {
+ throw new IllegalArgumentException("Unrecognized root element: " + name);
+ }
+ }
+
+ private static Document load(URI uri) throws IOException, SAXException, ParserConfigurationException {
+ InputStream stream = null;
+ try {
+ URLConnection conn;
+ try {
+ conn = uri.toURL().openConnection();
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("invalid URI: " + uri, e);
+ }
+ conn.setDefaultUseCaches(false);
+ stream = conn.getInputStream();
+ // load document and check the root element for namespace declaration
+ DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
+ dFactory.setNamespaceAware(true);
+ return dFactory.newDocumentBuilder().parse(stream);
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ private static void validate(Document doc, String schemaLocation) throws SAXException {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ // root element has namespace - we can use schema validation
+ Schema schema = factory.newSchema(new StreamSource(FeatureValidationUtil.class.getResourceAsStream(schemaLocation)));
+ // create schema by reading it from an XSD file:
+ Validator validator = schema.newValidator();
+ try {
+ validator.validate(new DOMSource(doc));
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to validate " + doc.getDocumentURI(), e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
new file mode 100644
index 0000000..6c16650
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -0,0 +1,1455 @@
+/*
+ * 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.internal.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeatureEvent;
+import org.apache.karaf.features.FeaturesListener;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.RepositoryEvent;
+import org.apache.karaf.features.internal.deployment.DeploymentBuilder;
+import org.apache.karaf.features.internal.deployment.StreamProvider;
+import org.apache.karaf.features.internal.resolver.FeatureNamespace;
+import org.apache.karaf.features.internal.resolver.UriNamespace;
+import org.apache.karaf.features.internal.util.ChecksumUtils;
+import org.apache.karaf.features.internal.util.Macro;
+import org.apache.karaf.features.internal.util.MultiException;
+import org.apache.karaf.util.collections.CopyOnWriteArrayIdentityList;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.felix.resolver.Util.getSymbolicName;
+import static org.apache.felix.resolver.Util.getVersion;
+
+/**
+ *
+ */
+public class FeaturesServiceImpl implements FeaturesService {
+
+ public static final String UPDATE_SNAPSHOTS_NONE = "none";
+ public static final String UPDATE_SNAPSHOTS_CRC = "crc";
+ public static final String UPDATE_SNAPSHOTS_ALWAYS = "always";
+ public static final String DEFAULT_UPDATE_SNAPSHOTS = UPDATE_SNAPSHOTS_CRC;
+
+ public static final String DEFAULT_FEATURE_RESOLUTION_RANGE = "${range;[====,====]}";
+ public static final String DEFAULT_BUNDLE_UPDATE_RANGE = "${range;[==,=+)}";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
+ private static final String SNAPSHOT = "SNAPSHOT";
+ private static final String MAVEN = "mvn:";
+
+ /**
+ * Our bundle.
+ * We use it to check bundle operations affecting our own bundle.
+ */
+ private final Bundle bundle;
+
+ /**
+ * The system bundle context.
+ * For all bundles related operations, we use the system bundle context
+ * to allow this bundle to be stopped and still allow the deployment to
+ * take place.
+ */
+ private final BundleContext systemBundleContext;
+ /**
+ * Used to load and save the {@link State} of this service.
+ */
+ private final StateStorage storage;
+ private final FeatureFinder featureFinder;
+ private final EventAdminListener eventAdminListener;
+ private final FeatureConfigInstaller configInstaller;
+ private final String overrides;
+ /**
+ * Range to use when a version is specified on a feature dependency.
+ * The default is {@link FeaturesServiceImpl#DEFAULT_FEATURE_RESOLUTION_RANGE}
+ */
+ private final String featureResolutionRange;
+ /**
+ * Range to use when verifying if a bundle should be updated or
+ * new bundle installed.
+ * The default is {@link FeaturesServiceImpl#DEFAULT_BUNDLE_UPDATE_RANGE}
+ */
+ private final String bundleUpdateRange;
+ /**
+ * Use CRC to check snapshot bundles and update them if changed.
+ * Either:
+ * - none : never update snapshots
+ * - always : always update snapshots
+ * - crc : use CRC to detect changes
+ */
+ private final String updateSnaphots;
+
+ private final List<FeaturesListener> listeners = new CopyOnWriteArrayIdentityList<FeaturesListener>();
+
+ // Synchronized on lock
+ private final Object lock = new Object();
+ private final State state = new State();
+ private final Map<String, Repository> repositoryCache = new HashMap<String, Repository>();
+ private Map<String, Map<String, Feature>> featureCache;
+
+
+ public FeaturesServiceImpl(Bundle bundle,
+ BundleContext systemBundleContext,
+ StateStorage storage,
+ FeatureFinder featureFinder,
+ EventAdminListener eventAdminListener,
+ FeatureConfigInstaller configInstaller,
+ String overrides,
+ String featureResolutionRange,
+ String bundleUpdateRange,
+ String updateSnaphots) {
+ this.bundle = bundle;
+ this.systemBundleContext = systemBundleContext;
+ this.storage = storage;
+ this.featureFinder = featureFinder;
+ this.eventAdminListener = eventAdminListener;
+ this.configInstaller = configInstaller;
+ this.overrides = overrides;
+ this.featureResolutionRange = featureResolutionRange;
+ this.bundleUpdateRange = bundleUpdateRange;
+ this.updateSnaphots = updateSnaphots;
+ loadState();
+ }
+
+ //
+ // State support
+ //
+
+ protected void loadState() {
+ try {
+ synchronized (lock) {
+ storage.load(state);
+ }
+ } catch (IOException e) {
+ LOGGER.warn("Error loading FeaturesService state", e);
+ }
+ }
+
+ protected void saveState() {
+ try {
+ synchronized (lock) {
+ // Make sure we don't store bundle checksums if
+ // it has been disabled through configadmin
+ // so that we don't keep out-of-date checksums.
+ if (!UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
+ state.bundleChecksums.clear();
+ }
+ storage.save(state);
+ }
+ } catch (IOException e) {
+ LOGGER.warn("Error saving FeaturesService state", e);
+ }
+ }
+
+ boolean isBootDone() {
+ synchronized (lock) {
+ return state.bootDone.get();
+ }
+ }
+
+ void bootDone() {
+ synchronized (lock) {
+ state.bootDone.set(true);
+ saveState();
+ }
+ }
+
+ //
+ // Listeners support
+ //
+
+ public void registerListener(FeaturesListener listener) {
+ listeners.add(listener);
+ try {
+ Set<String> repositories = new TreeSet<String>();
+ Set<String> installedFeatures = new TreeSet<String>();
+ synchronized (lock) {
+ repositories.addAll(state.repositories);
+ installedFeatures.addAll(state.installedFeatures);
+ }
+ for (String uri : repositories) {
+ Repository repository = new RepositoryImpl(URI.create(uri));
+ listener.repositoryEvent(new RepositoryEvent(repository, RepositoryEvent.EventType.RepositoryAdded, true));
+ }
+ for (String id : installedFeatures) {
+ Feature feature = org.apache.karaf.features.internal.model.Feature.valueOf(id);
+ listener.featureEvent(new FeatureEvent(feature, FeatureEvent.EventType.FeatureInstalled, true));
+ }
+ } catch (Exception e) {
+ LOGGER.error("Error notifying listener about the current state", e);
+ }
+ }
+
+ public void unregisterListener(FeaturesListener listener) {
+ listeners.remove(listener);
+ }
+
+ protected void callListeners(FeatureEvent event) {
+ if (eventAdminListener != null) {
+ eventAdminListener.featureEvent(event);
+ }
+ for (FeaturesListener listener : listeners) {
+ listener.featureEvent(event);
+ }
+ }
+
+ protected void callListeners(RepositoryEvent event) {
+ if (eventAdminListener != null) {
+ eventAdminListener.repositoryEvent(event);
+ }
+ for (FeaturesListener listener : listeners) {
+ listener.repositoryEvent(event);
+ }
+ }
+
+ //
+ // Feature Finder support
+ //
+
+ @Override
+ public URI getRepositoryUriFor(String name, String version) {
+ return featureFinder.getUriFor(name, version);
+ }
+
+ @Override
+ public String[] getRepositoryNames() {
+ return featureFinder.getNames();
+ }
+
+
+ //
+ // Repositories support
+ //
+
+ public Repository loadRepository(URI uri) throws Exception {
+ // TODO: merge validation and loading by loading the DOM, validating, unmarshalling
+ FeatureValidationUtil.validate(uri);
+ RepositoryImpl repo = new RepositoryImpl(uri);
+ repo.load();
+ return repo;
+ }
+
+ @Override
+ public void validateRepository(URI uri) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addRepository(URI uri) throws Exception {
+ addRepository(uri, false);
+ }
+
+ @Override
+ public void addRepository(URI uri, boolean install) throws Exception {
+ if (install) {
+ // TODO: implement
+ throw new UnsupportedOperationException();
+ }
+ Repository repository = loadRepository(uri);
+ synchronized (lock) {
+ // Clean cache
+ repositoryCache.put(uri.toString(), repository);
+ featureCache = null;
+ // Add repo
+ if (!state.repositories.add(uri.toString())) {
+ return;
+ }
+ saveState();
+ }
+ callListeners(new RepositoryEvent(repository, RepositoryEvent.EventType.RepositoryAdded, false));
+ }
+
+ @Override
+ public void removeRepository(URI uri) throws Exception {
+ removeRepository(uri, true);
+ }
+
+ @Override
+ public void removeRepository(URI uri, boolean uninstall) throws Exception {
+ // TODO: check we don't have any feature installed from this repository
+ Repository repo;
+ synchronized (lock) {
+ // Remove repo
+ if (!state.repositories.remove(uri.toString())) {
+ return;
+ }
+ // Clean cache
+ featureCache = null;
+ repo = repositoryCache.get(uri.toString());
+ List<String> toRemove = new ArrayList<String>();
+ toRemove.add(uri.toString());
+ while (!toRemove.isEmpty()) {
+ Repository rep = repositoryCache.remove(toRemove.remove(0));
+ if (rep != null) {
+ for (URI u : rep.getRepositories()) {
+ toRemove.add(u.toString());
+ }
+ }
+ }
+ saveState();
+ }
+ if (repo == null) {
+ repo = new RepositoryImpl(uri);
+ }
+ callListeners(new RepositoryEvent(repo, RepositoryEvent.EventType.RepositoryRemoved, false));
+ }
+
+ @Override
+ public void restoreRepository(URI uri) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void refreshRepository(URI uri) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Repository[] listRepositories() throws Exception {
+ // Make sure the cache is loaded
+ getFeatures();
+ synchronized (lock) {
+ return repositoryCache.values().toArray(new Repository[repositoryCache.size()]);
+ }
+ }
+
+ @Override
+ public Repository[] listRequiredRepositories() throws Exception {
+ // Make sure the cache is loaded
+ getFeatures();
+ synchronized (lock) {
+ List<Repository> repos = new ArrayList<Repository>();
+ for (Map.Entry<String, Repository> entry : repositoryCache.entrySet()) {
+ if (state.repositories.contains(entry.getKey())) {
+ repos.add(entry.getValue());
+ }
+ }
+ return repos.toArray(new Repository[repos.size()]);
+ }
+ }
+
+ @Override
+ public Repository getRepository(String name) throws Exception {
+ // Make sure the cache is loaded
+ getFeatures();
+ synchronized (lock) {
+ for (Repository repo : this.repositoryCache.values()) {
+ if (name.equals(repo.getName())) {
+ return repo;
+ }
+ }
+ return null;
+ }
+ }
+
+ //
+ // Features support
+ //
+
+ public Feature getFeature(String name) throws Exception {
+ return getFeature(name, null);
+ }
+
+ public Feature getFeature(String name, String version) throws Exception {
+ Map<String, Feature> versions = getFeatures().get(name);
+ return getFeatureMatching(versions, version);
+ }
+
+ protected Feature getFeatureMatching(Map<String, Feature> versions, String version) {
+ if (version != null) {
+ version = version.trim();
+ if (version.equals(org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION)) {
+ version = "";
+ }
+ } else {
+ version = "";
+ }
+ if (versions == null || versions.isEmpty()) {
+ return null;
+ } else {
+ Feature feature = version.isEmpty() ? null : versions.get(version);
+ if (feature == null) {
+ // Compute version range. If an version has been given, assume exact range
+ VersionRange versionRange = version.isEmpty() ?
+ new VersionRange(Version.emptyVersion) :
+ new VersionRange(version, true, true);
+ Version latest = Version.emptyVersion;
+ for (String available : versions.keySet()) {
+ Version availableVersion = VersionTable.getVersion(available);
+ if (availableVersion.compareTo(latest) >= 0 && versionRange.contains(availableVersion)) {
+ feature = versions.get(available);
+ latest = availableVersion;
+ }
+ }
+ }
+ return feature;
+ }
+ }
+
+ public Feature[] listFeatures() throws Exception {
+ Set<Feature> features = new HashSet<Feature>();
+ for (Map<String, Feature> featureWithDifferentVersion : getFeatures().values()) {
+ for (Feature f : featureWithDifferentVersion.values()) {
+ features.add(f);
+ }
+ }
+ return features.toArray(new Feature[features.size()]);
+ }
+
+ protected Map<String, Map<String, Feature>> getFeatures() throws Exception {
+ List<String> uris;
+ synchronized (lock) {
+ if (featureCache != null) {
+ return featureCache;
+ }
+ uris = new ArrayList<String>(state.repositories);
+ }
+ //the outer map's key is feature name, the inner map's key is feature version
+ Map<String, Map<String, Feature>> map = new HashMap<String, Map<String, Feature>>();
+ // Two phase load:
+ // * first load dependent repositories
+ List<String> toLoad = new ArrayList<String>(uris);
+ while (!toLoad.isEmpty()) {
+ String uri = toLoad.remove(0);
+ Repository repo;
+ synchronized (lock) {
+ repo = repositoryCache.get(uri);
+ }
+ if (repo == null) {
+ RepositoryImpl rep = new RepositoryImpl(URI.create(uri));
+ rep.load();
+ repo = rep;
+ synchronized (lock) {
+ repositoryCache.put(uri, repo);
+ }
+ }
+ for (URI u : repo.getRepositories()) {
+ toLoad.add(u.toString());
+ }
+ }
+ List<Repository> repos;
+ synchronized (lock) {
+ repos = new ArrayList<Repository>(repositoryCache.values());
+ }
+ // * then load all features
+ for (Repository repo : repos) {
+ for (Feature f : repo.getFeatures()) {
+ if (map.get(f.getName()) == null) {
+ Map<String, Feature> versionMap = new HashMap<String, Feature>();
+ versionMap.put(f.getVersion(), f);
+ map.put(f.getName(), versionMap);
+ } else {
+ map.get(f.getName()).put(f.getVersion(), f);
+ }
+ }
+ }
+ synchronized (lock) {
+ if (uris.size() == state.repositories.size() &&
+ state.repositories.containsAll(uris)) {
+ featureCache = map;
+ }
+ }
+ return map;
+ }
+
+ //
+ // Installed features
+ //
+
+ @Override
+ public Feature[] listInstalledFeatures() throws Exception {
+ Set<Feature> features = new HashSet<Feature>();
+ Map<String, Map<String, Feature>> allFeatures = getFeatures();
+ synchronized (lock) {
+ for (Map<String, Feature> featureWithDifferentVersion : allFeatures.values()) {
+ for (Feature f : featureWithDifferentVersion.values()) {
+ if (isInstalled(f)) {
+ features.add(f);
+ }
+ }
+ }
+ }
+ return features.toArray(new Feature[features.size()]);
+ }
+
+ @Override
+ public Feature[] listRequiredFeatures() throws Exception {
+ Set<Feature> features = new HashSet<Feature>();
+ Map<String, Map<String, Feature>> allFeatures = getFeatures();
+ synchronized (lock) {
+ for (Map<String, Feature> featureWithDifferentVersion : allFeatures.values()) {
+ for (Feature f : featureWithDifferentVersion.values()) {
+ if (isRequired(f)) {
+ features.add(f);
+ }
+ }
+ }
+ }
+ return features.toArray(new Feature[features.size()]);
+ }
+
+
+ @Override
+ public boolean isInstalled(Feature f) {
+ String id = normalize(f.getId());
+ synchronized (lock) {
+ return state.installedFeatures.contains(id);
+ }
+ }
+
+ @Override
+ public boolean isRequired(Feature f) {
+ String id = normalize(f.getId());
+ synchronized (lock) {
+ return state.features.contains(id);
+ }
+ }
+
+ //
+ // Installation and uninstallation of features
+ //
+
+ public void installFeature(String name) throws Exception {
+ installFeature(name, EnumSet.noneOf(Option.class));
+ }
+
+ public void installFeature(String name, String version) throws Exception {
+ installFeature(version != null ? name + "/" + version : name, EnumSet.noneOf(Option.class));
+ }
+
+ public void installFeature(String name, EnumSet<Option> options) throws Exception {
+ installFeatures(Collections.singleton(name), options);
+ }
+
+ public void installFeature(String name, String version, EnumSet<Option> options) throws Exception {
+ installFeature(version != null ? name + "/" + version : name, options);
+ }
+
+ public void installFeature(Feature feature, EnumSet<Option> options) throws Exception {
+ installFeature(feature.getId());
+ }
+
+ @Override
+ public void uninstallFeature(String name, String version) throws Exception {
+ uninstallFeature(version != null ? name + "/" + version : name);
+ }
+
+ @Override
+ public void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception {
+ uninstallFeature(version != null ? name + "/" + version : name, options);
+ }
+
+ @Override
+ public void uninstallFeature(String name) throws Exception {
+ uninstallFeature(name, EnumSet.noneOf(Option.class));
+ }
+
+ @Override
+ public void uninstallFeature(String name, EnumSet<Option> options) throws Exception {
+ uninstallFeatures(Collections.singleton(name), options);
+ }
+
+
+ //
+ //
+ //
+ // RESOLUTION
+ //
+ //
+ //
+
+
+
+
+
+
+ public void installFeatures(Set<String> features, EnumSet<Option> options) throws Exception {
+ Set<String> required;
+ Set<String> installed;
+ Set<Long> managed;
+ synchronized (lock) {
+ required = new HashSet<String>(state.features);
+ installed = new HashSet<String>(state.installedFeatures);
+ managed = new HashSet<Long>(state.managedBundles);
+ }
+ List<String> featuresToAdd = new ArrayList<String>();
+ Map<String, Map<String, Feature>> featuresMap = getFeatures();
+ for (String feature : features) {
+ feature = normalize(feature);
+ String name = feature.substring(0, feature.indexOf("/"));
+ String version = feature.substring(feature.indexOf("/") + 1);
+ Feature f = getFeatureMatching(featuresMap.get(name), version);
+ if (f == null) {
+ if (!options.contains(Option.NoFailOnFeatureNotFound)) {
+ throw new IllegalArgumentException("No matching features for " + feature);
+ }
+ } else {
+ featuresToAdd.add(normalize(f.getId()));
+ }
+ }
+ featuresToAdd = new ArrayList<String>(new LinkedHashSet<String>(featuresToAdd));
+ StringBuilder sb = new StringBuilder();
+ sb.append("Adding features: ");
+ for (int i = 0; i < featuresToAdd.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(featuresToAdd.get(i));
+ }
+ print(sb.toString(), options.contains(Option.Verbose));
+ required.addAll(featuresToAdd);
+ doInstallFeaturesInThread(required, installed, managed, options);
+ }
+
+ public void uninstallFeatures(Set<String> features, EnumSet<Option> options) throws Exception {
+ Set<String> required;
+ Set<String> installed;
+ Set<Long> managed;
+ synchronized (lock) {
+ required = new HashSet<String>(state.features);
+ installed = new HashSet<String>(state.installedFeatures);
+ managed = new HashSet<Long>(state.managedBundles);
+ }
+ List<String> featuresToRemove = new ArrayList<String>();
+ for (String feature : new HashSet<String>(features)) {
+ List<String> toRemove = new ArrayList<String>();
+ feature = normalize(feature);
+ if (feature.endsWith("/0.0.0")) {
+ String nameSep = feature.substring(0, feature.indexOf("/") + 1);
+ for (String f : required) {
+ if (normalize(f).startsWith(nameSep)) {
+ toRemove.add(f);
+ }
+ }
+ } else {
+ toRemove.add(feature);
+ }
+ toRemove.retainAll(required);
+ if (toRemove.isEmpty()) {
+ throw new IllegalArgumentException("Feature named '" + feature + "' is not installed");
+ } else if (toRemove.size() > 1) {
+ String name = feature.substring(0, feature.indexOf("/"));
+ StringBuilder sb = new StringBuilder();
+ sb.append("Feature named '").append(name).append("' has multiple versions installed (");
+ for (int i = 0; i < toRemove.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(toRemove.get(i));
+ }
+ sb.append("). Please specify the version to uninstall.");
+ throw new IllegalArgumentException(sb.toString());
+ }
+ featuresToRemove.addAll(toRemove);
+ }
+ featuresToRemove = new ArrayList<String>(new LinkedHashSet<String>(featuresToRemove));
+ StringBuilder sb = new StringBuilder();
+ sb.append("Removing features: ");
+ for (int i = 0; i < featuresToRemove.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(featuresToRemove.get(i));
+ }
+ print(sb.toString(), options.contains(Option.Verbose));
+ required.removeAll(featuresToRemove);
+ doInstallFeaturesInThread(required, installed, managed, options);
+ }
+
+ protected String normalize(String feature) {
+ if (!feature.contains("/")) {
+ feature += "/0.0.0";
+ }
+ int idx = feature.indexOf("/");
+ String name = feature.substring(0, idx);
+ String version = feature.substring(idx + 1);
+ return name + "/" + VersionTable.getVersion(version).toString();
+ }
+
+ /**
+ * Actual deployment needs to be done in a separate thread.
+ * The reason is that if the console is refreshed, the current thread which is running
+ * the command may be interrupted while waiting for the refresh to be done, leading
+ * to bundles not being started after the refresh.
+ */
+ public void doInstallFeaturesInThread(final Set<String> features,
+ final Set<String> installed,
+ final Set<Long> managed,
+ final EnumSet<Option> options) throws Exception {
+ ExecutorService executor = Executors.newCachedThreadPool();
+ try {
+ executor.submit(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ doInstallFeatures(features, installed, managed, options);
+ return null;
+ }
+ }).get();
+ } catch (ExecutionException e) {
+ Throwable t = e.getCause();
+ if (t instanceof RuntimeException) {
+ throw ((RuntimeException) t);
+ } else if (t instanceof Error) {
+ throw ((Error) t);
+ } else if (t instanceof Exception) {
+ throw (Exception) t;
+ } else {
+ throw e;
+ }
+ } finally {
+ executor.shutdown();
+ }
+ }
+
+ public void doInstallFeatures(Set<String> features, // all request features
+ Set<String> installed, // installed features
+ Set<Long> managed, // currently managed bundles
+ EnumSet<Option> options // installation options
+ ) throws Exception {
+
+ boolean noRefreshUnmanaged = options.contains(Option.NoAutoRefreshUnmanagedBundles);
+ boolean noRefreshManaged = options.contains(Option.NoAutoRefreshManagedBundles);
+ boolean noRefresh = options.contains(Option.NoAutoRefreshBundles);
+ boolean noStart = options.contains(Option.NoAutoStartBundles);
+ boolean verbose = options.contains(Option.Verbose);
+ boolean simulate = options.contains(Option.Simulate);
+
+ // Get a list of resolved and unmanaged bundles to use as capabilities during resolution
+ List<Resource> systemBundles = new ArrayList<Resource>();
+ Bundle[] bundles = systemBundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ if (bundle.getState() >= Bundle.RESOLVED && !managed.contains(bundle.getBundleId())) {
+ Resource res = bundle.adapt(BundleRevision.class);
+ systemBundles.add(res);
+ }
+ }
+ // Resolve
+ // TODO: requirements
+ // TODO: bundles
+ // TODO: regions: on isolated regions, we may need different resolution for each region
+ Set<String> overrides = Overrides.loadOverrides(this.overrides);
+ Repository[] repositories = listRepositories();
+ DeploymentBuilder builder = createDeploymentBuilder(repositories);
+ builder.setFeatureRange(featureResolutionRange);
+ builder.download(features,
+ Collections.<String>emptySet(),
+ Collections.<String>emptySet(),
+ overrides,
+ Collections.<String>emptySet());
+ Map<Resource, List<Wire>> resolution = builder.resolve(systemBundles, false);
+ Collection<Resource> allResources = resolution.keySet();
+ Map<String, StreamProvider> providers = builder.getProviders();
+
+ // Install conditionals
+ List<String> installedFeatureIds = getFeatureIds(allResources);
+ List<Feature> installedFeatures = getFeatures(repositories, installedFeatureIds);
+
+ //
+ // Compute list of installable resources (those with uris)
+ //
+ List<Resource> resources = getBundles(allResources);
+
+ // Compute information for each bundle
+ Map<String, BundleInfo> bundleInfos = new HashMap<String, BundleInfo>();
+ for (Feature feature : getFeatures(repositories, getFeatureIds(allResources))) {
+ for (BundleInfo bi : feature.getBundles()) {
+ BundleInfo oldBi = bundleInfos.get(bi.getLocation());
+ if (oldBi != null) {
+ bi = mergeBundleInfo(bi, oldBi);
+ }
+ bundleInfos.put(bi.getLocation(), bi);
+ }
+ }
+
+ // TODO: handle bundleInfo.isStart()
+
+ // Get all resources that will be used to satisfy the old features set
+ Set<Resource> resourceLinkedToOldFeatures = new HashSet<Resource>();
+ if (noStart) {
+ for (Resource resource : resolution.keySet()) {
+ String name = FeatureNamespace.getName(resource);
+ if (name != null) {
+ Version version = FeatureNamespace.getVersion(resource);
+ String id = version != null ? name + "/" + version : name;
+ if (installed.contains(id)) {
+ addTransitive(resource, resourceLinkedToOldFeatures, resolution);
+ }
+ }
+ }
+ }
+
+ //
+ // Compute deployment
+ //
+ Map<String, Long> bundleChecksums = new HashMap<String, Long>();
+ synchronized (lock) {
+ bundleChecksums.putAll(state.bundleChecksums);
+ }
+ Deployment deployment = computeDeployment(managed, bundles, providers, resources, bundleChecksums);
+
+ if (deployment.toDelete.isEmpty() &&
+ deployment.toUpdate.isEmpty() &&
+ deployment.toInstall.isEmpty()) {
+ print("No deployment change.", verbose);
+ return;
+ }
+ //
+ // Log deployment
+ //
+ logDeployment(deployment, verbose);
+
+ if (simulate) {
+ // TODO: it would be nice to print bundles that will be refreshed
+ // TODO: it could be done by checking the differences between
+ // TODO: the resolution result and the actual wiring state
+ return;
+ }
+
+ Set<Bundle> toRefresh = new HashSet<Bundle>();
+ Set<Bundle> toStart = new HashSet<Bundle>();
+
+ //
+ // Execute deployment
+ //
+
+ // TODO: handle update on the features service itself
+ if (deployment.toUpdate.containsKey(bundle) ||
+ deployment.toDelete.contains(bundle)) {
+
+ LOGGER.warn("Updating or uninstalling of the FeaturesService is not supported");
+ deployment.toUpdate.remove(bundle);
+ deployment.toDelete.remove(bundle);
+
+ }
+
+ //
+ // Perform bundle operations
+ //
+
+ // Stop bundles by chunks
+ Set<Bundle> toStop = new HashSet<Bundle>();
+ toStop.addAll(deployment.toUpdate.keySet());
+ toStop.addAll(deployment.toDelete);
+ removeFragmentsAndBundlesInState(toStop, Bundle.UNINSTALLED | Bundle.RESOLVED | Bundle.STOPPING);
+ if (!toStop.isEmpty()) {
+ print("Stopping bundles:", verbose);
+ while (!toStop.isEmpty()) {
+ List<Bundle> bs = getBundlesToStop(toStop);
+ for (Bundle bundle : bs) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ bundle.stop(Bundle.STOP_TRANSIENT);
+ toStop.remove(bundle);
+ }
+ }
+ }
+ if (!deployment.toDelete.isEmpty()) {
+ print("Uninstalling bundles:", verbose);
+ for (Bundle bundle : deployment.toDelete) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ bundle.uninstall();
+ managed.remove(bundle.getBundleId());
+ toRefresh.add(bundle);
+ }
+ }
+ if (!deployment.toUpdate.isEmpty()) {
+ print("Updating bundles:", verbose);
+ for (Map.Entry<Bundle, Resource> entry : deployment.toUpdate.entrySet()) {
+ Bundle bundle = entry.getKey();
+ Resource resource = entry.getValue();
+ String uri = UriNamespace.getUri(resource);
+ print(" " + uri, verbose);
+ InputStream is = getBundleInputStream(resource, providers);
+ bundle.update(is);
+ toRefresh.add(bundle);
+ toStart.add(bundle);
+ BundleInfo bi = bundleInfos.get(uri);
+ if (bi != null && bi.getStartLevel() > 0) {
+ bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
+ }
+ // TODO: handle region
+ }
+ }
+ if (!deployment.toInstall.isEmpty()) {
+ print("Installing bundles:", verbose);
+ for (Resource resource : deployment.toInstall) {
+ String uri = UriNamespace.getUri(resource);
+ print(" " + uri, verbose);
+ InputStream is = getBundleInputStream(resource, providers);
+ Bundle bundle = systemBundleContext.installBundle(uri, is);
+ managed.add(bundle.getBundleId());
+ if (!noStart || resourceLinkedToOldFeatures.contains(resource)) {
+ toStart.add(bundle);
+ }
+ toRefresh.add(bundle);
+ deployment.resToBnd.put(resource, bundle);
+ // save a checksum of installed snapshot bundle
+ if (UPDATE_SNAPSHOTS_CRC.equals(updateSnaphots)
+ && isUpdateable(resource) && !deployment.newCheckums.containsKey(bundle.getLocation())) {
+ deployment.newCheckums.put(bundle.getLocation(), ChecksumUtils.checksum(getBundleInputStream(resource, providers)));
+ }
+ BundleInfo bi = bundleInfos.get(uri);
+ if (bi != null && bi.getStartLevel() > 0) {
+ bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
+ }
+ // TODO: handle region
+ }
+ }
+
+ //
+ // Update and save state
+ //
+ List<String> newFeatures = new ArrayList<String>();
+ synchronized (lock) {
+ List<String> allFeatures = new ArrayList<String>();
+ for (Resource resource : allResources) {
+ String name = FeatureNamespace.getName(resource);
+ if (name != null) {
+ Version version = FeatureNamespace.getVersion(resource);
+ String id = version != null ? name + "/" + version : name;
+ allFeatures.add(id);
+ if (!state.installedFeatures.contains(id)) {
+ newFeatures.add(id);
+ }
+ }
+ }
+ state.bundleChecksums.putAll(deployment.newCheckums);
+ state.features.clear();
+ state.features.addAll(features);
+ state.installedFeatures.clear();
+ state.installedFeatures.addAll(allFeatures);
+ state.managedBundles.clear();
+ state.managedBundles.addAll(managed);
+ saveState();
+ }
+
+ //
+ // Install configurations
+ //
+ if (configInstaller != null && !newFeatures.isEmpty()) {
+ for (Repository repository : repositories) {
+ for (Feature feature : repository.getFeatures()) {
+ if (newFeatures.contains(feature.getId())) {
+ configInstaller.installFeatureConfigs(feature);
+ }
+ }
+ }
+ }
+
+ if (!noRefreshManaged) {
+ findBundlesWithOptionalPackagesToRefresh(toRefresh);
+ findBundlesWithFragmentsToRefresh(toRefresh);
+ }
+
+ if (noRefreshUnmanaged) {
+ Set<Bundle> newSet = new HashSet<Bundle>();
+ for (Bundle bundle : toRefresh) {
+ if (managed.contains(bundle.getBundleId())) {
+ newSet.add(bundle);
+ }
+ }
+ toRefresh = newSet;
+ }
+
+ // TODO: remove this hack, but it avoids loading the class after the bundle is refreshed
+ RequirementSort sort = new RequirementSort();
+
+ if (!noRefresh) {
+ toStop = new HashSet<Bundle>();
+ toStop.addAll(toRefresh);
+ removeFragmentsAndBundlesInState(toStop, Bundle.UNINSTALLED | Bundle.RESOLVED | Bundle.STOPPING);
+ if (!toStop.isEmpty()) {
+ print("Stopping bundles:", verbose);
+ while (!toStop.isEmpty()) {
+ List<Bundle> bs = getBundlesToStop(toStop);
+ for (Bundle bundle : bs) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ bundle.stop(Bundle.STOP_TRANSIENT);
+ toStop.remove(bundle);
+ toStart.add(bundle);
+ }
+ }
+ }
+
+ if (!toRefresh.isEmpty()) {
+ print("Refreshing bundles:", verbose);
+ for (Bundle bundle : toRefresh) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ }
+ if (!toRefresh.isEmpty()) {
+ refreshPackages(toRefresh);
+ }
+ }
+ }
+
+ // Compute bundles to start
+ removeFragmentsAndBundlesInState(toStart, Bundle.UNINSTALLED | Bundle.ACTIVE | Bundle.STARTING);
+ if (!toStart.isEmpty()) {
+ // Compute correct start order
+ List<Exception> exceptions = new ArrayList<Exception>();
+ print("Starting bundles:", verbose);
+ while (!toStart.isEmpty()) {
+ List<Bundle> bs = getBundlesToStart(toStart);
+ for (Bundle bundle : bs) {
+ LOGGER.info(" " + bundle.getSymbolicName() + " / " + bundle.getVersion());
+ try {
+ bundle.start();
+ } catch (BundleException e) {
+ exceptions.add(e);
+ }
+ toStart.remove(bundle);
+ }
+ }
+ if (!exceptions.isEmpty()) {
+ throw new MultiException("Error restarting bundles", exceptions);
+ }
+ }
+
+ // TODO: call listeners for features added and removed
+
+ print("Done.", verbose);
+ }
+
+ private void addTransitive(Resource resource, Set<Resource> resources, Map<Resource, List<Wire>> resolution) {
+ if (resources.add(resource)) {
+ for (Wire wire : resolution.get(resource)) {
+ addTransitive(wire.getProvider(), resources, resolution);
+ }
+ }
+ }
+
+ protected BundleInfo mergeBundleInfo(BundleInfo bi, BundleInfo oldBi) {
+ // TODO: we need a proper merge strategy when a bundle
+ // TODO: comes from different features
+ return bi;
+ }
+
+ private void print(String message, boolean verbose) {
+ LOGGER.info(message);
+ if (verbose) {
+ System.out.println(message);
+ }
+ }
+
+ private void removeFragmentsAndBundlesInState(Collection<Bundle> bundles, int state) {
+ for (Bundle bundle : new ArrayList<Bundle>(bundles)) {
+ if ((bundle.getState() & state) != 0
+ || bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null) {
+ bundles.remove(bundle);
+ }
+ }
+ }
+
+ protected void logDeployment(Deployment deployment, boolean verbose) {
+ print("Changes to perform:", verbose);
+ if (!deployment.toDelete.isEmpty()) {
+ print(" Bundles to uninstall:", verbose);
+ for (Bundle bundle : deployment.toDelete) {
+ print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
+ }
+ }
+ if (!deployment.toUpdate.isEmpty()) {
+ print(" Bundles to update:", verbose);
+ for (Map.Entry<Bundle, Resource> entry : deployment.toUpdate.entrySet()) {
+ print(" " + entry.getKey().getSymbolicName() + " / " + entry.getKey().getVersion() + " with " + UriNamespace.getUri(entry.getValue()), verbose);
+ }
+ }
+ if (!deployment.toInstall.isEmpty()) {
+ print(" Bundles to install:", verbose);
+ for (Resource resource : deployment.toInstall) {
+ print(" " + UriNamespace.getUri(resource), verbose);
+ }
+ }
+ }
+
+ protected Deployment computeDeployment(
+ Set<Long> managed,
+ Bundle[] bundles,
+ Map<String, StreamProvider> providers,
+ List<Resource> resources,
+ Map<String, Long> bundleChecksums) throws IOException {
+ Deployment deployment = new Deployment();
+
+ // TODO: regions
+ List<Resource> toDeploy = new ArrayList<Resource>(resources);
+
+ // First pass: go through all installed bundles and mark them
+ // as either to ignore or delete
+ for (Bundle bundle : bundles) {
+ if (bundle.getSymbolicName() != null && bundle.getBundleId() != 0) {
+ Resource resource = null;
+ for (Resource res : toDeploy) {
+ if (bundle.getSymbolicName().equals(getSymbolicName(res))) {
+ if (bundle.getVersion().equals(getVersion(res))) {
+ resource = res;
+ break;
+ }
+ }
+ }
+ // We found a matching bundle
+ if (resource != null) {
+ // In case of snapshots, check if the snapshot is out of date
+ // and flag it as to update
+ if (managed.contains(bundle.getBundleId()) && isUpdateable(resource)) {
+ // Always update snapshots
+ if (UPDATE_SNAPSHOTS_ALWAYS.equalsIgnoreCase(updateSnaphots)) {
+ LOGGER.debug("Update snapshot for " + bundle.getLocation());
+ deployment.toUpdate.put(bundle, resource);
+ }
+ else if (UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
+ // if the checksum are different
+ InputStream is = null;
+ try {
+ is = getBundleInputStream(resource, providers);
+ long newCrc = ChecksumUtils.checksum(is);
+ long oldCrc = bundleChecksums.containsKey(bundle.getLocation()) ? bundleChecksums.get(bundle.getLocation()) : 0l;
+ if (newCrc != oldCrc) {
+ LOGGER.debug("New snapshot available for " + bundle.getLocation());
+ deployment.toUpdate.put(bundle, resource);
+ deployment.newCheckums.put(bundle.getLocation(), newCrc);
+ }
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+ }
+ // We're done for this resource
+ toDeploy.remove(resource);
+ deployment.resToBnd.put(resource, bundle);
+ // There's no matching resource
+ // If the bundle is managed, we need to delete it
+ } else if (managed.contains(bundle.getBundleId())) {
+ deployment.toDelete.add(bundle);
+ }
+ }
+ }
+
+ // Second pass on remaining resources
+ for (Resource resource : toDeploy) {
+ TreeMap<Version, Bundle> matching = new TreeMap<Version, Bundle>();
+ VersionRange range = new VersionRange(Macro.transform(bundleUpdateRange, getVersion(resource).toString()));
+ for (Bundle bundle : deployment.toDelete) {
+ if (bundle.getSymbolicName().equals(getSymbolicName(resource)) && range.contains(bundle.getVersion())) {
+ matching.put(bundle.getVersion(), bundle);
+ }
+ }
+ if (!matching.isEmpty()) {
+ Bundle bundle = matching.lastEntry().getValue();
+ deployment.toUpdate.put(bundle, resource);
+ deployment.toDelete.remove(bundle);
+ deployment.resToBnd.put(resource, bundle);
+ } else {
+ deployment.toInstall.add(resource);
+ }
+ }
+ return deployment;
+ }
+
+ protected List<Resource> getBundles(Collection<Resource> allResources) {
+ Map<String, Resource> deploy = new TreeMap<String, Resource>();
+ for (Resource res : allResources) {
+ String uri = UriNamespace.getUri(res);
+ if (uri != null) {
+ deploy.put(uri, res);
+ }
+ }
+ return new ArrayList<Resource>(deploy.values());
+ }
+
+ protected List<Feature> getFeatures(Repository[] repositories, List<String> featureIds) throws Exception {
+ List<Feature> installedFeatures = new ArrayList<Feature>();
+ for (Repository repository : repositories) {
+ for (Feature feature : repository.getFeatures()) {
+ String id = feature.getName() + "/" + VersionTable.getVersion(feature.getVersion());
+ if (featureIds.contains(id)) {
+ installedFeatures.add(feature);
+ }
+ }
+ }
+ return installedFeatures;
+ }
+
+ protected List<String> getFeatureIds(Collection<Resource> allResources) {
+ List<String> installedFeatureIds = new ArrayList<String>();
+ for (Resource resource : allResources) {
+ String name = FeatureNamespace.getName(resource);
+ if (name != null) {
+ Version version = FeatureNamespace.getVersion(resource);
+ String id = version != null ? name + "/" + version : name;
+ installedFeatureIds.add(id);
+ }
+ }
+ return installedFeatureIds;
+ }
+
+ protected DeploymentBuilder createDeploymentBuilder(Repository[] repositories) {
+ return new DeploymentBuilder(new SimpleDownloader(), Arrays.asList(repositories));
+ }
+
+
+ protected boolean isUpdateable(Resource resource) {
+ return (getVersion(resource).getQualifier().endsWith(SNAPSHOT) ||
+ UriNamespace.getUri(resource).contains(SNAPSHOT) ||
+ !UriNamespace.getUri(resource).contains(MAVEN));
+ }
+
+ protected List<Bundle> getBundlesToStart(Collection<Bundle> bundles) {
+ // TODO: make this pluggable ?
+ // TODO: honor respectStartLvlDuringFeatureStartup
+
+ // We hit FELIX-2949 if we don't use the correct order as Felix resolver isn't greedy.
+ // In order to minimize that, we make sure we resolve the bundles in the order they
+ // are given back by the resolution, meaning that all root bundles (i.e. those that were
+ // not flagged as dependencies in features) are started before the others. This should
+ // make sure those important bundles are started first and minimize the problem.
+
+ // Restart the features service last, regardless of any other consideration
+ // so that we don't end up with the service trying to do stuff before we're done
+ boolean restart = bundles.remove(bundle);
+
+ List<BundleRevision> revs = new ArrayList<BundleRevision>();
+ for (Bundle bundle : bundles) {
+ revs.add(bundle.adapt(BundleRevision.class));
+ }
+ List<Bundle> sorted = new ArrayList<Bundle>();
+ for (BundleRevision rev : RequirementSort.sort(revs)) {
+ sorted.add(rev.getBundle());
+ }
+ if (restart) {
+ sorted.add(bundle);
+ }
+ return sorted;
+ }
+
+ protected List<Bundle> getBundlesToStop(Collection<Bundle> bundles) {
+ // TODO: make this pluggable ?
+ // TODO: honor respectStartLvlDuringFeatureUninstall
+
+ List<Bundle> bundlesToDestroy = new ArrayList<Bundle>();
+ for (Bundle bundle : bundles) {
+ ServiceReference[] references = bundle.getRegisteredServices();
+ int usage = 0;
+ if (references != null) {
+ for (ServiceReference reference : references) {
+ usage += getServiceUsage(reference, bundles);
+ }
+ }
+ LOGGER.debug("Usage for bundle {} is {}", bundle, usage);
+ if (usage == 0) {
+ bundlesToDestroy.add(bundle);
+ }
+ }
+ if (!bundlesToDestroy.isEmpty()) {
+ Collections.sort(bundlesToDestroy, new Comparator<Bundle>() {
+ public int compare(Bundle b1, Bundle b2) {
+ return (int) (b2.getLastModified() - b1.getLastModified());
+ }
+ });
+ LOGGER.debug("Selected bundles {} for destroy (no services in use)", bundlesToDestroy);
+ } else {
+ ServiceReference ref = null;
+ for (Bundle bundle : bundles) {
+ ServiceReference[] references = bundle.getRegisteredServices();
+ for (ServiceReference reference : references) {
+ if (getServiceUsage(reference, bundles) == 0) {
+ continue;
+ }
+ if (ref == null || reference.compareTo(ref) < 0) {
+ LOGGER.debug("Currently selecting bundle {} for destroy (with reference {})", bundle, reference);
+ ref = reference;
+ }
+ }
+ }
+ if (ref != null) {
+ bundlesToDestroy.add(ref.getBundle());
+ }
+ LOGGER.debug("Selected bundle {} for destroy (lowest ranking service)", bundlesToDestroy);
+ }
+ return bundlesToDestroy;
+ }
+
+ private static int getServiceUsage(ServiceReference ref, Collection<Bundle> bundles) {
+ Bundle[] usingBundles = ref.getUsingBundles();
+ int nb = 0;
+ if (usingBundles != null) {
+ for (Bundle bundle : usingBundles) {
+ if (bundles.contains(bundle)) {
+ nb++;
+ }
+ }
+ }
+ return nb;
+ }
+
+ protected InputStream getBundleInputStream(Resource resource, Map<String, StreamProvider> providers) throws IOException {
+ String uri = UriNamespace.getUri(resource);
+ if (uri == null) {
+ throw new IllegalStateException("Resource has no uri");
+ }
+ StreamProvider provider = providers.get(uri);
+ if (provider == null) {
+ throw new IllegalStateException("Resource " + uri + " has no StreamProvider");
+ }
+ return provider.open();
+ }
+
+ protected void findBundlesWithOptionalPackagesToRefresh(Set<Bundle> toRefresh) {
+ // First pass: include all bundles contained in these features
+ if (toRefresh.isEmpty()) {
+ return;
+ }
+ Set<Bundle> bundles = new HashSet<Bundle>(Arrays.asList(systemBundleContext.getBundles()));
+ bundles.removeAll(toRefresh);
+ if (bundles.isEmpty()) {
+ return;
+ }
+ // Second pass: for each bundle, check if there is any unresolved optional package that could be resolved
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ boolean matches = false;
+ if (rev != null) {
+ for (BundleRequirement req : rev.getDeclaredRequirements(null)) {
+ if (PackageNamespace.PACKAGE_NAMESPACE.equals(req.getNamespace())
+ && PackageNamespace.RESOLUTION_OPTIONAL.equals(req.getDirectives().get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE))) {
+ // This requirement is an optional import package
+ for (Bundle provider : toRefresh) {
+ BundleRevision providerRev = provider.adapt(BundleRevision.class);
+ if (providerRev != null) {
+ for (BundleCapability cap : providerRev.getDeclaredCapabilities(null)) {
+ if (req.matches(cap)) {
+ matches = true;
+ break;
+ }
+ }
+ }
+ if (matches) {
+ break;
+ }
+ }
+ }
+ if (matches) {
+ break;
+ }
+ }
+ }
+ if (matches) {
+ toRefresh.add(bundle);
+ }
+ }
+ }
+
+ protected void findBundlesWithFragmentsToRefresh(Set<Bundle> toRefresh) {
+ if (toRefresh.isEmpty()) {
+ return;
+ }
+ Set<Bundle> bundles = new HashSet<Bundle>(Arrays.asList(systemBundleContext.getBundles()));
+ bundles.removeAll(toRefresh);
+ if (bundles.isEmpty()) {
+ return;
+ }
+ for (Bundle bundle : new ArrayList<Bundle>(toRefresh)) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev != null) {
+ for (BundleRequirement req : rev.getDeclaredRequirements(null)) {
+ if (BundleRevision.HOST_NAMESPACE.equals(req.getNamespace())) {
+ for (Bundle hostBundle : bundles) {
+ if (!toRefresh.contains(hostBundle)) {
+ BundleRevision hostRev = hostBundle.adapt(BundleRevision.class);
+ if (hostRev != null) {
+ for (BundleCapability cap : hostRev.getDeclaredCapabilities(null)) {
+ if (req.matches(cap)) {
+ toRefresh.add(hostBundle);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected void refreshPackages(Collection<Bundle> bundles) throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ FrameworkWiring fw = systemBundleContext.getBundle().adapt(FrameworkWiring.class);
+ fw.refreshBundles(bundles, new FrameworkListener() {
+ @Override
+ public void frameworkEvent(FrameworkEvent event) {
+ if (event.getType() == FrameworkEvent.ERROR) {
+ LOGGER.error("Framework error", event.getThrowable());
+ }
+ latch.countDown();
+ }
+ });
+ latch.await();
+ }
+
+
+ static class Deployment {
+ Map<String, Long> newCheckums = new HashMap<String, Long>();
+ Map<Resource, Bundle> resToBnd = new HashMap<Resource, Bundle>();
+ List<Resource> toInstall = new ArrayList<Resource>();
+ List<Bundle> toDelete = new ArrayList<Bundle>();
+ Map<Bundle, Resource> toUpdate = new HashMap<Bundle, Resource>();
+ }
+
+}
[16/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/NOTICE
----------------------------------------------------------------------
diff --git a/features/core/NOTICE b/features/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/features/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/999f4970/features/core/pom.xml
----------------------------------------------------------------------
diff --git a/features/core/pom.xml b/features/core/pom.xml
deleted file mode 100644
index fc9f9ce..0000000
--- a/features/core/pom.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?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.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Features :: Core</name>
- <description>This bundle is the core implementation of the Karaf features support.</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>
- <optional>true</optional>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.resolver</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.ops4j.pax.tinybundles</groupId>
- <artifactId>tinybundles</artifactId>
- <scope>test</scope>
- </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>
- <Export-Package>
- org.apache.karaf.features;
- org.apache.karaf.features.management;
- org.apache.karaf.features.management.codec;
- -noimport:=true
- </Export-Package>
- <Provide-Capability>
- service-reference;effective:=active;objectClass=org.apache.karaf.features.FeaturesService
- </Provide-Capability>
- <Private-Package>
- org.apache.karaf.features.internal.*,
- org.apache.felix.resolver,
- org.apache.felix.utils.version,
- org.apache.felix.utils.manifest,
- org.apache.karaf.util.collections,
- org.apache.karaf.util.json,
- org.apache.karaf.util.tracker,
- org.osgi.service.resolver,
- org.osgi.service.repository
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.features.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/BootFinished.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/BootFinished.java b/features/core/src/main/java/org/apache/karaf/features/BootFinished.java
deleted file mode 100644
index aa72248..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/BootFinished.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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;
-
-/**
- * Marker interface for a service that announces when the karaf boot is finished
- */
-public interface BootFinished {
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/BundleInfo.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/BundleInfo.java b/features/core/src/main/java/org/apache/karaf/features/BundleInfo.java
deleted file mode 100644
index 97a541f..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/BundleInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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;
-
-/**
- * A bundle info holds info about a Bundle.
- */
-public interface BundleInfo {
-
- String getLocation();
-
- int getStartLevel();
-
- boolean isStart();
-
- boolean isDependency();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Capability.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Capability.java b/features/core/src/main/java/org/apache/karaf/features/Capability.java
deleted file mode 100644
index d329708..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Capability.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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;
-
-public interface Capability {
-
- String getValue();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Conditional.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Conditional.java b/features/core/src/main/java/org/apache/karaf/features/Conditional.java
deleted file mode 100644
index c0e4d59..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Conditional.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-import java.util.Map;
-
-public interface Conditional {
-
- List<? extends Dependency> getCondition();
-
- List<Dependency> getDependencies();
-
- List<BundleInfo> getBundles();
-
- Map<String, Map<String, String>> getConfigurations();
-
- List<ConfigFileInfo> getConfigurationFiles();
-
- Feature asFeature(String name, String version);
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/ConfigFileInfo.java b/features/core/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
deleted file mode 100644
index 960fb31..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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;
-
-public interface ConfigFileInfo {
-
- String getLocation();
-
- String getFinalname();
-
- boolean isOverride();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Dependency.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Dependency.java b/features/core/src/main/java/org/apache/karaf/features/Dependency.java
deleted file mode 100644
index cafdd92..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Dependency.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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;
-
-public interface Dependency {
-
- String getName();
-
- String getVersion();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/EventConstants.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/EventConstants.java b/features/core/src/main/java/org/apache/karaf/features/EventConstants.java
deleted file mode 100644
index f83f185..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/EventConstants.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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;
-
-/**
- * Constants for EventAdmin events
- */
-public final class EventConstants {
-
- public static final String TYPE = "type";
- public static final String EVENT = "event";
- public static final String TIMESTAMP = "timestamp";
-
- public static final String FEATURE_NAME = "name";
- public static final String FEATURE_VERSION = "version";
-
- public static final String REPOSITORY_NAME = "name";
- public static final String REPOSITORY_URI = "uri";
-
- public static final String TOPIC_EVENTS = "org/apache/karaf/features";
- public static final String TOPIC_FEATURES_INSTALLED = TOPIC_EVENTS + "/features/INSTALLED";
- public static final String TOPIC_FEATURES_UNINSTALLED = TOPIC_EVENTS + "/features/UNINSTALLED";
- public static final String TOPIC_REPOSITORY_ADDED = TOPIC_EVENTS + "/repositories/ADDED";
- public static final String TOPIC_REPOSITORY_REMOVED = TOPIC_EVENTS + "/repositories/REMOVED";
-
- private EventConstants() {
- // non-instantiable class
- }
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Feature.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Feature.java b/features/core/src/main/java/org/apache/karaf/features/Feature.java
deleted file mode 100644
index 2f9f001..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Feature.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * A feature is a list of bundles associated identified by its name.
- */
-public interface Feature {
-
- public static String DEFAULT_INSTALL_MODE = "auto";
-
- String getId();
-
- String getName();
-
- String getDescription();
-
- String getDetails();
-
- String getVersion();
-
- boolean hasVersion();
-
- String getResolver();
-
- String getInstall();
-
- List<Dependency> getDependencies();
-
- List<BundleInfo> getBundles();
-
- Map<String, Map<String, String>> getConfigurations();
-
- List<ConfigFileInfo> getConfigurationFiles();
-
- List<? extends Conditional> getConditional();
-
- int getStartLevel();
-
- String getRegion();
-
- List<? extends Capability> getCapabilities();
-
- List<? extends Requirement> getRequirements();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/FeatureEvent.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeatureEvent.java b/features/core/src/main/java/org/apache/karaf/features/FeatureEvent.java
deleted file mode 100644
index 516c988..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/FeatureEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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;
-
-import java.util.EventObject;
-
-public class FeatureEvent extends EventObject {
-
- public static enum EventType {
- FeatureInstalled,
- FeatureUninstalled
- }
-
- private final EventType type;
- private final Feature feature;
- private final boolean replay;
-
- public FeatureEvent(Feature feature, EventType type, boolean replay) {
- super(feature);
- this.type = type;
- this.feature = feature;
- this.replay = replay;
- }
-
- public EventType getType() {
- return type;
- }
-
- public Feature getFeature() {
- return feature;
- }
-
- public boolean isReplay() {
- return replay;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/FeaturesListener.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesListener.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesListener.java
deleted file mode 100644
index 69f68c6..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesListener.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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;
-
-public interface FeaturesListener {
-
- void featureEvent(FeatureEvent event);
-
- void repositoryEvent(RepositoryEvent event);
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
deleted file mode 100644
index 282ff71..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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;
-
-import javax.xml.namespace.QName;
-
-/**
- * Provides features XML/XSD constants.
- */
-public interface FeaturesNamespaces {
-
- String URI_0_0_0 = "";
- String URI_1_0_0 = "http://karaf.apache.org/xmlns/features/v1.0.0";
- String URI_1_1_0 = "http://karaf.apache.org/xmlns/features/v1.1.0";
- String URI_1_2_0 = "http://karaf.apache.org/xmlns/features/v1.2.0";
- String URI_1_3_0 = "http://karaf.apache.org/xmlns/features/v1.3.0";
-
- String URI_CURRENT = URI_1_3_0;
-
- QName FEATURES_0_0_0 = new QName("features");
- QName FEATURES_1_0_0 = new QName(URI_1_0_0, "features");
- QName FEATURES_1_1_0 = new QName(URI_1_1_0, "features");
- QName FEATURES_1_2_0 = new QName(URI_1_2_0, "features");
- QName FEATURES_1_3_0 = new QName(URI_1_3_0, "features");
-
- QName FEATURES_CURRENT = FEATURES_1_3_0;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
deleted file mode 100644
index ef3dbcf..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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;
-
-import java.net.URI;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * The service managing features repositories.
- */
-public interface FeaturesService {
-
- enum Option {
- NoFailOnFeatureNotFound,
- NoAutoRefreshManagedBundles,
- NoAutoRefreshUnmanagedBundles,
- NoAutoRefreshBundles,
- NoAutoStartBundles,
- Simulate,
- Verbose
- }
-
- /**
- * Validate repository contents.
- *
- * @param uri Repository uri.
- * @throws Exception When validation fails.
- */
- void validateRepository(URI uri) throws Exception;
-
- void addRepository(URI uri) throws Exception;
-
- void addRepository(URI uri, boolean install) throws Exception;
-
- void removeRepository(URI uri) throws Exception;
-
- void removeRepository(URI uri, boolean uninstall) throws Exception;
-
- void restoreRepository(URI uri) throws Exception;
-
- Repository[] listRequiredRepositories() throws Exception;
-
- Repository[] listRepositories() throws Exception;
-
- Repository getRepository(String repoName) throws Exception;
-
- void installFeature(String name) throws Exception;
-
- void installFeature(String name, EnumSet<Option> options) throws Exception;
-
- void installFeature(String name, String version) throws Exception;
-
- void installFeature(String name, String version, EnumSet<Option> options) throws Exception;
-
- void installFeature(Feature f, EnumSet<Option> options) throws Exception;
-
- void installFeatures(Set<String> features, EnumSet<Option> options) throws Exception;
-
- void uninstallFeature(String name, EnumSet<Option> options) throws Exception;
-
- void uninstallFeature(String name) throws Exception;
-
- void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception;
-
- void uninstallFeature(String name, String version) throws Exception;
-
- void uninstallFeatures(Set<String> features, EnumSet<Option> options) throws Exception;
-
- Feature[] listFeatures() throws Exception;
-
- Feature[] listRequiredFeatures() throws Exception;
-
- Feature[] listInstalledFeatures() throws Exception;
-
- boolean isRequired(Feature f);
-
- boolean isInstalled(Feature f);
-
- Feature getFeature(String name, String version) throws Exception;
-
- Feature getFeature(String name) throws Exception;
-
- void refreshRepository(URI uri) throws Exception;
-
- public URI getRepositoryUriFor(String name, String version);
-
- public String[] getRepositoryNames();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/RegionsPersistence.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/RegionsPersistence.java b/features/core/src/main/java/org/apache/karaf/features/RegionsPersistence.java
deleted file mode 100644
index 96ca7da..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/RegionsPersistence.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-
-public interface RegionsPersistence {
- void install(Bundle b, String regionName) throws BundleException;
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Repository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Repository.java b/features/core/src/main/java/org/apache/karaf/features/Repository.java
deleted file mode 100644
index 6ee96da..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Repository.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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;
-
-import java.net.URI;
-
-/**
- * A repository of features.
- */
-public interface Repository {
-
- String getName();
-
- URI getURI();
-
- URI[] getRepositories() throws Exception;
-
- Feature[] getFeatures() throws Exception;
-
- boolean isValid();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/RepositoryEvent.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/RepositoryEvent.java b/features/core/src/main/java/org/apache/karaf/features/RepositoryEvent.java
deleted file mode 100644
index 68f287b..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/RepositoryEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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;
-
-import java.util.EventObject;
-
-public class RepositoryEvent extends EventObject {
-
- public static enum EventType {
- RepositoryAdded,
- RepositoryRemoved,
- }
-
- private final EventType type;
- private final Repository repository;
- private final boolean replay;
-
- public RepositoryEvent(Repository repository, EventType type, boolean replay) {
- super(repository);
- this.type = type;
- this.repository = repository;
- this.replay = replay;
- }
-
- public EventType getType() {
- return type;
- }
-
- public Repository getRepository() {
- return repository;
- }
-
- public boolean isReplay() {
- return replay;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Requirement.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Requirement.java b/features/core/src/main/java/org/apache/karaf/features/Requirement.java
deleted file mode 100644
index 4446335..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Requirement.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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;
-
-public interface Requirement {
-
- String getValue();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/Resolver.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Resolver.java b/features/core/src/main/java/org/apache/karaf/features/Resolver.java
deleted file mode 100644
index d2fa941..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/Resolver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-
-public interface Resolver {
-
- List<BundleInfo> resolve(Feature feature) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java b/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
deleted file mode 100644
index 00a91c4..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.internal.deployment;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.apache.felix.resolver.ResolverImpl;
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.Conditional;
-import org.apache.karaf.features.Dependency;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.Repository;
-import org.apache.karaf.features.internal.repository.AggregateRepository;
-import org.apache.karaf.features.internal.repository.StaticRepository;
-import org.apache.karaf.features.internal.resolver.FeatureNamespace;
-import org.apache.karaf.features.internal.resolver.FeatureResource;
-import org.apache.karaf.features.internal.resolver.RequirementImpl;
-import org.apache.karaf.features.internal.resolver.ResolveContextImpl;
-import org.apache.karaf.features.internal.resolver.ResourceBuilder;
-import org.apache.karaf.features.internal.resolver.ResourceImpl;
-import org.apache.karaf.features.internal.resolver.Slf4jResolverLog;
-import org.apache.karaf.features.internal.service.Overrides;
-import org.apache.karaf.features.internal.util.Macro;
-import org.apache.karaf.features.internal.util.MultiException;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-import org.osgi.resource.Wire;
-import org.osgi.service.resolver.ResolutionException;
-import org.osgi.service.resolver.ResolveContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- */
-public class DeploymentBuilder {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DeploymentBuilder.class);
-
- public static final String REQ_PROTOCOL = "req:";
-
- private final Collection<Repository> repositories;
-
- private final List<org.osgi.service.repository.Repository> resourceRepos;
-
- String featureRange = "${range;[====,====]}";
-
- Downloader downloader;
- ResourceImpl requirements;
- Map<String, Resource> resources;
- Set<Resource> optionals;
- Map<String, StreamProvider> providers;
-
- Set<Feature> featuresToRegister = new HashSet<Feature>();
-
- public DeploymentBuilder(Downloader downloader,
- Collection<Repository> repositories) {
- this.downloader = downloader;
- this.repositories = repositories;
- this.resourceRepos = new ArrayList<org.osgi.service.repository.Repository>();
- }
-
- public void addResourceRepository(org.osgi.service.repository.Repository repository) {
- resourceRepos.add(repository);
- }
-
- public Map<String, StreamProvider> getProviders() {
- return providers;
- }
-
- public void setFeatureRange(String featureRange) {
- this.featureRange = featureRange;
- }
-
- public Map<String, Resource> download(
- Set<String> features,
- Set<String> bundles,
- Set<String> reqs,
- Set<String> overrides,
- Set<String> optionals)
- throws IOException, MultiException, InterruptedException, ResolutionException, BundleException {
- this.resources = new ConcurrentHashMap<String, Resource>();
- this.optionals = new HashSet<Resource>();
- this.providers = new ConcurrentHashMap<String, StreamProvider>();
- this.requirements = new ResourceImpl("dummy", "dummy", Version.emptyVersion);
- // First, gather all bundle resources
- for (String feature : features) {
- registerMatchingFeatures(feature);
- }
- for (String bundle : bundles) {
- downloadAndBuildResource(bundle);
- }
- for (String req : reqs) {
- buildRequirement(req);
- }
- for (String override : overrides) {
- // TODO: ignore download failures for overrides
- downloadAndBuildResource(Overrides.extractUrl(override));
- }
- for (String optional : optionals) {
- downloadAndBuildResource(optional);
- }
- // Wait for all resources to be created
- downloader.await();
- // Do override replacement
- Overrides.override(resources, overrides);
- // Build features resources
- for (Feature feature : featuresToRegister) {
- Resource resource = FeatureResource.build(feature, featureRange, resources);
- resources.put("feature:" + feature.getName() + "/" + feature.getVersion(), resource);
- for (Conditional cond : feature.getConditional()) {
- this.optionals.add(FeatureResource.build(feature, cond, featureRange, resources));
- }
- }
- // Build requirements
- for (String feature : features) {
- requireFeature(feature);
- }
- for (String bundle : bundles) {
- requireResource(bundle);
- }
- for (String req : reqs) {
- requireResource(REQ_PROTOCOL + req);
- }
- return resources;
- }
-
- public Map<Resource, List<Wire>> resolve(List<Resource> systemBundles,
- boolean resolveOptionalImports) throws ResolutionException {
- // Resolve
- for (int i = 0; i < systemBundles.size(); i++) {
- resources.put("system-bundle-" + i, systemBundles.get(i));
- }
-
- List<org.osgi.service.repository.Repository> repos = new ArrayList<org.osgi.service.repository.Repository>();
- repos.add(new StaticRepository(resources.values()));
- repos.addAll(resourceRepos);
-
- ResolverImpl resolver = new ResolverImpl(new Slf4jResolverLog(LOGGER));
- ResolveContext context = new ResolveContextImpl(
- Collections.<Resource>singleton(requirements),
- this.optionals,
- new AggregateRepository(repos),
- resolveOptionalImports);
-
- return resolver.resolve(context);
- }
-
- public void requireFeature(String feature) throws IOException {
- // Find name and version range
- String[] split = feature.split("/");
- String name = split[0].trim();
- String version = (split.length > 1) ? split[1].trim() : null;
- if (version != null && !version.equals("0.0.0") && !version.startsWith("[") && !version.startsWith("(")) {
- version = Macro.transform(featureRange, version);
- }
- VersionRange range = version != null ? new VersionRange(version) : VersionRange.ANY_VERSION;
- // Add requirement
- Map<String, Object> attrs = new HashMap<String, Object>();
- attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
- attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, FeatureNamespace.TYPE_FEATURE);
- attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, range);
- requirements.addRequirement(
- new RequirementImpl(requirements, IdentityNamespace.IDENTITY_NAMESPACE,
- Collections.<String, String>emptyMap(), attrs)
- );
- }
-
- public void requireResource(String location) {
- Resource res = resources.get(location);
- if (res == null) {
- throw new IllegalStateException("Could not find resource for " + location);
- }
- List<Capability> caps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
- if (caps.size() != 1) {
- throw new IllegalStateException("Resource does not have a single " + IdentityNamespace.IDENTITY_NAMESPACE + " capability");
- }
- Capability cap = caps.get(0);
- // Add requirement
- Map<String, Object> attrs = new HashMap<String, Object>();
- attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
- attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
- attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((Version) cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE), true));
- requirements.addRequirement(
- new RequirementImpl(requirements, IdentityNamespace.IDENTITY_NAMESPACE,
- Collections.<String, String>emptyMap(), attrs));
-
- }
-
- public void registerMatchingFeatures(String feature) throws IOException {
- // Find name and version range
- String[] split = feature.split("/");
- String name = split[0].trim();
- String version = (split.length > 1)
- ? split[1].trim() : Version.emptyVersion.toString();
- // Register matching features
- registerMatchingFeatures(name, new VersionRange(version));
- }
-
- public void registerMatchingFeatures(String name, String version) throws IOException {
- if (version != null && !version.equals("0.0.0") && !version.startsWith("[") && !version.startsWith("(")) {
- version = Macro.transform(featureRange, version);
- }
- registerMatchingFeatures(name, version != null ? new VersionRange(version) : VersionRange.ANY_VERSION);
- }
-
- public void registerMatchingFeatures(String name, VersionRange range) throws IOException {
- for (Repository repo : repositories) {
- Feature[] features;
- try {
- features = repo.getFeatures();
- } catch (Exception e) {
- // This should not happen as the repository has been loaded already
- throw new IllegalStateException(e);
- }
- for (Feature f : features) {
- if (name.equals(f.getName())) {
- Version v = VersionTable.getVersion(f.getVersion());
- if (range.contains(v)) {
- featuresToRegister.add(f);
- for (Dependency dep : f.getDependencies()) {
- registerMatchingFeatures(dep.getName(), dep.getVersion());
- }
- for (BundleInfo bundle : f.getBundles()) {
- downloadAndBuildResource(bundle.getLocation());
- }
- for (Conditional cond : f.getConditional()) {
- Feature c = cond.asFeature(f.getName(), f.getVersion());
- featuresToRegister.add(c);
- for (BundleInfo bundle : c.getBundles()) {
- downloadAndBuildResource(bundle.getLocation());
- }
- }
- }
- }
- }
- }
- }
-
- public void buildRequirement(String requirement) {
- try {
- String location = REQ_PROTOCOL + requirement;
- ResourceImpl resource = new ResourceImpl(location, "dummy", Version.emptyVersion);
- for (Requirement req : ResourceBuilder.parseRequirement(resource, requirement)) {
- resource.addRequirement(req);
- }
- resources.put(location, resource);
- } catch (BundleException e) {
- throw new IllegalArgumentException("Error parsing requirement: " + requirement, e);
- }
- }
-
- public void downloadAndBuildResource(final String location) throws IOException {
- if (!resources.containsKey(location)) {
- downloader.download(location, new Downloader.DownloadCallback() {
- @Override
- public void downloaded(StreamProvider provider) throws Exception {
- manageResource(location, provider);
- }
- });
- }
- }
-
- private void manageResource(String location, StreamProvider provider) throws Exception {
- if (!resources.containsKey(location)) {
- Attributes attributes = getAttributes(location, provider);
- Resource resource = createResource(location, attributes);
- resources.put(location, resource);
- providers.put(location, provider);
- }
- }
-
- private Resource createResource(String uri, Attributes attributes) throws Exception {
- Map<String, String> headers = new HashMap<String, String>();
- for (Map.Entry attr : attributes.entrySet()) {
- headers.put(attr.getKey().toString(), attr.getValue().toString());
- }
- try {
- return ResourceBuilder.build(uri, headers);
- } catch (BundleException e) {
- throw new Exception("Unable to create resource for bundle " + uri, e);
- }
- }
-
- protected Attributes getAttributes(String uri, StreamProvider provider) throws Exception {
- InputStream is = provider.open();
- try {
- ZipInputStream zis = new ZipInputStream(is);
- ZipEntry entry;
- while ( (entry = zis.getNextEntry()) != null ) {
- if ("META-INF/MANIFEST.MF".equals(entry.getName())) {
- return new Manifest(zis).getMainAttributes();
- }
- }
- } finally {
- is.close();
- }
- throw new IllegalArgumentException("Resource " + uri + " does not contain a manifest");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java b/features/core/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
deleted file mode 100644
index 2d5dd98..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.internal.deployment;
-
-import java.net.MalformedURLException;
-
-import org.apache.karaf.features.internal.util.MultiException;
-
-public interface Downloader {
-
- void await() throws InterruptedException, MultiException;
-
- void download(String location, DownloadCallback downloadCallback) throws MalformedURLException;
-
- interface DownloadCallback {
-
- void downloaded(StreamProvider provider) throws Exception;
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java b/features/core/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
deleted file mode 100644
index 60a3dfc..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.internal.deployment;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public interface StreamProvider {
-
- InputStream open() throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
deleted file mode 100644
index b1a5865..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Licensed 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.internal.management;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.ObjectName;
-import javax.management.openmbean.TabularData;
-
-import org.apache.karaf.features.*;
-import org.apache.karaf.features.management.FeaturesServiceMBean;
-import org.apache.karaf.features.management.codec.JmxFeature;
-import org.apache.karaf.features.management.codec.JmxFeatureEvent;
-import org.apache.karaf.features.management.codec.JmxRepository;
-import org.apache.karaf.features.management.codec.JmxRepositoryEvent;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Implementation of {@link FeaturesServiceMBean}.
- */
-public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
- MBeanRegistration, FeaturesServiceMBean {
-
- private ServiceRegistration<FeaturesListener> registration;
-
- private BundleContext bundleContext;
-
- private ObjectName objectName;
-
- private volatile long sequenceNumber = 0;
-
- private org.apache.karaf.features.FeaturesService featuresService;
-
- public FeaturesServiceMBeanImpl() throws NotCompliantMBeanException {
- super(FeaturesServiceMBean.class);
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
- objectName = name;
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- registration = bundleContext.registerService(FeaturesListener.class,
- getFeaturesListener(), new Hashtable<String, String>());
- }
-
- public void preDeregister() throws Exception {
- registration.unregister();
- }
-
- public void postDeregister() {
- }
-
- /**
- * {@inheritDoc}
- */
- public TabularData getFeatures() throws Exception {
- try {
- List<Feature> allFeatures = Arrays.asList(featuresService.listFeatures());
- List<Feature> insFeatures = Arrays.asList(featuresService.listInstalledFeatures());
- ArrayList<JmxFeature> features = new ArrayList<JmxFeature>();
- for (Feature feature : allFeatures) {
- try {
- features.add(new JmxFeature(feature, insFeatures.contains(feature)));
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
- TabularData table = JmxFeature.tableFrom(features);
- return table;
- } catch (Throwable t) {
- t.printStackTrace();
- return null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public TabularData getRepositories() throws Exception {
- try {
- List<Repository> allRepositories = Arrays.asList(featuresService.listRepositories());
- ArrayList<JmxRepository> repositories = new ArrayList<JmxRepository>();
- for (Repository repository : allRepositories) {
- try {
- repositories.add(new JmxRepository(repository));
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
- TabularData table = JmxRepository.tableFrom(repositories);
- return table;
- } catch (Throwable t) {
- t.printStackTrace();
- return null;
- }
- }
-
- public void addRepository(String uri) throws Exception {
- featuresService.addRepository(new URI(uri));
- }
-
- public void addRepository(String uri, boolean install) throws Exception {
- featuresService.addRepository(new URI(uri), install);
- }
-
- public void removeRepository(String uri) throws Exception {
- featuresService.removeRepository(new URI(uri));
- }
-
- public void removeRepository(String uri, boolean uninstall) throws Exception {
- featuresService.removeRepository(new URI(uri), uninstall);
- }
-
- public void installFeature(String name) throws Exception {
- featuresService.installFeature(name);
- }
-
- public void installFeature(String name, boolean noRefresh) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- featuresService.installFeature(name, options);
- }
-
- public void installFeature(String name, boolean noRefresh, boolean noStart) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- if (noStart) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoStartBundles);
- }
- featuresService.installFeature(name, options);
- }
-
- public void installFeature(String name, String version) throws Exception {
- featuresService.installFeature(name, version);
- }
-
- public void installFeature(String name, String version, boolean noRefresh) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- featuresService.installFeature(name, version, options);
- }
-
- public void installFeature(String name, String version, boolean noRefresh, boolean noStart) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- if (noStart) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoStartBundles);
- }
- featuresService.installFeature(name, version, options);
- }
-
- public TabularData infoFeature(String name) throws Exception {
- try {
- Feature feature = featuresService.getFeature(name);
- return infoFeature(feature);
- } catch (Throwable t) {
- t.printStackTrace();
- return null;
- }
- }
-
- public TabularData infoFeature(String name, String version) throws Exception {
- try {
- Feature feature = featuresService.getFeature(name, version);
- return infoFeature(feature);
- } catch (Throwable t) {
- t.printStackTrace();
- return null;
- }
- }
-
- private TabularData infoFeature(Feature feature) throws Exception {
- JmxFeature jmxFeature = null;
- if (featuresService.isInstalled(feature)) {
- jmxFeature = new JmxFeature(feature, true);
- } else {
- jmxFeature = new JmxFeature(feature, false);
- }
- ArrayList<JmxFeature> features = new ArrayList<JmxFeature>();
- features.add(jmxFeature);
- TabularData table = JmxFeature.tableFrom(features);
- return table;
- }
-
- public void uninstallFeature(String name) throws Exception {
- featuresService.uninstallFeature(name);
- }
-
- public void uninstallFeature(String name, boolean noRefresh) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- featuresService.uninstallFeature(name, options);
- }
-
- public void uninstallFeature(String name, String version) throws Exception {
- featuresService.uninstallFeature(name, version);
- }
-
- public void uninstallFeature(String name, String version, boolean noRefresh) throws Exception {
- EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
- if (noRefresh) {
- options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
- }
- featuresService.uninstallFeature(name, version, options);
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void setFeaturesService(org.apache.karaf.features.FeaturesService featuresService) {
- this.featuresService = featuresService;
- }
-
- public FeaturesListener getFeaturesListener() {
- return new FeaturesListener() {
- public void featureEvent(FeatureEvent event) {
- if (!event.isReplay()) {
- Notification notification = new Notification(FEATURE_EVENT_TYPE, objectName, sequenceNumber++);
- notification.setUserData(new JmxFeatureEvent(event).asCompositeData());
- sendNotification(notification);
- }
- }
-
- public void repositoryEvent(RepositoryEvent event) {
- if (!event.isReplay()) {
- Notification notification = new Notification(REPOSITORY_EVENT_TYPE, objectName, sequenceNumber++);
- notification.setUserData(new JmxRepositoryEvent(event).asCompositeData());
- sendNotification(notification);
- }
- }
-
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- return o.equals(this);
- }
-
- };
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return getBroadcastInfo();
- }
-
- private static MBeanNotificationInfo[] getBroadcastInfo() {
- String type = Notification.class.getCanonicalName();
- MBeanNotificationInfo info1 = new MBeanNotificationInfo(new String[]{FEATURE_EVENT_EVENT_TYPE},
- type, "Some features notification");
- MBeanNotificationInfo info2 = new MBeanNotificationInfo(new String[]{REPOSITORY_EVENT_EVENT_TYPE},
- type, "Some repository notification");
- return new MBeanNotificationInfo[]{info1, info2};
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java b/features/core/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
deleted file mode 100644
index 13a4b6c..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed 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.internal.management;
-
-import javax.management.*;
-
-public class StandardEmitterMBean extends StandardMBean implements NotificationEmitter {
-
- private final NotificationBroadcasterSupport emitter;
-
- @SuppressWarnings("rawtypes")
- public StandardEmitterMBean(Class mbeanInterface) throws NotCompliantMBeanException {
- super(mbeanInterface);
- this.emitter = new NotificationBroadcasterSupport() {
- @Override
- public MBeanNotificationInfo[] getNotificationInfo() {
- return StandardEmitterMBean.this.getNotificationInfo();
- }
- };
- }
-
- public void sendNotification(Notification notification) {
- emitter.sendNotification(notification);
- }
-
-
- public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
- emitter.removeNotificationListener(listener, filter, handback);
- }
-
- public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
- emitter.addNotificationListener(listener, filter, handback);
- }
-
- public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
- emitter.removeNotificationListener(listener);
- }
-
- public MBeanNotificationInfo[] getNotificationInfo() {
- return new MBeanNotificationInfo[0];
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- MBeanInfo mbeanInfo = super.getMBeanInfo();
- if (mbeanInfo != null) {
- MBeanNotificationInfo[] notificationInfo = getNotificationInfo();
- mbeanInfo = new MBeanInfo(mbeanInfo.getClassName(), mbeanInfo.getDescription(), mbeanInfo.getAttributes(),
- mbeanInfo.getConstructors(), mbeanInfo.getOperations(), notificationInfo);
- }
- return mbeanInfo;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Bundle.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
deleted file mode 100644
index 7eebbe5..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlSchemaType;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-import org.apache.karaf.features.BundleInfo;
-
-
-/**
- *
- * Deployable element to install.
- *
- *
- * <p>Java class for bundle complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="bundle">
- * <simpleContent>
- * <extension base="<http://www.w3.org/2001/XMLSchema>anyURI">
- * <attribute name="start-level" type="{http://www.w3.org/2001/XMLSchema}int" />
- * <attribute name="start" type="{http://www.w3.org/2001/XMLSchema}boolean" />
- * <attribute name="dependency" type="{http://www.w3.org/2001/XMLSchema}boolean" />
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "bundle", propOrder = {
- "value"
-})
-public class Bundle implements BundleInfo {
-
- @XmlValue
- @XmlSchemaType(name = "anyURI")
- protected String value;
- @XmlAttribute(name = "start-level")
- protected Integer startLevel;
- @XmlAttribute
- protected Boolean start;// = true;
- @XmlAttribute
- protected Boolean dependency;
-
-
- public Bundle() {
- }
-
- public Bundle(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the value property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getLocation() {
- return value;
- }
-
- /**
- * Sets the value of the value property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setLocation(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the startLevel property.
- *
- * @return
- * possible object is
- * {@link Integer }
- *
- */
- public int getStartLevel() {
- return startLevel == null? 0: startLevel;
- }
-
- /**
- * Sets the value of the startLevel property.
- *
- * @param value
- * allowed object is
- * {@link Integer }
- *
- */
- public void setStartLevel(Integer value) {
- this.startLevel = value;
- }
-
- /**
- * Gets the value of the start property.
- *
- * @return
- * possible object is
- * {@link Boolean }
- *
- */
- public boolean isStart() {
- return start == null? true: start;
- }
-
- /**
- * Sets the value of the start property.
- *
- * @param value
- * allowed object is
- * {@link Boolean }
- *
- */
- public void setStart(Boolean value) {
- this.start = value;
- }
-
- /**
- * Gets the value of the dependency property.
- *
- * @return
- * possible object is
- * {@link Boolean }
- *
- */
- public boolean isDependency() {
- return dependency == null? false: dependency;
- }
-
- /**
- * Sets the value of the dependency property.
- *
- * @param value
- * allowed object is
- * {@link Boolean }
- *
- */
- public void setDependency(Boolean value) {
- this.dependency = value;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Bundle bundle = (Bundle) o;
-
- if (dependency != bundle.dependency) return false;
- if (start != bundle.start) return false;
- if (startLevel != bundle.startLevel) return false;
- if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = value != null ? value.hashCode() : 0;
- result = 31 * result + getStartLevel();
- result = 31 * result + (isStart() ? 1 : 0);
- result = 31 * result + (isDependency() ? 1 : 0);
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Capability.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Capability.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Capability.java
deleted file mode 100644
index b866151..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Capability.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlSchemaType;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-
-import org.apache.karaf.features.BundleInfo;
-
-
-/**
- *
- * Additional capability for a feature.
- *
- *
- * <p>Java class for bundle complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="capability">
- * <simpleContent>
- * <extension base="<http://www.w3.org/2001/XMLSchema>string">
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "capability", propOrder = {
- "value"
-})
-public class Capability implements org.apache.karaf.features.Capability {
-
- @XmlValue
- protected String value;
-
-
- public Capability() {
- }
-
- public Capability(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Capability bundle = (Capability) o;
-
- if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = value != null ? value.hashCode() : 0;
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Conditional.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
deleted file mode 100644
index 5bc0b95..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.internal.model;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.karaf.features.Feature;
-
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "conditional", propOrder = {
- "condition",
- "config",
- "configfile",
- "feature",
- "bundle"
-})
-public class Conditional extends Content implements org.apache.karaf.features.Conditional {
-
- @XmlElement(name = "condition")
- protected List<Dependency> condition;
-
- public List<Dependency> getCondition() {
- if (condition == null) {
- this.condition = new ArrayList<Dependency>();
- }
- return condition;
- }
-
- @Override
- public Feature asFeature(String name, String version) {
- String conditionName = name + "-condition-" + getConditionId().replaceAll("[^A-Za-z0-9 ]", "_");
- org.apache.karaf.features.internal.model.Feature f = new org.apache.karaf.features.internal.model.Feature(conditionName, version);
- f.getBundle().addAll(getBundle());
- f.getConfig().addAll(getConfig());
- f.getConfigfile().addAll(getConfigfile());
- f.getFeature().addAll(getFeature());
- return f;
- }
-
- private String getConditionId() {
- StringBuffer sb = new StringBuffer();
- Iterator<Dependency> di = getCondition().iterator();
- while (di.hasNext()) {
- Dependency dependency = di.next();
- sb.append(dependency.getName() + "_" + dependency.getVersion());
- if (di.hasNext()) {
- sb.append("_");
- }
- }
- return sb.toString();
- }
-}
[13/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
deleted file mode 100644
index cb2c36a..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.utils.version.VersionRange;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-public class ResourceBuilder {
-
- public static final String RESOLUTION_DYNAMIC = "dynamic";
-
- public static Resource build(String uri, Map<String, String> headerMap)
- throws BundleException {
-
- // Verify that only manifest version 2 is specified.
- String manifestVersion = getManifestVersion(headerMap);
- if (manifestVersion == null || !manifestVersion.equals("2")) {
- throw new BundleException("Unsupported 'Bundle-ManifestVersion' value: " + manifestVersion);
- }
-
- //
- // Parse bundle version.
- //
-
- Version bundleVersion = Version.emptyVersion;
- if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
- bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
- }
-
- //
- // Parse bundle symbolic name.
- //
-
- String bundleSymbolicName = null;
- ParsedHeaderClause bundleCap = parseBundleSymbolicName(headerMap);
- if (bundleCap == null) {
- throw new BundleException("Bundle manifest must include bundle symbolic name");
- }
- bundleSymbolicName = (String) bundleCap.attrs.get(BundleRevision.BUNDLE_NAMESPACE);
-
- // Now that we have symbolic name and version, create the resource
- String type = headerMap.get(Constants.FRAGMENT_HOST) == null ? IdentityNamespace.TYPE_BUNDLE : IdentityNamespace.TYPE_FRAGMENT;
- ResourceImpl resource = new ResourceImpl(bundleSymbolicName, type, bundleVersion);
- if (uri != null) {
- Map<String, Object> attrs = new HashMap<String, Object>();
- attrs.put(UriNamespace.URI_NAMESPACE, uri);
- resource.addCapability(new CapabilityImpl(resource, UriNamespace.URI_NAMESPACE, Collections.<String, String>emptyMap(), attrs));
- }
-
- // Add a bundle and host capability to all
- // non-fragment bundles. A host capability is the same
- // as a require capability, but with a different capability
- // namespace. Bundle capabilities resolve required-bundle
- // dependencies, while host capabilities resolve fragment-host
- // dependencies.
- if (headerMap.get(Constants.FRAGMENT_HOST) == null) {
- // All non-fragment bundles have bundle capability.
- resource.addCapability(new CapabilityImpl(resource, BundleRevision.BUNDLE_NAMESPACE, bundleCap.dirs, bundleCap.attrs));
- // A non-fragment bundle can choose to not have a host capability.
- String attachment = bundleCap.dirs.get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
- attachment = (attachment == null) ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME : attachment;
- if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
- Map<String, Object> hostAttrs = new HashMap<String, Object>(bundleCap.attrs);
- Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
- hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
- resource.addCapability(new CapabilityImpl(
- resource, BundleRevision.HOST_NAMESPACE,
- bundleCap.dirs,
- hostAttrs));
- }
- }
-
- //
- // Parse Fragment-Host.
- //
-
- List<RequirementImpl> hostReqs = parseFragmentHost(resource, headerMap);
-
- //
- // Parse Require-Bundle
- //
-
- List<ParsedHeaderClause> rbClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_BUNDLE));
- rbClauses = normalizeRequireClauses(rbClauses);
- List<Requirement> rbReqs = convertRequires(rbClauses, resource);
-
- //
- // Parse Import-Package.
- //
-
- List<ParsedHeaderClause> importClauses = parseStandardHeader(headerMap.get(Constants.IMPORT_PACKAGE));
- importClauses = normalizeImportClauses(importClauses);
- List<Requirement> importReqs = convertImports(importClauses, resource);
-
- //
- // Parse DynamicImport-Package.
- //
-
- List<ParsedHeaderClause> dynamicClauses = parseStandardHeader(headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
- dynamicClauses = normalizeDynamicImportClauses(dynamicClauses);
- List<Requirement> dynamicReqs = convertImports(dynamicClauses, resource);
-
- //
- // Parse Require-Capability.
- //
-
- List<ParsedHeaderClause> requireClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_CAPABILITY));
- requireClauses = normalizeRequireCapabilityClauses(requireClauses);
- List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
-
- //
- // Parse Export-Package.
- //
-
- List<ParsedHeaderClause> exportClauses = parseStandardHeader(headerMap.get(Constants.EXPORT_PACKAGE));
- exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
- List<Capability> exportCaps = convertExports(exportClauses, resource);
-
- //
- // Parse Provide-Capability.
- //
-
- List<ParsedHeaderClause> provideClauses = parseStandardHeader(headerMap.get(Constants.PROVIDE_CAPABILITY));
- provideClauses = normalizeProvideCapabilityClauses(provideClauses);
- List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
-
- //
- // Parse Import-Service and Export-Service
- // if Require-Capability and Provide-Capability are not set for services
- //
-
- boolean hasServiceReferenceCapability = false;
- for (Capability cap : exportCaps) {
- hasServiceReferenceCapability |= ServiceNamespace.SERVICE_NAMESPACE.equals(cap.getNamespace());
- }
- if (!hasServiceReferenceCapability) {
- List<ParsedHeaderClause> exportServices = parseStandardHeader(headerMap.get(Constants.EXPORT_SERVICE));
- List<Capability> caps = convertExportService(exportServices, resource);
- provideCaps.addAll(caps);
- }
-
- boolean hasServiceReferenceRequirement = false;
- for (Requirement req : requireReqs) {
- hasServiceReferenceRequirement |= ServiceNamespace.SERVICE_NAMESPACE.equals(req.getNamespace());
- }
- if (!hasServiceReferenceRequirement) {
- List<ParsedHeaderClause> importServices = parseStandardHeader(headerMap.get(Constants.IMPORT_SERVICE));
- List<Requirement> reqs = convertImportService(importServices, resource);
- requireReqs.addAll(reqs);
- }
-
- // Combine all capabilities.
- resource.addCapabilities(exportCaps);
- resource.addCapabilities(provideCaps);
-
- // Combine all requirements.
- resource.addRequirements(hostReqs);
- resource.addRequirements(importReqs);
- resource.addRequirements(rbReqs);
- resource.addRequirements(requireReqs);
- resource.addRequirements(dynamicReqs);
-
- return resource;
- }
-
- public static List<Requirement> parseImport(Resource resource, String imports) throws BundleException {
- List<ParsedHeaderClause> importClauses = parseStandardHeader(imports);
- importClauses = normalizeImportClauses(importClauses);
- List<Requirement> importReqs = convertImports(importClauses, resource);
- return importReqs;
- }
-
- public static List<Requirement> parseRequirement(Resource resource, String requirement) throws BundleException {
- List<ParsedHeaderClause> requireClauses = parseStandardHeader(requirement);
- requireClauses = normalizeRequireCapabilityClauses(requireClauses);
- List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
- return requireReqs;
- }
-
- public static List<Capability> parseExport(Resource resource, String bundleSymbolicName, Version bundleVersion, String exports) throws BundleException {
- List<ParsedHeaderClause> exportClauses = parseStandardHeader(exports);
- exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
- List<Capability> exportCaps = convertExports(exportClauses, resource);
- return exportCaps;
- }
-
- public static List<Capability> parseCapability(Resource resource, String capability) throws BundleException {
- List<ParsedHeaderClause> provideClauses = parseStandardHeader(capability);
- provideClauses = normalizeProvideCapabilityClauses(provideClauses);
- List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
- return provideCaps;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeImportClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
- // Verify that the values are equals if the package specifies
- // both version and specification-version attributes.
- Set<String> dupeSet = new HashSet<String>();
- for (ParsedHeaderClause clause : clauses) {
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim())) {
- throw new IllegalArgumentException(
- "Both version and specification-version are specified, but they are not equal.");
- }
- }
-
- // Ensure that only the "version" attribute is used and convert
- // it to the VersionRange type.
- if ((v != null) || (sv != null)) {
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // If bundle version is specified, then convert its type to VersionRange.
- v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (v != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // Verify java.* is not imported, nor any duplicate imports.
- for (String pkgName : clause.paths) {
- if (!dupeSet.contains(pkgName)) {
- // Verify that java.* packages are not imported.
- if (pkgName.startsWith("java.")) {
- throw new BundleException("Importing java.* packages not allowed: " + pkgName);
- }
- // The character "." has no meaning in the OSGi spec except
- // when placed on the bundle class path. Some people, however,
- // mistakenly think it means the default package when imported
- // or exported. This is not correct. It is invalid.
- else if (pkgName.equals(".")) {
- throw new BundleException("Importing '.' is invalid.");
- }
- // Make sure a package name was specified.
- else if (pkgName.length() == 0) {
- throw new BundleException(
- "Imported package names cannot be zero length.");
- }
- dupeSet.add(pkgName);
- } else {
- throw new BundleException("Duplicate import: " + pkgName);
- }
- }
- }
-
- return clauses;
- }
-
- private static List<Capability> convertExportService(List<ParsedHeaderClause> clauses, Resource resource) {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- Map<String, String> dirs = new LinkedHashMap<String, String>();
- dirs.put(ServiceNamespace.CAPABILITY_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
- Map<String, Object> attrs = new LinkedHashMap<String, Object>();
- attrs.put(Constants.OBJECTCLASS, path);
- attrs.putAll(clause.attrs);
- capList.add(new CapabilityImpl(
- resource,
- ServiceNamespace.SERVICE_NAMESPACE,
- dirs,
- attrs));
- }
- }
- return capList;
- }
-
- private static List<Requirement> convertImportService(List<ParsedHeaderClause> clauses, Resource resource) throws BundleException {
- try {
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- String multiple = clause.dirs.get("multiple");
- String avail = clause.dirs.get("availability");
- String filter = (String) clause.attrs.get("filter");
- Map<String, String> dirs = new LinkedHashMap<String, String>();
- dirs.put(ServiceNamespace.REQUIREMENT_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
- if ("optional".equals(avail)) {
- dirs.put(ServiceNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, ServiceNamespace.RESOLUTION_OPTIONAL);
- }
- if ("true".equals(multiple)) {
- dirs.put(ServiceNamespace.REQUIREMENT_CARDINALITY_DIRECTIVE, ServiceNamespace.CARDINALITY_MULTIPLE);
- }
- if (filter == null) {
- filter = "(" + Constants.OBJECTCLASS + "=" + path + ")";
- } else if (!filter.startsWith("(") && !filter.endsWith(")")) {
- filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")(" + filter + "))";
- } else {
- filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")" + filter + ")";
- }
- dirs.put(ServiceNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
- reqList.add(new RequirementImpl(
- resource,
- ServiceNamespace.SERVICE_NAMESPACE,
- dirs,
- Collections.<String, Object>emptyMap(),
- SimpleFilter.parse(filter)));
- }
- }
- return reqList;
- } catch (Exception ex) {
- throw new BundleException("Error creating requirement: " + ex, ex);
- }
- }
-
- private static List<Requirement> convertImports(List<ParsedHeaderClause> clauses, Resource resource) {
- // Now convert generic header clauses into requirements.
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- // Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- // Note that we use a linked hash map here to ensure the
- // package attribute is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the package name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clause.dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- // Create package requirement and add to requirement list.
- reqList.add(
- new RequirementImpl(
- resource,
- BundleRevision.PACKAGE_NAMESPACE,
- newDirs,
- Collections.<String, Object>emptyMap(),
- sf));
- }
- }
-
- return reqList;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeDynamicImportClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
- // Verify that the values are equals if the package specifies
- // both version and specification-version attributes.
- for (ParsedHeaderClause clause : clauses) {
- // Add the resolution directive to indicate that these are
- // dynamic imports.
- clause.dirs.put(Constants.RESOLUTION_DIRECTIVE, RESOLUTION_DYNAMIC);
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim())) {
- throw new IllegalArgumentException(
- "Both version and specification-version are specified, but they are not equal.");
- }
- }
-
- // Ensure that only the "version" attribute is used and convert
- // it to the VersionRange type.
- if ((v != null) || (sv != null)) {
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // If bundle version is specified, then convert its type to VersionRange.
- v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (v != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
- }
-
- // Dynamic imports can have duplicates, so verify that java.*
- // packages are not imported.
- for (String pkgName : clause.paths) {
- if (pkgName.startsWith("java.")) {
- throw new BundleException("Dynamically importing java.* packages not allowed: " + pkgName);
- } else if (!pkgName.equals("*") && pkgName.endsWith("*") && !pkgName.endsWith(".*")) {
- throw new BundleException("Partial package name wild carding is not allowed: " + pkgName);
- }
- }
- }
-
- return clauses;
- }
-
- private static List<ParsedHeaderClause> normalizeRequireCapabilityClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException {
-
- return clauses;
- }
-
- private static List<ParsedHeaderClause> normalizeProvideCapabilityClauses(
- List<ParsedHeaderClause> clauses)
- throws BundleException
- {
-
- // Convert attributes into specified types.
- for (ParsedHeaderClause clause : clauses)
- {
- for (Map.Entry<String, String> entry : clause.types.entrySet())
- {
- String type = entry.getValue();
- if (!type.equals("String"))
- {
- if (type.equals("Double"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Double(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Version"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Version(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Long"))
- {
- clause.attrs.put(
- entry.getKey(),
- new Long(clause.attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.startsWith("List"))
- {
- int startIdx = type.indexOf('<');
- int endIdx = type.indexOf('>');
- if (((startIdx > 0) && (endIdx <= startIdx))
- || ((startIdx < 0) && (endIdx > 0)))
- {
- throw new BundleException(
- "Invalid Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
-
- String listType = "String";
- if (endIdx > startIdx)
- {
- listType = type.substring(startIdx + 1, endIdx).trim();
- }
-
- List<String> tokens = parseDelimitedString(
- clause.attrs.get(entry.getKey()).toString(), ",", false);
- List<Object> values = new ArrayList<Object>(tokens.size());
- for (String token : tokens)
- {
- if (listType.equals("String"))
- {
- values.add(token);
- }
- else if (listType.equals("Double"))
- {
- values.add(new Double(token.trim()));
- }
- else if (listType.equals("Version"))
- {
- values.add(new Version(token.trim()));
- }
- else if (listType.equals("Long"))
- {
- values.add(new Long(token.trim()));
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- clause.attrs.put(
- entry.getKey(),
- values);
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- }
- }
-
- return clauses;
- }
-
- private static List<Requirement> convertRequireCapabilities(
- List<ParsedHeaderClause> clauses, Resource resource)
- throws BundleException {
- // Now convert generic header clauses into requirements.
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- try {
- String filterStr = clause.dirs.get(Constants.FILTER_DIRECTIVE);
- SimpleFilter sf = (filterStr != null)
- ? SimpleFilter.parse(filterStr)
- : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- for (String path : clause.paths) {
- // Create requirement and add to requirement list.
- reqList.add(new RequirementImpl(
- resource, path, clause.dirs, clause.attrs, sf));
- }
- } catch (Exception ex) {
- throw new BundleException("Error creating requirement: " + ex, ex);
- }
- }
-
- return reqList;
- }
-
- private static List<Capability> convertProvideCapabilities(
- List<ParsedHeaderClause> clauses, Resource resource)
- throws BundleException {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- if (path.startsWith("osgi.wiring.")) {
-// throw new BundleException("Manifest cannot use Provide-Capability for '" + path + "' namespace.");
- }
-
- // Create package capability and add to capability list.
- capList.add(new CapabilityImpl(resource, path, clause.dirs, clause.attrs));
- }
- }
-
- return capList;
- }
-
- @SuppressWarnings( "deprecation" )
- private static List<ParsedHeaderClause> normalizeExportClauses(
- List<ParsedHeaderClause> clauses,
- String bsn, Version bv)
- throws BundleException {
- // Verify that "java.*" packages are not exported.
- for (ParsedHeaderClause clause : clauses) {
- // Verify that the named package has not already been declared.
- for (String pkgName : clause.paths) {
- // Verify that java.* packages are not exported.
- if (pkgName.startsWith("java.")) {
- throw new BundleException("Exporting java.* packages not allowed: " + pkgName);
- }
- // The character "." has no meaning in the OSGi spec except
- // when placed on the bundle class path. Some people, however,
- // mistakenly think it means the default package when imported
- // or exported. This is not correct. It is invalid.
- else if (pkgName.equals(".")) {
- throw new BundleException("Exporing '.' is invalid.");
- }
- // Make sure a package name was specified.
- else if (pkgName.length() == 0) {
- throw new BundleException("Exported package names cannot be zero length.");
- }
- }
-
- // Check for "version" and "specification-version" attributes
- // and verify they are the same if both are specified.
- Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
- Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
- if ((v != null) && (sv != null)) {
- // Verify they are equal.
- if (!((String) v).trim().equals(((String) sv).trim())) {
- throw new IllegalArgumentException("Both version and specification-version are specified, but they are not equal.");
- }
- }
-
- // Always add the default version if not specified.
- if ((v == null) && (sv == null)) {
- v = Version.emptyVersion;
- }
-
- // Ensure that only the "version" attribute is used and convert
- // it to the appropriate type.
- if ((v != null) || (sv != null)) {
- // Convert version attribute to type Version.
- clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
- v = (v == null) ? sv : v;
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, Version.parseVersion(v.toString()));
- }
-
- // Find symbolic name and version attribute, if present.
- if (clause.attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
- || clause.attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)) {
- throw new BundleException("Exports must not specify bundle symbolic name or bundle version.");
- }
-
- // Now that we know that there are no bundle symbolic name and version
- // attributes, add them since the spec says they are there implicitly.
- clause.attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
- }
-
- return clauses;
- }
-
- private static List<Capability> convertExports(
- List<ParsedHeaderClause> clauses, Resource resource) {
- List<Capability> capList = new ArrayList<Capability>();
- for (ParsedHeaderClause clause : clauses) {
- for (String pkgName : clause.paths) {
- // Prepend the package name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
- newAttrs.putAll(attrs);
- newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, pkgName);
-
- // Create package capability and add to capability list.
- capList.add(new CapabilityImpl(resource, BundleRevision.PACKAGE_NAMESPACE, clause.dirs, newAttrs));
- }
- }
-
- return capList;
- }
-
- private static String getManifestVersion(Map<String, String> headerMap) {
- String manifestVersion = headerMap.get(Constants.BUNDLE_MANIFESTVERSION);
- return (manifestVersion == null) ? "1" : manifestVersion.trim();
- }
-
- private static List<ParsedHeaderClause> calculateImplicitImports(
- List<BundleCapability> exports, List<ParsedHeaderClause> imports)
- throws BundleException {
- List<ParsedHeaderClause> clauseList = new ArrayList<ParsedHeaderClause>();
-
- // Since all R3 exports imply an import, add a corresponding
- // requirement for each existing export capability. Do not
- // duplicate imports.
- Map<String, String> map = new HashMap<String, String>();
- // Add existing imports.
- for (ParsedHeaderClause anImport : imports) {
- for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
- map.put(anImport.paths.get(pathIdx), anImport.paths.get(pathIdx));
- }
- }
- // Add import requirement for each export capability.
- for (BundleCapability export : exports) {
- if (map.get(export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString()) == null) {
- // Convert Version to VersionRange.
- Object version = export.getAttributes().get(Constants.VERSION_ATTRIBUTE);
- ParsedHeaderClause clause = new ParsedHeaderClause();
- if (version != null) {
- clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(version.toString()));
- }
- clause.paths.add((String) export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
- clauseList.add(clause);
- }
- }
-
- return clauseList;
- }
-
- private static List<Capability> calculateImplicitUses(
- List<Capability> exports, List<ParsedHeaderClause> imports)
- throws BundleException {
- // Add a "uses" directive onto each export of R3 bundles
- // that references every other import (which will include
- // exports, since export implies import); this is
- // necessary since R3 bundles assumed a single class space,
- // but R4 allows for multiple class spaces.
- String usesValue = "";
- for (ParsedHeaderClause anImport : imports) {
- for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
- usesValue = usesValue
- + ((usesValue.length() > 0) ? "," : "")
- + anImport.paths.get(pathIdx);
- }
- }
- for (int i = 0; i < exports.size(); i++) {
- Map<String, String> dirs = new HashMap<String, String>(1);
- dirs.put(Constants.USES_DIRECTIVE, usesValue);
- exports.set(i, new CapabilityImpl(
- exports.get(i).getResource(),
- BundleRevision.PACKAGE_NAMESPACE,
- dirs,
- exports.get(i).getAttributes()));
- }
-
- return exports;
- }
-
- private static ParsedHeaderClause parseBundleSymbolicName(Map<String, String> headerMap)
- throws BundleException {
- List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
- if (clauses.size() > 0) {
- if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
- throw new BundleException("Cannot have multiple symbolic names: " + headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
- }
-
- // Get bundle version.
- Version bundleVersion = Version.emptyVersion;
- if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
- bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
- }
-
- // Create a require capability and return it.
- ParsedHeaderClause clause = clauses.get(0);
- String symName = clause.paths.get(0);
- clause.attrs.put(BundleRevision.BUNDLE_NAMESPACE, symName);
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
- return clause;
- }
-
- return null;
- }
-
- private static List<RequirementImpl> parseFragmentHost(
- Resource resource, Map<String, String> headerMap)
- throws BundleException {
- List<RequirementImpl> reqs = new ArrayList<RequirementImpl>();
-
- List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.FRAGMENT_HOST));
- if (clauses.size() > 0) {
- // Make sure that only one fragment host symbolic name is specified.
- if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
- throw new BundleException("Fragments cannot have multiple hosts: " + headerMap.get(Constants.FRAGMENT_HOST));
- }
-
- // If the bundle-version attribute is specified, then convert
- // it to the proper type.
- Object value = clauses.get(0).attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- value = (value == null) ? "0.0.0" : value;
- clauses.get(0).attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
-
- // Note that we use a linked hash map here to ensure the
- // host symbolic name is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the host symbolic name to the map of attributes.
- Map<String, Object> attrs = clauses.get(0).attrs;
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clauses.get(0).dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- reqs.add(new RequirementImpl(
- resource, BundleRevision.HOST_NAMESPACE,
- newDirs,
- newAttrs));
- }
-
- return reqs;
- }
-
- private static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses) {
- // Convert bundle version attribute to VersionRange type.
- for (ParsedHeaderClause clause : clauses) {
- Object value = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (value != null) {
- clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
- }
- }
-
- return clauses;
- }
-
- private static List<Requirement> convertRequires(List<ParsedHeaderClause> clauses, Resource resource) {
- List<Requirement> reqList = new ArrayList<Requirement>();
- for (ParsedHeaderClause clause : clauses) {
- for (String path : clause.paths) {
- // Prepend the bundle symbolic name to the array of attributes.
- Map<String, Object> attrs = clause.attrs;
- // Note that we use a linked hash map here to ensure the
- // symbolic name attribute is first, which will make indexing
- // more efficient.
- // TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the symbolic name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
- // TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clause.dirs;
- Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
-
- // Create package requirement and add to requirement list.
- reqList.add(new RequirementImpl(resource, BundleRevision.BUNDLE_NAMESPACE, newDirs, newAttrs));
- }
- }
-
- return reqList;
- }
-
- private static final char EOF = (char) -1;
-
- private static char charAt(int pos, String headers, int length)
- {
- if (pos >= length)
- {
- return EOF;
- }
- return headers.charAt(pos);
- }
-
- private static final int CLAUSE_START = 0;
- private static final int PARAMETER_START = 1;
- private static final int KEY = 2;
- private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
- private static final int ARGUMENT = 8;
- private static final int VALUE = 16;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static List<ParsedHeaderClause> parseStandardHeader(String header)
- {
- List<ParsedHeaderClause> clauses = new ArrayList<ParsedHeaderClause>();
- if (header == null)
- {
- return clauses;
- }
- ParsedHeaderClause clause = null;
- String key = null;
- Map targetMap = null;
- int state = CLAUSE_START;
- int currentPosition = 0;
- int startPosition = 0;
- int length = header.length();
- boolean quoted = false;
- boolean escaped = false;
-
- char currentChar = EOF;
- do
- {
- currentChar = charAt(currentPosition, header, length);
- switch (state)
- {
- case CLAUSE_START:
- clause = new ParsedHeaderClause();
- clauses.add(clause);
- state = PARAMETER_START;
- case PARAMETER_START:
- startPosition = currentPosition;
- state = KEY;
- case KEY:
- switch (currentChar)
- {
- case ':':
- case '=':
- key = header.substring(startPosition, currentPosition).trim();
- startPosition = currentPosition + 1;
- targetMap = clause.attrs;
- state = currentChar == ':' ? DIRECTIVE_OR_TYPEDATTRIBUTE : ARGUMENT;
- break;
- case EOF:
- case ',':
- case ';':
- clause.paths.add(header.substring(startPosition, currentPosition).trim());
- state = currentChar == ',' ? CLAUSE_START : PARAMETER_START;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case DIRECTIVE_OR_TYPEDATTRIBUTE:
- switch(currentChar)
- {
- case '=':
- if (startPosition != currentPosition)
- {
- clause.types.put(key, header.substring(startPosition, currentPosition).trim());
- }
- else
- {
- targetMap = clause.dirs;
- }
- state = ARGUMENT;
- startPosition = currentPosition + 1;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case ARGUMENT:
- if (currentChar == '\"')
- {
- quoted = true;
- currentPosition++;
- }
- else
- {
- quoted = false;
- }
- if (!Character.isWhitespace(currentChar)) {
- state = VALUE;
- }
- else {
- currentPosition++;
- }
- break;
- case VALUE:
- if (escaped)
- {
- escaped = false;
- }
- else
- {
- if (currentChar == '\\' )
- {
- escaped = true;
- }
- else if (quoted && currentChar == '\"')
- {
- quoted = false;
- }
- else if (!quoted)
- {
- String value = null;
- switch(currentChar)
- {
- case EOF:
- case ';':
- case ',':
- value = header.substring(startPosition, currentPosition).trim();
- if (value.startsWith("\"") && value.endsWith("\""))
- {
- value = value.substring(1, value.length() - 1);
- }
- if (targetMap.put(key, value) != null)
- {
- throw new IllegalArgumentException(
- "Duplicate '" + key + "' in: " + header);
- }
- state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
- break;
- default:
- break;
- }
- }
- }
- currentPosition++;
- break;
- default:
- break;
- }
- } while ( currentChar != EOF);
-
- if (state > PARAMETER_START)
- {
- throw new IllegalArgumentException("Unable to parse header: " + header);
- }
- return clauses;
- }
-
- public static List<String> parseDelimitedString(String value, String delim)
- {
- return parseDelimitedString(value, delim, true);
- }
-
- /**
- * Parses delimited string and returns an array containing the tokens. This
- * parser obeys quotes, so the delimiter character will be ignored if it is
- * inside of a quote. This method assumes that the quote character is not
- * included in the set of delimiter characters.
- * @param value the delimited string to parse.
- * @param delim the characters delimiting the tokens.
- * @return a list of string or an empty list if there are none.
- **/
- public static List<String> parseDelimitedString(String value, String delim, boolean trim)
- {
- if (value == null)
- {
- value = "";
- }
-
- List<String> list = new ArrayList();
-
- int CHAR = 1;
- int DELIMITER = 2;
- int STARTQUOTE = 4;
- int ENDQUOTE = 8;
-
- StringBuffer sb = new StringBuffer();
-
- int expecting = (CHAR | DELIMITER | STARTQUOTE);
-
- boolean isEscaped = false;
- for (int i = 0; i < value.length(); i++)
- {
- char c = value.charAt(i);
-
- boolean isDelimiter = (delim.indexOf(c) >= 0);
-
- if (!isEscaped && (c == '\\'))
- {
- isEscaped = true;
- continue;
- }
-
- if (isEscaped)
- {
- sb.append(c);
- }
- else if (isDelimiter && ((expecting & DELIMITER) > 0))
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- sb.delete(0, sb.length());
- expecting = (CHAR | DELIMITER | STARTQUOTE);
- }
- else if ((c == '"') && ((expecting & STARTQUOTE) > 0))
- {
- sb.append(c);
- expecting = CHAR | ENDQUOTE;
- }
- else if ((c == '"') && ((expecting & ENDQUOTE) > 0))
- {
- sb.append(c);
- expecting = (CHAR | STARTQUOTE | DELIMITER);
- }
- else if ((expecting & CHAR) > 0)
- {
- sb.append(c);
- }
- else
- {
- throw new IllegalArgumentException("Invalid delimited string: " + value);
- }
-
- isEscaped = false;
- }
-
- if (sb.length() > 0)
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- }
-
- return list;
- }
-
-
- static class ParsedHeaderClause {
- public final List<String> paths = new ArrayList<String>();
- public final Map<String, String> dirs = new LinkedHashMap<String, String>();
- public final Map<String, Object> attrs = new LinkedHashMap<String, Object>();
- public final Map<String, String> types = new LinkedHashMap<String, String>();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
deleted file mode 100644
index 18e0dc3..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-/**
- */
-public class ResourceImpl implements Resource {
-
- private final List<Capability> m_caps;
- private final List<Requirement> m_reqs;
-
- public ResourceImpl(String name, Version version) {
- this(name, IdentityNamespace.TYPE_BUNDLE, version);
- }
-
- public ResourceImpl(String name, String type, Version version)
- {
- m_caps = new ArrayList<Capability>();
- m_caps.add(0, new IdentityCapability(this, name, type, version));
- m_reqs = new ArrayList<Requirement>();
- }
-
- public void addCapability(Capability capability) {
- assert capability.getResource() == this;
- m_caps.add(capability);
- }
-
- public void addCapabilities(Iterable<? extends Capability> capabilities) {
- for (Capability cap : capabilities) {
- addCapability(cap);
- }
- }
-
- public void addRequirement(Requirement requirement) {
- assert requirement.getResource() == this;
- m_reqs.add(requirement);
- }
-
- public void addRequirements(Iterable<? extends Requirement> requirements) {
- for (Requirement req : requirements) {
- addRequirement(req);
- }
- }
-
- public List<Capability> getCapabilities(String namespace)
- {
- List<Capability> result = m_caps;
- if (namespace != null)
- {
- result = new ArrayList<Capability>();
- for (Capability cap : m_caps)
- {
- if (cap.getNamespace().equals(namespace))
- {
- result.add(cap);
- }
- }
- }
- return result;
- }
-
- public List<Requirement> getRequirements(String namespace)
- {
- List<Requirement> result = m_reqs;
- if (namespace != null)
- {
- result = new ArrayList<Requirement>();
- for (Requirement req : m_reqs)
- {
- if (req.getNamespace().equals(namespace))
- {
- result.add(req);
- }
- }
- }
- return result;
- }
-
- @Override
- public String toString()
- {
- Capability cap = getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
- return cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE) + "/"
- + cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
deleted file mode 100644
index 4fe3bf8..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import org.osgi.resource.Namespace;
-
-/**
- */
-public final class ServiceNamespace extends Namespace {
-
- public static final String SERVICE_NAMESPACE = "service-reference";
-
- private ServiceNamespace() {
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
deleted file mode 100644
index ae10441..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.felix.utils.version.VersionRange;
-
-public class SimpleFilter
-{
- public static final int MATCH_ALL = 0;
- public static final int AND = 1;
- public static final int OR = 2;
- public static final int NOT = 3;
- public static final int EQ = 4;
- public static final int LTE = 5;
- public static final int GTE = 6;
- public static final int SUBSTRING = 7;
- public static final int PRESENT = 8;
- public static final int APPROX = 9;
-
- private final String m_name;
- private final Object m_value;
- private final int m_op;
-
- public SimpleFilter(String attr, Object value, int op)
- {
- m_name = attr;
- m_value = value;
- m_op = op;
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public Object getValue()
- {
- return m_value;
- }
-
- public int getOperation()
- {
- return m_op;
- }
-
- public String toString()
- {
- String s = null;
- switch (m_op)
- {
- case AND:
- s = "(&" + toString((List) m_value) + ")";
- break;
- case OR:
- s = "(|" + toString((List) m_value) + ")";
- break;
- case NOT:
- s = "(!" + toString((List) m_value) + ")";
- break;
- case EQ:
- s = "(" + m_name + "=" + toEncodedString(m_value) + ")";
- break;
- case LTE:
- s = "(" + m_name + "<=" + toEncodedString(m_value) + ")";
- break;
- case GTE:
- s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
- break;
- case SUBSTRING:
- s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
- break;
- case PRESENT:
- s = "(" + m_name + "=*)";
- break;
- case APPROX:
- s = "(" + m_name + "~=" + toEncodedString(m_value) + ")";
- break;
- case MATCH_ALL:
- s = "(*)";
- break;
- }
- return s;
- }
-
- private static String toString(List list)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < list.size(); i++)
- {
- sb.append(list.get(i).toString());
- }
- return sb.toString();
- }
-
- private static String toDecodedString(String s, int startIdx, int endIdx)
- {
- StringBuffer sb = new StringBuffer(endIdx - startIdx);
- boolean escaped = false;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = s.charAt(startIdx + i);
- if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- private static String toEncodedString(Object o)
- {
- if (o instanceof String)
- {
- String s = (String) o;
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
- {
- sb.append('\\');
- }
- sb.append(c);
- }
-
- o = sb.toString();
- }
-
- return o.toString();
- }
-
- public static SimpleFilter parse(String filter)
- {
- int idx = skipWhitespace(filter, 0);
-
- if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
- {
- throw new IllegalArgumentException("Null or empty filter.");
- }
- else if (filter.charAt(idx) != '(')
- {
- throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
- }
-
- SimpleFilter sf = null;
- List stack = new ArrayList();
- boolean isEscaped = false;
- while (idx < filter.length())
- {
- if (sf != null)
- {
- throw new IllegalArgumentException(
- "Only one top-level operation allowed: " + filter);
- }
-
- if (!isEscaped && (filter.charAt(idx) == '('))
- {
- // Skip paren and following whitespace.
- idx = skipWhitespace(filter, idx + 1);
-
- if (filter.charAt(idx) == '&')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '|')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '!')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == ')'))
- {
- Object top = stack.remove(0);
- if (top instanceof SimpleFilter)
- {
- if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
- }
- else
- {
- sf = (SimpleFilter) top;
- }
- }
- else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(
- SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx));
- }
- else
- {
- sf = SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx);
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == '\\'))
- {
- isEscaped = true;
- }
- else
- {
- isEscaped = false;
- }
-
- idx = skipWhitespace(filter, idx + 1);
- }
-
- if (sf == null)
- {
- throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
- }
-
- return sf;
- }
-
- private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
- {
- final String opChars = "=<>~";
-
- // Determine the ending index of the attribute name.
- int attrEndIdx = startIdx;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = filter.charAt(startIdx + i);
- if (opChars.indexOf(c) >= 0)
- {
- break;
- }
- else if (!Character.isWhitespace(c))
- {
- attrEndIdx = startIdx + i + 1;
- }
- }
- if (attrEndIdx == startIdx)
- {
- throw new IllegalArgumentException(
- "Missing attribute name: " + filter.substring(startIdx, endIdx));
- }
- String attr = filter.substring(startIdx, attrEndIdx);
-
- // Skip the attribute name and any following whitespace.
- startIdx = skipWhitespace(filter, attrEndIdx);
-
- // Determine the operator type.
- int op = -1;
- switch (filter.charAt(startIdx))
- {
- case '=':
- op = EQ;
- startIdx++;
- break;
- case '<':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = LTE;
- startIdx += 2;
- break;
- case '>':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = GTE;
- startIdx += 2;
- break;
- case '~':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = APPROX;
- startIdx += 2;
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
-
- // Parse value.
- Object value = toDecodedString(filter, startIdx, endIdx);
-
- // Check if the equality comparison is actually a substring
- // or present operation.
- if (op == EQ)
- {
- String valueStr = filter.substring(startIdx, endIdx);
- List<String> values = parseSubstring(valueStr);
- if ((values.size() == 2)
- && (values.get(0).length() == 0)
- && (values.get(1).length() == 0))
- {
- op = PRESENT;
- }
- else if (values.size() > 1)
- {
- op = SUBSTRING;
- value = values;
- }
- }
-
- return new SimpleFilter(attr, value, op);
- }
-
- public static List<String> parseSubstring(String value)
- {
- List<String> pieces = new ArrayList();
- StringBuffer ss = new StringBuffer();
- // int kind = SIMPLE; // assume until proven otherwise
- boolean wasStar = false; // indicates last piece was a star
- boolean leftstar = false; // track if the initial piece is a star
- boolean rightstar = false; // track if the final piece is a star
-
- int idx = 0;
-
- // We assume (sub)strings can contain leading and trailing blanks
- boolean escaped = false;
- loop: for (;;)
- {
- if (idx >= value.length())
- {
- if (wasStar)
- {
- // insert last piece as "" to handle trailing star
- rightstar = true;
- }
- else
- {
- pieces.add(ss.toString());
- // accumulate the last piece
- // note that in the case of
- // (cn=); this might be
- // the string "" (!=null)
- }
- ss.setLength(0);
- break loop;
- }
-
- // Read the next character and account for escapes.
- char c = value.charAt(idx++);
- if (!escaped && (c == '*'))
- {
- // If we have successive '*' characters, then we can
- // effectively collapse them by ignoring succeeding ones.
- if (!wasStar)
- {
- if (ss.length() > 0)
- {
- pieces.add(ss.toString()); // accumulate the pieces
- // between '*' occurrences
- }
- ss.setLength(0);
- // if this is a leading star, then track it
- if (pieces.isEmpty())
- {
- leftstar = true;
- }
- wasStar = true;
- }
- }
- else if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- wasStar = false;
- ss.append(c);
- }
- }
- if (leftstar || rightstar || pieces.size() > 1)
- {
- // insert leading and/or trailing "" to anchor ends
- if (rightstar)
- {
- pieces.add("");
- }
- if (leftstar)
- {
- pieces.add(0, "");
- }
- }
- return pieces;
- }
-
- public static String unparseSubstring(List<String> pieces)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < pieces.size(); i++)
- {
- if (i > 0)
- {
- sb.append("*");
- }
- sb.append(toEncodedString(pieces.get(i)));
- }
- return sb.toString();
- }
-
- public static boolean compareSubstring(List<String> pieces, String s)
- {
- // Walk the pieces to match the string
- // There are implicit stars between each piece,
- // and the first and last pieces might be "" to anchor the match.
- // assert (pieces.length > 1)
- // minimal case is <string>*<string>
-
- boolean result = true;
- int len = pieces.size();
-
- // Special case, if there is only one piece, then
- // we must perform an equality test.
- if (len == 1)
- {
- return s.equals(pieces.get(0));
- }
-
- // Otherwise, check whether the pieces match
- // the specified string.
-
- int index = 0;
-
- loop: for (int i = 0; i < len; i++)
- {
- String piece = pieces.get(i);
-
- // If this is the first piece, then make sure the
- // string starts with it.
- if (i == 0)
- {
- if (!s.startsWith(piece))
- {
- result = false;
- break loop;
- }
- }
-
- // If this is the last piece, then make sure the
- // string ends with it.
- if (i == (len - 1))
- {
- if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
- {
- result = true;
- }
- else
- {
- result = false;
- }
- break loop;
- }
-
- // If this is neither the first or last piece, then
- // make sure the string contains it.
- if ((i > 0) && (i < (len - 1)))
- {
- index = s.indexOf(piece, index);
- if (index < 0)
- {
- result = false;
- break loop;
- }
- }
-
- // Move string index beyond the matching piece.
- index += piece.length();
- }
-
- return result;
- }
-
- private static int skipWhitespace(String s, int startIdx)
- {
- int len = s.length();
- while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
- {
- startIdx++;
- }
- return startIdx;
- }
-
- /**
- * Converts a attribute map to a filter. The filter is created by iterating
- * over the map's entry set. If ordering of attributes is important (e.g.,
- * for hitting attribute indices), then the map's entry set should iterate
- * in the desired order. Equality testing is assumed for all attribute types
- * other than version ranges, which are handled appropriated. If the attribute
- * map is empty, then a filter that matches anything is returned.
- * @param attrs Map of attributes to convert to a filter.
- * @return A filter corresponding to the attributes.
- */
- public static SimpleFilter convert(Map<String, Object> attrs)
- {
- // Rather than building a filter string to be parsed into a SimpleFilter,
- // we will just create the parsed SimpleFilter directly.
-
- List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
-
- for (Entry<String, Object> entry : attrs.entrySet())
- {
- if (entry.getValue() instanceof VersionRange)
- {
- VersionRange vr = (VersionRange) entry.getValue();
- if (!vr.isOpenFloor())
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getFloor().toString(),
- SimpleFilter.GTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getFloor().toString(),
- SimpleFilter.LTE));
- filters.add(not);
- }
-
- if (vr.getCeiling() != null)
- {
- if (!vr.isOpenCeiling())
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getCeiling().toString(),
- SimpleFilter.LTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getCeiling().toString(),
- SimpleFilter.GTE));
- filters.add(not);
- }
- }
- }
- else
- {
- List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
- if (values.size() > 1)
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values,
- SimpleFilter.SUBSTRING));
- }
- else
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values.get(0),
- SimpleFilter.EQ));
- }
- }
- }
-
- SimpleFilter sf = null;
-
- if (filters.size() == 1)
- {
- sf = filters.get(0);
- }
- else if (attrs.size() > 1)
- {
- sf = new SimpleFilter(null, filters, SimpleFilter.AND);
- }
- else if (filters.isEmpty())
- {
- sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- }
-
- return sf;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
deleted file mode 100644
index 2f4a1f3..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import org.slf4j.Logger;
-
-/**
- */
-public class Slf4jResolverLog extends org.apache.felix.resolver.Logger {
-
- private final Logger logger;
-
- public Slf4jResolverLog(Logger logger) {
- super(LOG_DEBUG);
- this.logger = logger;
- }
-
- @Override
- protected void doLog(int level, String msg, Throwable throwable) {
- switch (level) {
- case LOG_ERROR:
- logger.error(msg, throwable);
- break;
- case LOG_WARNING:
- logger.warn(msg, throwable);
- break;
- case LOG_INFO:
- logger.info(msg, throwable);
- break;
- case LOG_DEBUG:
- logger.debug(msg, throwable);
- break;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
deleted file mode 100644
index b5158bf..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.List;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Namespace;
-import org.osgi.resource.Resource;
-
-/**
- */
-public final class UriNamespace extends Namespace {
-
- public static final String URI_NAMESPACE = "karaf.uri";
-
- public static String getUri(Resource resource)
- {
- List<Capability> caps = resource.getCapabilities(null);
- for (Capability cap : caps)
- {
- if (cap.getNamespace().equals(UriNamespace.URI_NAMESPACE))
- {
- return cap.getAttributes().get(UriNamespace.URI_NAMESPACE).toString();
- }
- }
- return null;
- }
-
-
- private UriNamespace() {
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/Artifact.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Artifact.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Artifact.java
deleted file mode 100644
index 44e9a7c..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Artifact.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.net.URI;
-
-/**
- * Simple abstraction of a maven artifact to avoid external deps
- */
-public class Artifact {
- String groupId;
- String artifactId;
- String version;
- String extension;
- String classifier;
-
- public Artifact(String coords) {
- String[] coordsAr = coords.split(":");
- if (coordsAr.length != 5) {
- throw new IllegalArgumentException("Maven URL " + coords + " is malformed or not complete");
- }
- this.groupId = coordsAr[0];
- this.artifactId = coordsAr[1];
- this.version = coordsAr[4];
- this.extension = coordsAr[2];
- this.classifier = coordsAr[3];
- }
-
- public Artifact(String coords, String version) {
- this(coords);
- this.version = version;
- }
-
- public URI getMavenUrl(String version) {
- String uriSt = "mvn:" + this.groupId + "/" + this.artifactId + "/" + version + "/" + this.extension + "/" + this.classifier;
- try {
- return new URI(uriSt);
- } catch (Exception e) {
- return null;
- }
- }
-}
[31/59] [abbrv] [KARAF-2852] Merge diagnostic/core and
diagnostic/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
deleted file mode 100644
index 7a01daf..0000000
--- a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.diagnostic.core.internal.osgi;
-
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.List;
-
-import org.apache.karaf.diagnostic.core.DumpProvider;
-import org.apache.karaf.diagnostic.core.internal.BundleDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.DiagnosticDumpMBeanImpl;
-import org.apache.karaf.diagnostic.core.internal.EnvironmentDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.FeaturesDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.HeapDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.LogDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.MemoryDumpProvider;
-import org.apache.karaf.diagnostic.core.internal.ThreadDumpProvider;
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.util.tracker.SingleServiceTracker;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public class Activator implements BundleActivator {
-
- private List<ServiceRegistration<DumpProvider>> registrations;
- private ServiceRegistration<DumpProvider> featuresProviderRegistration;
- private ServiceRegistration mbeanRegistration;
- private SingleServiceTracker<FeaturesService> featuresServiceTracker;
- private ServiceTracker<DumpProvider, DumpProvider> providersTracker;
-
- @Override
- public void start(final BundleContext context) throws Exception {
- registrations = new ArrayList<ServiceRegistration<DumpProvider>>();
- registrations.add(context.registerService(DumpProvider.class, new BundleDumpProvider(context), null));
- registrations.add(context.registerService(DumpProvider.class, new EnvironmentDumpProvider(context), null));
- registrations.add(context.registerService(DumpProvider.class, new HeapDumpProvider(), null));
- registrations.add(context.registerService(DumpProvider.class, new LogDumpProvider(context), null));
- registrations.add(context.registerService(DumpProvider.class, new MemoryDumpProvider(), null));
- registrations.add(context.registerService(DumpProvider.class, new ThreadDumpProvider(), null));
-
- featuresServiceTracker = new SingleServiceTracker<FeaturesService>(context, FeaturesService.class, new SingleServiceTracker.SingleServiceListener() {
- @Override
- public void serviceFound() {
- featuresProviderRegistration =
- context.registerService(
- DumpProvider.class,
- new FeaturesDumpProvider(featuresServiceTracker.getService()),
- null);
- }
- @Override
- public void serviceLost() {
- }
- @Override
- public void serviceReplaced() {
- featuresProviderRegistration.unregister();
- }
- });
-
- final DiagnosticDumpMBeanImpl diagnostic = new DiagnosticDumpMBeanImpl();
- providersTracker = new ServiceTracker<DumpProvider, DumpProvider>(
- context, DumpProvider.class, new ServiceTrackerCustomizer<DumpProvider, DumpProvider>() {
- @Override
- public DumpProvider addingService(ServiceReference<DumpProvider> reference) {
- DumpProvider service = context.getService(reference);
- diagnostic.registerProvider(service);
- return service;
- }
- @Override
- public void modifiedService(ServiceReference<DumpProvider> reference, DumpProvider service) {
- }
- @Override
- public void removedService(ServiceReference<DumpProvider> reference, DumpProvider service) {
- diagnostic.unregisterProvider(service);
- context.ungetService(reference);
- }
- });
- providersTracker.open();
-
- Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put("jmx.objectname", "org.apache.karaf:type=diagnostic,name=" + System.getProperty("karaf.name"));
- mbeanRegistration = context.registerService(
- getInterfaceNames(diagnostic),
- diagnostic,
- props
- );
- }
-
- @Override
- public void stop(BundleContext context) throws Exception {
- mbeanRegistration.unregister();
- featuresServiceTracker.close();
- providersTracker.close();
- for (ServiceRegistration<DumpProvider> reg : registrations) {
- reg.unregister();
- }
- }
-
- private String[] getInterfaceNames(Object object) {
- List<String> names = new ArrayList<String>();
- for (Class cl = object.getClass(); cl != Object.class; cl = cl.getSuperclass()) {
- addSuperInterfaces(names, cl);
- }
- return names.toArray(new String[names.size()]);
- }
-
- private void addSuperInterfaces(List<String> names, Class clazz) {
- for (Class cl : clazz.getInterfaces()) {
- names.add(cl.getName());
- addSuperInterfaces(names, cl);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/diagnostic/core/src/main/resources/OSGI-INF/bundle.info b/diagnostic/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 15bc3cb..0000000
--- a/diagnostic/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,18 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-The diagnostic core bundle is the diagnostic core implementation.
-
-It's used by the diagnostic commands bundle and is responsible of the dump generation (environment, features, logs, bundles, threads).
-
-h1. See also
-
-Diagnostic - section of the Karaf User Guide.
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/pom.xml
----------------------------------------------------------------------
diff --git a/diagnostic/pom.xml b/diagnostic/pom.xml
index c40d93c..db61e04 100644
--- a/diagnostic/pom.xml
+++ b/diagnostic/pom.xml
@@ -29,13 +29,90 @@
</parent>
<groupId>org.apache.karaf.diagnostic</groupId>
- <artifactId>diagnostic</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Diagnostic</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.diagnostic.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Diagnostic :: Core</name>
+ <description>Core implementation using Karaf diagnostic using the diagnostic common services</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</groupId>
+ <artifactId>org.apache.karaf.util</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>
+ <optional>true</optional>
+ </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>
+ <Export-Package>
+ org.apache.karaf.diagnostic.command,
+ org.apache.karaf.diagnostic.core,
+ org.apache.karaf.diagnostic.core.common
+ </Export-Package>
+ <Import-Package>
+ com.sun.management*;resolution:=optional,
+ *
+ </Import-Package>
+ <Private-Package>
+ org.apache.karaf.diagnostic.core.internal,
+ org.apache.karaf.diagnostic.core.internal.osgi,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.diagnostic.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
new file mode 100644
index 0000000..3f6c607
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/command/DumpCommand.java
@@ -0,0 +1,97 @@
+/*
+ * 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.diagnostic.command;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+import org.apache.karaf.diagnostic.core.common.DirectoryDumpDestination;
+import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * Command to create dump from shell.
+ */
+@Command(scope = "dev", name = "dump-create", description = "Creates zip archive with diagnostic info.")
+@Service
+public class DumpCommand implements Action {
+
+ /**
+ * Output format of the filename if not defined otherwise
+ */
+ private SimpleDateFormat dumpFormat = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
+
+ /**
+ * Directory switch.
+ */
+ @Option(name = "-d", aliases = "--directory", description = "Creates dump in a directory in place of a ZIP archive")
+ boolean directory;
+
+ /**
+ * Name of created directory or archive.
+ */
+ @Argument(name = "name", description = "Name of created zip or directory", required = false)
+ String fileName;
+
+ @Reference
+ List<DumpProvider> providers;
+
+ @Override
+ public Object execute() throws Exception {
+ DumpDestination destination;
+
+ if (providers.isEmpty()) {
+ System.out.println("Unable to create dump. No providers were found");
+ return null;
+ }
+
+ // create default file name if none provided
+ if (fileName == null || fileName.trim().length() == 0) {
+ fileName = dumpFormat.format(new Date());
+ if (!directory) {
+ fileName += ".zip";
+ }
+ }
+ File target = new File(fileName);
+
+ // if directory switch is on, create dump in directory
+ if (directory) {
+ destination = new DirectoryDumpDestination(target);
+ } else {
+ destination = new ZipDumpDestination(target);
+ }
+
+ for (DumpProvider provider : providers) {
+ provider.createDump(destination);
+ }
+ destination.save();
+ System.out.println("Diagnostic dump created at " + target.getAbsolutePath() + ".");
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.java
new file mode 100644
index 0000000..f59982a
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DiagnosticDumpMBean.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.diagnostic.core;
+
+import javax.management.MBeanException;
+
+/**
+ * Diagnostic MBean which allows to create dumps over JMX.
+ */
+public interface DiagnosticDumpMBean {
+
+ /**
+ * Creates dump over JMX.
+ *
+ * @param name Name of the dump.
+ * @throws Exception In case of any problems.
+ */
+ void createDump(String name) throws MBeanException;
+
+ /**
+ * Create dump with directory switch and name.
+ *
+ * @param directory Should dump be created in directory.
+ * @param name Name of the dump.
+ * @throws Exception In case of any problems.
+ */
+ void createDump(boolean directory, String name) throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.java
new file mode 100644
index 0000000..39c4edc
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpDestination.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.diagnostic.core;
+
+import java.io.OutputStream;
+
+/**
+ * Destination for created dumps.
+ */
+public interface DumpDestination {
+
+ /**
+ * Creates new entry in dump destination.
+ *
+ * Destination does not close returned output stream by default, dump
+ * provider should do this after completing write operation.
+ *
+ * @param name Name of file in destination.
+ * @return Output stream ready to write.
+ * @throws Exception When entry cannot be added.
+ */
+ OutputStream add(String name) throws Exception;
+
+ /**
+ * Complete creation of the dump.
+ */
+ void save() throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
new file mode 100644
index 0000000..ec7724c
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/DumpProvider.java
@@ -0,0 +1,29 @@
+/*
+ * 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.diagnostic.core;
+
+/**
+ * Interface which represents instance of tool which can provide dump
+ * information.
+ */
+public interface DumpProvider {
+
+ /**
+ * Creates dump in given entry.
+ */
+ void createDump(DumpDestination destination) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
new file mode 100644
index 0000000..0c4f9db
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ClosingEntryOutputStreamWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.diagnostic.core.common;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Output stream which closes entry instead closing whole stream.
+ */
+public class ClosingEntryOutputStreamWrapper extends OutputStream {
+
+ /**
+ * Wrapped ZIP output stream.
+ */
+ private ZipOutputStream outputStream;
+
+ /**
+ * Creates new OutputStream.
+ *
+ * @param outputStream Wrapped output stream.
+ */
+ public ClosingEntryOutputStreamWrapper(ZipOutputStream outputStream) {
+ this.outputStream = outputStream;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(int b) throws IOException {
+ outputStream.write(b);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b) throws IOException {
+ outputStream.write(b);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b, int off, int len)
+ throws IOException {
+ outputStream.write(b, off, len);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() throws IOException {
+ // close entry instead of closing zip stream.
+ outputStream.closeEntry();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
new file mode 100644
index 0000000..37ae72e
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/DirectoryDumpDestination.java
@@ -0,0 +1,55 @@
+/*
+ * 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.diagnostic.core.common;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import org.apache.karaf.diagnostic.core.DumpDestination;
+
+/**
+ * Class which packages dumps to given directory.
+ */
+public class DirectoryDumpDestination implements DumpDestination {
+
+ /**
+ * Directory where dump files will be created.
+ */
+ private File directory;
+
+ public DirectoryDumpDestination(File file) {
+ this.directory = file;
+
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+ }
+
+ public OutputStream add(String name) throws Exception {
+ File destination = new File(directory, name);
+ if (name.contains("/") || name.contains("\\")) {
+ // if name contains slashes we need to create sub directory
+ destination.getParentFile().mkdirs();
+ }
+ return new FileOutputStream(destination);
+ }
+
+ public void save() throws Exception {
+ // do nothing, all should be written to output streams
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
new file mode 100644
index 0000000..0b97d6f
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/TextDumpProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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.diagnostic.core.common;
+
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+
+/**
+ * Base class for dump providers which writes text to destination.
+ */
+public abstract class TextDumpProvider implements DumpProvider {
+
+ /**
+ * Name of the file.
+ */
+ private final String name;
+
+ /**
+ * Creates new dump provider.
+ *
+ * @param name Name of the file.
+ */
+ protected TextDumpProvider(String name) {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void createDump(DumpDestination destination) throws Exception {
+ OutputStream outputStream = destination.add(name);
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
+ try {
+ writeDump(outputStreamWriter);
+ } finally {
+ outputStreamWriter.close();
+ outputStream.close();
+ }
+ }
+
+ /**
+ * This method should create output.
+ *
+ * @param outputStreamWriter Stream which points to file specified in constructor.
+ * @throws Exception If any problem occur.
+ */
+ protected abstract void writeDump(OutputStreamWriter outputStreamWriter) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
new file mode 100644
index 0000000..bafd38d
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/common/ZipDumpDestination.java
@@ -0,0 +1,79 @@
+/*
+ * 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.diagnostic.core.common;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.karaf.diagnostic.core.DumpDestination;
+
+/**
+ * Class which packages dumps to ZIP archive.
+ */
+public class ZipDumpDestination implements DumpDestination {
+
+ /**
+ * Destination streem.
+ */
+ private ZipOutputStream outputStream;
+
+ /**
+ * Creates new dump in given directory.
+ *
+ * @param directory Target directory.
+ * @param name Name of the archive.
+ */
+ public ZipDumpDestination(File directory, String name) {
+ this(new File(directory, name));
+ }
+
+ /**
+ * Creates new dump in given file (zip archive).
+ *
+ * @param file Destination file.
+ */
+ public ZipDumpDestination(File file) {
+ try {
+ outputStream = new ZipOutputStream(new FileOutputStream(
+ file));
+ } catch (FileNotFoundException e) {
+ // sometimes this can occur, but we simply re throw and let
+ // caller handle exception
+ throw new RuntimeException("Unable to create dump destination", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OutputStream add(String name) throws Exception {
+ ZipEntry zipEntry = new ZipEntry(name);
+ outputStream.putNextEntry(zipEntry);
+ return new ClosingEntryOutputStreamWrapper(outputStream);
+ }
+
+ /**
+ * Closes archive handle.
+ */
+ public void save() throws Exception {
+ outputStream.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
new file mode 100644
index 0000000..774dc1f
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/BundleDumpProvider.java
@@ -0,0 +1,85 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Dump provider which produces file named bundles.txt with list of
+ * installed bundles and it's state.
+ */
+public class BundleDumpProvider extends TextDumpProvider {
+
+ /**
+ * Static map with state mask to string representation.
+ */
+ private static Map<Integer, String> stateMap = new HashMap<Integer, String>();
+
+ /**
+ * Map bundle states to string representation.
+ */
+ static {
+ stateMap.put(0x00000001, "UNINSTALLED");
+ stateMap.put(0x00000002, "INSTALLED");
+ stateMap.put(0x00000004, "RESOLVED");
+ stateMap.put(0x00000008, "STARTING");
+ stateMap.put(0x00000010, "STOPPING");
+ stateMap.put(0x00000020, "ACTIVE");
+ }
+
+ /**
+ * Bundle context.
+ */
+ private BundleContext bundleContext;
+
+ /**
+ * Creates new bundle information file.
+ *
+ * @param context Bundle context to access framework state.
+ */
+ public BundleDumpProvider(BundleContext context) {
+ super("bundles.txt");
+ this.bundleContext = context;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeDump(OutputStreamWriter writer) throws IOException {
+ // get bundle states
+ Bundle[] bundles = bundleContext.getBundles();
+
+ writer.write("Number of installed bundles " + bundles.length + "\n");
+
+ // create file header
+ writer.write("Id\tSymbolic name\tVersion\tState\n");
+ for (Bundle bundle : bundles) {
+ // write row :)
+ writer.write(bundle.getBundleId() + "\t" + bundle.getSymbolicName() + '\t' + bundle.getVersion()
+ + "\t" + stateMap.get(bundle.getState()) + "\n");
+ }
+
+ writer.flush();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
new file mode 100644
index 0000000..22e09c9
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/DiagnosticDumpMBeanImpl.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed 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.diagnostic.core.internal;
+
+import java.io.File;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+
+import org.apache.karaf.diagnostic.core.DiagnosticDumpMBean;
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+import org.apache.karaf.diagnostic.core.common.DirectoryDumpDestination;
+import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
+
+/**
+ * Implementation of diagnostic MBean.
+ */
+public class DiagnosticDumpMBeanImpl extends StandardMBean implements DiagnosticDumpMBean {
+
+ /**
+ * Dump providers.
+ */
+ private final List<DumpProvider> providers = new CopyOnWriteArrayList<DumpProvider>();
+
+ /**
+ * Creates new diagnostic mbean.
+ *
+ * @throws NotCompliantMBeanException
+ */
+ public DiagnosticDumpMBeanImpl() throws NotCompliantMBeanException {
+ super(DiagnosticDumpMBean.class);
+ }
+
+ /**
+ * Creates dump witch given name
+ *
+ * @param name Name of the dump.
+ */
+ public void createDump(String name) throws MBeanException {
+ createDump(false, name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void createDump(boolean directory, String name) throws MBeanException {
+ try {
+ File target = new File(name);
+
+ DumpDestination destination;
+ if (directory) {
+ destination = new DirectoryDumpDestination(target);
+ } else {
+ destination = new ZipDumpDestination(target);
+ }
+
+ for (DumpProvider provider : providers) {
+ provider.createDump(destination);
+ }
+
+ destination.save();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void registerProvider(DumpProvider provider) {
+ providers.add(provider);
+ }
+
+ public void unregisterProvider(DumpProvider provider) {
+ providers.add(provider);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
new file mode 100644
index 0000000..3328067
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/EnvironmentDumpProvider.java
@@ -0,0 +1,291 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+
+/**
+ * Provider which dumps runtime environment information to file named environment.txt.
+ */
+public class EnvironmentDumpProvider extends TextDumpProvider {
+
+ private static final String KEY_VALUE_FORMAT = "%1$s\t: %2$s";
+ private static final String INDENT_KEY_VALUE_FORMAT = " "+KEY_VALUE_FORMAT;
+ private final BundleContext bundleContext;
+
+ /**
+ * Creates new dump entry which contains information about the runtime environment.
+ */
+ public EnvironmentDumpProvider(final BundleContext context) {
+ super("environment.txt");
+ this.bundleContext = context;
+ }
+
+ @Override
+ protected void writeDump(final OutputStreamWriter outputStream) throws Exception {
+ if( null == outputStream) {
+ return;
+ }
+ final PrintWriter outPW = new PrintWriter(outputStream);
+ // current date/time
+ final DateFormat dateTimeFormatInstance = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);
+ outPW.printf(KEY_VALUE_FORMAT,"Dump timestamp", dateTimeFormatInstance.format(new Date(System.currentTimeMillis()))).println();
+ outPW.println();
+ // karaf information
+ dumpKarafInformation(outPW);
+ outPW.println();
+ // OSGi information
+ dumpOSGiInformation(outPW);
+ outPW.println();
+ // OS information
+ dumpOSInformation(outPW);
+ outPW.println();
+ // general information about JVM
+ dumpVMInformation(outPW, dateTimeFormatInstance);
+ outPW.println();
+ // threads
+ dumpThreadsInformation(outPW);
+ outPW.println();
+ // classes
+ dumpClassesInformation(outPW);
+ outPW.println();
+ // memory
+ dumpMemoryInformation(outPW);
+ outPW.println();
+ // garbage collector
+ dumpGCInformation(outPW);
+ }
+
+ private void dumpKarafInformation(final PrintWriter outPW) {
+ outPW.printf(KEY_VALUE_FORMAT, "Karaf", System.getProperty("karaf.name", "root") + ' ' + System.getProperty("karaf.version", "")).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "home", System.getProperty("karaf.home", "")).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "base", System.getProperty("karaf.base", "")).println();
+ }
+
+ private void dumpOSGiInformation(final PrintWriter outPW) {
+ if( null == bundleContext ) {
+ return;
+ }
+ outPW.println("OSGi:");
+ final Bundle[] bundles = bundleContext.getBundles();
+ for (final Bundle bundle : bundles) {
+ if( null == bundle || !!!"osgi.core".equals(bundle.getSymbolicName())) {
+ continue;
+ }
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", bundle.getVersion()).println();
+ break;
+ }
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "framework", bundleContext.getBundle(0).getSymbolicName() + " - " +
+ bundleContext.getBundle(0).getVersion()).println();
+ }
+
+ private void dumpOSInformation(final PrintWriter outPW) {
+ final OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
+ if( null == mxBean) {
+ return;
+ }
+ outPW.printf(KEY_VALUE_FORMAT, "Operating System", mxBean.getName() + ' ' + mxBean.getVersion()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "architecture", mxBean.getArch()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "processors", mxBean.getAvailableProcessors()).println();
+// outPW.printf(INDENT_KEY_VALUE_FORMAT, "current system load average", mxBean.getSystemLoadAverage()).println();
+ }
+
+ private void dumpVMInformation(final PrintWriter outPW,
+ final DateFormat dateTimeFormatInstance) {
+ final RuntimeMXBean mxBean = ManagementFactory.getRuntimeMXBean();
+ if( mxBean == null ) {
+ return;
+ }
+ outPW.printf(KEY_VALUE_FORMAT,"Instance name", mxBean.getName()).println();
+ outPW.printf(KEY_VALUE_FORMAT,"Start time", dateTimeFormatInstance.format(new Date(mxBean.getStartTime()))).println();
+ outPW.printf(KEY_VALUE_FORMAT,"Uptime", printDuration(mxBean.getUptime())).println();
+ outPW.println();
+ outPW.printf(KEY_VALUE_FORMAT, "Java VM", mxBean.getVmName() + " " + mxBean.getVmVersion()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "vendor", mxBean.getVmVendor()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", System.getProperty("java.version")).println();
+ outPW.println();
+ outPW.println("Input arguments:");
+ final List<String> inputArguments = mxBean.getInputArguments();
+ for (final String argument : inputArguments) {
+ if( argument != null && argument.contains("=")) {
+ final String[] split = argument.split("=");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, split[0], split[1]).println();
+ } else {
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, argument,"").println();
+ }
+ }
+ outPW.println("Classpath:");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "boot classpath", mxBean.getBootClassPath()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "library path", mxBean.getLibraryPath()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "classpath", mxBean.getClassPath()).println();
+ outPW.println("System properties:");
+ final Map<String, String> systemProperties = mxBean.getSystemProperties();
+ for (final Entry<String, String> property : systemProperties.entrySet()) {
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, property.getKey(), property.getValue()).println();
+ }
+ outPW.println();
+ // JIT information
+ final CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
+ if( compilationMXBean != null ) {
+ outPW.printf(KEY_VALUE_FORMAT, "JIT compiler", compilationMXBean.getName()).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "total compile time", printDuration(compilationMXBean.getTotalCompilationTime())).println();
+ }
+ }
+
+ private void dumpThreadsInformation(final PrintWriter outPW) {
+ final ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
+ if( null == mxBean) {
+ return;
+ }
+ outPW.println("Threads:");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "live", formatLong(mxBean.getThreadCount())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "daemon", formatLong(mxBean.getDaemonThreadCount())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "peak", formatLong(mxBean.getPeakThreadCount())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", formatLong(mxBean.getTotalStartedThreadCount())).println();
+ }
+
+ private void dumpClassesInformation(final PrintWriter outPW) {
+ final ClassLoadingMXBean mxBean = ManagementFactory.getClassLoadingMXBean();
+ if( null == mxBean) {
+ return;
+ }
+ outPW.println("Classes:");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "loaded", formatLong(mxBean.getLoadedClassCount())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", formatLong(mxBean.getTotalLoadedClassCount())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "unloaded", formatLong(mxBean.getUnloadedClassCount())).println();
+ }
+
+ private void dumpMemoryInformation(final PrintWriter outPW) {
+ final MemoryMXBean mxBean = ManagementFactory.getMemoryMXBean();
+ if( null == mxBean) {
+ return;
+ }
+ final MemoryUsage heapMemoryUsage = mxBean.getHeapMemoryUsage();
+ final MemoryUsage nonHeapMemoryUsage = mxBean.getNonHeapMemoryUsage();
+ if( heapMemoryUsage != null ) {
+ outPW.println("HEAP Memory:");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", printMemory(heapMemoryUsage.getCommitted())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", printMemory(heapMemoryUsage.getInit())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", printMemory(heapMemoryUsage.getUsed())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", printMemory(heapMemoryUsage.getMax())).println();
+ }
+ if( nonHeapMemoryUsage != null ) {
+ outPW.println("NON-HEAP Memory:");
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", printMemory(nonHeapMemoryUsage.getCommitted())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", printMemory(nonHeapMemoryUsage.getInit())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", printMemory(nonHeapMemoryUsage.getUsed())).println();
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", printMemory(nonHeapMemoryUsage.getMax())).println();
+ }
+ }
+
+ private void dumpGCInformation(final PrintWriter outPW) {
+ final List<GarbageCollectorMXBean> mxBeans = ManagementFactory.getGarbageCollectorMXBeans();
+ if( null == mxBeans || mxBeans.isEmpty()) {
+ return;
+ }
+ final MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();
+ if( memoryMxBean != null ) {
+ outPW.printf(INDENT_KEY_VALUE_FORMAT, "pending objects", formatLong(memoryMxBean.getObjectPendingFinalizationCount())).println();
+ }
+ final String gcFormat ="'%1$s' collections: %2$s\ttime: %3$s";
+ outPW.println();
+ for (final GarbageCollectorMXBean mxBean : mxBeans) {
+ if( null == mxBean) {
+ continue;
+ }
+ outPW.printf(KEY_VALUE_FORMAT, "Garbage Collectors", String.format(gcFormat, mxBean.getName(), formatLong(mxBean.getCollectionCount()), printDuration(mxBean.getCollectionTime()))).println();
+ }
+ }
+
+
+ private String formatLong(final long longValue) {
+ final NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
+ return fmtI.format(longValue);
+ }
+
+ private String printMemory(final long bytes) {
+ if( bytes <= 1024) {
+ return formatLong(bytes)+" bytes";
+ }
+ return formatLong(bytes/1024)+" kbytes";
+ }
+
+ /**
+ * Prints the duration in a human readable format as X days Y hours Z minutes etc.
+ *
+ * @param uptime the uptime in millis
+ * @return the time used for displaying on screen or in logs
+ */
+ private String printDuration(double uptime) {
+ // Code based on code taken from Karaf
+ // https://svn.apache.org/repos/asf/karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/InfoAction.java
+
+ uptime /= 1000;
+ if (uptime < 60) {
+ final NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
+ return fmtD.format(uptime) + " seconds";
+ }
+ uptime /= 60;
+ if (uptime < 60) {
+ final long minutes = (long) uptime;
+ final String s = formatLong(minutes) + (minutes > 1 ? " minutes" : " minute");
+ return s;
+ }
+ uptime /= 60;
+ if (uptime < 24) {
+ final long hours = (long) uptime;
+ final long minutes = (long) ((uptime - hours) * 60);
+ String s = formatLong(hours) + (hours > 1 ? " hours" : " hour");
+ if (minutes != 0) {
+ s += " " + formatLong(minutes) + (minutes > 1 ? " minutes" : " minute");
+ }
+ return s;
+ }
+ uptime /= 24;
+ final long days = (long) uptime;
+ final long hours = (long) ((uptime - days) * 24);
+ String s = formatLong(days) + (days > 1 ? " days" : " day");
+ if (hours != 0) {
+ s += " " + formatLong(hours) + (hours > 1 ? " hours" : " hour");
+ }
+ return s;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
new file mode 100644
index 0000000..e5fa55e
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/FeaturesDumpProvider.java
@@ -0,0 +1,79 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import java.io.OutputStreamWriter;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+
+/**
+ * Dump provider which add file named features.txt with informations
+ * about installed features and repositories.
+ */
+public class FeaturesDumpProvider extends TextDumpProvider {
+
+ /**
+ * Feature service.
+ */
+ private final FeaturesService features;
+
+ /**
+ * Creates new dump entry witch contains information about
+ * karaf features.
+ *
+ * @param features Feature service.
+ */
+ public FeaturesDumpProvider(FeaturesService features) {
+ super("features.txt");
+ this.features = features;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeDump(OutputStreamWriter outputStreamWriter) throws Exception {
+ // creates header
+ outputStreamWriter.write("Repositories:\n");
+
+ // list repositories
+ for (Repository repo : features.listRepositories()) {
+ outputStreamWriter.write(repo.getURI() + " (" + repo.getName() + ")\n");
+ }
+
+ // list features
+ outputStreamWriter.write("\nfeatures:\n");
+ for (Feature feature : features.listFeatures()) {
+ outputStreamWriter.write(feature.getName() + " " + feature.getVersion());
+ outputStreamWriter.write(" installed: " + features.isInstalled(feature));
+ outputStreamWriter.write("\nBundles:\n");
+ for (BundleInfo bundle : feature.getBundles()) {
+ outputStreamWriter.write("\t" + bundle.getLocation());
+ if (bundle.getStartLevel() != 0) {
+ outputStreamWriter.write(" start level " + bundle.getStartLevel());
+ }
+ outputStreamWriter.write("\n\n");
+ }
+ }
+
+ // flush & close stream
+ outputStreamWriter.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
new file mode 100644
index 0000000..b86f57b
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/HeapDumpProvider.java
@@ -0,0 +1,68 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+
+import javax.management.MBeanServer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+
+/**
+ * Create a heap dump.
+ */
+public class HeapDumpProvider implements DumpProvider {
+
+ @Override
+ public void createDump(DumpDestination destination) throws Exception {
+ FileInputStream in = null;
+ OutputStream out = null;
+ try {
+ MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+ HotSpotDiagnosticMXBean diagnosticMXBean = ManagementFactory.newPlatformMXBeanProxy(mBeanServer,
+ "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
+ diagnosticMXBean.dumpHeap("heapdump.txt", false);
+ // copy the dump in the destination
+ File heapDumpFile = new File("heapdump.txt");
+ in = new FileInputStream(heapDumpFile);
+ out = destination.add("heapdump.txt");
+ byte[] buffer = new byte[2048];
+ while ((in.read(buffer) != -1)) {
+ out.write(buffer);
+ }
+ // remove the original dump
+ if (heapDumpFile.exists()) {
+ heapDumpFile.delete();
+ }
+ } catch (Exception e) {
+ // nothing to do
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.flush();
+ out.close();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
new file mode 100644
index 0000000..64b45f1
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/LogDumpProvider.java
@@ -0,0 +1,98 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Dump provider which copies log files from data/log directory to
+ * destination.
+ */
+public class LogDumpProvider implements DumpProvider {
+
+ private final BundleContext bundleContext;
+
+ public LogDumpProvider(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * Attach log entries from directory.
+ */
+ public void createDump(DumpDestination destination) throws Exception {
+ // get the ConfigAdmin service
+ ServiceReference ref = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
+ if (ref == null) {
+ return;
+ }
+
+ // get the PAX Logging configuration
+ ConfigurationAdmin configurationAdmin = (ConfigurationAdmin) bundleContext.getService(ref);
+ try {
+ Configuration configuration = configurationAdmin.getConfiguration("org.ops4j.pax.logging");
+
+ // get the ".file" Pax Logging properties
+ Dictionary dictionary = configuration.getProperties();
+ for (Enumeration e = dictionary.keys(); e.hasMoreElements(); ) {
+ String property = (String) e.nextElement();
+ if (property.endsWith(".file")) {
+ // it's a file appender, get the file location
+ String location = (String) dictionary.get(property);
+ File file = new File(location);
+ if (file.exists()) {
+ FileInputStream inputStream = new FileInputStream(file);
+ OutputStream outputStream = destination.add("log/" + file.getName());
+ copy(inputStream, outputStream);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ bundleContext.ungetService(ref);
+ }
+ }
+
+ /**
+ * Rewrites data from input stream to output stream. This code is very common
+ * but we would avoid additional dependencies in diagnostic stuff.
+ *
+ * @param inputStream Source stream.
+ * @param outputStream Destination stream.
+ * @throws IOException When IO operation fails.
+ */
+ private void copy(InputStream inputStream, OutputStream outputStream) throws IOException {
+ byte[] buffer = new byte[4096];
+ int n = 0;
+ while (-1 != (n = inputStream.read(buffer))) {
+ outputStream.write(buffer, 0, n);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.java
new file mode 100644
index 0000000..ff23f9d
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/MemoryDumpProvider.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.diagnostic.core.internal;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+
+import java.io.OutputStreamWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+
+/**
+ * Provider which dump the memory information in the memory.txt file.
+ */
+public class MemoryDumpProvider extends TextDumpProvider {
+
+ public MemoryDumpProvider() {
+ super("memory.txt");
+ }
+
+ @Override
+ protected void writeDump(OutputStreamWriter outputStream) throws Exception {
+ MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+
+ outputStream.write("Number of objects waiting finalization: " + memoryMXBean.getObjectPendingFinalizationCount() + "\n\n");
+
+ outputStream.write("Heap:\n");
+ outputStream.write("\tInit: " + memoryMXBean.getHeapMemoryUsage().getInit() + "\n");
+ outputStream.write("\tUser: " + memoryMXBean.getHeapMemoryUsage().getUsed() + "\n");
+ outputStream.write("\tCommitted: " + memoryMXBean.getHeapMemoryUsage().getCommitted() + "\n");
+ outputStream.write("\tMax: " + memoryMXBean.getHeapMemoryUsage().getMax() + "\n");
+
+ outputStream.write("Non-Heap: \n");
+ outputStream.write("\tInit: " + memoryMXBean.getNonHeapMemoryUsage().getInit() + "\n");
+ outputStream.write("\tUser: " + memoryMXBean.getNonHeapMemoryUsage().getUsed() + "\n");
+ outputStream.write("\tCommitted: " + memoryMXBean.getNonHeapMemoryUsage().getCommitted() + "\n");
+ outputStream.write("\tMax: " + memoryMXBean.getNonHeapMemoryUsage().getMax() + "\n");
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
new file mode 100644
index 0000000..31edad6
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/ThreadDumpProvider.java
@@ -0,0 +1,118 @@
+/*
+ * 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.diagnostic.core.internal;
+
+import java.io.OutputStreamWriter;
+import java.lang.management.LockInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+
+/**
+ * Provider which dumps thread info to file named threads.txt.
+ */
+public class ThreadDumpProvider extends TextDumpProvider {
+
+ /**
+ * Creates new dump entry which contains information about threads.
+ */
+ public ThreadDumpProvider() {
+ super("threads.txt");
+ }
+
+ @Override
+ protected void writeDump(OutputStreamWriter outputStream) throws Exception {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+
+ outputStream.write("Number of threads: " + threadMXBean.getThreadCount() + "\n");
+
+ for (ThreadInfo threadInfo : threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), Integer.MAX_VALUE)) {
+ outputStream.write(getDumpThreadString(threadInfo) + "\n\n");
+ }
+
+ }
+
+ protected String getDumpThreadString(ThreadInfo threadInfo) {
+ StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" + " Id=" + threadInfo.getThreadId() + " "
+ + threadInfo.getThreadState());
+ if (threadInfo.getLockName() != null) {
+ sb.append(" on " + threadInfo.getLockName());
+ }
+ if (threadInfo.getLockOwnerName() != null) {
+ sb.append(" owned by \"" + threadInfo.getLockOwnerName() + "\" Id=" + threadInfo.getLockOwnerId());
+ }
+ if (threadInfo.isSuspended()) {
+ sb.append(" (suspended)");
+ }
+ if (threadInfo.isInNative()) {
+ sb.append(" (in native)");
+ }
+ sb.append('\n');
+ int i = 0;
+ StackTraceElement[] stackTrace = threadInfo.getStackTrace();
+ for (; i < stackTrace.length; i++) {
+ StackTraceElement ste = stackTrace[i];
+ sb.append("\tat " + ste.toString());
+ sb.append('\n');
+ if (i == 0 && threadInfo.getLockInfo() != null) {
+ Thread.State ts = threadInfo.getThreadState();
+ switch (ts) {
+ case BLOCKED:
+ sb.append("\t- blocked on " + threadInfo.getLockInfo());
+ sb.append('\n');
+ break;
+ case WAITING:
+ sb.append("\t- waiting on " + threadInfo.getLockInfo());
+ sb.append('\n');
+ break;
+ case TIMED_WAITING:
+ sb.append("\t- waiting on " + threadInfo.getLockInfo());
+ sb.append('\n');
+ break;
+ default:
+ }
+ }
+
+ for (MonitorInfo mi : threadInfo.getLockedMonitors()) {
+ if (mi.getLockedStackDepth() == i) {
+ sb.append("\t- locked " + mi);
+ sb.append('\n');
+ }
+ }
+ }
+ if (i < stackTrace.length) {
+ sb.append("\t...");
+ sb.append('\n');
+ }
+
+ LockInfo[] locks = threadInfo.getLockedSynchronizers();
+ if (locks.length > 0) {
+ sb.append("\n\tNumber of locked synchronizers = " + locks.length);
+ sb.append('\n');
+ for (LockInfo li : locks) {
+ sb.append("\t- " + li);
+ sb.append('\n');
+ }
+ }
+ sb.append('\n');
+ return sb.toString();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..7a01daf
--- /dev/null
+++ b/diagnostic/src/main/java/org/apache/karaf/diagnostic/core/internal/osgi/Activator.java
@@ -0,0 +1,131 @@
+/*
+ * 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.diagnostic.core.internal.osgi;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.karaf.diagnostic.core.DumpProvider;
+import org.apache.karaf.diagnostic.core.internal.BundleDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.DiagnosticDumpMBeanImpl;
+import org.apache.karaf.diagnostic.core.internal.EnvironmentDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.FeaturesDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.HeapDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.LogDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.MemoryDumpProvider;
+import org.apache.karaf.diagnostic.core.internal.ThreadDumpProvider;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.util.tracker.SingleServiceTracker;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class Activator implements BundleActivator {
+
+ private List<ServiceRegistration<DumpProvider>> registrations;
+ private ServiceRegistration<DumpProvider> featuresProviderRegistration;
+ private ServiceRegistration mbeanRegistration;
+ private SingleServiceTracker<FeaturesService> featuresServiceTracker;
+ private ServiceTracker<DumpProvider, DumpProvider> providersTracker;
+
+ @Override
+ public void start(final BundleContext context) throws Exception {
+ registrations = new ArrayList<ServiceRegistration<DumpProvider>>();
+ registrations.add(context.registerService(DumpProvider.class, new BundleDumpProvider(context), null));
+ registrations.add(context.registerService(DumpProvider.class, new EnvironmentDumpProvider(context), null));
+ registrations.add(context.registerService(DumpProvider.class, new HeapDumpProvider(), null));
+ registrations.add(context.registerService(DumpProvider.class, new LogDumpProvider(context), null));
+ registrations.add(context.registerService(DumpProvider.class, new MemoryDumpProvider(), null));
+ registrations.add(context.registerService(DumpProvider.class, new ThreadDumpProvider(), null));
+
+ featuresServiceTracker = new SingleServiceTracker<FeaturesService>(context, FeaturesService.class, new SingleServiceTracker.SingleServiceListener() {
+ @Override
+ public void serviceFound() {
+ featuresProviderRegistration =
+ context.registerService(
+ DumpProvider.class,
+ new FeaturesDumpProvider(featuresServiceTracker.getService()),
+ null);
+ }
+ @Override
+ public void serviceLost() {
+ }
+ @Override
+ public void serviceReplaced() {
+ featuresProviderRegistration.unregister();
+ }
+ });
+
+ final DiagnosticDumpMBeanImpl diagnostic = new DiagnosticDumpMBeanImpl();
+ providersTracker = new ServiceTracker<DumpProvider, DumpProvider>(
+ context, DumpProvider.class, new ServiceTrackerCustomizer<DumpProvider, DumpProvider>() {
+ @Override
+ public DumpProvider addingService(ServiceReference<DumpProvider> reference) {
+ DumpProvider service = context.getService(reference);
+ diagnostic.registerProvider(service);
+ return service;
+ }
+ @Override
+ public void modifiedService(ServiceReference<DumpProvider> reference, DumpProvider service) {
+ }
+ @Override
+ public void removedService(ServiceReference<DumpProvider> reference, DumpProvider service) {
+ diagnostic.unregisterProvider(service);
+ context.ungetService(reference);
+ }
+ });
+ providersTracker.open();
+
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put("jmx.objectname", "org.apache.karaf:type=diagnostic,name=" + System.getProperty("karaf.name"));
+ mbeanRegistration = context.registerService(
+ getInterfaceNames(diagnostic),
+ diagnostic,
+ props
+ );
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ mbeanRegistration.unregister();
+ featuresServiceTracker.close();
+ providersTracker.close();
+ for (ServiceRegistration<DumpProvider> reg : registrations) {
+ reg.unregister();
+ }
+ }
+
+ private String[] getInterfaceNames(Object object) {
+ List<String> names = new ArrayList<String>();
+ for (Class cl = object.getClass(); cl != Object.class; cl = cl.getSuperclass()) {
+ addSuperInterfaces(names, cl);
+ }
+ return names.toArray(new String[names.size()]);
+ }
+
+ private void addSuperInterfaces(List<String> names, Class clazz) {
+ for (Class cl : clazz.getInterfaces()) {
+ names.add(cl.getName());
+ addSuperInterfaces(names, cl);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/886863a2/diagnostic/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/diagnostic/src/main/resources/OSGI-INF/bundle.info b/diagnostic/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..15bc3cb
--- /dev/null
+++ b/diagnostic/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,18 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+The diagnostic core bundle is the diagnostic core implementation.
+
+It's used by the diagnostic commands bundle and is responsible of the dump generation (environment, features, logs, bundles, threads).
+
+h1. See also
+
+Diagnostic - section of the Karaf User Guide.
[19/59] [abbrv] [KARAF-2852] Merge bundle/command into bundle/core
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java
new file mode 100644
index 0000000..271fc42
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.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.bundle.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.support.MultiException;
+import org.osgi.framework.Bundle;
+
+/**
+ * Command related to bundles requiring read-write access to the bundle (including system bundle).
+ */
+public abstract class BundlesCommandWithConfirmation extends BundlesCommand {
+
+ @Option(name = "--force", aliases = {"-f"}, description = "Forces the command to execute", required = false, multiValued = false)
+ boolean force;
+
+ protected String errorMessage = "Unable to execute command on bundle ";
+
+ public BundlesCommandWithConfirmation() {
+ super(false);
+ }
+
+ protected Object doExecute() throws Exception {
+ doExecute(force);
+ return null;
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ if (bundles.isEmpty()) {
+ System.err.println("No bundles specified.");
+ return;
+ }
+ List<Exception> exceptions = new ArrayList<Exception>();
+ for (Bundle bundle : bundles) {
+ try {
+ executeOnBundle(bundle);
+ } catch (Exception e) {
+ exceptions.add(new Exception(errorMessage + bundle.getBundleId() + ": " + e.getMessage(), e));
+ }
+ }
+ MultiException.throwIf("Error executing command on bundles", exceptions);
+ }
+
+ protected abstract void executeOnBundle(Bundle bundle) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Capabilities.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
new file mode 100644
index 0000000..de83a1d
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
@@ -0,0 +1,239 @@
+/*
+ * 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.bundle.command;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+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.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+@Command(scope = "bundle", name = "capabilities", description = "Displays OSGi capabilities of a given bundles.")
+@Service
+public class Capabilities extends BundlesCommand {
+ public static final String NONSTANDARD_SERVICE_NAMESPACE = "service";
+
+ private static final String EMPTY_MESSAGE = "[EMPTY]";
+ private static final String UNUSED_MESSAGE = "[UNUSED]";
+
+ @Option(name = "--namespace")
+ String namespace = "*";
+
+ public Capabilities() {
+ super(true);
+ }
+
+ @Override
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ boolean separatorNeeded = false;
+ Pattern ns = Pattern.compile(namespace.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*"));
+ for (Bundle b : bundles)
+ {
+ if (separatorNeeded)
+ {
+ System.out.println("");
+ }
+
+ // Print out any matching generic capabilities.
+ BundleWiring wiring = b.adapt(BundleWiring.class);
+ if (wiring != null)
+ {
+ String title = b + " provides:";
+ System.out.println(title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+
+ // Print generic capabilities for matching namespaces.
+ boolean matches = printMatchingCapabilities(wiring, ns);
+
+ // Handle service capabilities separately, since they aren't part
+ // of the generic model in OSGi.
+ if (matchNamespace(ns, NONSTANDARD_SERVICE_NAMESPACE))
+ {
+ matches |= printServiceCapabilities(b);
+ }
+
+ // If there were no capabilities for the specified namespace,
+ // then say so.
+ if (!matches)
+ {
+ System.out.println(namespace + " " + EMPTY_MESSAGE);
+ }
+ }
+ else
+ {
+ System.out.println("Bundle " + b.getBundleId() + " is not resolved.");
+ }
+ separatorNeeded = true;
+ }
+ }
+
+ private static boolean printMatchingCapabilities(BundleWiring wiring, Pattern namespace)
+ {
+ List<BundleWire> wires = wiring.getProvidedWires(null);
+ Map<BundleCapability, List<BundleWire>> aggregateCaps =
+ aggregateCapabilities(namespace, wires);
+ List<BundleCapability> allCaps = wiring.getCapabilities(null);
+ boolean matches = false;
+ for (BundleCapability cap : allCaps)
+ {
+ if (matchNamespace(namespace, cap.getNamespace()))
+ {
+ matches = true;
+ List<BundleWire> dependents = aggregateCaps.get(cap);
+ Object keyAttr =
+ cap.getAttributes().get(cap.getNamespace());
+ if (dependents != null)
+ {
+ String msg;
+ if (keyAttr != null)
+ {
+ msg = cap.getNamespace()
+ + "; "
+ + keyAttr
+ + " "
+ + getVersionFromCapability(cap);
+ }
+ else
+ {
+ msg = cap.toString();
+ }
+ msg = msg + " required by:";
+ System.out.println(msg);
+ for (BundleWire wire : dependents)
+ {
+ System.out.println(" " + wire.getRequirerWiring().getBundle());
+ }
+ }
+ else if (keyAttr != null)
+ {
+ System.out.println(cap.getNamespace()
+ + "; "
+ + cap.getAttributes().get(cap.getNamespace())
+ + " "
+ + getVersionFromCapability(cap)
+ + " "
+ + UNUSED_MESSAGE);
+ }
+ else
+ {
+ System.out.println(cap + " " + UNUSED_MESSAGE);
+ }
+ }
+ }
+ return matches;
+ }
+
+ private static Map<BundleCapability, List<BundleWire>> aggregateCapabilities(
+ Pattern namespace, List<BundleWire> wires)
+ {
+ // Aggregate matching capabilities.
+ Map<BundleCapability, List<BundleWire>> map =
+ new HashMap<BundleCapability, List<BundleWire>>();
+ for (BundleWire wire : wires)
+ {
+ if (matchNamespace(namespace, wire.getCapability().getNamespace()))
+ {
+ List<BundleWire> dependents = map.get(wire.getCapability());
+ if (dependents == null)
+ {
+ dependents = new ArrayList<BundleWire>();
+ map.put(wire.getCapability(), dependents);
+ }
+ dependents.add(wire);
+ }
+ }
+ return map;
+ }
+
+ static boolean printServiceCapabilities(Bundle b)
+ {
+ boolean matches = false;
+
+ try
+ {
+ ServiceReference<?>[] refs = b.getRegisteredServices();
+
+ if ((refs != null) && (refs.length > 0))
+ {
+ matches = true;
+ // Print properties for each service.
+ for (ServiceReference<?> ref : refs)
+ {
+ // Print object class with "namespace".
+ System.out.println(
+ NONSTANDARD_SERVICE_NAMESPACE
+ + "; "
+ + ShellUtil.getValueString(ref.getProperty("objectClass"))
+ + " with properties:");
+ // Print service properties.
+ String[] keys = ref.getPropertyKeys();
+ for (String key : keys)
+ {
+ if (!key.equalsIgnoreCase(Constants.OBJECTCLASS))
+ {
+ Object v = ref.getProperty(key);
+ System.out.println(" "
+ + key + " = " + ShellUtil.getValueString(v));
+ }
+ }
+ Bundle[] users = ref.getUsingBundles();
+ if ((users != null) && (users.length > 0))
+ {
+ System.out.println(" Used by:");
+ for (Bundle user : users)
+ {
+ System.out.println(" " + user);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ System.err.println(ex.toString());
+ }
+
+ return matches;
+ }
+
+ private static String getVersionFromCapability(BundleCapability c)
+ {
+ Object o = c.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+ if (o == null)
+ {
+ o = c.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ }
+ return (o == null) ? "" : o.toString();
+ }
+
+ private static boolean matchNamespace(Pattern namespace, String actual)
+ {
+ return namespace.matcher(actual).matches();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Classes.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Classes.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Classes.java
new file mode 100644
index 0000000..b0f80ff
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Classes.java
@@ -0,0 +1,63 @@
+/*
+ * 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.bundle.command;
+
+import java.util.Collection;
+import java.util.List;
+
+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.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+
+@Command(scope = "bundle", name = "classes", description = "Displays a list of classes contained in the bundle")
+@Service
+public class Classes extends BundlesCommand {
+
+ @Option(name = "-a", aliases={"--display-all-files"}, description="List all classes and files in the bundle", required = false, multiValued = false)
+ boolean displayAllFiles;
+
+ public Classes() {
+ super(true);
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ for (Bundle bundle : bundles) {
+ printResources(bundle);
+ }
+ }
+
+ protected void printResources(Bundle bundle) {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring != null){
+ Collection<String> resources;
+ if (displayAllFiles){
+ resources = wiring.listResources("/", null, BundleWiring.LISTRESOURCES_RECURSE);
+ }else{
+ resources = wiring.listResources("/", "*class", BundleWiring.LISTRESOURCES_RECURSE);
+ }
+ for (String resource:resources){
+ System.out.println(resource);
+ }
+ } else {
+ System.out.println("Bundle " + bundle.getBundleId() + " is not resolved.");
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
new file mode 100644
index 0000000..1e8e11b
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
@@ -0,0 +1,51 @@
+/*
+ * 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.bundle.command;
+
+import java.util.List;
+
+import org.apache.karaf.bundle.core.BundleInfo;
+import org.apache.karaf.bundle.core.BundleState;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "diag", description = "Displays diagnostic information why a bundle is not Active")
+@Service
+public class Diag extends BundlesCommand {
+
+ public Diag() {
+ super(true);
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ for (Bundle bundle : bundles) {
+ BundleInfo info = bundleService.getInfo(bundle);
+ if (info.getState() == BundleState.Failure || info.getState() == BundleState.Waiting
+ || info.getState() == BundleState.GracePeriod || info.getState() == BundleState.Installed) {
+ String title = ShellUtil.getBundleName(bundle);
+ System.out.println(title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+ System.out.println("Status: " + info.getState().toString());
+ System.out.println(this.bundleService.getDiag(bundle));
+ System.out.println();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
new file mode 100644
index 0000000..74fc20a
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
@@ -0,0 +1,46 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+
+/**
+ * Command for enabling/disabling debug logging on a bundle and calculating the difference in
+ * wired imports.
+ */
+@Command(scope = "bundle", name = "dynamic-import", description = "Enables/disables dynamic-import for a given bundle.")
+@Service
+public class DynamicImport extends BundleCommand {
+
+ public DynamicImport() {
+ super(true);
+ }
+
+ @Override
+ protected void doExecute(Bundle bundle) throws Exception {
+ if (bundleService.isDynamicImport(bundle)) {
+ System.out.printf("Disabling dynamic imports on bundle %s%n", bundle);
+ bundleService.disableDynamicImports(bundle);
+ } else {
+ System.out.printf("Enabling dynamic imports on bundle %s%n", bundle);
+ bundleService.enableDynamicImports(bundle);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/FindClass.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/FindClass.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/FindClass.java
new file mode 100644
index 0000000..4a9fc75
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/FindClass.java
@@ -0,0 +1,68 @@
+package org.apache.karaf.bundle.command;
+
+/*
+ * 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.
+ */
+
+import java.util.Collection;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+
+@Command(scope = "bundle", name = "find-class", description = "Locates a specified class in any deployed bundle")
+@Service
+public class FindClass implements Action {
+
+ @Argument(index = 0, name = "className", description = "Class name or partial class name to be found", required = true, multiValued = false)
+ String className;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ findResource();
+ return null;
+ }
+
+ protected void findResource() {
+ Bundle[] bundles = bundleContext.getBundles();
+ String filter = "*" + className + "*";
+ for (Bundle bundle:bundles){
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring != null){
+ Collection<String> resources = wiring.listResources("/", filter, BundleWiring.LISTRESOURCES_RECURSE);
+ if (resources.size() > 0){
+ String title = ShellUtil.getBundleName(bundle);
+ System.out.println("\n" + title);
+ }
+ for (String resource:resources){
+ System.out.println(resource);
+ }
+ } else {
+ System.out.println("Bundle " + bundle.getBundleId() + " is not resolved.");
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Headers.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Headers.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Headers.java
new file mode 100644
index 0000000..16083ff
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Headers.java
@@ -0,0 +1,333 @@
+/*
+ * 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.bundle.command;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.utils.manifest.Attribute;
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Directive;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+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.Terminal;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.fusesource.jansi.Ansi;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+@Command(scope = "bundle", name = "headers", description = "Displays OSGi headers of a given bundles.")
+@Service
+public class Headers extends BundlesCommand {
+
+ protected final static String BUNDLE_PREFIX = "Bundle-";
+ protected final static String PACKAGE_SUFFFIX = "-Package";
+ protected final static String SERVICE_SUFFIX = "-Service";
+ protected final static String CAPABILITY_SUFFIX = "-Capability";
+ protected final static String IMPORT_PACKAGES_ATTRIB = "Import-Package";
+ protected final static String REQUIRE_BUNDLE_ATTRIB = "Require-Bundle";
+
+ @Option(name = "--indent", description = "Indentation method")
+ int indent = -1;
+
+ @Reference
+ Terminal terminal;
+
+ public Headers() {
+ super(true);
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ for (Bundle bundle : bundles) {
+ printHeaders(bundle);
+ }
+ }
+
+ protected void printHeaders(Bundle bundle) throws Exception {
+ String title = ShellUtil.getBundleName(bundle);
+ System.out.println("\n" + title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+ if (indent == 0) {
+ Dictionary<String, String> dict = bundle.getHeaders();
+ Enumeration<String> keys = dict.keys();
+ while (keys.hasMoreElements()) {
+ Object k = keys.nextElement();
+ Object v = dict.get(k);
+ System.out.println(k + " = " + ShellUtil.getValueString(v));
+ }
+ } else {
+ System.out.println(generateFormattedOutput(bundle));
+ }
+ }
+
+ protected String generateFormattedOutput(Bundle bundle) {
+ StringBuilder output = new StringBuilder();
+ Map<String, Object> otherAttribs = new HashMap<String, Object>();
+ Map<String, Object> bundleAttribs = new HashMap<String, Object>();
+ Map<String, Object> serviceAttribs = new HashMap<String, Object>();
+ Map<String, Object> packagesAttribs = new HashMap<String, Object>();
+ Dictionary<String, String> dict = bundle.getHeaders();
+ Enumeration<String> keys = dict.keys();
+
+ // do an initial loop and separate the attributes in different groups
+ while (keys.hasMoreElements()) {
+ String k = (String) keys.nextElement();
+ Object v = dict.get(k);
+ if (k.startsWith(BUNDLE_PREFIX)) {
+ // starts with Bundle-xxx
+ bundleAttribs.put(k, v);
+ } else if (k.endsWith(SERVICE_SUFFIX) || k.endsWith(CAPABILITY_SUFFIX)) {
+ // ends with xxx-Service
+ serviceAttribs.put(k, v);
+ } else if (k.endsWith(PACKAGE_SUFFFIX)) {
+ // ends with xxx-Package
+ packagesAttribs.put(k, v);
+ } else if (k.endsWith(REQUIRE_BUNDLE_ATTRIB)) {
+ // require bundle statement
+ packagesAttribs.put(k, v);
+ } else {
+ // the remaining attribs
+ otherAttribs.put(k, v);
+ }
+ }
+
+ // we will display the formatted result like this:
+ // Bundle-Name (ID)
+ // -----------------------
+ // all other attributes
+ //
+ // all Bundle attributes
+ //
+ // all Service attributes
+ //
+ // all Package attributes
+ Iterator<Map.Entry<String, Object>> it = otherAttribs.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> e = it.next();
+ output.append(String.format("%s = %s\n", e.getKey(), ShellUtil.getValueString(e.getValue())));
+ }
+ if (otherAttribs.size() > 0) {
+ output.append('\n');
+ }
+
+ it = bundleAttribs.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> e = it.next();
+ output.append(String.format("%s = %s\n", e.getKey(), ShellUtil.getValueString(e.getValue())));
+ }
+ if (bundleAttribs.size() > 0) {
+ output.append('\n');
+ }
+
+ it = serviceAttribs.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> e = it.next();
+ output.append(e.getKey());
+ output.append(" = \n");
+ formatHeader(ShellUtil.getValueString(e.getValue()), null, output, indent);
+ output.append("\n");
+ }
+ if (serviceAttribs.size() > 0) {
+ output.append('\n');
+ }
+
+ Map<String, ClauseFormatter> formatters = new HashMap<String, ClauseFormatter>();
+ formatters.put(REQUIRE_BUNDLE_ATTRIB, new ClauseFormatter() {
+ public void pre(Clause clause, StringBuilder output) {
+ boolean isSatisfied = checkBundle(clause.getName(), clause.getAttribute("bundle-version"));
+ Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED).a("");
+ }
+ public void post(Clause clause, StringBuilder output) {
+ Ansi.ansi(output).reset().a("");
+ }
+ });
+ formatters.put(IMPORT_PACKAGES_ATTRIB, new ClauseFormatter() {
+ public void pre(Clause clause, StringBuilder output) {
+ boolean isSatisfied = checkPackage(clause.getName(), clause.getAttribute("version"));
+ boolean isOptional = "optional".equals(clause.getDirective("resolution"));
+ Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED)
+ .a(isSatisfied || isOptional ? Ansi.Attribute.INTENSITY_BOLD_OFF : Ansi.Attribute.INTENSITY_BOLD)
+ .a("");
+ }
+ public void post(Clause clause, StringBuilder output) {
+ Ansi.ansi(output).reset().a("");
+ }
+ });
+
+ it = packagesAttribs.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, Object> e = it.next();
+ output.append(e.getKey());
+ output.append(" = \n");
+ formatHeader(ShellUtil.getValueString(e.getValue()), formatters.get(e.getKey()), output, indent);
+ output.append("\n");
+ }
+ if (packagesAttribs.size() > 0) {
+ output.append('\n');
+ }
+
+ return output.toString();
+ }
+
+ protected interface ClauseFormatter {
+ void pre(Clause clause, StringBuilder output);
+ void post(Clause clause, StringBuilder output);
+ }
+
+ protected void formatHeader(String header, ClauseFormatter formatter, StringBuilder builder, int indent) {
+ Clause[] clauses = Parser.parseHeader(header);
+ formatClauses(clauses, formatter, builder, indent);
+ }
+
+ protected void formatClauses(Clause[] clauses, ClauseFormatter formatter, StringBuilder builder, int indent) {
+ boolean first = true;
+ for (Clause clause : clauses) {
+ if (first) {
+ first = false;
+ } else {
+ builder.append(",\n");
+ }
+ formatClause(clause, formatter, builder, indent);
+ }
+ }
+
+ protected void formatClause(Clause clause, ClauseFormatter formatter, StringBuilder builder, int indent) {
+ builder.append("\t");
+ if (formatter != null) {
+ formatter.pre(clause, builder);
+ }
+ formatClause(clause, builder, indent);
+ if (formatter != null) {
+ formatter.post(clause, builder);
+ }
+ }
+
+ protected int getTermWidth() {
+ return terminal.getWidth();
+
+ }
+
+ protected void formatClause(Clause clause, StringBuilder builder, int indent) {
+ if (indent < 0) {
+ if (clause.toString().length() < getTermWidth() - 8) { // -8 for tabs
+ indent = 1;
+ } else {
+ indent = 3;
+ }
+ }
+ String name = clause.getName();
+ Directive[] directives = clause.getDirectives();
+ Attribute[] attributes = clause.getAttributes();
+ Arrays.sort(directives, new Comparator<Directive>() {
+ public int compare(Directive o1, Directive o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ Arrays.sort(attributes, new Comparator<Attribute>() {
+ public int compare(Attribute o1, Attribute o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ builder.append(name);
+ for (int i = 0; directives != null && i < directives.length; i++) {
+ builder.append(";");
+ if (indent > 1) {
+ builder.append("\n\t\t");
+ }
+ builder.append(directives[i].getName()).append(":=");
+ String v = directives[i].getValue();
+ if (v.contains(",")) {
+ if (indent > 2 && v.length() > 20) {
+ v = v.replace(",", ",\n\t\t\t");
+ }
+ builder.append("\"").append(v).append("\"");
+ } else {
+ builder.append(v);
+ }
+ }
+ for (int i = 0; attributes != null && i < attributes.length; i++) {
+ builder.append(";");
+ if (indent > 1) {
+ builder.append("\n\t\t");
+ }
+ builder.append(attributes[i].getName()).append("=");
+ String v = attributes[i].getValue();
+ if (v.contains(",")) {
+ if (indent > 2 && v.length() > 20) {
+ v = v.replace(",", ",\n\t\t\t");
+ }
+ builder.append("\"").append(v).append("\"");
+ } else {
+ builder.append(v);
+ }
+ }
+ }
+
+
+ private boolean checkBundle(String bundleName, String version) {
+ VersionRange vr = VersionRange.parseVersionRange(version);
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; (bundles != null) && (i < bundles.length); i++) {
+ String sym = bundles[i].getSymbolicName();
+ if ((sym != null) && sym.equals(bundleName)) {
+ if (vr.contains(bundles[i].getVersion())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean checkPackage(String packageName, String version) {
+ VersionRange range = VersionRange.parseVersionRange(version);
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; (bundles != null) && (i < bundles.length); i++) {
+ BundleWiring wiring = bundles[i].adapt(BundleWiring.class);
+ List<BundleCapability> caps = wiring != null ? wiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE) : null;
+ if (caps != null) {
+ for (BundleCapability cap : caps) {
+ String n = getAttribute(cap, BundleRevision.PACKAGE_NAMESPACE);
+ String v = getAttribute(cap, Constants.VERSION_ATTRIBUTE);
+ if (packageName.equals(n) && range.contains(VersionTable.getVersion(v))) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private String getAttribute(BundleCapability cap, String name) {
+ Object obj = cap.getAttributes().get(name);
+ return obj != null ? obj.toString() : null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Info.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Info.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Info.java
new file mode 100644
index 0000000..451ec87
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Info.java
@@ -0,0 +1,79 @@
+/*
+ * 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.bundle.command;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.karaf.bundle.command.wikidoc.AnsiPrintingWikiVisitor;
+import org.apache.karaf.bundle.command.wikidoc.WikiParser;
+import org.apache.karaf.bundle.command.wikidoc.WikiVisitor;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "info", description = "Displays detailed information of a given bundles.")
+@Service
+public class Info extends BundlesCommand {
+
+ public Info() {
+ super(true);
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ for (Bundle bundle : bundles) {
+ printInfo(bundle);
+ }
+ }
+
+ /**
+ * <p>
+ * Get the OSGI-INF/bundle.info entry from the bundle and display it.
+ * </p>
+ *
+ * @param bundle the bundle.
+ */
+ protected void printInfo(Bundle bundle) {
+ String title = ShellUtil.getBundleName(bundle);
+ System.out.println("\n" + title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+ URL bundleInfo = bundle.getEntry("OSGI-INF/bundle.info");
+ if (bundleInfo != null) {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(bundleInfo.openStream()));
+ WikiVisitor visitor = new AnsiPrintingWikiVisitor(System.out);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(reader);
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Install.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Install.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Install.java
new file mode 100644
index 0000000..11fba89
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Install.java
@@ -0,0 +1,81 @@
+/*
+ * 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.bundle.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.MultiException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+@Command(scope = "bundle", name = "install", description = "Installs one or more bundles.")
+@Service
+public class Install implements Action {
+
+ @Argument(index = 0, name = "urls", description = "Bundle URLs separated by whitespaces", required = true, multiValued = true)
+ List<String> urls;
+
+ @Option(name = "-s", aliases={"--start"}, description="Starts the bundles after installation", required = false, multiValued = false)
+ boolean start;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ List<Exception> exceptions = new ArrayList<Exception>();
+ List<Bundle> bundles = new ArrayList<Bundle>();
+ for (String url : urls) {
+ try {
+ bundles.add(bundleContext.installBundle(url, null));
+ } catch (Exception e) {
+ exceptions.add(new Exception("Unable to install bundle " + url, e));
+ }
+ }
+ if (start) {
+ for (Bundle bundle : bundles) {
+ try {
+ bundle.start();
+ } catch (Exception e) {
+ exceptions.add(new Exception("Unable to start bundle " + bundle.getLocation(), e));
+ }
+ }
+ }
+ if (bundles.size() == 1) {
+ System.out.println("Bundle ID: " + bundles.get(0).getBundleId());
+ } else {
+ StringBuffer sb = new StringBuffer("Bundle IDs: ");
+ for (Bundle bundle : bundles) {
+ if (sb.length() > 0) {
+ sb.append(", ");
+ }
+ sb.append(bundle.getBundleId());
+ }
+ System.out.println(sb);
+ }
+ MultiException.throwIf("Error installing bundles", exceptions);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
new file mode 100644
index 0000000..28f8264
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
@@ -0,0 +1,116 @@
+/*
+ * 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.bundle.command;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@Command(scope = "bundle", name = "services", description = "Lists OSGi services per Bundle")
+@Service
+public class ListBundleServices extends BundlesCommand {
+
+ @Option(name = "-a", aliases = {}, description = "Shows all services. (By default Karaf commands are hidden)", required = false, multiValued = false)
+ boolean showAll;
+
+ @Option(name = "-u", aliases = {}, description = "Shows the services each bundle uses. (By default the provided services are shown)", required = false, multiValued = false)
+ boolean inUse;
+
+ @Option(name = "-p", aliases = {}, description = "Shows the properties of the services", required = false, multiValued = false)
+ boolean showProperties = false;
+
+ Set<String> hidden = new HashSet<String>(Arrays.asList(new String[] {
+ "org.apache.felix.service.command.Function",
+ "org.apache.karaf.shell.console.Completer"
+ }));
+
+ public ListBundleServices() {
+ super(true);
+ }
+
+ @Override
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] refs = (inUse) ? bundle.getServicesInUse() : bundle.getRegisteredServices();
+ printServices(bundle, refs, showProperties);
+ }
+ }
+
+ private void printServices(Bundle bundle, ServiceReference<?>[] refs, boolean showProperties) {
+ boolean headerPrinted = false;
+ boolean needSeparator = false;
+
+ if (refs == null) {
+ return;
+ }
+
+ for (ServiceReference<?> serviceRef : refs) {
+ String[] objectClass = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS);
+
+ boolean print = showAll || !isCommandOrCompleter(objectClass);
+
+ // Print header if we have not already done so.
+ if (!headerPrinted) {
+ headerPrinted = true;
+ System.out.println("");
+ String title = ShellUtil.getBundleName(bundle) + ((inUse) ? " uses:" : " provides:");
+ System.out.println(title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+ }
+
+ if (print) {
+ // Print service separator if necessary.
+ if (needSeparator && showProperties) {
+ System.out.println("----");
+ }
+
+ if (showProperties) {
+ printProperties(serviceRef);
+ } else {
+ System.out.println(ShellUtil.getValueString(objectClass));
+ }
+
+ needSeparator = true;
+ }
+ }
+ }
+
+ private boolean isCommandOrCompleter(String[] objectClasses) {
+ for (String objectClass : objectClasses) {
+ if (hidden.contains(objectClass)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void printProperties(ServiceReference<?> serviceRef) {
+ for (String key : serviceRef.getPropertyKeys()) {
+ System.out.println(key + " = " + ShellUtil.getValueString(serviceRef.getProperty(key)));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundles.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
new file mode 100644
index 0000000..107e578
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
@@ -0,0 +1,176 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.bundle.core.BundleInfo;
+import org.apache.karaf.bundle.core.BundleService;
+import org.apache.karaf.bundle.core.BundleState;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+
+@Command(scope = "bundle", name = "list", description = "Lists all installed bundles.")
+@Service
+public class ListBundles implements Action {
+
+ @Option(name = "-l", aliases = {}, description = "Show the locations", required = false, multiValued = false)
+ boolean showLoc;
+
+ @Option(name = "-s", description = "Shows the symbolic name", required = false, multiValued = false)
+ boolean showSymbolic;
+
+ @Option(name = "-u", description = "Shows the update locations", required = false, multiValued = false)
+ boolean showUpdate;
+
+ @Option(name = "-t", valueToShowInHelp = "", description = "Specifies the bundle threshold; bundles with a start-level less than this value will not get printed out.", required = false, multiValued = false)
+ int bundleLevelThreshold = -1;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Reference
+ private BundleService bundleService;
+
+ public void setBundleService(BundleService bundleService) {
+ this.bundleService = bundleService;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ Bundle[] bundles = bundleContext.getBundles();
+ if (bundles == null) {
+ System.out.println("There are no installed bundles.");
+ return null;
+ }
+
+ determineBundleLevelThreshold();
+
+ // Display active start level.
+ FrameworkStartLevel fsl = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class);
+ if (fsl != null) {
+ System.out.println("START LEVEL " + fsl.getStartLevel() + " , List Threshold: " + bundleLevelThreshold);
+ }
+
+ ShellTable table = new ShellTable();
+ table.column("ID").alignRight();
+ table.column("State");
+ table.column("Lvl").alignRight();
+ table.column("Version");
+ table.column(getNameHeader());
+
+ for (int i = 0; i < bundles.length; i++) {
+ Bundle bundle = bundles[i];
+ BundleInfo info = this.bundleService.getInfo(bundle);
+ if (info.getStartLevel() >= bundleLevelThreshold) {
+ String name = getNameToShow(info) + printFragments(info) + printHosts(info);
+ String version = info.getVersion();
+ table.addRow().addContent(info.getBundleId(), getStateString(info.getState()),
+ info.getStartLevel(), version, name);
+ }
+ }
+ table.print(System.out, !noFormat);
+
+ return null;
+ }
+
+ private String getNameHeader() {
+ String msg = "Name";
+ if (showLoc) {
+ msg = "Location";
+ } else if (showSymbolic) {
+ msg = "Symbolic name";
+ } else if (showUpdate) {
+ msg = "Update location";
+ }
+ return msg;
+ }
+
+ private void determineBundleLevelThreshold() {
+ final String sbslProp = bundleContext.getProperty("karaf.systemBundlesStartLevel");
+ if (sbslProp != null) {
+ try {
+ if (bundleLevelThreshold < 0) {
+ bundleLevelThreshold = Integer.valueOf(sbslProp);
+ }
+ } catch (Exception ignore) {
+ // ignore
+ }
+ }
+ }
+
+ private String printHosts(BundleInfo info) {
+ if (info.getFragmentHosts().size() <= 0) {
+ return "";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append(", Hosts: ");
+ boolean first = true;
+ for (Bundle host : info.getFragmentHosts()) {
+ builder.append((first ? "" : ", ") + host.getBundleId());
+ first = false;
+ }
+ return builder.toString();
+ }
+
+ private String printFragments(BundleInfo info) {
+ if (info.getFragments().size() <= 0) {
+ return "";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append(", Fragments: ");
+ boolean first = true;
+ for (Bundle host : info.getFragments()) {
+ builder.append((first ? "" : ", ") + host.getBundleId());
+ first = false;
+ }
+ return builder.toString();
+ }
+
+ private String getStateString(BundleState state) {
+ return (state == null) ? "" : state.toString();
+ }
+
+ /**
+ * Overwrite the default value is the user specifically requested to display
+ * one or the other.
+ *
+ * @param info
+ * @return
+ */
+ private String getNameToShow(BundleInfo info) {
+ if (showLoc) {
+ return info.getUpdateLocation();
+ } else if (showSymbolic) {
+ return info.getSymbolicName() == null ? "<no symbolic name>" : info.getSymbolicName();
+ } else if (showUpdate) {
+ return info.getUpdateLocation();
+ } else {
+ String name = (info.getName() == null) ? info.getSymbolicName() : info.getName();
+ return (name == null) ? info.getUpdateLocation() : name;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/LoadTest.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
new file mode 100644
index 0000000..8ed318f
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.bundle.command;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+@Command(scope = "bundle", name = "load-test", description = "Load test bundle lifecycle")
+@Service
+public class LoadTest implements Action {
+
+ @Option(name = "--threads", description = "number of concurrent threads")
+ int threads = 2;
+
+ @Option(name = "--delay", description = "maximum delay between actions")
+ int delay = 1;
+
+ @Option(name = "--iterations", description = "number of iterations per thread")
+ int iterations = 100;
+
+ @Option(name = "--refresh", description = "percentage of bundle refresh vs restart")
+ int refresh = 20;
+
+ @Option(name = "--excludes", description = "List of bundles (ids or symbolic names) to exclude")
+ List<String> excludes = Arrays.asList("0", "org.ops4j.pax.url.mvn", "org.ops4j.pax.logging.pax-logging-api", "org.ops4j.pax.logging.pax-logging-service");
+
+ @Reference
+ Session session;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ if (!confirm(session)) {
+ return null;
+ }
+ final BundleContext bundleContext = this.bundleContext.getBundle(0).getBundleContext();
+ final FrameworkWiring wiring = bundleContext.getBundle().adapt(FrameworkWiring.class);
+ final CountDownLatch latch = new CountDownLatch(threads);
+ final Bundle[] bundles = bundleContext.getBundles();
+ final AtomicBoolean[] locks = new AtomicBoolean[bundles.length];
+ for (int b = 0; b < locks.length; b++) {
+ locks[b] = new AtomicBoolean(true);
+ // Avoid touching excluded bundles
+ if (excludes.contains(Long.toString(bundles[b].getBundleId()))
+ || excludes.contains(bundles[b].getSymbolicName())) {
+ continue;
+ }
+ // Only touch active bundles
+ if (bundles[b].getState() != Bundle.ACTIVE) {
+ continue;
+ }
+ // Now set the lock to available
+ locks[b].set(false);
+ }
+ for (int i = 0; i < threads; i++) {
+ new Thread() {
+ public void run() {
+ try {
+ Random rand = new Random();
+ for (int j = 0; j < iterations; j++) {
+ for (;;) {
+ int b = rand.nextInt(bundles.length);
+ if (locks[b].compareAndSet(false, true)) {
+ try {
+ // Only touch active bundles
+ if (bundles[b].getState() != Bundle.ACTIVE) {
+ continue;
+ }
+ if (rand.nextInt(100) < refresh) {
+ try {
+ bundles[b].update();
+ final CountDownLatch latch = new CountDownLatch(1);
+ wiring.refreshBundles(Collections.singletonList(bundles[b]), new FrameworkListener() {
+ public void frameworkEvent(FrameworkEvent event) {
+ latch.countDown();
+ }
+ });
+ latch.await();
+ } finally {
+ while (true) {
+ try {
+ bundles[b].start(Bundle.START_TRANSIENT);
+ break;
+ } catch (Exception e) {
+ Thread.sleep(1);
+ }
+ }
+ }
+ } else {
+ try {
+ bundles[b].stop(Bundle.STOP_TRANSIENT);
+ } finally {
+ while (true) {
+ try {
+ bundles[b].start(Bundle.START_TRANSIENT);
+ break;
+ } catch (Exception e) {
+ Thread.sleep(1);
+ }
+ }
+ }
+ }
+ Thread.sleep(rand.nextInt(delay));
+ } catch (Exception e) {
+ boolean ignore = false;
+ if (e instanceof BundleException && e.getMessage() != null) {
+ String msg = e.getMessage();
+ if ("Cannot acquire global lock to update the bundle.".equals(msg) ||
+ "Unable to acquire global lock for resolve.".equals(msg) ||
+ msg.matches("Bundle .* cannot be update, since it is either starting or stopping.")) {
+ ignore = true;
+ }
+ }
+ if (!ignore) {
+ e.printStackTrace();
+ }
+ } finally {
+ locks[b].set(false);
+ }
+ }
+ break;
+ }
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ } finally {
+ latch.countDown();
+ }
+ }
+ }.start();
+ }
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.err.println("Load test finished");
+ }
+ }.start();
+ return null;
+ }
+
+ private boolean confirm(Session session) throws IOException {
+ for (;;) {
+ String msg = "You are about to perform a start/stop/refresh load test on bundles.\nDo you wish to continue (yes/no): ";
+ String str = session.readLine(msg, null);
+ if ("yes".equalsIgnoreCase(str)) {
+ return true;
+ }
+ if ("no".equalsIgnoreCase(str)) {
+ return false;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Refresh.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Refresh.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Refresh.java
new file mode 100644
index 0000000..53adaeb
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Refresh.java
@@ -0,0 +1,43 @@
+/*
+ * 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.bundle.command;
+
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+@Command(scope = "bundle", name = "refresh", description = "Refresh bundles.")
+@Service
+public class Refresh extends BundlesCommandWithConfirmation {
+
+ public Refresh() {
+ this.defaultAllBundles = false;
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ FrameworkWiring wiring = bundleContext.getBundle(0).adapt(FrameworkWiring.class);
+ wiring.refreshBundles(bundles == null || bundles.isEmpty() ? null : bundles);
+ }
+
+ @Override
+ protected void executeOnBundle(Bundle bundle) throws Exception {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Requirements.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Requirements.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Requirements.java
new file mode 100644
index 0000000..c87d4d4
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Requirements.java
@@ -0,0 +1,177 @@
+/*
+ * 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.bundle.command;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+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.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+@Command(scope = "bundle", name = "requirements", description = "Displays OSGi requirements of a given bundles.")
+@Service
+public class Requirements extends BundlesCommand {
+
+ public static final String NONSTANDARD_SERVICE_NAMESPACE = "service";
+
+ private static final String EMPTY_MESSAGE = "[EMPTY]";
+ private static final String UNRESOLVED_MESSAGE = "[UNRESOLVED]";
+
+ @Option(name = "--namespace")
+ String namespace = "*";
+
+ public Requirements() {
+ super(true);
+ }
+
+ @Override
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ boolean separatorNeeded = false;
+ Pattern ns = Pattern.compile(namespace.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*"));
+ for (Bundle b : bundles) {
+ if (separatorNeeded) {
+ System.out.println("");
+ }
+
+ // Print out any matching generic requirements.
+ BundleWiring wiring = b.adapt(BundleWiring.class);
+ if (wiring != null) {
+ String title = b + " requires:";
+ System.out.println(title);
+ System.out.println(ShellUtil.getUnderlineString(title));
+ boolean matches = printMatchingRequirements(wiring, ns);
+
+ // Handle service requirements separately, since they aren't part
+ // of the generic model in OSGi.
+ if (matchNamespace(ns, NONSTANDARD_SERVICE_NAMESPACE)) {
+ matches |= printServiceRequirements(b);
+ }
+
+ // If there were no requirements for the specified namespace,
+ // then say so.
+ if (!matches) {
+ System.out.println(namespace + " " + EMPTY_MESSAGE);
+ }
+ } else {
+ System.out.println("Bundle " + b.getBundleId() + " is not resolved.");
+ }
+
+ separatorNeeded = true;
+ }
+ }
+
+ private static boolean printMatchingRequirements(BundleWiring wiring, Pattern namespace) {
+ List<BundleWire> wires = wiring.getRequiredWires(null);
+ Map<BundleRequirement, List<BundleWire>> aggregateReqs = aggregateRequirements(namespace, wires);
+ List<BundleRequirement> allReqs = wiring.getRequirements(null);
+ boolean matches = false;
+ for (BundleRequirement req : allReqs) {
+ if (matchNamespace(namespace, req.getNamespace())) {
+ matches = true;
+ List<BundleWire> providers = aggregateReqs.get(req);
+ if (providers != null) {
+ System.out.println(req.getNamespace() + "; "
+ + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " resolved by:");
+ for (BundleWire wire : providers) {
+ String msg;
+ Object keyAttr = wire.getCapability().getAttributes().get(wire.getCapability().getNamespace());
+ if (keyAttr != null) {
+ msg = wire.getCapability().getNamespace() + "; "
+ + keyAttr + " " + getVersionFromCapability(wire.getCapability());
+ } else {
+ msg = wire.getCapability().toString();
+ }
+ msg = " " + msg + " from " + wire.getProviderWiring().getBundle();
+ System.out.println(msg);
+ }
+ } else {
+ System.out.println(req.getNamespace() + "; "
+ + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " " + UNRESOLVED_MESSAGE);
+ }
+ }
+ }
+ return matches;
+ }
+
+ private static Map<BundleRequirement, List<BundleWire>> aggregateRequirements(
+ Pattern namespace, List<BundleWire> wires) {
+ // Aggregate matching capabilities.
+ Map<BundleRequirement, List<BundleWire>> map = new HashMap<BundleRequirement, List<BundleWire>>();
+ for (BundleWire wire : wires) {
+ if (matchNamespace(namespace, wire.getRequirement().getNamespace())) {
+ List<BundleWire> providers = map.get(wire.getRequirement());
+ if (providers == null) {
+ providers = new ArrayList<BundleWire>();
+ map.put(wire.getRequirement(), providers);
+ }
+ providers.add(wire);
+ }
+ }
+ return map;
+ }
+
+ static boolean printServiceRequirements(Bundle b) {
+ boolean matches = false;
+
+ try {
+ ServiceReference<?>[] refs = b.getServicesInUse();
+
+ if ((refs != null) && (refs.length > 0)) {
+ matches = true;
+ // Print properties for each service.
+ for (ServiceReference<?> ref : refs) {
+ // Print object class with "namespace".
+ System.out.println(
+ NONSTANDARD_SERVICE_NAMESPACE
+ + "; "
+ + ShellUtil.getValueString(ref.getProperty("objectClass"))
+ + " provided by:");
+ System.out.println(" " + ref.getBundle());
+ }
+ }
+ } catch (Exception ex) {
+ System.err.println(ex.toString());
+ }
+
+ return matches;
+ }
+
+ private static String getVersionFromCapability(BundleCapability c) {
+ Object o = c.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+ if (o == null) {
+ o = c.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ }
+ return (o == null) ? "" : o.toString();
+ }
+
+ private static boolean matchNamespace(Pattern namespace, String actual) {
+ return namespace.matcher(actual).matches();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Resolve.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Resolve.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Resolve.java
new file mode 100644
index 0000000..720f118
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Resolve.java
@@ -0,0 +1,39 @@
+/*
+ * 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.bundle.command;
+
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+@Command(scope = "bundle", name = "resolve", description = "Resolve bundles.")
+@Service
+public class Resolve extends BundlesCommand {
+
+ public Resolve() {
+ super(true);
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ FrameworkWiring wiring = bundleContext.getBundle(0).adapt(FrameworkWiring.class);
+ wiring.resolveBundles(bundles == null || bundles.isEmpty() ? null : bundles);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Restart.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Restart.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Restart.java
new file mode 100644
index 0000000..95d5dfe
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Restart.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.bundle.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.MultiException;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "restart", description = "Restarts bundles.")
+@Service
+public class Restart extends BundlesCommandWithConfirmation {
+
+ public Restart() {
+ errorMessage = "Error restarting bundle";
+ }
+
+ protected void doExecute(List<Bundle> bundles) throws Exception {
+ if (bundles.isEmpty()) {
+ System.err.println("No bundles specified.");
+ return;
+ }
+ List<Exception> exceptions = new ArrayList<Exception>();
+ for (Bundle bundle : bundles) {
+ try {
+ bundle.stop();
+ } catch (Exception e) {
+ exceptions.add(new Exception("Unable to stop bundle " + bundle.getBundleId() + ": " + e.getMessage(), e));
+ }
+ }
+ for (Bundle bundle : bundles) {
+ try {
+ bundle.start();
+ } catch (Exception e) {
+ exceptions.add(new Exception("Unable to start bundle " + bundle.getBundleId() + ": " + e.getMessage(), e));
+ }
+ }
+ MultiException.throwIf("Error restarting bundles", exceptions);
+ }
+
+ @Override
+ protected void executeOnBundle(Bundle bundle) throws Exception {
+ }
+
+}
[15/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Config.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Config.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Config.java
deleted file mode 100644
index a2c6674..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Config.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-
-
-/**
- *
- * Configuration entries which should be created during feature installation. This
- * configuration may be used with OSGi Configuration Admin.
- *
- *
- * <p>Java class for config complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="config">
- * <simpleContent>
- * <extension base="<http://www.w3.org/2001/XMLSchema>string">
- * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "config", propOrder = {
- "value"
-})
-public class Config {
-
- @XmlValue
- protected String value;
- @XmlAttribute(required = true)
- protected String name;
-
- /**
- * Gets the value of the value property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Sets the value of the value property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setValue(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
deleted file mode 100644
index e5d9d94..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-import org.apache.karaf.features.ConfigFileInfo;
-
-
-/**
- *
- * Additional configuration files which should be created during feature installation.
- *
- *
- * <p>Java class for configFile complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="configFile">
- * <simpleContent>
- * <extension base="<http://www.w3.org/2001/XMLSchema>string">
- * <attribute name="finalname" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="override" type="{http://www.w3.org/2001/XMLSchema}boolean" />
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "configFile", propOrder = {
- "value"
-})
-public class ConfigFile implements ConfigFileInfo {
-
- @XmlValue
- protected String value;
- @XmlAttribute(required = true)
- protected String finalname;
- @XmlAttribute
- protected Boolean override;
-
- /**
- * Gets the value of the value property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getLocation() {
- return value;
- }
-
- /**
- * Sets the value of the value property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setLocation(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the finalname property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getFinalname() {
- return finalname;
- }
-
- /**
- * Sets the value of the finalname property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setFinalname(String value) {
- this.finalname = value;
- }
-
- /**
- * Gets the value of the override property.
- *
- * @return
- * possible object is
- * {@link Boolean }
- *
- */
- public boolean isOverride() {
- return override == null? false: override;
- }
-
- /**
- * Sets the value of the override property.
- *
- * @param value
- * allowed object is
- * {@link Boolean }
- *
- */
- public void setOverride(Boolean value) {
- this.override = value;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Content.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Content.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Content.java
deleted file mode 100644
index 756e4c1..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Content.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.internal.model;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.xml.bind.annotation.XmlTransient;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.ConfigFileInfo;
-
-@XmlTransient
-public class Content {
-
- protected List<Config> config;
- protected List<ConfigFile> configfile;
- protected List<Dependency> feature;
- protected List<Bundle> bundle;
-
- /**
- * Gets the value of the config property.
- * <p/>
- * <p/>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the config property.
- * <p/>
- * <p/>
- * For example, to add a new item, do as follows:
- * <pre>
- * getConfig().add(newItem);
- * </pre>
- * <p/>
- * <p/>
- * <p/>
- * Objects of the following type(s) are allowed in the list
- * {@link Config }
- */
- public List<Config> getConfig() {
- if (config == null) {
- config = new ArrayList<Config>();
- }
- return this.config;
- }
-
- /**
- * Gets the value of the configfile property.
- * <p/>
- * <p/>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the configfile property.
- * <p/>
- * <p/>
- * For example, to add a new item, do as follows:
- * <pre>
- * getConfigfile().add(newItem);
- * </pre>
- * <p/>
- * <p/>
- * <p/>
- * Objects of the following type(s) are allowed in the list
- * {@link ConfigFile }
- */
- public List<ConfigFile> getConfigfile() {
- if (configfile == null) {
- configfile = new ArrayList<ConfigFile>();
- }
- return this.configfile;
- }
-
- /**
- * Gets the value of the feature property.
- * <p/>
- * <p/>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the feature property.
- * <p/>
- * <p/>
- * For example, to add a new item, do as follows:
- * <pre>
- * getFeature().add(newItem);
- * </pre>
- * <p/>
- * <p/>
- * <p/>
- * Objects of the following type(s) are allowed in the list
- * {@link Dependency }
- */
- public List<Dependency> getFeature() {
- if (feature == null) {
- feature = new ArrayList<Dependency>();
- }
- return this.feature;
- }
-
- /**
- * Gets the value of the bundle property.
- * <p/>
- * <p/>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the bundle property.
- * <p/>
- * <p/>
- * For example, to add a new item, do as follows:
- * <pre>
- * getBundle().add(newItem);
- * </pre>
- * <p/>
- * <p/>
- * <p/>
- * Objects of the following type(s) are allowed in the list
- * {@link Bundle }
- */
- public List<Bundle> getBundle() {
- if (bundle == null) {
- bundle = new ArrayList<Bundle>();
- }
- return this.bundle;
- }
-
- public List<org.apache.karaf.features.Dependency> getDependencies() {
- return Collections.<org.apache.karaf.features.Dependency>unmodifiableList(getFeature());
- }
-
- public List<BundleInfo> getBundles() {
- return Collections.<BundleInfo>unmodifiableList(getBundle());
- }
-
- public Map<String, Map<String, String>> getConfigurations() {
- Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
- for (Config config : getConfig()) {
- String name = config.getName();
- StringReader propStream = new StringReader(config.getValue());
- Properties props = new Properties();
- try {
- props.load(propStream);
- } catch (IOException e) {
- //ignore??
- }
- interpolation(props);
- Map<String, String> propMap = new HashMap<String, String>();
- for (Map.Entry<Object, Object> entry : props.entrySet()) {
- propMap.put((String) entry.getKey(), (String) entry.getValue());
- }
- result.put(name, propMap);
- }
- return result;
- }
-
- public List<ConfigFileInfo> getConfigurationFiles() {
- return Collections.<ConfigFileInfo>unmodifiableList(getConfigfile());
- }
-
- @SuppressWarnings("rawtypes")
- protected void interpolation(Properties properties) {
- for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
- String key = (String) e.nextElement();
- String val = properties.getProperty(key);
- Matcher matcher = Pattern.compile("\\$\\{([^}]+)\\}").matcher(val);
- while (matcher.find()) {
- String rep = System.getProperty(matcher.group(1));
- if (rep != null) {
- val = val.replace(matcher.group(0), rep);
- matcher.reset(val);
- }
- }
- properties.put(key, val);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
deleted file mode 100644
index 9c92a93..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-
-
-/**
- *
- * Dependency of feature.
- *
- *
- * <p>Java class for dependency complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="dependency">
- * <simpleContent>
- * <extension base="<http://karaf.apache.org/xmlns/features/v1.0.0>featureName">
- * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" default="0.0.0" />
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "dependency", propOrder = {
- "value"
-})
-public class Dependency implements org.apache.karaf.features.Dependency {
-
- @XmlValue
- protected String value;
- @XmlAttribute
- protected String version;
-
- /**
- *
- * Feature name should be non empty string.
- *
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return value;
- }
-
- /**
- * Sets the value of the value property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the version property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getVersion() {
- if (version == null) {
- return "0.0.0";
- } else {
- return version;
- }
- }
-
- /**
- * Sets the value of the version property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setVersion(String value) {
- this.version = value;
- }
-
- public String toString() {
- String ret = getName() + Feature.SPLIT_FOR_NAME_AND_VERSION + getVersion();
- return ret;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
deleted file mode 100644
index 46580da..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * 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.internal.model;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- *
- * Definition of the Feature.
- *
- *
- * <p>Java class for feature complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="feature">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="details" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- * <element name="config" type="{http://karaf.apache.org/xmlns/features/v1.0.0}config" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="configfile" type="{http://karaf.apache.org/xmlns/features/v1.0.0}configFile" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="feature" type="{http://karaf.apache.org/xmlns/features/v1.0.0}dependency" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="bundle" type="{http://karaf.apache.org/xmlns/features/v1.0.0}bundle" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="conditional" type="{http://karaf.apache.org/xmlns/features/v1.0.0}conditional" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="capability" type="{http://karaf.apache.org/xmlns/features/v1.0.0}capability" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="requirement" type="{http://karaf.apache.org/xmlns/features/v1.0.0}requirement" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="name" use="required" type="{http://karaf.apache.org/xmlns/features/v1.0.0}featureName" />
- * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" default="0.0.0" />
- * <attribute name="description" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="resolver" type="{http://karaf.apache.org/xmlns/features/v1.0.0}resolver" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "feature", propOrder = {
- "details",
- "config",
- "configfile",
- "feature",
- "bundle",
- "conditional",
- "capability",
- "requirement"
-})
-public class Feature extends Content implements org.apache.karaf.features.Feature {
- public static String SPLIT_FOR_NAME_AND_VERSION = "/";
- public static String DEFAULT_VERSION = "0.0.0";
-
-
- protected String details;
- @XmlAttribute(required = true)
- protected String name;
- @XmlAttribute
- protected String version;
- @XmlAttribute
- protected String description;
- @XmlAttribute
- protected String resolver;
- @XmlAttribute
- protected String install;
- @XmlAttribute(name = "start-level")
- protected Integer startLevel;
- @XmlAttribute
- protected String region;
- protected List<Conditional> conditional;
- protected List<Capability> capability;
- protected List<Requirement> requirement;
-
- public Feature() {
- }
-
- public Feature(String name) {
- this.name = name;
- }
-
- public Feature(String name, String version) {
- this.name = name;
- this.version = version;
- }
-
-
- public static org.apache.karaf.features.Feature valueOf(String str) {
- if (str.contains(SPLIT_FOR_NAME_AND_VERSION)) {
- String strName = str.substring(0, str.indexOf(SPLIT_FOR_NAME_AND_VERSION));
- String strVersion = str.substring(str.indexOf(SPLIT_FOR_NAME_AND_VERSION)
- + SPLIT_FOR_NAME_AND_VERSION.length(), str.length());
- return new Feature(strName, strVersion);
- } else {
- return new Feature(str);
- }
-
-
- }
-
-
- public String getId() {
- return getName() + SPLIT_FOR_NAME_AND_VERSION + getVersion();
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
- /**
- * Gets the value of the version property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getVersion() {
- if (version == null) {
- return DEFAULT_VERSION;
- } else {
- return version;
- }
- }
-
- /**
- * Sets the value of the version property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setVersion(String value) {
- this.version = value;
- }
-
- /**
- * Since version has a default value ("0.0.0"), returns
- * whether or not the version has been set.
- */
- public boolean hasVersion() {
- return this.version != null;
- }
-
- /**
- * Gets the value of the description property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Sets the value of the description property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setDescription(String value) {
- this.description = value;
- }
-
- public String getDetails() {
- return details;
- }
-
- public void setDetails(String details) {
- this.details = details;
- }
-
- /**
- * Gets the value of the resolver property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getResolver() {
- return resolver;
- }
-
- public String getInstall() {
- return install;
- }
-
- public void setInstall(String install) {
- this.install = install;
- }
-
- /**
- * Sets the value of the resolver property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setResolver(String value) {
- this.resolver = value;
- }
-
- /**
- * Gets the value of the startLevel property.
- *
- * @return
- * possible object is
- * {@link Integer }
- *
- */
- public int getStartLevel() {
- return startLevel == null? 0: startLevel;
- }
-
- /**
- * Sets the value of the startLevel property.
- *
- * @param value
- * allowed object is
- * {@link Integer }
- *
- */
- public void setStartLevel(Integer value) {
- this.startLevel = value;
- }
-
-
- public String getRegion() {
- return region;
- }
-
- public void setRegion(String region) {
- this.region = region;
- }
-
- /**
- * Gets the value of the conditional property.
- * <p/>
- * <p/>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the feature property.
- * <p/>
- * <p/>
- * For example, to add a new item, do as follows:
- * <pre>
- * getConditionals().add(newItem);
- * </pre>
- * <p/>
- * <p/>
- * <p/>
- * Objects of the following type(s) are allowed in the list
- * {@link Conditional }
- */
- public List<Conditional> getConditional() {
- if (conditional == null) {
- conditional = new ArrayList<Conditional>();
- }
- return this.conditional;
- }
-
- public List<Capability> getCapabilities() {
- if (capability == null) {
- capability = new ArrayList<Capability>();
- }
- return this.capability;
- }
-
- public List<Requirement> getRequirements() {
- if (requirement == null) {
- requirement = new ArrayList<Requirement>();
- }
- return this.requirement;
- }
-
- public String toString() {
- return getId();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Feature feature = (Feature) o;
-
- if (name != null ? !name.equals(feature.name) : feature.name != null) return false;
- if (version != null ? !version.equals(feature.version) : feature.version != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = name != null ? name.hashCode() : 0;
- result = 31 * result + (version != null ? version.hashCode() : 0);
- return result;
- }
-
- @SuppressWarnings("rawtypes")
- protected void interpolation(Properties properties) {
- for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- String val = properties.getProperty(key);
- Matcher matcher = Pattern.compile("\\$\\{([^}]+)\\}").matcher(val);
- while (matcher.find()) {
- String rep = System.getProperty(matcher.group(1));
- if (rep != null) {
- val = val.replace(matcher.group(0), rep);
- matcher.reset(val);
- }
- }
- properties.put(key, val);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Features.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Features.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Features.java
deleted file mode 100644
index e116f31..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Features.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSchemaType;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- *
- * Root element of Feature definition. It contains optional attribute which allow
- * name of repository. This name will be used in shell to display source repository
- * of given feature.
- *
- *
- * <p>Java class for featuresRoot complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="features">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="repository" type="{http://www.w3.org/2001/XMLSchema}anyURI" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="feature" type="{http://karaf.apache.org/xmlns/features/v1.0.0}feature" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlRootElement(name = "features")
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "features", propOrder = {
- "repository",
- "feature"
-})
-public class Features {
-
- @XmlSchemaType(name = "anyURI")
- protected List<String> repository;
- protected List<Feature> feature;
- @XmlAttribute
- protected String name;
-
- /**
- * Gets the value of the repository property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the repository property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getRepository().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link String }
- *
- *
- */
- public List<String> getRepository() {
- if (repository == null) {
- repository = new ArrayList<String>();
- }
- return this.repository;
- }
-
- /**
- * Gets the value of the feature property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the feature property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getFeature().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link Feature }
- *
- *
- */
- public List<Feature> getFeature() {
- if (feature == null) {
- feature = new ArrayList<Feature>();
- }
- return this.feature;
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
deleted file mode 100644
index 39c057a..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.internal.model;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Writer;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.ValidationEvent;
-import javax.xml.bind.ValidationEventHandler;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.transform.sax.SAXSource;
-
-import org.apache.karaf.features.FeaturesNamespaces;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLFilterImpl;
-
-public class JaxbUtil {
-
- public static final XMLInputFactory XMLINPUT_FACTORY = XMLInputFactory.newInstance();
- private static final JAXBContext FEATURES_CONTEXT;
- static {
- try {
- FEATURES_CONTEXT = JAXBContext.newInstance(Features.class);
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static void marshal(Features features, OutputStream out) throws JAXBException {
- Marshaller marshaller = FEATURES_CONTEXT.createMarshaller();
-
- marshaller.setProperty("jaxb.formatted.output", true);
-
- marshaller.marshal(features, out);
- }
-
- public static void marshal(Features features, Writer out) throws JAXBException {
- Marshaller marshaller = FEATURES_CONTEXT.createMarshaller();
-
- marshaller.setProperty("jaxb.formatted.output", true);
-
- marshaller.marshal(features, out);
- }
-
-
- /**
- * Read in a Features from the input stream.
- *
- * @param in input stream to read
- * @param validate whether to validate the input.
- * @return a Features read from the input stream
- * @throws ParserConfigurationException is the SAX parser can not be configured
- * @throws SAXException if there is an xml problem
- * @throws JAXBException if the xml cannot be marshalled into a T.
- */
- public static Features unmarshal(InputStream in, boolean validate) {
- InputSource inputSource = new InputSource(in);
-
- SAXParserFactory factory = SAXParserFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setValidating(validate);
- SAXParser parser;
- try {
- parser = factory.newSAXParser();
-
-
- Unmarshaller unmarshaller = FEATURES_CONTEXT.createUnmarshaller();
- unmarshaller.setEventHandler(new ValidationEventHandler() {
- public boolean handleEvent(ValidationEvent validationEvent) {
- System.out.println(validationEvent);
- return false;
- }
- });
-
- XMLFilter xmlFilter = new NoSourceAndNamespaceFilter(parser.getXMLReader());
- xmlFilter.setContentHandler(unmarshaller.getUnmarshallerHandler());
-
- SAXSource source = new SAXSource(xmlFilter, inputSource);
-
- return (Features)unmarshaller.unmarshal(source);
-
- } catch (ParserConfigurationException e) {
- throw new RuntimeException(e);
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- } catch (SAXException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Provides an empty inputsource for the entity resolver.
- * Converts all elements to the features namespace to make old feature files
- * compatible to the new format
- */
- public static class NoSourceAndNamespaceFilter extends XMLFilterImpl {
- private static final InputSource EMPTY_INPUT_SOURCE = new InputSource(new ByteArrayInputStream(new byte[0]));
-
- public NoSourceAndNamespaceFilter(XMLReader xmlReader) {
- super(xmlReader);
- }
-
- @Override
- public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
- return EMPTY_INPUT_SOURCE;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
- super.startElement(FeaturesNamespaces.URI_CURRENT, localName, qName, atts);
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- super.endElement(FeaturesNamespaces.URI_CURRENT, localName, qName);
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
deleted file mode 100644
index 96fbb0f..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.annotation.XmlElementDecl;
-import javax.xml.bind.annotation.XmlRegistry;
-import javax.xml.namespace.QName;
-
-
-/**
- * This object contains factory methods for each
- * Java content interface and Java element interface
- * generated in the org.apache.karaf.features.wrapper package.
- * <p>An ObjectFactory allows you to programatically
- * construct new instances of the Java representation
- * for XML content. The Java representation of XML
- * content can consist of schema derived interfaces
- * and classes representing the binding of schema
- * type definitions, element declarations and model
- * groups. Factory methods for each of these are
- * provided in this class.
- *
- */
-@XmlRegistry
-public class ObjectFactory {
-
- private final static QName _Features_QNAME = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features");
-
- /**
- * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.karaf.features.wrapper
- *
- */
- public ObjectFactory() {
- }
-
- /**
- * Create an instance of {@link ConfigFile }
- *
- */
- public ConfigFile createConfigFile() {
- return new ConfigFile();
- }
-
- /**
- * Create an instance of {@link Dependency }
- *
- */
- public Dependency createDependency() {
- return new Dependency();
- }
-
- /**
- * Create an instance of {@link Bundle }
- *
- */
- public Bundle createBundle() {
- return new Bundle();
- }
-
- /**
- * Create an instance of {@link Features }
- *
- */
- public Features createFeaturesRoot() {
- return new Features();
- }
-
- /**
- * Create an instance of {@link Config }
- *
- */
- public Config createConfig() {
- return new Config();
- }
-
- /**
- * Create an instance of {@link Feature }
- *
- */
- public Feature createFeature() {
- return new Feature();
- }
-
- /**
- * Create an instance of {@link JAXBElement }{@code <}{@link Features }{@code >}}
- *
- */
- @XmlElementDecl(namespace = "http://karaf.apache.org/xmlns/features/v1.0.0", name = "features")
- public JAXBElement<Features> createFeatures(Features value) {
- return new JAXBElement<Features>(_Features_QNAME, Features.class, null, value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Requirement.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
deleted file mode 100644
index f7b5775..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.XmlValue;
-
-
-/**
- *
- * Additional requirement for a feature.
- *
- *
- * <p>Java class for bundle complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="capability">
- * <simpleContent>
- * <extension base="<http://www.w3.org/2001/XMLSchema>string">
- * </extension>
- * </simpleContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "requirement", propOrder = {
- "value"
-})
-public class Requirement implements org.apache.karaf.features.Requirement {
-
- @XmlValue
- protected String value;
-
-
- public Requirement() {
- }
-
- public Requirement(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Requirement bundle = (Requirement) o;
-
- if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = value != null ? value.hashCode() : 0;
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/model/package-info.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/package-info.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/package-info.java
deleted file mode 100644
index c86a58c..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-
-@javax.xml.bind.annotation.XmlSchema(namespace = org.apache.karaf.features.FeaturesNamespaces.URI_CURRENT, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
-package org.apache.karaf.features.internal.model;
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
deleted file mode 100644
index be0da05..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.internal.osgi;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Properties;
-
-import org.apache.karaf.features.FeaturesListener;
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.features.internal.service.EventAdminListener;
-import org.apache.karaf.features.internal.service.FeatureConfigInstaller;
-import org.apache.karaf.features.internal.service.FeatureFinder;
-import org.apache.karaf.features.internal.service.BootFeaturesInstaller;
-import org.apache.karaf.features.internal.service.FeaturesServiceImpl;
-import org.apache.karaf.features.internal.service.StateStorage;
-import org.apache.karaf.features.internal.management.FeaturesServiceMBeanImpl;
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.apache.karaf.util.tracker.SingleServiceTracker;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.url.URLStreamHandlerService;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public class Activator extends BaseActivator {
-
- public static final String FEATURES_REPOS_PID = "org.apache.karaf.features.repos";
- public static final String FEATURES_SERVICE_CONFIG_FILE = "org.apache.karaf.features.cfg";
-
- private ServiceTracker<FeaturesListener, FeaturesListener> featuresListenerTracker;
- private FeaturesServiceImpl featuresService;
- private SingleServiceTracker<RegionsPersistence> regionsTracker;
-
- public Activator() {
- // Special case here, as we don't want the activator to wait for current job to finish,
- // else it would forbid the features service to refresh itself
- setSchedulerStopTimeout(0);
- }
-
- @Override
- protected void doOpen() throws Exception {
- trackService(URLStreamHandlerService.class, "(url.handler.protocol=mvn)");
- trackService(ConfigurationAdmin.class);
-
- Properties configuration = new Properties();
- File configFile = new File(System.getProperty("karaf.etc"), FEATURES_SERVICE_CONFIG_FILE);
- if (configFile.isFile() && configFile.canRead()) {
- try {
- configuration.load(new FileReader(configFile));
- } catch (IOException e) {
- logger.warn("Error reading configuration file " + configFile.toString(), e);
- }
- }
- updated((Dictionary) configuration);
- }
-
- protected void doStart() throws Exception {
- ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
- URLStreamHandlerService mvnUrlHandler = getTrackedService(URLStreamHandlerService.class);
-
- if (configurationAdmin == null || mvnUrlHandler == null) {
- return;
- }
-
- FeatureFinder featureFinder = new FeatureFinder();
- Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put(Constants.SERVICE_PID, FEATURES_REPOS_PID);
- register(ManagedService.class, featureFinder, props);
-
- // TODO: region support
-// final BundleManager bundleManager = new BundleManager(bundleContext);
-// regionsTracker = new SingleServiceTracker<RegionsPersistence>(bundleContext, RegionsPersistence.class,
-// new SingleServiceTracker.SingleServiceListener() {
-// @Override
-// public void serviceFound() {
-// bundleManager.setRegionsPersistence(regionsTracker.getService());
-// }
-// @Override
-// public void serviceLost() {
-// serviceFound();
-// }
-// @Override
-// public void serviceReplaced() {
-// serviceFound();
-// }
-// });
-// regionsTracker.open();
-
-
- FeatureConfigInstaller configInstaller = new FeatureConfigInstaller(configurationAdmin);
- // TODO: honor respectStartLvlDuringFeatureStartup and respectStartLvlDuringFeatureUninstall
-// boolean respectStartLvlDuringFeatureStartup = getBoolean("respectStartLvlDuringFeatureStartup", true);
-// boolean respectStartLvlDuringFeatureUninstall = getBoolean("respectStartLvlDuringFeatureUninstall", true);
- String overrides = getString("overrides", new File(System.getProperty("karaf.etc"), "overrides.properties").toURI().toString());
- String featureResolutionRange = getString("featureResolutionRange", FeaturesServiceImpl.DEFAULT_FEATURE_RESOLUTION_RANGE);
- String bundleUpdateRange = getString("bundleUpdateRange", FeaturesServiceImpl.DEFAULT_BUNDLE_UPDATE_RANGE);
- String updateSnapshots = getString("updateSnapshots", FeaturesServiceImpl.DEFAULT_UPDATE_SNAPSHOTS);
- StateStorage stateStorage = new StateStorage() {
- @Override
- protected InputStream getInputStream() throws IOException {
- File file = bundleContext.getDataFile("FeaturesServiceState.properties");
- if (file.exists()) {
- return new FileInputStream(file);
- } else {
- return null;
- }
- }
-
- @Override
- protected OutputStream getOutputStream() throws IOException {
- File file = bundleContext.getDataFile("FeaturesServiceState.properties");
- return new FileOutputStream(file);
- }
- };
- EventAdminListener eventAdminListener;
- try {
- eventAdminListener = new EventAdminListener(bundleContext);
- } catch (Throwable t) {
- eventAdminListener = null;
- }
- featuresService = new FeaturesServiceImpl(
- bundleContext.getBundle(),
- bundleContext.getBundle(0).getBundleContext(),
- stateStorage,
- featureFinder,
- eventAdminListener,
- configInstaller,
- overrides,
- featureResolutionRange,
- bundleUpdateRange,
- updateSnapshots);
- register(FeaturesService.class, featuresService);
-
- featuresListenerTracker = new ServiceTracker<FeaturesListener, FeaturesListener>(
- bundleContext, FeaturesListener.class, new ServiceTrackerCustomizer<FeaturesListener, FeaturesListener>() {
- @Override
- public FeaturesListener addingService(ServiceReference<FeaturesListener> reference) {
- FeaturesListener service = bundleContext.getService(reference);
- featuresService.registerListener(service);
- return service;
- }
- @Override
- public void modifiedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
- }
- @Override
- public void removedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
- featuresService.unregisterListener(service);
- bundleContext.ungetService(reference);
- }
- }
- );
- featuresListenerTracker.open();
-
- String featuresRepositories = getString("featuresRepositories", "");
- String featuresBoot = getString("featuresBoot", "");
- boolean featuresBootAsynchronous = getBoolean("featuresBootAsynchronous", false);
- BootFeaturesInstaller bootFeaturesInstaller = new BootFeaturesInstaller(
- bundleContext, featuresService,
- featuresRepositories, featuresBoot, featuresBootAsynchronous);
- bootFeaturesInstaller.start();
-
- FeaturesServiceMBeanImpl featuresServiceMBean = new FeaturesServiceMBeanImpl();
- featuresServiceMBean.setBundleContext(bundleContext);
- featuresServiceMBean.setFeaturesService(featuresService);
- registerMBean(featuresServiceMBean, "type=feature");
- }
-
- protected void doStop() {
- if (regionsTracker != null) {
- regionsTracker.close();
- regionsTracker = null;
- }
- if (featuresListenerTracker != null) {
- featuresListenerTracker.close();
- featuresListenerTracker = null;
- }
- super.doStop();
- if (featuresService != null) {
- featuresService = null;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
deleted file mode 100644
index 0d5e83d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.service.repository.Repository;
-
-public class AggregateRepository implements Repository {
-
- private final Collection<Repository> repositories;
-
- public AggregateRepository(Collection<Repository> repositories) {
- this.repositories = repositories;
- }
-
- @Override
- public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
- Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
- for (Requirement requirement : requirements) {
- List<Capability> caps = new ArrayList<Capability>();
- for (Repository repository : repositories) {
- Map<Requirement, Collection<Capability>> resMap =
- repository.findProviders(Collections.singleton(requirement));
- Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
- if (res != null) {
- caps.addAll(res);
- }
- }
- result.put(requirement, caps);
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
deleted file mode 100644
index c4c0d16..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.karaf.features.internal.resolver.CapabilitySet;
-import org.apache.karaf.features.internal.resolver.RequirementImpl;
-import org.apache.karaf.features.internal.resolver.SimpleFilter;
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-import org.osgi.service.repository.Repository;
-
-/**
- */
-public class BaseRepository implements Repository {
-
- protected final List<Resource> resources;
- protected final Map<String, CapabilitySet> capSets;
-
- public BaseRepository() {
- this.resources = new ArrayList<Resource>();
- this.capSets = new HashMap<String, CapabilitySet>();
- }
-
- protected void addResource(Resource resource) {
- for (Capability cap : resource.getCapabilities(null)) {
- String ns = cap.getNamespace();
- CapabilitySet set = capSets.get(ns);
- if (set == null) {
- set = new CapabilitySet(Collections.singletonList(ns));
- capSets.put(ns, set);
- }
- set.addCapability(cap);
- }
- resources.add(resource);
- }
-
- public List<Resource> getResources() {
- return resources;
- }
-
- @Override
- public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
- Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
- for (Requirement requirement : requirements) {
- CapabilitySet set = capSets.get(requirement.getNamespace());
- if (set != null) {
- SimpleFilter sf;
- if (requirement instanceof RequirementImpl) {
- sf = ((RequirementImpl) requirement).getFilter();
- } else {
- String filter = requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
- sf = (filter != null)
- ? SimpleFilter.parse(filter)
- : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- }
- result.put(requirement, set.match(sf, true));
- } else {
- result.put(requirement, Collections.<Capability>emptyList());
- }
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java
deleted file mode 100644
index 7916821..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.service.repository.Repository;
-
-public class CacheRepository implements Repository {
-
- private final Repository repository;
- private final Map<Requirement, Collection<Capability>> cache =
- new ConcurrentHashMap<Requirement, Collection<Capability>>();
-
- public CacheRepository(Repository repository) {
- this.repository = repository;
- }
-
- @Override
- public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
- List<Requirement> missing = new ArrayList<Requirement>();
- Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
- for (Requirement requirement : requirements) {
- Collection<Capability> caps = cache.get(requirement);
- if (caps == null) {
- missing.add(requirement);
- } else {
- result.put(requirement, caps);
- }
- }
- Map<Requirement, Collection<Capability>> newCache = repository.findProviders(missing);
- for (Requirement requirement : newCache.keySet()) {
- cache.put(requirement, newCache.get(requirement));
- result.put(requirement, newCache.get(requirement));
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
deleted file mode 100644
index 1aecef1..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Map;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.karaf.features.internal.util.JsonReader;
-
-/**
- */
-public class HttpMetadataProvider implements MetadataProvider {
-
- public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
- public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
- public static final String GZIP = "gzip";
-
- private final String url;
- private long lastModified;
- private Map<String, Map<String, String>> metadatas;
-
- public HttpMetadataProvider(String url) {
- this.url = url;
- }
-
- @Override
- public long getLastModified() {
- return lastModified;
- }
-
- @Override
- public Map<String, Map<String, String>> getMetadatas() {
- try {
- HttpURLConnection.setFollowRedirects(false);
- HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
- if (lastModified > 0) {
- con.setIfModifiedSince(lastModified);
- }
- con.setRequestProperty(HEADER_ACCEPT_ENCODING, GZIP);
- if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
- lastModified = con.getLastModified();
- InputStream is = con.getInputStream();
- if (GZIP.equals(con.getHeaderField(HEADER_CONTENT_ENCODING))) {
- is = new GZIPInputStream(is);
- }
- metadatas = verify(JsonReader.read(is));
- } else if (con.getResponseCode() != HttpURLConnection.HTTP_NOT_MODIFIED) {
- throw new IOException("Unexpected http response: "
- + con.getResponseCode() + " " + con.getResponseMessage());
- }
- return metadatas;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private Map<String, Map<String, String>> verify(Object value) {
- Map<?,?> obj = Map.class.cast(value);
- for (Map.Entry<?,?> entry : obj.entrySet()) {
- String.class.cast(entry.getKey());
- Map<?,?> child = Map.class.cast(entry.getValue());
- for (Map.Entry<?,?> ce : child.entrySet()) {
- String.class.cast(ce.getKey());
- String.class.cast(ce.getValue());
- }
- }
- return (Map<String, Map<String, String>>) obj;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
deleted file mode 100644
index 9ac54a1..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.Map;
-
-/**
- */
-public interface MetadataProvider {
-
- long getLastModified();
-
- Map<String, Map<String, String>> getMetadatas();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
deleted file mode 100644
index 2d4fbba..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.Map;
-
-import org.apache.karaf.features.internal.resolver.ResourceBuilder;
-import org.osgi.resource.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- */
-public class MetadataRepository extends BaseRepository {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(MetadataRepository.class);
-
- public MetadataRepository(MetadataProvider provider) {
- Map<String, Map<String, String>> metadatas = provider.getMetadatas();
- for (Map.Entry<String, Map<String, String>> metadata : metadatas.entrySet()) {
- try {
- Resource resource = ResourceBuilder.build(metadata.getKey(), metadata.getValue());
- addResource(resource);
- } catch (Exception e) {
- LOGGER.info("Unable to build resource for " + metadata.getKey(), e);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java b/features/core/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java
deleted file mode 100644
index f289c8d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.internal.repository;
-
-import java.util.Collection;
-
-import org.osgi.resource.Resource;
-
-/**
- */
-public class StaticRepository extends BaseRepository {
-
- public StaticRepository(Collection<Resource> resources) {
- for (Resource resource : resources) {
- addResource(resource);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
deleted file mode 100644
index 0653398..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.internal.resolver;
-
-import java.util.Map;
-
-import org.osgi.framework.Version;
-import org.osgi.resource.Resource;
-
-/**
- */
-public abstract class BaseClause {
-
- public abstract Resource getResource();
-
- public abstract String getNamespace();
-
- public abstract Map<String, String> getDirectives();
-
- public abstract Map<String, Object> getAttributes();
-
- @Override
- public String toString() {
- return toString(getResource(), getNamespace(), getAttributes(), getDirectives());
- }
-
- public static String toString(Resource res, String namespace, Map<String, Object> attrs, Map<String, String> dirs) {
- StringBuilder sb = new StringBuilder();
- if (res != null) {
- sb.append("[").append(res).append("] ");
- }
- sb.append(namespace);
- for (String key : attrs.keySet()) {
- sb.append("; ");
- append(sb, key, attrs.get(key), true);
- }
- for (String key : dirs.keySet()) {
- sb.append("; ");
- append(sb, key, dirs.get(key), false);
- }
- return sb.toString();
- }
-
- private static void append(StringBuilder sb, String key, Object val, boolean attribute) {
- sb.append(key);
- if (val instanceof Version) {
- sb.append(":Version=");
- sb.append(val);
- } else if (val instanceof Long) {
- sb.append(":Long=");
- sb.append(val);
- } else if (val instanceof Double) {
- sb.append(":Double=");
- sb.append(val);
- } else if (val instanceof Iterable) {
- Iterable it = (Iterable) val;
- String scalar = null;
- for (Object o : it) {
- String ts;
- if (o instanceof String) {
- ts = "String";
- } else if (o instanceof Long) {
- ts = "Long";
- } else if (o instanceof Double) {
- ts = "Double";
- } else if (o instanceof Version) {
- ts = "Version";
- } else {
- throw new IllegalArgumentException("Unsupported scalar type: " + o);
- }
- if (scalar == null) {
- scalar = ts;
- } else if (!scalar.equals(ts)) {
- throw new IllegalArgumentException("Unconsistent list type for attribute " + key);
- }
- }
- sb.append(":List<").append(scalar).append(">=");
- sb.append("\"");
- boolean first = true;
- for (Object o : it) {
- if (first) {
- first = false;
- } else {
- sb.append(",");
- }
- sb.append(o.toString().replace("\"", "\\\"").replace(",", "\\,"));
- }
- sb.append("\"");
- } else {
- sb.append(attribute ? "=" : ":=");
- String s = val.toString();
- if (s.matches("[0-9a-zA-Z_\\-.]*")) {
- sb.append(s);
- } else {
- sb.append("\"").append(s.replace("\"", "\\\\")).append("\"");
- }
- }
- }
-
-}
[17/59] [abbrv] git commit: [KARAF-2852] Merge features/core and
features/command
Posted by gn...@apache.org.
[KARAF-2852] Merge features/core and features/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/999f4970
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/999f4970
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/999f4970
Branch: refs/heads/master
Commit: 999f4970fecd3710da36b709f2d484cd0db38d09
Parents: 2c4e8da
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 21:46:31 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 15:59:05 2014 +0200
----------------------------------------------------------------------
assemblies/apache-karaf-minimal/pom.xml | 1 +
assemblies/apache-karaf/pom.xml | 1 +
.../standard/src/main/feature/feature.xml | 1 -
features/command/NOTICE | 71 -
features/command/pom.xml | 90 --
.../command/FeaturesCommandSupport.java | 42 -
.../features/command/InfoFeatureCommand.java | 292 ----
.../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 | 71 -
.../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 | 138 --
.../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 | 36 -
.../apache/karaf/features/RepositoryEvent.java | 50 -
.../org/apache/karaf/features/Requirement.java | 23 -
.../org/apache/karaf/features/Resolver.java | 25 -
.../internal/deployment/DeploymentBuilder.java | 334 ----
.../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 | 71 -
.../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 | 149 --
.../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 | 121 --
.../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 | 113 --
.../internal/service/FeaturesServiceImpl.java | 1454 -----------------
.../features/internal/service/Overrides.java | 132 --
.../internal/service/RepositoryImpl.java | 103 --
.../internal/service/RequirementSort.java | 107 --
.../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 | 47 -
.../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 | 65 -
.../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 | 32 -
.../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 | 123 +-
.../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 | 36 +
.../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 | 292 ++++
.../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 | 71 +
.../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 | 334 ++++
.../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 | 71 +
.../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 | 149 ++
.../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 | 121 ++
.../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 | 113 ++
.../internal/service/FeaturesServiceImpl.java | 1455 ++++++++++++++++++
.../features/internal/service/Overrides.java | 132 ++
.../internal/service/RepositoryImpl.java | 103 ++
.../internal/service/RequirementSort.java | 107 ++
.../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 | 47 +
.../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 | 65 +
.../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 | 32 +
.../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 +
259 files changed, 15808 insertions(+), 16110 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/assemblies/apache-karaf-minimal/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf-minimal/pom.xml b/assemblies/apache-karaf-minimal/pom.xml
index 63c174e..385d3bd 100644
--- a/assemblies/apache-karaf-minimal/pom.xml
+++ b/assemblies/apache-karaf-minimal/pom.xml
@@ -116,6 +116,7 @@
</installedFeatures>
<bootFeatures>
<feature>jaas</feature>
+ <feature>shell</feature>
<feature>ssh</feature>
<feature>management</feature>
<feature>bundle</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index efc0acf..ce631b8 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -162,6 +162,7 @@
<bootFeatures>
<feature>aries-blueprint</feature>
<feature>shell-compat</feature>
+ <feature>shell</feature>
<feature>jaas</feature>
<feature>ssh</feature>
<feature>management</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/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 49028d2..fde555c 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -73,7 +73,6 @@
<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/999f4970/features/command/NOTICE
----------------------------------------------------------------------
diff --git a/features/command/NOTICE b/features/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/features/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/999f4970/features/command/pom.xml
----------------------------------------------------------------------
diff --git a/features/command/pom.xml b/features/command/pom.xml
deleted file mode 100644
index 4f49bb1..0000000
--- a/features/command/pom.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?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/999f4970/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
deleted file mode 100644
index 076650d..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 7084a6e..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * 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<? extends Dependency> 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();
- Iterator<? extends Dependency> di = cond.getCondition().iterator();
- while (di.hasNext()) {
- Dependency dep = di.next();
- sb.append(dep.getName()).append("/").append(dep.getVersion());
- if (di.hasNext()) {
- sb.append(" ");
- }
- }
- return sb.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/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
deleted file mode 100644
index b7f8184..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index b2c5e42..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index e86ff64..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 16faf42..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 591a1c6..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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) {
- 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/999f4970/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
deleted file mode 100644
index 8c7ed79..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 0710b72..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index e62f697..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 7444b95..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 79cd280..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index acefe77..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index d01e5af..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 94e4cf7..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 7a760c2..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index a51f75f..0000000
--- a/features/command/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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/999f4970/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
deleted file mode 100644
index 8f0598b..0000000
--- a/features/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,30 +0,0 @@
-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.
[25/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
new file mode 100644
index 0000000..d831fb7
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/impl/ProcessImpl.java
@@ -0,0 +1,155 @@
+/*
+ * 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.jpm.impl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.InterruptedIOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.karaf.jpm.Process;
+
+public class ProcessImpl implements Process {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8140632422386086507L;
+
+ private int pid;
+ //private File input;
+ //private File output;
+ //private File error;
+
+ public ProcessImpl(int pid/*, File input, File output, File error*/) {
+ this.pid = pid;
+ //this.input = input;
+ //this.output = output;
+ //this.error = error;
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public boolean isRunning() throws IOException {
+ if (ScriptUtils.isWindows()) {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("${pid}", Integer.toString(pid));
+ int ret = ScriptUtils.execute("running", props);
+ return ret == 0;
+ } else {
+ try {
+ java.lang.Process process = new java.lang.ProcessBuilder("ps", "-p", Integer.toString(pid)).start();
+ BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ r.readLine(); // skip headers
+ String s = r.readLine();
+ boolean running = s != null && s.length() > 0;
+ process.waitFor();
+ return running;
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ }
+ }
+
+ public void destroy() throws IOException {
+ int ret;
+ if (ScriptUtils.isWindows()) {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("${pid}", Integer.toString(pid));
+ ret = ScriptUtils.execute("destroy", props);
+ } else {
+ ret = ScriptUtils.executeProcess(new java.lang.ProcessBuilder("kill", "-9", Integer.toString(pid)));
+ }
+ if (ret != 0) {
+ throw new IOException("Unable to destroy process, it may already be terminated");
+ }
+ }
+
+ /*
+ public OutputStream getInputStream() throws FileNotFoundException {
+ return new FileOutputStream(input);
+ }
+
+ public InputStream getOutputStream() throws FileNotFoundException {
+ return new FileInputStream(output);
+ }
+
+ public InputStream getErrorStream() throws FileNotFoundException {
+ return new FileInputStream(error);
+ }
+ */
+
+ public int waitFor() throws InterruptedException {
+ return 0;
+ }
+
+ public int exitValue() {
+ return 0;
+ }
+
+ public static Process create(File dir, String command) throws IOException {
+ //File input = File.createTempFile("jpm.", ".input");
+ //File output = File.createTempFile("jpm.", ".output");
+ //File error = File.createTempFile("jpm.", ".error");
+ File pidFile = File.createTempFile("jpm.", ".pid");
+ try {
+ Map<String, String> props = new HashMap<String, String>();
+ //props.put("${in.file}", input.getCanonicalPath());
+ //props.put("${out.file}", output.getCanonicalPath());
+ //props.put("${err.file}", error.getCanonicalPath());
+ props.put("${pid.file}", pidFile.getCanonicalPath());
+ props.put("${dir}", dir != null ? dir.getCanonicalPath() : "");
+ if (ScriptUtils.isWindows()) {
+ command = command.replaceAll("\"", "\"\"");
+ }
+ props.put("${command}", command);
+ int ret = ScriptUtils.execute("start", props);
+ if (ret != 0) {
+ throw new IOException("Unable to create process (error code: " + ret + ")");
+ }
+ int pid = readPid(pidFile);
+ return new ProcessImpl(pid/*, input, output, error*/);
+ } finally {
+ pidFile.delete();
+ }
+ }
+
+ public static Process attach(int pid) throws IOException {
+ return new ProcessImpl(pid);
+ }
+
+ private static int readPid(File pidFile) throws IOException {
+ InputStream is = new FileInputStream(pidFile);
+ try {
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ String pidString = r.readLine();
+ return Integer.valueOf(pidString);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {}
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java b/instance/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
new file mode 100644
index 0000000..a96e28e
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/jpm/impl/ScriptUtils.java
@@ -0,0 +1,128 @@
+/*
+ * 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.jpm.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Scanner;
+
+public class ScriptUtils {
+
+ public static int execute(String name, Map<String, String> props) throws IOException {
+ File script = File.createTempFile("jpm.", ".script");
+ try {
+ if (isWindows()) {
+ String res = "windows/" + name + ".vbs";
+ ScriptUtils.copyFilteredResource(res, script, props);
+ return executeProcess(new java.lang.ProcessBuilder("cscript",
+ "/NOLOGO",
+ "//E:vbs",
+ script.getCanonicalPath()));
+ } else {
+ String res = "unix/" + name + ".sh";
+ ScriptUtils.copyFilteredResource(res, script, props);
+ return executeProcess(new java.lang.ProcessBuilder("/bin/sh",
+ script.getCanonicalPath()));
+ }
+ } finally {
+ script.delete();
+ }
+ }
+
+ public static int executeProcess(java.lang.ProcessBuilder builder) throws IOException {
+ try {
+ java.lang.Process process = builder.start();
+ return process.waitFor();
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ public static void copyFilteredResource(String resource, File outFile, Map<String, String> props) throws IOException {
+ InputStream is = null;
+ try {
+ is = ScriptUtils.class.getResourceAsStream(resource);
+ // Read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine() ) {
+ String line = scanner.nextLine();
+ line = filter(line, props);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(is);
+ }
+ }
+
+ private static void safeClose(InputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private static void safeClose(OutputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private static String filter(String line, Map<String, String> props) {
+ for (Map.Entry<String, String> i : props.entrySet()) {
+ int p1 = line.indexOf(i.getKey());
+ if( p1 >= 0 ) {
+ String l1 = line.substring(0, p1);
+ String l2 = line.substring(p1+i.getKey().length());
+ line = l1+i.getValue()+l2;
+ }
+ }
+ return line;
+ }
+
+ private static final boolean windows;
+
+ static {
+ windows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
+ }
+
+ public static boolean isWindows() {
+ return windows;
+ }
+
+ public static String getJavaCommandPath() throws IOException {
+ return new File(System.getProperty("java.home"), isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/META-INF/services/org/apache/karaf/shell/commands b/instance/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
new file mode 100644
index 0000000..92245c7
--- /dev/null
+++ b/instance/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
@@ -0,0 +1,30 @@
+##---------------------------------------------------------------------------
+## 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.
+##---------------------------------------------------------------------------
+org.apache.karaf.instance.core.internal.InstanceServiceImpl
+org.apache.karaf.instance.command.ChangeOptsCommand
+org.apache.karaf.instance.command.ChangeRmiRegistryPortCommand
+org.apache.karaf.instance.command.ChangeRmiServerPortCommand
+org.apache.karaf.instance.command.ChangeSshPortCommand
+org.apache.karaf.instance.command.CloneCommand
+org.apache.karaf.instance.command.ConnectCommand
+org.apache.karaf.instance.command.CreateCommand
+org.apache.karaf.instance.command.DestroyCommand
+org.apache.karaf.instance.command.ListCommand
+org.apache.karaf.instance.command.RenameCommand
+org.apache.karaf.instance.command.StartCommand
+org.apache.karaf.instance.command.StatusCommand
+org.apache.karaf.instance.command.StopCommand
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/OSGI-INF/bundle.info b/instance/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..9d305c3
--- /dev/null
+++ b/instance/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,36 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle is the core implementation of the Karaf instance feature.
+
+Karaf instance allows you to manage Karaf child instances.
+
+You can create new Karaf instances, configure attributes, rename instances, stop instances, etc.
+
+It also provides JMX MBeans related to the Karaf instance feature.
+
+In particular, an InstanceServiceMBean is provided that can be remotely administered using a JMX client (for instance
+JConsole).
+
+With this InstanceServiceMBean, you have the following operations available:
+* createInstance(name, sshPort, rmiPort, location, javaOpts, features, featureURLs) - Creates a new Karaf instance.
+* changeSshPort(name, port) - Changes the SSH port number of an existing Karaf instance.
+* changeRmiRegistryPort(name, port) - Changes the RMI registry port number of an existing Karaf instance.
+* changeRmiServerPort(name, port) - Changes the RMI server port number of an existing Karaf instance.
+* changeJavaOpts(name, javaopts) - Changes the Java options of an existing Karaf instance.
+* destroyInstance(name) - Destroys an existing Karaf instance.
+* startInstance(name) - Starts an existing Karaf instance.
+* stopInstance(name) - Stops an existing Karaf instance.
+* renameInstance(originalName, newName) - Renames an existing Karaf instance.
+
+h1. See also
+
+Managing child instances - of the Karaf User Guide.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
new file mode 100644
index 0000000..8967cea
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf
@@ -0,0 +1,25 @@
+#!/bin/sh
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+KARAF_HOME=${SUBST-KARAF-HOME}
+KARAF_BASE=${SUBST-KARAF-BASE}
+
+export KARAF_BASE
+exec ${KARAF_HOME}/bin/karaf "$*"
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
new file mode 100644
index 0000000..e054d83
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/karaf.bat
@@ -0,0 +1,25 @@
+@ECHO OFF
+REM =========================================================================
+REM
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM
+REM =========================================================================
+
+SETLOCAL
+SET KARAF_HOME=${SUBST-KARAF-HOME}
+SET KARAF_BASE=${SUBST-KARAF-BASE}
+
+"%KARAF_HOME%\bin\karaf.bat" %*
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start
new file mode 100644
index 0000000..d45d749
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start
@@ -0,0 +1,25 @@
+#!/bin/sh
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+KARAF_HOME=${SUBST-KARAF-HOME}
+KARAF_NAME=${SUBST-KARAF-NAME}
+
+exec ${KARAF_HOME}/bin/instance start ${KARAF_NAME} "$@"
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
new file mode 100644
index 0000000..0c530c8
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/start.bat
@@ -0,0 +1,24 @@
+@ECHO OFF
+REM =========================================================================
+REM
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM
+REM =========================================================================
+
+SET KARAF_HOME=${SUBST-KARAF-HOME}
+SET KARAF_NAME=${SUBST-KARAF-NAME}
+
+"%KARAF_HOME%\bin\instance.bat" start %KARAF_NAME%
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop
new file mode 100644
index 0000000..fb91985
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop
@@ -0,0 +1,25 @@
+#!/bin/sh
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+KARAF_HOME=${SUBST-KARAF-HOME}
+KARAF_NAME=${SUBST-KARAF-NAME}
+
+exec ${KARAF_HOME}/bin/instance stop ${KARAF_NAME} "$@"
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
new file mode 100644
index 0000000..8520acb
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/bin/stop.bat
@@ -0,0 +1,24 @@
+@ECHO OFF
+REM =========================================================================
+REM
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM
+REM =========================================================================
+
+SET KARAF_HOME=${SUBST-KARAF-HOME}
+SET KARAF_NAME=${SUBST-KARAF-NAME}
+
+"%KARAF_HOME%\bin\instance.bat" stop %KARAF_NAME%
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
new file mode 100644
index 0000000..57b2957
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.management.cfg
@@ -0,0 +1,63 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#
+# The properties in this file define the configuration of Apache Karaf's JMX Management
+#
+
+#
+# Port number for RMI registry connection
+#
+rmiRegistryPort = ${SUBST-RMI-REGISTRY-PORT}
+
+#
+# Port number for RMI server connection
+#
+rmiServerPort = ${SUBST-RMI-SERVER-PORT}
+
+#
+# Name of the JAAS realm used for authentication
+#
+jmxRealm = karaf
+
+#
+# The service URL for the JMXConnectorServer
+#
+serviceUrl = service:jmx:rmi://0.0.0.0:${rmiServerPort}/jndi/rmi://0.0.0.0:${rmiRegistryPort}/karaf-${karaf.name}
+
+#
+# Whether any threads started for the JMXConnectorServer should be started as daemon threads
+#
+daemon = true
+
+#
+# Whether the JMXConnectorServer should be started in a separate thread
+#
+threaded = true
+
+#
+# The ObjectName used to register the JMXConnectorServer
+#
+objectName = connector:name=rmi
+
+#
+# Role name used for JMX access authorization
+# If not set, this defaults to the ${karaf.admin.role} configured in etc/system.properties
+#
+# jmxRole=admin
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
new file mode 100644
index 0000000..077f5da
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.shell.cfg
@@ -0,0 +1,75 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#
+# These properties are used to configure Karaf's ssh shell.
+#
+
+#
+# Via sshPort and sshHost you define the address you can login into Karaf.
+#
+sshPort = ${SUBST-SSH-PORT}
+sshHost = 0.0.0.0
+
+#
+# The sshIdleTimeout defines the inactivity timeout to logout the SSH session.
+# The sshIdleTimeout is in milliseconds, and the default is set to 30 minutes.
+#
+sshIdleTimeout = 1800000
+
+#
+# sshRealm defines which JAAS domain to use for password authentication.
+#
+sshRealm = karaf
+
+#
+# The location of the hostKey file defines where the private/public key of the server
+# is located. If no file is at the defined location it will be ignored.
+#
+hostKey = ${karaf.etc}/host.key
+
+#
+# Role name used for SSH access authorization
+# If not set, this defaults to the ${karaf.admin.role} configured in etc/system.properties
+#
+# sshRole = admin
+
+#
+# Self defined key size in 1024, 2048, 3072, or 4096
+# If not set, this defaults to 1024.
+#
+# keySize = 1024
+
+#
+# Specify host key algorithm, defaults to DSA
+#
+# algorithm = DSA
+
+#
+# Defines the completion mode on the Karaf shell console. The possible values are:
+# - GLOBAL: it's the same behavior as in previous Karaf releases. The completion displays all commands and all aliases
+# ignoring if you are in a subshell or not.
+# - FIRST: the completion displays all commands and all aliases only when you are not in a subshell. When you are
+# in a subshell, the completion displays only the commands local to the subshell.
+# - SUBSHELL: the completion displays only the subshells on the root level. When you are in a subshell, the completion
+# displays only the commands local to the subshell.
+# This property define the default value when you use the Karaf shell console.
+# You can change the completion mode directly in the shell console, using shell:completion command.
+#
+completionMode = GLOBAL
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
new file mode 100644
index 0000000..a683a34
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/system.properties
@@ -0,0 +1,120 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#
+# The properties defined in this file will be made available through system
+# properties at the very beginning of the Karaf's boot process.
+#
+
+
+# Log level when the pax-logging service is not available
+# This level will only be used while the pax-logging service bundle
+# is not fully available.
+# To change log levels, please refer to the org.ops4j.pax.logging.cfg file
+# instead.
+org.ops4j.pax.logging.DefaultServiceLog.level = ERROR
+
+#
+# Name of this Karaf instance.
+#
+karaf.name = ${SUBST-KARAF-NAME}
+
+#
+# Default repository where bundles will be loaded from before using
+# other Maven repositories. For the full Maven configuration, see
+# the org.ops4j.pax.url.mvn.cfg file.
+#
+karaf.default.repository = system
+
+#
+# Location of a shell script that will be run when starting a shell
+# session. This script can be used to create aliases and define
+# additional commands.
+#
+karaf.shell.init.script = ${karaf.etc}/shell.init.script
+
+#
+# Sets the maximum size of the shell command history. If not set,
+# defaults to 500 entries. Setting to 0 will disable history.
+#
+# karaf.shell.history.maxSize = 0
+
+#
+# Deletes the entire karaf.data directory at every start
+#
+karaf.clean.all = false
+
+#
+# Deletes the karaf.data/cache directory at every start
+#
+karaf.clean.cache = false
+
+#
+# Roles to use when logging into a local Karaf console.
+#
+# The syntax is the following:
+# [classname:]principal
+# where classname is the class name of the principal object
+# (defaults to org.apache.karaf.jaas.modules.RolePrincipal)
+# and principal is the name of the principal of that class
+# (defaults to instance).
+#
+karaf.local.roles = admin,manager,viewer
+
+#
+# Set this empty property to avoid errors when validating xml documents.
+#
+xml.catalog.files =
+
+#
+# Suppress the bell in the console when hitting backspace too many times
+# for example
+#
+jline.nobell = true
+
+#
+# ServiceMix specs options
+#
+org.apache.servicemix.specs.debug = false
+org.apache.servicemix.specs.timeout = 100
+
+#
+# Settings for the OSGi 4.3 Weaving
+# By default, we will not weave any classes. Change this setting to include classes
+# that you application needs to have woven.
+#
+org.apache.aries.proxy.weaving.enabled = none
+# Classes not to weave - Aries default + Xerces which is known to have issues.
+org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.*
+
+#
+# By default, only Karaf shell commands are secured, but additional services can be
+# secured by expanding this filter
+#
+karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*))
+
+#
+# Security properties
+#
+# To enable OSGi security, uncomment the properties below,
+# install the framework-security feature and restart.
+#
+#java.security.policy=${karaf.etc}/all.policy
+#org.osgi.framework.security=osgi
+#org.osgi.framework.trust.repositories=${karaf.etc}/trustStore.ks
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh b/instance/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
new file mode 100644
index 0000000..1d1d720
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/jpm/impl/unix/start.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#exec 1>${out.file}
+#exec 2>${err.file}
+exec 1>/dev/null
+exec 2>/dev/null
+if [ "x${dir}" != "x" ]; then
+ cd ${dir}
+fi
+nohup ${command} &
+echo $! > ${pid.file}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
new file mode 100644
index 0000000..abd60eb
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/destroy.vbs
@@ -0,0 +1,27 @@
+'===============================================================================
+'
+' 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.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
+intRetVal = 1
+For Each objProcess in colProcessList
+ objProcess.Terminate()
+ intRetVal = 0
+Next
+WScript.Quit(intRetVal)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
new file mode 100644
index 0000000..32c65c5
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/running.vbs
@@ -0,0 +1,26 @@
+'===============================================================================
+'
+' 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.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
+intRetVal = 1
+For Each objProcess in colProcessList
+ intRetVal = 0
+Next
+WScript.Quit(intRetVal)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
----------------------------------------------------------------------
diff --git a/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
new file mode 100644
index 0000000..6004c86
--- /dev/null
+++ b/instance/src/main/resources/org/apache/karaf/jpm/impl/windows/start.vbs
@@ -0,0 +1,34 @@
+'===============================================================================
+'
+' 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.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set objConfig = objWMIService.Get("Win32_ProcessStartup").SpawnInstance_
+objConfig.ShowWindow = SW_HIDE
+objConfig.CreateFlags = 8
+If Len("${dir}") > 0 Then
+ intReturn = objWMIService.Get("Win32_Process").Create("${command}", "${dir}", objConfig, intProcessID)
+Else
+ intReturn = objWMIService.Get("Win32_Process").Create("${command}", Null, objConfig, intProcessID)
+End If
+If intReturn = 0 Then
+ Set objOutputFile = CreateObject("Scripting.fileSystemObject").CreateTextFile("${pid.file}", TRUE)
+ objOutputFile.WriteLine(intProcessID)
+ objOutputFile.Close
+End If
+WScript.Quit(intReturn)
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java b/instance/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
new file mode 100644
index 0000000..359a183
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/command/CreateCommandTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.instance.command;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.easymock.EasyMock;
+
+public class CreateCommandTest extends TestCase {
+
+ public void testCreateCommandExecute() throws Exception {
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.replay(instanceService);
+
+ CreateCommand cc = new CreateCommand();
+ cc.setInstanceService(instanceService);
+ cc.sshPort = 9941;
+ cc.rmiRegistryPort = 1122;
+ cc.rmiServerPort = 44444;
+ cc.location = "top";
+ cc.javaOpts = "foo";
+ cc.features = Arrays.asList("abc", "def");
+ cc.featureURLs = Collections.singletonList("http://something");
+ cc.instance = "myInstance";
+ cc.verbose = true;
+
+ EasyMock.verify(instanceService); // check precondition
+ EasyMock.reset(instanceService);
+ InstanceSettings expectedIS =
+ new InstanceSettings(9941, 1122, 44444, "top", "foo", Collections.singletonList("http://something"), Arrays.asList("abc", "def"));
+ EasyMock.expect(instanceService.createInstance("myInstance", expectedIS, true)).andReturn(null);
+ EasyMock.replay(instanceService);
+
+ cc.doExecute();
+ EasyMock.verify(instanceService);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java b/instance/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.java
new file mode 100644
index 0000000..264176b
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/core/InstanceSettingsTest.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.instance.core;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.junit.Assert;
+
+public class InstanceSettingsTest extends TestCase {
+ public void testInstanceSettings() {
+ InstanceSettings is =
+ new InstanceSettings(1, 1, 1, null, null, Collections.<String>emptyList(), Arrays.asList("hi"));
+ assertEquals(1, is.getSshPort());
+ assertEquals(1, is.getRmiRegistryPort());
+ assertEquals(1, is.getRmiServerPort());
+ Assert.assertNull(is.getLocation());
+ assertEquals(Arrays.asList("hi"), is.getFeatures());
+ assertEquals(0, is.getFeatureURLs().size());
+ }
+
+ public void testEqualsHashCode() {
+ testEqualsHashCode(1, 1, 1, "top", "foo", Collections.<String>emptyList(), Arrays.asList("hi"));
+ testEqualsHashCode(0, 0, 0, null, null, null, null);
+ }
+
+ private void testEqualsHashCode(int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, List<String> featureURLs, List<String> features) {
+ InstanceSettings is = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
+ InstanceSettings is2 = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
+ assertEquals(is, is2);
+ assertEquals(is.hashCode(), is2.hashCode());
+ }
+
+ public void testEqualsHashCode2() {
+ InstanceSettings is = new InstanceSettings(1, 1, 1, "top", "foo", Collections.<String>emptyList(), Arrays.asList("hi"));
+ Assert.assertFalse(is.equals(null));
+ Assert.assertFalse(is.equals(new Object()));
+ assertEquals(is, is);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java b/instance/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
new file mode 100644
index 0000000..9c77934
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/core/internal/InstanceServiceImplTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.instance.core.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class InstanceServiceImplTest {
+
+ @Rule
+ public TestName name = new TestName();
+
+ @Rule
+ public TemporaryFolder tempFolder = new TemporaryFolder();
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ String buildDirectory = ClassLoader.getSystemResource("etc/startup.properties").getFile()
+ .replace("startup.properties", "");
+ System.setProperty("karaf.etc", buildDirectory);
+ }
+
+ @Test
+ public void testHandleFeatures() throws Exception {
+ InstanceServiceImpl as = new InstanceServiceImpl();
+
+ File f = tempFolder.newFile(getName() + ".test");
+ Properties p = new Properties();
+ p.put("featuresBoot", "abc,def ");
+ p.put("featuresRepositories", "somescheme://xyz");
+ OutputStream os = new FileOutputStream(f);
+ try {
+ p.store(os, "Test comment");
+ } finally {
+ os.close();
+ }
+
+ InstanceSettings s = new InstanceSettings(8122, 1122, 44444, null, null, null, Arrays.asList("test"));
+ as.addFeaturesFromSettings(f, s);
+
+ Properties p2 = new Properties();
+ InputStream is = new FileInputStream(f);
+ try {
+ p2.load(is);
+ } finally {
+ is.close();
+ }
+ assertEquals(2, p2.size());
+ assertEquals("abc,def,test", p2.get("featuresBoot"));
+ assertEquals("somescheme://xyz", p2.get("featuresRepositories"));
+ }
+
+ @Test
+ public void testConfigurationFiles() throws Exception {
+ InstanceServiceImpl service = new InstanceServiceImpl();
+ service.setStorageLocation(tempFolder.newFolder("instances"));
+
+ InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
+ Instance instance = service.createInstance(getName(), settings, true);
+
+ assertFileExists(instance.getLocation(), "etc/config.properties");
+ assertFileExists(instance.getLocation(), "etc/users.properties");
+ assertFileExists(instance.getLocation(), "etc/startup.properties");
+
+ assertFileExists(instance.getLocation(), "etc/java.util.logging.properties");
+ assertFileExists(instance.getLocation(), "etc/org.apache.karaf.features.cfg");
+ assertFileExists(instance.getLocation(), "etc/org.apache.felix.fileinstall-deploy.cfg");
+ assertFileExists(instance.getLocation(), "etc/org.apache.karaf.log.cfg");
+ assertFileExists(instance.getLocation(), "etc/org.apache.karaf.management.cfg");
+ assertFileExists(instance.getLocation(), "etc/org.ops4j.pax.logging.cfg");
+ assertFileExists(instance.getLocation(), "etc/org.ops4j.pax.url.mvn.cfg");
+ }
+
+ /**
+ * <p>
+ * Test the renaming of an existing instance.
+ * </p>
+ */
+ @Test
+ public void testRenameInstance() throws Exception {
+ InstanceServiceImpl service = new InstanceServiceImpl();
+ service.setStorageLocation(tempFolder.newFolder("instances"));
+
+ InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
+ service.createInstance(getName(), settings, true);
+
+ service.renameInstance(getName(), getName() + "b", true);
+ assertNotNull(service.getInstance(getName() + "b"));
+ }
+
+ /**
+ * <p>
+ * Test the renaming of an existing instance.
+ * </p>
+ */
+ @Test
+ public void testToSimulateRenameInstanceByExternalProcess() throws Exception {
+ InstanceServiceImpl service = new InstanceServiceImpl();
+ File storageLocation = tempFolder.newFolder("instances");
+ service.setStorageLocation(storageLocation);
+
+ InstanceSettings settings = new InstanceSettings(8122, 1122, 44444, getName(), null, null, null);
+ service.createInstance(getName(), settings, true);
+
+ //to simulate the scenario that the instance name get changed by
+ //external process, likely the admin command CLI tool, which cause
+ //the instance storage file get updated, the AdminService should be
+ //able to reload the storage file before check any status for the
+ //instance
+
+ File storageFile = new File(storageLocation, InstanceServiceImpl.STORAGE_FILE);
+ assertTrue(storageFile.isFile());
+ Properties storage = loadStorage(storageFile);
+ storage.setProperty("item.0.name", getName() + "b");
+ saveStorage(storage, storageFile, "testToSimulateRenameInstanceByExternalProcess");
+
+ assertNotNull(service.getInstance(getName() + "b"));
+ }
+
+ private String getName() {
+ return name.getMethodName();
+ }
+
+ private void saveStorage(Properties props, File location, String comment) throws IOException {
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(location);
+ props.store(os, comment);
+ } finally {
+ if (os != null) {
+ os.close();
+ }
+ }
+ }
+
+ private Properties loadStorage(File location) throws IOException {
+ InputStream is = null;
+ try {
+ is = new FileInputStream(location);
+ Properties props = new Properties();
+ props.load(is);
+ return props;
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ private void assertFileExists(String path, String name) throws IOException {
+ File file = new File(path, name);
+ assertTrue("Expected " + file.getCanonicalPath() + " to exist",
+ file.exists());
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java b/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
new file mode 100644
index 0000000..bb67041
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceServiceMBeanImplTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.instance.core.management.internal;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.apache.karaf.instance.core.InstancesMBean;
+import org.apache.karaf.instance.core.internal.InstancesMBeanImpl;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+public class InstanceServiceMBeanImplTest extends TestCase {
+
+ public void testCreateInstance() throws Exception {
+ final InstanceSettings instanceSettings = new InstanceSettings(123, 456,789, "somewhere", "someopts",
+ Collections.<String>emptyList(), Arrays.asList("webconsole", "funfeat"));
+
+ final Instance inst = EasyMock.createMock(Instance.class);
+ EasyMock.expect(inst.getPid()).andReturn(42);
+ EasyMock.replay(inst);
+
+ org.apache.karaf.instance.core.InstanceService instanceService = EasyMock.createMock(org.apache.karaf.instance.core.InstanceService.class);
+ EasyMock.expect(instanceService.createInstance("t1", instanceSettings, false)).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBeanImpl ab = new InstancesMBeanImpl(instanceService);
+ assertEquals(42, ab.createInstance("t1", 123, 456, 789, "somewhere", "someopts", " webconsole, funfeat", ""));
+ }
+
+ public void testCreateInstance2() throws Exception {
+ final InstanceSettings instanceSettings = new InstanceSettings(0, 0, 0, null, null,
+ Collections.<String>emptyList(), Collections.<String>emptyList());
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.createInstance("t1", instanceSettings, false)).andReturn(null);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean ab = new InstancesMBeanImpl(instanceService);
+ assertEquals(-1, ab.createInstance("t1", 0, 0, 0, "", "", "", ""));
+ }
+
+ public void testGetInstances() throws Exception {
+ Instance i1 = EasyMock.createMock(Instance.class);
+ EasyMock.expect(i1.getPid()).andReturn(1234);
+ EasyMock.expect(i1.getSshPort()).andReturn(8818);
+ EasyMock.expect(i1.getRmiRegistryPort()).andReturn(1122);
+ EasyMock.expect(i1.getRmiServerPort()).andReturn(44444);
+ EasyMock.expect(i1.getName()).andReturn("i1");
+ EasyMock.expect(i1.isRoot()).andReturn(true);
+ EasyMock.expect(i1.getLocation()).andReturn("somewhere");
+ EasyMock.expect(i1.getJavaOpts()).andReturn("someopts");
+ EasyMock.expect(i1.getState()).andReturn("Stopped");
+ EasyMock.replay(i1);
+ Instance i2 = EasyMock.createNiceMock(Instance.class);
+ EasyMock.expect(i2.getName()).andReturn("i2");
+ EasyMock.replay(i2);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstances()).andReturn(new Instance[]{i1, i2});
+ EasyMock.replay(instanceService);
+
+ InstancesMBeanImpl instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+ TabularData tabularData = instanceServiceMBean.getInstances();
+ Assert.assertEquals(2, tabularData.size());
+ CompositeData cd1 = tabularData.get(new Object[]{"i1"});
+ Assert.assertTrue(cd1.containsValue("i1"));
+ Assert.assertTrue(cd1.containsValue(true));
+ Assert.assertTrue(cd1.containsValue(1234));
+ Assert.assertTrue(cd1.containsValue(8818));
+ Assert.assertTrue(cd1.containsValue(1122));
+ Assert.assertTrue(cd1.containsValue(44444));
+ Assert.assertTrue(cd1.containsValue("somewhere"));
+ Assert.assertTrue(cd1.containsValue("someopts"));
+ Assert.assertTrue(cd1.containsValue("Stopped"));
+
+ CompositeData cd2 = tabularData.get(new Object [] {"i2"});
+ Assert.assertTrue(cd2.containsValue("i2"));
+ }
+
+ public void testStartInstanceWithJavaOpts() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.start("-x -y -z");
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.startInstance("test instance", "-x -y -z");
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testStartInstanceWithNoJavaOpts() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.start(null);
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.startInstance("test instance", null);
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testStopInstance() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.stop();
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.stopInstance("test instance");
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testDestroyInstance() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.destroy();
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.destroyInstance("test instance");
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testSshChangePort() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.changeSshPort(7788);
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.changeSshPort("test instance", 7788);
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testRmiRegistryChangePort() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.changeRmiRegistryPort(1123);
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.changeRmiRegistryPort("test instance", 1123);
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testRmiServerChangePort() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.changeRmiServerPort(44444);
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.changeRmiServerPort("test instance", 44444);
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+ public void testChangeOptions() throws Exception {
+ Instance inst = EasyMock.createMock(Instance.class);
+ inst.changeJavaOpts("new opts");
+ EasyMock.expectLastCall();
+ EasyMock.replay(inst);
+
+ InstanceService instanceService = EasyMock.createMock(InstanceService.class);
+ EasyMock.expect(instanceService.getInstance("test instance")).andReturn(inst);
+ EasyMock.replay(instanceService);
+
+ InstancesMBean instanceServiceMBean = new InstancesMBeanImpl(instanceService);
+
+ instanceServiceMBean.changeJavaOpts("test instance", "new opts");
+ EasyMock.verify(instanceService);
+ EasyMock.verify(inst);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java b/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
new file mode 100644
index 0000000..c9541d3
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.instance.core.management.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.internal.InstanceToTableMapper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+
+public class InstanceToTableMapperTest extends TestCase {
+ public void testJMXInstance() throws Exception {
+ Instance instance = EasyMock.createMock(Instance.class);
+ EasyMock.expect(instance.getPid()).andReturn(1712);
+ EasyMock.expect(instance.getName()).andReturn("MyInstance");
+ EasyMock.expect(instance.isRoot()).andReturn(false);
+ EasyMock.expect(instance.getSshPort()).andReturn(0);
+ EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
+ EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
+ EasyMock.expect(instance.getState()).andThrow(new Exception("gotcha"));
+ EasyMock.expect(instance.getLocation()).andReturn("somewhere");
+ EasyMock.expect(instance.getJavaOpts()).andReturn("someopts");
+ EasyMock.replay(instance);
+
+ TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
+ Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
+ Assert.assertEquals("MyInstance", keys.iterator().next());
+
+ CompositeData cd = td.get(keys.toArray());
+ Assert.assertEquals(1712, cd.get("Pid"));
+ Assert.assertEquals("MyInstance", cd.get("Name"));
+ Assert.assertEquals(false, cd.get("Is Root"));
+ Assert.assertEquals(0, cd.get("SSH Port"));
+ Assert.assertEquals(0, cd.get("RMI Registry Port"));
+ Assert.assertEquals(0, cd.get("RMI Server Port"));
+ Assert.assertEquals("Error", cd.get("State"));
+ Assert.assertEquals("somewhere", cd.get("Location"));
+ Assert.assertEquals("someopts", cd.get("JavaOpts"));
+ }
+
+ public void testJMXInstance2() throws Exception {
+ Instance instance = EasyMock.createMock(Instance.class);
+ EasyMock.expect(instance.getPid()).andReturn(1712);
+ EasyMock.expect(instance.getName()).andReturn("MyInstance");
+ EasyMock.expect(instance.isRoot()).andReturn(true);
+ EasyMock.expect(instance.getSshPort()).andReturn(0);
+ EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
+ EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
+ EasyMock.expect(instance.getState()).andReturn("Started");
+ EasyMock.expect(instance.getLocation()).andReturn(null);
+ EasyMock.expect(instance.getJavaOpts()).andReturn(null);
+ EasyMock.replay(instance);
+
+ TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
+ Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
+ Assert.assertEquals("MyInstance", keys.iterator().next());
+
+ CompositeData cd = td.get(keys.toArray());
+ Assert.assertEquals(1712, cd.get("Pid"));
+ Assert.assertEquals("MyInstance", cd.get("Name"));
+ Assert.assertEquals(true, cd.get("Is Root"));
+ Assert.assertEquals(0, cd.get("SSH Port"));
+ Assert.assertEquals(0, cd.get("RMI Registry Port"));
+ Assert.assertEquals(0, cd.get("RMI Server Port"));
+ Assert.assertEquals("Started", cd.get("State"));
+ Assert.assertNull(cd.get("Location"));
+ Assert.assertNull(cd.get("JavaOpts"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java b/instance/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
new file mode 100644
index 0000000..1e49a88
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/instance/main/ExecuteTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.instance.main;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class ExecuteTest extends TestCase {
+ private String userDir;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Execute.exitAllowed = false;
+ userDir = System.getProperty("user.dir");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ Execute.exitAllowed = true;
+ System.setProperty("user.dir", userDir);
+ }
+
+ public void testListCommands() throws Exception {
+ PrintStream oldOut = System.out;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream capturedOut = new PrintStream(baos);
+ System.setOut(capturedOut);
+
+ try {
+ Execute.main(new String [] {});
+ } catch (RuntimeException re) {
+ assertEquals("0", re.getMessage());
+
+ String s = new String(baos.toByteArray());
+ assertTrue(s.contains("list"));
+ assertTrue(s.contains("create"));
+ assertTrue(s.contains("destroy"));
+ } finally {
+ System.setOut(oldOut);
+ }
+ }
+
+ public void testNonexistingCommand() throws Exception {
+ try {
+ Execute.main(new String [] {"bheuaark"});
+ } catch (RuntimeException re) {
+ assertEquals("-1", re.getMessage());
+ }
+ }
+
+ public void testNoStorageFile() throws Exception {
+ PrintStream oldErr = System.err;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream capturedErr = new PrintStream(baos);
+ System.setErr(capturedErr);
+
+ try {
+ Execute.main(new String [] {"create"});
+ } catch (RuntimeException re) {
+ assertEquals("-2", re.getMessage());
+
+ String s = new String(baos.toByteArray());
+ assertTrue(s.contains("karaf.instances"));
+ assertTrue(s.contains("instance.properties"));
+ } finally {
+ System.setErr(oldErr);
+ }
+ }
+
+ public void testSetDir() throws Exception {
+ Properties oldProps = (Properties) System.getProperties().clone();
+ final File tempFile = createTempDir(getName());
+ assertFalse("Precondition failed",
+ tempFile.getParentFile().getParentFile().getCanonicalPath().equals(System.getProperty("user.dir")));
+
+ System.setProperty("karaf.instances", tempFile.getCanonicalPath());
+ try {
+ Execute.main(new String [] {"list"});
+ assertTrue(tempFile.getParentFile().getParentFile().getCanonicalPath().equals(System.getProperty("user.dir")));
+ } finally {
+ System.setProperties(oldProps);
+ assertNull("Postcondition failed", System.getProperty("karaf.instances"));
+ delete(tempFile);
+ }
+ }
+
+ private static File createTempDir(String name) throws IOException {
+ final File tempFile = File.createTempFile(name, null);
+ tempFile.delete();
+ tempFile.mkdirs();
+ return tempFile.getCanonicalFile();
+ }
+
+ private static void delete(File tmp) {
+ if (tmp.isDirectory()) {
+ for (File f : tmp.listFiles()) {
+ delete(f);
+ }
+ }
+ tmp.delete();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/jpm/MainTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/jpm/MainTest.java b/instance/src/test/java/org/apache/karaf/jpm/MainTest.java
new file mode 100644
index 0000000..e7f7c83
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/jpm/MainTest.java
@@ -0,0 +1,24 @@
+/*
+ * 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.jpm;
+
+public class MainTest {
+
+ public static void main(String[] args) throws Exception {
+ Thread.sleep(Long.parseLong(args[0]));
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/java/org/apache/karaf/jpm/ProcessTest.java
----------------------------------------------------------------------
diff --git a/instance/src/test/java/org/apache/karaf/jpm/ProcessTest.java b/instance/src/test/java/org/apache/karaf/jpm/ProcessTest.java
new file mode 100644
index 0000000..9cdc5ad
--- /dev/null
+++ b/instance/src/test/java/org/apache/karaf/jpm/ProcessTest.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.jpm;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.jpm.impl.ProcessBuilderFactoryImpl;
+import org.apache.karaf.jpm.impl.ScriptUtils;
+
+public class ProcessTest extends TestCase {
+
+ public void testCreate() throws Exception {
+ String javaPath = new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath();
+ System.err.println(javaPath);
+ StringBuilder command = new StringBuilder();
+ command.append("\"").append(javaPath).append("\"");
+ command.append(" -Dprop=\"key\"");
+ command.append(" -classpath ");
+ String clRes = getClass().getName().replace('.', '/') + ".class";
+ String str = getClass().getClassLoader().getResource(clRes).toString();
+ str = str.substring("file:".length(), str.indexOf(clRes));
+ command.append(str);
+ command.append(" ");
+ command.append(MainTest.class.getName());
+ command.append(" ");
+ command.append(60000);
+ System.err.println("Executing: " + command.toString());
+
+ ProcessBuilder builder = new ProcessBuilderFactoryImpl().newBuilder();
+ org.apache.karaf.jpm.Process p = builder.command(command.toString()).start();
+ assertNotNull(p);
+ System.err.println("Process: " + p.getPid());
+ assertNotNull(p.getPid());
+ Thread.sleep(1000);
+ System.err.println("Running: " + p.isRunning());
+ assertTrue(p.isRunning());
+ System.err.println("Destroying");
+ p.destroy();
+ Thread.sleep(1000);
+ System.err.println("Running: " + p.isRunning());
+ assertFalse(p.isRunning());
+ }
+
+ /*
+ * When the process creation fails, no error is reported by the script
+ *
+ public void testFailure() throws Exception {
+ ProcessBuilder builder = ProcessBuilderFactory.newInstance().newBuilder();
+ Process p = builder.command("ec").start();
+ fail("An exception should have been thrown");
+ }
+ */
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/test/resources/etc/startup.properties
----------------------------------------------------------------------
diff --git a/instance/src/test/resources/etc/startup.properties b/instance/src/test/resources/etc/startup.properties
new file mode 100644
index 0000000..df7c9bc
--- /dev/null
+++ b/instance/src/test/resources/etc/startup.properties
@@ -0,0 +1,20 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+# Fake startup.properties for unit tests as the startup properties in generated by the karaf-maven-plugin
\ No newline at end of file
[58/59] [abbrv] git commit: [KARAF-2852] Merge jndi/core and
jndi/command
Posted by gn...@apache.org.
[KARAF-2852] Merge jndi/core and jndi/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/85c65dd6
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/85c65dd6
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/85c65dd6
Branch: refs/heads/master
Commit: 85c65dd697e437ffc28c9c768090a0b0d8741686
Parents: 1bcdb17
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 10:20:22 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:03:15 2014 +0200
----------------------------------------------------------------------
.../enterprise/src/main/feature/feature.xml | 1 -
jndi/NOTICE | 71 +++++
jndi/command/NOTICE | 71 -----
jndi/command/pom.xml | 87 ------
.../apache/karaf/jndi/command/AliasCommand.java | 50 ---
.../apache/karaf/jndi/command/BindCommand.java | 50 ---
.../karaf/jndi/command/ContextsCommand.java | 64 ----
.../karaf/jndi/command/CreateCommand.java | 45 ---
.../karaf/jndi/command/DeleteCommand.java | 45 ---
.../apache/karaf/jndi/command/NamesCommand.java | 65 ----
.../karaf/jndi/command/UnbindCommand.java | 45 ---
.../command/completers/ContextsCompleter.java | 60 ----
.../jndi/command/completers/NamesCompleter.java | 59 ----
.../command/completers/ServicesIdCompleter.java | 66 ----
.../src/main/resources/OSGI-INF/bundle.info | 26 --
jndi/core/NOTICE | 71 -----
jndi/core/pom.xml | 89 ------
.../java/org/apache/karaf/jndi/JndiMBean.java | 104 ------
.../java/org/apache/karaf/jndi/JndiService.java | 103 ------
.../karaf/jndi/KarafInitialContextFactory.java | 33 --
.../karaf/jndi/internal/JndiMBeanImpl.java | 122 --------
.../karaf/jndi/internal/JndiServiceImpl.java | 313 -------------------
.../resources/OSGI-INF/blueprint/jndi-core.xml | 53 ----
.../src/main/resources/OSGI-INF/bundle.info | 19 --
jndi/pom.xml | 72 ++++-
.../java/org/apache/karaf/jndi/JndiMBean.java | 104 ++++++
.../java/org/apache/karaf/jndi/JndiService.java | 103 ++++++
.../karaf/jndi/KarafInitialContextFactory.java | 33 ++
.../apache/karaf/jndi/command/AliasCommand.java | 50 +++
.../apache/karaf/jndi/command/BindCommand.java | 50 +++
.../karaf/jndi/command/ContextsCommand.java | 64 ++++
.../karaf/jndi/command/CreateCommand.java | 45 +++
.../karaf/jndi/command/DeleteCommand.java | 45 +++
.../apache/karaf/jndi/command/NamesCommand.java | 65 ++++
.../karaf/jndi/command/UnbindCommand.java | 45 +++
.../command/completers/ContextsCompleter.java | 60 ++++
.../jndi/command/completers/NamesCompleter.java | 59 ++++
.../command/completers/ServicesIdCompleter.java | 66 ++++
.../karaf/jndi/internal/JndiMBeanImpl.java | 122 ++++++++
.../karaf/jndi/internal/JndiServiceImpl.java | 313 +++++++++++++++++++
.../resources/OSGI-INF/blueprint/jndi-core.xml | 53 ++++
jndi/src/main/resources/OSGI-INF/bundle.info | 19 ++
42 files changed, 1431 insertions(+), 1649 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/assemblies/features/enterprise/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/src/main/feature/feature.xml b/assemblies/features/enterprise/src/main/feature/feature.xml
index 69065ba..823d3ba 100644
--- a/assemblies/features/enterprise/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise/src/main/feature/feature.xml
@@ -182,7 +182,6 @@
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.rmi/${aries.jndi.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.url/${aries.jndi.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.legacy.support/${aries.jndi.version}</bundle>
- <bundle>mvn:org.apache.karaf.jndi/org.apache.karaf.jndi.command/${project.version}</bundle>
</feature>
<feature name="jdbc" description="JDBC service and commands" version="${project.version}" resolver="(obr)">
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/NOTICE
----------------------------------------------------------------------
diff --git a/jndi/NOTICE b/jndi/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/jndi/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/85c65dd6/jndi/command/NOTICE
----------------------------------------------------------------------
diff --git a/jndi/command/NOTICE b/jndi/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/jndi/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/85c65dd6/jndi/command/pom.xml
----------------------------------------------------------------------
diff --git a/jndi/command/pom.xml b/jndi/command/pom.xml
deleted file mode 100644
index 5dddd2e..0000000
--- a/jndi/command/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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.jndi</groupId>
- <artifactId>jndi</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.jndi.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: JNDI :: Command</name>
- <description>This bundle provides a set of commands to manipulate JNDI service.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.jndi</groupId>
- <artifactId>org.apache.karaf.jndi.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.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>
- <Export-Package>!*</Export-Package>
- <Karaf-Commands>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
deleted file mode 100644
index 08e3912..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.jndi.command.completers.NamesCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jndi", name = "alias", description = "Create a JNDI alias on a given name.")
-@Service
-public class AliasCommand implements Action {
-
- @Argument(index = 0, name = "name", description = "The JNDI name", required = true, multiValued = false)
- @Completion(NamesCompleter.class)
- String name;
-
- @Argument(index = 1, name = "alias", description = "The JNDI alias", required = true, multiValued = false)
- @Completion(ContextsCompleter.class)
- String alias;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- jndiService.alias(name, alias);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/BindCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
deleted file mode 100644
index b181762..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.jndi.command.completers.ServicesIdCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jndi", name = "bind", description = "Bind an OSGi service in the JNDI context")
-@Service
-public class BindCommand implements Action {
-
- @Argument(index = 0, name = "service", description = "The ID of the OSGi service to bind", required = true, multiValued = false)
- @Completion(ServicesIdCompleter.class)
- Long serviceId;
-
- @Argument(index = 1, name = "name", description = "The JNDI name to bind the OSGi service", required = true, multiValued = false)
- @Completion(ContextsCompleter.class)
- String name;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- jndiService.bind(serviceId, name);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
deleted file mode 100644
index 2209479..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-import java.util.List;
-
-@Command(scope = "jndi", name = "contexts", description = "List the JNDI sub-contexts.")
-@Service
-public class ContextsCommand implements Action {
-
- @Argument(index = 0, name = "context", description = "The base JNDI context", required = false, multiValued = false)
- @Completion(ContextsCompleter.class)
- String context;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
-
- table.column("JNDI Sub-Context");
-
- List<String> contexts;
- if (context == null) {
- contexts = jndiService.contexts();
- } else {
- contexts = jndiService.contexts(context);
- }
-
- for (String c : contexts) {
- table.addRow().addContent(c);
- }
-
- table.print(System.out);
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
deleted file mode 100644
index 86663bf..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jndi", name = "create", description = "Create a new JNDI sub-context.")
-@Service
-public class CreateCommand implements Action {
-
- @Argument(index = 0, name = "context", description = "The JNDI sub-context name", required = true, multiValued = false)
- @Completion(ContextsCompleter.class)
- String context;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- jndiService.create(context);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
deleted file mode 100644
index 3cd3a40..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jndi", name = "delete", description = "Delete a JNDI sub-context.")
-@Service
-public class DeleteCommand implements Action {
-
- @Argument(index = 0, name = "context", description = "The JNDI sub-context name", required = true, multiValued = false)
- @Completion(ContextsCompleter.class)
- String context;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- jndiService.delete(context);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java
deleted file mode 100644
index 0345f11..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.ContextsCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-import java.util.Map;
-
-@Command(scope = "jndi", name = "names", description = "List the JNDI names.")
-@Service
-public class NamesCommand implements Action {
-
- @Argument(index = 0, name = "context", description = "The JNDI context to display the names", required = false, multiValued = false)
- @Completion(ContextsCompleter.class)
- String context;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
-
- table.column("JNDI Name");
- table.column("Class Name");
-
- Map<String, String> names;
- if (context == null) {
- names = jndiService.names();
- } else {
- names = jndiService.names(context);
- }
-
- for (String name : names.keySet()) {
- table.addRow().addContent(name, names.get(name));
- }
-
- table.print(System.out);
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
deleted file mode 100644
index b93c7b9..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.jndi.command;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.command.completers.NamesCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jndi", name = "unbind", description = "Unbind a JNDI name.")
-@Service
-public class UnbindCommand implements Action {
-
- @Argument(index = 0, name = "name", description = "The JNDI name to unbind", required = true, multiValued = false)
- @Completion(NamesCompleter.class)
- String name;
-
- @Reference
- JndiService jndiService;
-
- @Override
- public Object execute() throws Exception {
- jndiService.unbind(name);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
deleted file mode 100644
index 8f2ac29..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.jndi.command.completers;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-import java.util.List;
-
-/**
- * Completers on the JNDI contexts.
- */
-@Service
-public class ContextsCompleter implements Completer {
-
- @Reference
- private JndiService jndiService;
-
- @Override
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- try {
- List<String> contexts = jndiService.contexts();
- for (String context : contexts) {
- delegate.getStrings().add(context);
- }
- } catch (Exception e) {
- // nothing to do
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
- public JndiService getJndiService() {
- return jndiService;
- }
-
- public void setJndiService(JndiService jndiService) {
- this.jndiService = jndiService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java
deleted file mode 100644
index d94e3f4..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.jndi.command.completers;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-import java.util.List;
-
-/**
- * Completer to the JNDI names.
- */
-@Service
-public class NamesCompleter implements Completer {
-
- @Reference
- private JndiService jndiService;
-
- @Override
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- try {
- for (String name : jndiService.names().keySet()) {
- delegate.getStrings().add(name);
- }
- } catch (Exception e) {
- // nothing to do
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
- public JndiService getJndiService() {
- return jndiService;
- }
-
- public void setJndiService(JndiService jndiService) {
- this.jndiService = jndiService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java b/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
deleted file mode 100644
index c7cdb80..0000000
--- a/jndi/command/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.jndi.command.completers;
-
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-import java.util.List;
-
-/**
- * Completer on the OSGi services ID.
- */
-@Service
-public class ServicesIdCompleter implements Completer {
-
- @Reference
- private BundleContext bundleContext;
-
- @Override
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference[] references = bundle.getRegisteredServices();
- if (references != null) {
- for (ServiceReference reference : references) {
- if (reference.getProperty(Constants.SERVICE_ID) != null) {
- delegate.getStrings().add(reference.getProperty(Constants.SERVICE_ID).toString());
- }
- }
- }
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
- public BundleContext getBundleContext() {
- return bundleContext;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/jndi/command/src/main/resources/OSGI-INF/bundle.info b/jndi/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index d97d132..0000000
--- a/jndi/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,26 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides the shell commands to manipulate the JNDI service.
-
-The following commands are available:
-
-* jndi:alias
-* jndi:bind
-* jndi:create
-* jndi:contexts
-* jndi:delete
-* jndi:names
-* jndi:unbind
-
-h1. See also
-
-JNDI - section of the Karaf User Guide
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/NOTICE
----------------------------------------------------------------------
diff --git a/jndi/core/NOTICE b/jndi/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/jndi/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/85c65dd6/jndi/core/pom.xml
----------------------------------------------------------------------
diff --git a/jndi/core/pom.xml b/jndi/core/pom.xml
deleted file mode 100644
index bf1f75c..0000000
--- a/jndi/core/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?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.jndi</groupId>
- <artifactId>jndi</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.jndi.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: JNDI :: Core</name>
- <description>This bundle provides core implementation of the JNDI management service.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.xbean</groupId>
- <artifactId>xbean-naming</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.aries.proxy</groupId>
- <artifactId>org.apache.aries.proxy.api</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>
- <Export-Package>
- org.apache.karaf.jndi
- </Export-Package>
- <Private-Package>
- org.apache.karaf.jndi.internal
- </Private-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/java/org/apache/karaf/jndi/JndiMBean.java
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/java/org/apache/karaf/jndi/JndiMBean.java b/jndi/core/src/main/java/org/apache/karaf/jndi/JndiMBean.java
deleted file mode 100644
index 0b2be41..0000000
--- a/jndi/core/src/main/java/org/apache/karaf/jndi/JndiMBean.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.jndi;
-
-import javax.management.MBeanException;
-import java.util.List;
-import java.util.Map;
-
-/**
- * JNDI Service MBean
- */
-public interface JndiMBean {
-
- /**
- * Get a map of JNDI names/class names (as attribute).
- *
- * @return the MBean attribute containing the map of names/class names.
- * @throws MBeanException
- */
- public Map<String, String> getNames() throws MBeanException;
-
- /**
- * Get a list of JNDI sub-contexts (as attribute).
- *
- * @return the MBean attribute containing the list of sub-contexts.
- * @throws MBeanException
- */
- public List<String> getContexts() throws MBeanException;
-
- /**
- * Get a map of JNDI names/class names children of a given base context.
- *
- * @param context the base context.
- * @return the map of names/class names.
- * @throws MBeanException
- */
- public Map<String, String> getNames(String context) throws MBeanException;
-
- /**
- * Get a list of JNDI sub-contexts children of a given base context.
- *
- * @param context the base context.
- * @return the list of sub-contexts.
- * @throws MBeanException
- */
- public List<String> getContexts(String context) throws MBeanException;
-
- /**
- * Create a JNDI sub-context.
- *
- * @param context the JNDI sub-context name.
- * @throws MBeanException
- */
- public void create(String context) throws MBeanException;
-
- /**
- * Delete a JNDI sub-context.
- *
- * @param context the JNDI sub-context name.
- * @throws MBeanException
- */
- public void delete(String context) throws MBeanException;
-
- /**
- * Create another JNDI name (alias) for a given one.
- *
- * @param name the "source" JNDI name.
- * @param alias the JNDI alias name.
- * @throws MBeanException
- */
- public void alias(String name, String alias) throws MBeanException;
-
- /**
- * Bind an OSGi service with a JNDI name.
- *
- * @param serviceId the OSGi service id (service.id property on the service, created by the framework).
- * @param name the JNDI name.
- * @throws MBeanException
- */
- public void bind(Long serviceId, String name) throws MBeanException;
-
- /**
- * Unbind a given JNDI name.
- *
- * @param name the JNDI name.
- * @throws MBeanException
- */
- public void unbind(String name) throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/java/org/apache/karaf/jndi/JndiService.java
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/java/org/apache/karaf/jndi/JndiService.java b/jndi/core/src/main/java/org/apache/karaf/jndi/JndiService.java
deleted file mode 100644
index c9f9c57..0000000
--- a/jndi/core/src/main/java/org/apache/karaf/jndi/JndiService.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.jndi;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * JNDI Service.
- */
-public interface JndiService {
-
- /**
- * List the current JNDI names (with the bound class name).
- *
- * @return the JNDI names.
- * @throws Exception
- */
- Map<String, String> names() throws Exception;
-
- /**
- * List the current JNDI names in the given context.
- *
- * @param context the JNDI context.
- * @return the JNDI names in the context.
- * @throws Exception
- */
- Map<String, String> names(String context) throws Exception;
-
- /**
- * List all JNDI sub-contexts.
- *
- * @return a list containing the sub-context names.
- * @throws Exception
- */
- List<String> contexts() throws Exception;
-
- /**
- * List the JNDI sub-context from a given context.
- *
- * @param context the base JNDI context.
- * @return a list containing the sub-context names.
- * @throws Exception
- */
- List<String> contexts(String context) throws Exception;
-
- /**
- * Create a sub-context.
- *
- * @param context the new sub-context name to create.
- * @throws Exception
- */
- void create(String context) throws Exception;
-
- /**
- * Delete a sub-context.
- *
- * @param context the sub-context name to delete.
- * @throws Exception
- */
- void delete(String context) throws Exception;
-
- /**
- * Create an alias on a given JNDI name.
- *
- * @param name the JNDI name.
- * @param alias the alias.
- * @throws Exception
- */
- void alias(String name, String alias) throws Exception;
-
- /**
- * Bind a given OSGi service to a JNDI name.
- *
- * @param serviceId the OSGi service ID.
- * @param name the JNDI name.
- * @throws Exception
- */
- void bind(long serviceId, String name) throws Exception;
-
- /**
- * Unbind an existing name.
- *
- * @param name the JNDI name to unbind.
- * @throws Exception
- */
- void unbind(String name) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java b/jndi/core/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java
deleted file mode 100644
index a540556..0000000
--- a/jndi/core/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.jndi;
-
-import org.apache.xbean.naming.context.WritableContext;
-import org.apache.xbean.naming.global.GlobalContextManager;
-
-/**
- * A very simple writable initial context factory.
- * @see org.apache.xbean.naming.context.WritableContext for details.
- */
-public class KarafInitialContextFactory extends GlobalContextManager {
-
- public KarafInitialContextFactory() throws Exception {
- super();
- setGlobalContext(new WritableContext());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java b/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
deleted file mode 100644
index 2433618..0000000
--- a/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.jndi.internal;
-
-import org.apache.karaf.jndi.JndiService;
-import org.apache.karaf.jndi.JndiMBean;
-
-import javax.management.MBeanException;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of the JndiMBean
- */
-public class JndiMBeanImpl implements JndiMBean {
-
- private JndiService jndiService;
-
- @Override
- public Map<String, String> getNames() throws MBeanException {
- try {
- return this.jndiService.names();
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public List<String> getContexts() throws MBeanException {
- try {
- return this.jndiService.contexts();
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public Map<String, String> getNames(String context) throws MBeanException {
- try {
- return this.jndiService.names(context);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public List<String> getContexts(String context) throws MBeanException {
- try {
- return this.jndiService.contexts(context);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public void alias(String name, String alias) throws MBeanException {
- try {
- this.jndiService.alias(name, alias);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public void bind(Long serviceId, String name) throws MBeanException {
- try {
- this.jndiService.bind(serviceId, name);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public void unbind(String name) throws MBeanException {
- try {
- this.jndiService.unbind(name);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public void create(String context) throws MBeanException {
- try {
- this.jndiService.create(context);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- @Override
- public void delete(String context) throws MBeanException {
- try {
- this.jndiService.delete(context);
- } catch (Throwable t) {
- throw new MBeanException(null, t.getMessage());
- }
- }
-
- public JndiService getJndiService() {
- return jndiService;
- }
-
- public void setJndiService(JndiService jndiService) {
- this.jndiService = jndiService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java b/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
deleted file mode 100644
index 68d6b94..0000000
--- a/jndi/core/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * 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.jndi.internal;
-
-import org.apache.aries.proxy.ProxyManager;
-import org.apache.karaf.jndi.JndiService;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-import javax.naming.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of the JNDI Service.
- */
-public class JndiServiceImpl implements JndiService {
-
- private BundleContext bundleContext;
- private ProxyManager proxyManager;
-
- private final static String OSGI_JNDI_CONTEXT_PREFIX = "osgi:service/";
- private final static String OSGI_JNDI_SERVICE_PROPERTY = "osgi.jndi.service.name";
-
- @Override
- public Map<String, String> names() throws Exception {
- Map<String, String> result = names("/");
- result.putAll(names(OSGI_JNDI_CONTEXT_PREFIX));
- return result;
- }
-
- @Override
- public Map<String, String> names(String name) throws Exception {
- Map<String, String> map = new HashMap<String, String>();
- if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
- // OSGi service binding
- // make a lookup using directly the OSGi service
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] services = bundle.getRegisteredServices();
- if (services != null) {
- for (ServiceReference service : services) {
- if (service.getProperty(OSGI_JNDI_SERVICE_PROPERTY) != null) {
- Object actualService = bundleContext.getService(service);
- if (proxyManager.isProxy(actualService)) {
- actualService = proxyManager.unwrap(actualService).call();
- }
- map.put(OSGI_JNDI_CONTEXT_PREFIX + service.getProperty(OSGI_JNDI_SERVICE_PROPERTY), actualService.getClass().getName());
- bundleContext.ungetService(service);
- }
- }
- }
- }
- } else {
- // "real" JNDI lookup
- Context context = new InitialContext();
- NamingEnumeration<NameClassPair> pairs = context.list(name);
- while (pairs.hasMoreElements()) {
- NameClassPair pair = pairs.nextElement();
- Object o;
- if (name != null) {
- o = context.lookup(name + "/" + pair.getName());
- } else {
- o = context.lookup(pair.getName());
- }
- if (o instanceof Context) {
- StringBuilder sb = new StringBuilder();
- sb.append("/" + pair.getName());
- names((Context) o, sb, map);
- } else {
- map.put("/" + pair.getName(), pair.getClassName());
- }
- }
- }
- return map;
- }
-
- public List<String> contexts() throws Exception {
- return contexts("/");
- }
-
- public List<String> contexts(String name) throws Exception {
- List<String> contexts = new ArrayList<String>();
- Context context = new InitialContext();
- NamingEnumeration<NameClassPair> pairs = context.list(name);
- while (pairs.hasMoreElements()) {
- NameClassPair pair = pairs.nextElement();
- Object o;
- if (name != null) {
- o = context.lookup(name + "/" + pair.getName());
- } else {
- o = context.lookup(pair.getName());
- }
- if (o instanceof Context) {
- StringBuilder sb = new StringBuilder();
- sb.append("/" + pair.getName());
- contexts((Context) o, sb, contexts);
- }
- }
- return contexts;
- }
-
- private void contexts(Context context, StringBuilder sb, List<String> contexts) throws Exception {
- NamingEnumeration list = context.listBindings("");
- while (list.hasMore()) {
- Binding item = (Binding) list.next();
- String name = item.getName();
- Object o = item.getObject();
- if (o instanceof Context) {
- if (((Context) o).list("").hasMoreElements()) {
- sb.append("/").append(name);
- contexts((Context) o, sb, contexts);
- } else {
- contexts.add(sb.toString() + "/" + name);
- }
- }
- }
- }
-
- /**
- * Recursively list a context/names
- *
- * @param ctx the startup context.
- * @param sb the string builder where to construct the full qualified name.
- * @param map the final map containing name/class name pairs.
- * @throws Exception
- */
- private static final void names(Context ctx, StringBuilder sb, Map<String, String> map) throws Exception {
- NamingEnumeration list = ctx.listBindings("");
- while (list.hasMore()) {
- Binding item = (Binding) list.next();
- String className = item.getClassName();
- String name = item.getName();
- Object o = item.getObject();
- if (o instanceof Context) {
- sb.append("/").append(name);
- names((Context) o, sb, map);
- } else {
- map.put(sb.toString() + "/" + name, className);
- }
- }
- }
-
- @Override
- public void create(String name) throws Exception {
- Context context = new InitialContext();
- String[] splitted = name.split("/");
- if (splitted.length > 0) {
- for (int i = 0; i < splitted.length; i++) {
- try {
- Object o = context.lookup(splitted[i]);
- if (!(o instanceof Context)) {
- throw new NamingException("Name " + splitted[i] + " already exists");
- }
- } catch (NameNotFoundException e) {
- context.createSubcontext(splitted[i]);
- }
- context = (Context) context.lookup(splitted[i]);
- }
- } else {
- context.createSubcontext(name);
- }
- }
-
- @Override
- public void delete(String name) throws Exception {
- Context context = new InitialContext();
- context.destroySubcontext(name);
- }
-
- @Override
- public void bind(long serviceId, String name) throws Exception {
- Context context = new InitialContext();
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] services = bundle.getRegisteredServices();
- if (services != null) {
- for (ServiceReference service : services) {
- if (service.getProperty(Constants.SERVICE_ID) != null && ((Long) service.getProperty(Constants.SERVICE_ID)) == serviceId) {
- Object actualService = bundleContext.getService(service);
- if (proxyManager.isProxy(actualService)) {
- actualService = proxyManager.unwrap(actualService).call();
- }
- try {
- String[] splitted = name.split("/");
- if (splitted.length > 0) {
- for (int i = 0; i < splitted.length - 1; i++) {
- try {
- Object o = context.lookup(splitted[i]);
- if (!(o instanceof Context)) {
- throw new NamingException("Name " + splitted[i] + " already exists");
- }
- } catch (NameNotFoundException nnfe) {
- context.createSubcontext(splitted[i]);
- }
- context = (Context) context.lookup(splitted[i]);
- }
- name = splitted[splitted.length - 1];
- }
- context.bind(name, actualService);
- } finally {
- bundleContext.ungetService(service);
- }
- }
- }
- }
- }
- }
-
- @Override
- public void alias(String name, String alias) throws Exception {
- Context context = new InitialContext();
- if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
- // get the object
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] services = bundle.getRegisteredServices();
- if (services != null) {
- for (ServiceReference service : services) {
- if (service.getProperty(OSGI_JNDI_SERVICE_PROPERTY) != null && ((String) service.getProperty(OSGI_JNDI_SERVICE_PROPERTY)).equals(name.substring(OSGI_JNDI_CONTEXT_PREFIX.length()))) {
- Object actualService = bundleContext.getService(service);
- try {
- if (proxyManager.isProxy(actualService)) {
- actualService = proxyManager.unwrap(actualService).call();
- }
- String[] splitted = alias.split("/");
- if (splitted.length > 0) {
- for (int i = 0; i < splitted.length - 1; i++) {
- try {
- Object o = context.lookup(splitted[i]);
- if (!(o instanceof Context)) {
- throw new NamingException("Name " + splitted[i] + " already exists");
- }
- } catch (NameNotFoundException nnfe) {
- context.createSubcontext(splitted[i]);
- }
- context = (Context) context.lookup(splitted[i]);
- }
- alias = splitted[splitted.length -1];
- }
- context.bind(alias, actualService);
- } finally {
- bundleContext.ungetService(service);
- }
- }
- }
- }
- }
- } else {
- Object object = context.lookup(name);
- String[] splitted = alias.split("/");
- if (splitted.length > 0) {
- for (int i = 0; i < splitted.length - 1; i++) {
- try {
- Object o = context.lookup(splitted[i]);
- if (!(o instanceof Context)) {
- throw new NamingException("Name " + splitted[i] + " already exists");
- }
- } catch (NameNotFoundException nnfe) {
- context.createSubcontext(splitted[i]);
- }
- context = (Context) context.lookup(splitted[i]);
- }
- alias = splitted[splitted.length - 1];
- }
- context.bind(alias, object);
- }
- }
-
- @Override
- public void unbind(String name) throws Exception {
- InitialContext context = new InitialContext();
- if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
- throw new IllegalArgumentException("You can't unbind a name from the " + OSGI_JNDI_CONTEXT_PREFIX + " JNDI context.");
- }
- context.unbind(name);
- }
-
- public BundleContext getBundleContext() {
- return bundleContext;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public ProxyManager getProxyManager() {
- return proxyManager;
- }
-
- public void setProxyManager(ProxyManager proxyManager) {
- this.proxyManager = proxyManager;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/resources/OSGI-INF/blueprint/jndi-core.xml b/jndi/core/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
deleted file mode 100644
index e6be3b1..0000000
--- a/jndi/core/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
- -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
- default-activation="lazy">
-
- <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]"/>
-
- <bean id="karafInitialContextFactory" class="org.apache.karaf.jndi.KarafInitialContextFactory"/>
-
- <reference id="proxyManager" interface="org.apache.aries.proxy.ProxyManager"/>
-
- <service ref="karafInitialContextFactory" interface="javax.naming.spi.InitialContextFactory"/>
-
- <bean id="jndiService" class="org.apache.karaf.jndi.internal.JndiServiceImpl">
- <property name="bundleContext" ref="blueprintBundleContext"/>
- <property name="proxyManager" ref="proxyManager"/>
- </bean>
-
- <service ref="jndiService" interface="org.apache.karaf.jndi.JndiService">
- <service-properties>
- <!-- bind the JNDI service itself in the JNDI context -->
- <entry key="osgi.jndi.service.name" value="jndi"/>
- </service-properties>
- </service>
-
- <!-- Management -->
- <bean id="jndiMBeanImpl" class="org.apache.karaf.jndi.internal.JndiMBeanImpl">
- <property name="jndiService" ref="jndiService"/>
- </bean>
-
- <service ref="jndiMBeanImpl" auto-export="interfaces">
- <service-properties>
- <entry key="jmx.objectname" value="org.apache.karaf:type=jndi,name=$[karaf.name]"/>
- </service-properties>
- </service>
-
-</blueprint>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/jndi/core/src/main/resources/OSGI-INF/bundle.info b/jndi/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 4a7a606..0000000
--- a/jndi/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,19 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle is the core implementation of the JNDI service support.
-
-JNDI allows to expose any OSGi services as JNDI names. Karaf JNDI also provides a set of commands and a MBean to list
-the current JNDI names, create JNDI aliases, ...
-
-h1. See also
-
-JNDI - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/pom.xml
----------------------------------------------------------------------
diff --git a/jndi/pom.xml b/jndi/pom.xml
index eb3a43e..f2db373 100644
--- a/jndi/pom.xml
+++ b/jndi/pom.xml
@@ -29,13 +29,69 @@
</parent>
<groupId>org.apache.karaf.jndi</groupId>
- <artifactId>jndi</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: JNDI</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.jndi.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: JNDI :: Core</name>
+ <description>This bundle provides core implementation of the JNDI management service.</description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.xbean</groupId>
+ <artifactId>xbean-naming</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.proxy</groupId>
+ <artifactId>org.apache.aries.proxy.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </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>
+ <Export-Package>
+ org.apache.karaf.jndi
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.jndi.command,
+ org.apache.karaf.jndi.internal
+ </Private-Package>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/JndiMBean.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/JndiMBean.java b/jndi/src/main/java/org/apache/karaf/jndi/JndiMBean.java
new file mode 100644
index 0000000..0b2be41
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/JndiMBean.java
@@ -0,0 +1,104 @@
+/*
+ * 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.jndi;
+
+import javax.management.MBeanException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JNDI Service MBean
+ */
+public interface JndiMBean {
+
+ /**
+ * Get a map of JNDI names/class names (as attribute).
+ *
+ * @return the MBean attribute containing the map of names/class names.
+ * @throws MBeanException
+ */
+ public Map<String, String> getNames() throws MBeanException;
+
+ /**
+ * Get a list of JNDI sub-contexts (as attribute).
+ *
+ * @return the MBean attribute containing the list of sub-contexts.
+ * @throws MBeanException
+ */
+ public List<String> getContexts() throws MBeanException;
+
+ /**
+ * Get a map of JNDI names/class names children of a given base context.
+ *
+ * @param context the base context.
+ * @return the map of names/class names.
+ * @throws MBeanException
+ */
+ public Map<String, String> getNames(String context) throws MBeanException;
+
+ /**
+ * Get a list of JNDI sub-contexts children of a given base context.
+ *
+ * @param context the base context.
+ * @return the list of sub-contexts.
+ * @throws MBeanException
+ */
+ public List<String> getContexts(String context) throws MBeanException;
+
+ /**
+ * Create a JNDI sub-context.
+ *
+ * @param context the JNDI sub-context name.
+ * @throws MBeanException
+ */
+ public void create(String context) throws MBeanException;
+
+ /**
+ * Delete a JNDI sub-context.
+ *
+ * @param context the JNDI sub-context name.
+ * @throws MBeanException
+ */
+ public void delete(String context) throws MBeanException;
+
+ /**
+ * Create another JNDI name (alias) for a given one.
+ *
+ * @param name the "source" JNDI name.
+ * @param alias the JNDI alias name.
+ * @throws MBeanException
+ */
+ public void alias(String name, String alias) throws MBeanException;
+
+ /**
+ * Bind an OSGi service with a JNDI name.
+ *
+ * @param serviceId the OSGi service id (service.id property on the service, created by the framework).
+ * @param name the JNDI name.
+ * @throws MBeanException
+ */
+ public void bind(Long serviceId, String name) throws MBeanException;
+
+ /**
+ * Unbind a given JNDI name.
+ *
+ * @param name the JNDI name.
+ * @throws MBeanException
+ */
+ public void unbind(String name) throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/JndiService.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/JndiService.java b/jndi/src/main/java/org/apache/karaf/jndi/JndiService.java
new file mode 100644
index 0000000..c9f9c57
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/JndiService.java
@@ -0,0 +1,103 @@
+/*
+ * 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.jndi;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JNDI Service.
+ */
+public interface JndiService {
+
+ /**
+ * List the current JNDI names (with the bound class name).
+ *
+ * @return the JNDI names.
+ * @throws Exception
+ */
+ Map<String, String> names() throws Exception;
+
+ /**
+ * List the current JNDI names in the given context.
+ *
+ * @param context the JNDI context.
+ * @return the JNDI names in the context.
+ * @throws Exception
+ */
+ Map<String, String> names(String context) throws Exception;
+
+ /**
+ * List all JNDI sub-contexts.
+ *
+ * @return a list containing the sub-context names.
+ * @throws Exception
+ */
+ List<String> contexts() throws Exception;
+
+ /**
+ * List the JNDI sub-context from a given context.
+ *
+ * @param context the base JNDI context.
+ * @return a list containing the sub-context names.
+ * @throws Exception
+ */
+ List<String> contexts(String context) throws Exception;
+
+ /**
+ * Create a sub-context.
+ *
+ * @param context the new sub-context name to create.
+ * @throws Exception
+ */
+ void create(String context) throws Exception;
+
+ /**
+ * Delete a sub-context.
+ *
+ * @param context the sub-context name to delete.
+ * @throws Exception
+ */
+ void delete(String context) throws Exception;
+
+ /**
+ * Create an alias on a given JNDI name.
+ *
+ * @param name the JNDI name.
+ * @param alias the alias.
+ * @throws Exception
+ */
+ void alias(String name, String alias) throws Exception;
+
+ /**
+ * Bind a given OSGi service to a JNDI name.
+ *
+ * @param serviceId the OSGi service ID.
+ * @param name the JNDI name.
+ * @throws Exception
+ */
+ void bind(long serviceId, String name) throws Exception;
+
+ /**
+ * Unbind an existing name.
+ *
+ * @param name the JNDI name to unbind.
+ * @throws Exception
+ */
+ void unbind(String name) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java b/jndi/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.java
new file mode 100644
index 0000000..a540556
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/KarafInitialContextFactory.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.jndi;
+
+import org.apache.xbean.naming.context.WritableContext;
+import org.apache.xbean.naming.global.GlobalContextManager;
+
+/**
+ * A very simple writable initial context factory.
+ * @see org.apache.xbean.naming.context.WritableContext for details.
+ */
+public class KarafInitialContextFactory extends GlobalContextManager {
+
+ public KarafInitialContextFactory() throws Exception {
+ super();
+ setGlobalContext(new WritableContext());
+ }
+
+}
[46/59] [abbrv] [KARAF-2852] Merge wrapper/core and wrapper/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll
new file mode 100644
index 0000000..cb553c1
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/wrapper.dll differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
new file mode 100644
index 0000000..0dd0474
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-service.bat
@@ -0,0 +1,51 @@
+@echo off
+
+REM ------------------------------------------------------------------------
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM ------------------------------------------------------------------------
+
+setlocal
+
+set APP_NAME=${name}
+set APP_LONG_NAME=${displayName}
+set APP_BASE=${karaf.base}
+set APP_ETC=${karaf.etc}
+
+if ""%1"" == ""run"" goto doRun
+if ""%1"" == ""install"" goto doInstall
+if ""%1"" == ""remove"" goto doRemove
+
+echo Usage: karaf-service ( commands ... )
+echo commands:
+echo run Start %APP_NAME% in the current console
+echo install Install %APP_NAME% as a Windows service
+echo remove Remove the %APP_NAME% Windows service
+goto end
+
+:doRun
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -c "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:doInstall
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -i "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:doRemove
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -r "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:end
+if not "%PAUSE%" == "" pause
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
new file mode 100644
index 0000000..def40f7
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.conf
@@ -0,0 +1,135 @@
+# ------------------------------------------------------------------------
+# 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.
+# ------------------------------------------------------------------------
+
+#********************************************************************
+# Wrapper Properties
+#********************************************************************
+set.default.JAVA_HOME=${java.home}
+set.default.KARAF_HOME=${karaf.home}
+set.default.KARAF_BASE=${karaf.base}
+set.default.KARAF_DATA=${karaf.data}
+set.default.KARAF_ETC=${karaf.etc}
+
+# Java Application
+wrapper.working.dir=%KARAF_BASE%
+wrapper.java.command=%JAVA_HOME%/bin/java
+wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
+wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
+wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
+wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
+wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
+wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
+wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
+wrapper.java.library.path.1=%KARAF_HOME%/lib/
+
+# Application Parameters. Add parameters as needed starting from 1
+#wrapper.app.parameter.1=
+
+# JVM Parameters
+# note that n is the parameter number starting from 1.
+wrapper.java.additional.1=-Dkaraf.home="%KARAF_HOME%"
+wrapper.java.additional.2=-Dkaraf.base="%KARAF_BASE%"
+wrapper.java.additional.3=-Dkaraf.data="%KARAF_DATA%"
+wrapper.java.additional.4=-Dkaraf.etc="%KARAF_ETC%"
+wrapper.java.additional.5=-Dcom.sun.management.jmxremote
+wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
+wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
+wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
+wrapper.java.additional.9=-Djava.endorsed.dirs="%JAVA_HOME%/jre/lib/endorsed;%JAVA_HOME%/lib/endorsed;%KARAF_HOME%/lib/endorsed"
+wrapper.java.additional.10=-Djava.ext.dirs="%JAVA_HOME%/jre/lib/ext;%JAVA_HOME%/lib/ext;%KARAF_HOME%/lib/ext"
+
+# Uncomment to enable jmx
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
+
+# Uncomment to enable YourKit profiling
+#wrapper.java.additional.n=-Xrunyjpagent
+
+# Uncomment to enable remote debugging
+#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
+#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
+
+# Initial Java Heap Size (in MB)
+#wrapper.java.initmemory=3
+
+# Maximum Java Heap Size (in MB)
+wrapper.java.maxmemory=512
+
+
+#********************************************************************
+# Wrapper Logging Properties
+#********************************************************************
+# Format of output for the console. (See docs for formats)
+wrapper.console.format=PM
+
+# Log Level for console output. (See docs for log levels)
+wrapper.console.loglevel=INFO
+
+# Log file to use for wrapper output logging.
+wrapper.logfile=%KARAF_DATA%/log/wrapper.log
+
+# Format of output for the log file. (See docs for formats)
+wrapper.logfile.format=LPTM
+
+# Log Level for log file output. (See docs for log levels)
+wrapper.logfile.loglevel=INFO
+
+# Maximum size that the log file will be allowed to grow to before
+# the log is rolled. Size is specified in bytes. The default value
+# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
+# 'm' (mb) suffix. For example: 10m = 10 megabytes.
+wrapper.logfile.maxsize=10m
+
+# Maximum number of rolled log files which will be allowed before old
+# files are deleted. The default value of 0 implies no limit.
+wrapper.logfile.maxfiles=5
+
+# Log Level for sys/event log output. (See docs for log levels)
+wrapper.syslog.loglevel=NONE
+
+#********************************************************************
+# Wrapper Windows Properties
+#********************************************************************
+# Title to use when running as a console
+wrapper.console.title=${name}
+
+#********************************************************************
+# Wrapper Windows NT/2000/XP Service Properties
+#********************************************************************
+# WARNING - Do not modify any of these properties when an application
+# using this configuration file has been installed as a service.
+# Please uninstall the service before modifying this section. The
+# service can then be reinstalled.
+
+# Name of the service
+wrapper.ntservice.name=${name}
+
+# Display name of the service
+wrapper.ntservice.displayname=${displayName}
+
+# Description of the service
+wrapper.ntservice.description=${description}
+
+# Service dependencies. Add dependencies as needed starting from 1
+wrapper.ntservice.dependency.1=
+
+# Mode in which the service is installed. AUTO_START or DEMAND_START
+wrapper.ntservice.starttype=${startType}
+
+# Allow the service to interact with the desktop.
+wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe
new file mode 100755
index 0000000..db2ddda
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/karaf-wrapper.exe differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll
new file mode 100644
index 0000000..f07fc9e
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows64/wrapper.dll differ
[08/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/RegionsPersistence.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/RegionsPersistence.java b/features/src/main/java/org/apache/karaf/features/RegionsPersistence.java
new file mode 100644
index 0000000..96ca7da
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/RegionsPersistence.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+public interface RegionsPersistence {
+ void install(Bundle b, String regionName) throws BundleException;
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Repository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Repository.java b/features/src/main/java/org/apache/karaf/features/Repository.java
new file mode 100644
index 0000000..6ee96da
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Repository.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.net.URI;
+
+/**
+ * A repository of features.
+ */
+public interface Repository {
+
+ String getName();
+
+ URI getURI();
+
+ URI[] getRepositories() throws Exception;
+
+ Feature[] getFeatures() throws Exception;
+
+ boolean isValid();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/RepositoryEvent.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/RepositoryEvent.java b/features/src/main/java/org/apache/karaf/features/RepositoryEvent.java
new file mode 100644
index 0000000..68f287b
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/RepositoryEvent.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import java.util.EventObject;
+
+public class RepositoryEvent extends EventObject {
+
+ public static enum EventType {
+ RepositoryAdded,
+ RepositoryRemoved,
+ }
+
+ private final EventType type;
+ private final Repository repository;
+ private final boolean replay;
+
+ public RepositoryEvent(Repository repository, EventType type, boolean replay) {
+ super(repository);
+ this.type = type;
+ this.repository = repository;
+ this.replay = replay;
+ }
+
+ public EventType getType() {
+ return type;
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public boolean isReplay() {
+ return replay;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Requirement.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Requirement.java b/features/src/main/java/org/apache/karaf/features/Requirement.java
new file mode 100644
index 0000000..4446335
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Requirement.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.features;
+
+public interface Requirement {
+
+ String getValue();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Resolver.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Resolver.java b/features/src/main/java/org/apache/karaf/features/Resolver.java
new file mode 100644
index 0000000..d2fa941
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Resolver.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+import java.util.List;
+
+public interface Resolver {
+
+ List<BundleInfo> resolve(Feature feature) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java b/features/src/main/java/org/apache/karaf/features/command/FeaturesCommandSupport.java
new file mode 100644
index 0000000..076650d
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java b/features/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
new file mode 100644
index 0000000..7084a6e
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/command/InfoFeatureCommand.java
@@ -0,0 +1,292 @@
+/*
+ * 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<? extends Dependency> 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();
+ Iterator<? extends Dependency> di = cond.getCondition().iterator();
+ while (di.hasNext()) {
+ Dependency dep = di.next();
+ sb.append(dep.getName()).append("/").append(dep.getVersion());
+ if (di.hasNext()) {
+ sb.append(" ");
+ }
+ }
+ return sb.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java b/features/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
new file mode 100644
index 0000000..b7f8184
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java b/features/src/main/java/org/apache/karaf/features/command/ListFeatureVersionsCommand.java
new file mode 100644
index 0000000..b2c5e42
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java b/features/src/main/java/org/apache/karaf/features/command/ListFeaturesCommand.java
new file mode 100644
index 0000000..e86ff64
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java b/features/src/main/java/org/apache/karaf/features/command/RepoAddCommand.java
new file mode 100644
index 0000000..16faf42
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/RepoListCommand.java b/features/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
new file mode 100644
index 0000000..591a1c6
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/command/RepoListCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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) {
+ 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/999f4970/features/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java b/features/src/main/java/org/apache/karaf/features/command/RepoRefreshCommand.java
new file mode 100644
index 0000000..8c7ed79
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java b/features/src/main/java/org/apache/karaf/features/command/RepoRemoveCommand.java
new file mode 100644
index 0000000..0710b72
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java b/features/src/main/java/org/apache/karaf/features/command/UninstallFeatureCommand.java
new file mode 100644
index 0000000..e62f697
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/AllFeatureCompleter.java
new file mode 100644
index 0000000..7444b95
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/AvailableFeatureCompleter.java
new file mode 100644
index 0000000..79cd280
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/AvailableRepoNameCompleter.java
new file mode 100644
index 0000000..acefe77
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java b/features/src/main/java/org/apache/karaf/features/command/completers/FeatureCompleterSupport.java
new file mode 100644
index 0000000..d01e5af
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoNameCompleter.java
new file mode 100644
index 0000000..94e4cf7
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/InstalledRepoUriCompleter.java
new file mode 100644
index 0000000..7a760c2
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java b/features/src/main/java/org/apache/karaf/features/command/completers/RequiredFeatureCompleter.java
new file mode 100644
index 0000000..a51f75f
--- /dev/null
+++ b/features/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/999f4970/features/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java b/features/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
new file mode 100644
index 0000000..00a91c4
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/deployment/DeploymentBuilder.java
@@ -0,0 +1,334 @@
+/*
+ * 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.internal.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.felix.resolver.ResolverImpl;
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Conditional;
+import org.apache.karaf.features.Dependency;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.internal.repository.AggregateRepository;
+import org.apache.karaf.features.internal.repository.StaticRepository;
+import org.apache.karaf.features.internal.resolver.FeatureNamespace;
+import org.apache.karaf.features.internal.resolver.FeatureResource;
+import org.apache.karaf.features.internal.resolver.RequirementImpl;
+import org.apache.karaf.features.internal.resolver.ResolveContextImpl;
+import org.apache.karaf.features.internal.resolver.ResourceBuilder;
+import org.apache.karaf.features.internal.resolver.ResourceImpl;
+import org.apache.karaf.features.internal.resolver.Slf4jResolverLog;
+import org.apache.karaf.features.internal.service.Overrides;
+import org.apache.karaf.features.internal.util.Macro;
+import org.apache.karaf.features.internal.util.MultiException;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.resolver.ResolveContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ */
+public class DeploymentBuilder {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DeploymentBuilder.class);
+
+ public static final String REQ_PROTOCOL = "req:";
+
+ private final Collection<Repository> repositories;
+
+ private final List<org.osgi.service.repository.Repository> resourceRepos;
+
+ String featureRange = "${range;[====,====]}";
+
+ Downloader downloader;
+ ResourceImpl requirements;
+ Map<String, Resource> resources;
+ Set<Resource> optionals;
+ Map<String, StreamProvider> providers;
+
+ Set<Feature> featuresToRegister = new HashSet<Feature>();
+
+ public DeploymentBuilder(Downloader downloader,
+ Collection<Repository> repositories) {
+ this.downloader = downloader;
+ this.repositories = repositories;
+ this.resourceRepos = new ArrayList<org.osgi.service.repository.Repository>();
+ }
+
+ public void addResourceRepository(org.osgi.service.repository.Repository repository) {
+ resourceRepos.add(repository);
+ }
+
+ public Map<String, StreamProvider> getProviders() {
+ return providers;
+ }
+
+ public void setFeatureRange(String featureRange) {
+ this.featureRange = featureRange;
+ }
+
+ public Map<String, Resource> download(
+ Set<String> features,
+ Set<String> bundles,
+ Set<String> reqs,
+ Set<String> overrides,
+ Set<String> optionals)
+ throws IOException, MultiException, InterruptedException, ResolutionException, BundleException {
+ this.resources = new ConcurrentHashMap<String, Resource>();
+ this.optionals = new HashSet<Resource>();
+ this.providers = new ConcurrentHashMap<String, StreamProvider>();
+ this.requirements = new ResourceImpl("dummy", "dummy", Version.emptyVersion);
+ // First, gather all bundle resources
+ for (String feature : features) {
+ registerMatchingFeatures(feature);
+ }
+ for (String bundle : bundles) {
+ downloadAndBuildResource(bundle);
+ }
+ for (String req : reqs) {
+ buildRequirement(req);
+ }
+ for (String override : overrides) {
+ // TODO: ignore download failures for overrides
+ downloadAndBuildResource(Overrides.extractUrl(override));
+ }
+ for (String optional : optionals) {
+ downloadAndBuildResource(optional);
+ }
+ // Wait for all resources to be created
+ downloader.await();
+ // Do override replacement
+ Overrides.override(resources, overrides);
+ // Build features resources
+ for (Feature feature : featuresToRegister) {
+ Resource resource = FeatureResource.build(feature, featureRange, resources);
+ resources.put("feature:" + feature.getName() + "/" + feature.getVersion(), resource);
+ for (Conditional cond : feature.getConditional()) {
+ this.optionals.add(FeatureResource.build(feature, cond, featureRange, resources));
+ }
+ }
+ // Build requirements
+ for (String feature : features) {
+ requireFeature(feature);
+ }
+ for (String bundle : bundles) {
+ requireResource(bundle);
+ }
+ for (String req : reqs) {
+ requireResource(REQ_PROTOCOL + req);
+ }
+ return resources;
+ }
+
+ public Map<Resource, List<Wire>> resolve(List<Resource> systemBundles,
+ boolean resolveOptionalImports) throws ResolutionException {
+ // Resolve
+ for (int i = 0; i < systemBundles.size(); i++) {
+ resources.put("system-bundle-" + i, systemBundles.get(i));
+ }
+
+ List<org.osgi.service.repository.Repository> repos = new ArrayList<org.osgi.service.repository.Repository>();
+ repos.add(new StaticRepository(resources.values()));
+ repos.addAll(resourceRepos);
+
+ ResolverImpl resolver = new ResolverImpl(new Slf4jResolverLog(LOGGER));
+ ResolveContext context = new ResolveContextImpl(
+ Collections.<Resource>singleton(requirements),
+ this.optionals,
+ new AggregateRepository(repos),
+ resolveOptionalImports);
+
+ return resolver.resolve(context);
+ }
+
+ public void requireFeature(String feature) throws IOException {
+ // Find name and version range
+ String[] split = feature.split("/");
+ String name = split[0].trim();
+ String version = (split.length > 1) ? split[1].trim() : null;
+ if (version != null && !version.equals("0.0.0") && !version.startsWith("[") && !version.startsWith("(")) {
+ version = Macro.transform(featureRange, version);
+ }
+ VersionRange range = version != null ? new VersionRange(version) : VersionRange.ANY_VERSION;
+ // Add requirement
+ Map<String, Object> attrs = new HashMap<String, Object>();
+ attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
+ attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, FeatureNamespace.TYPE_FEATURE);
+ attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, range);
+ requirements.addRequirement(
+ new RequirementImpl(requirements, IdentityNamespace.IDENTITY_NAMESPACE,
+ Collections.<String, String>emptyMap(), attrs)
+ );
+ }
+
+ public void requireResource(String location) {
+ Resource res = resources.get(location);
+ if (res == null) {
+ throw new IllegalStateException("Could not find resource for " + location);
+ }
+ List<Capability> caps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (caps.size() != 1) {
+ throw new IllegalStateException("Resource does not have a single " + IdentityNamespace.IDENTITY_NAMESPACE + " capability");
+ }
+ Capability cap = caps.get(0);
+ // Add requirement
+ Map<String, Object> attrs = new HashMap<String, Object>();
+ attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
+ attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+ attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((Version) cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE), true));
+ requirements.addRequirement(
+ new RequirementImpl(requirements, IdentityNamespace.IDENTITY_NAMESPACE,
+ Collections.<String, String>emptyMap(), attrs));
+
+ }
+
+ public void registerMatchingFeatures(String feature) throws IOException {
+ // Find name and version range
+ String[] split = feature.split("/");
+ String name = split[0].trim();
+ String version = (split.length > 1)
+ ? split[1].trim() : Version.emptyVersion.toString();
+ // Register matching features
+ registerMatchingFeatures(name, new VersionRange(version));
+ }
+
+ public void registerMatchingFeatures(String name, String version) throws IOException {
+ if (version != null && !version.equals("0.0.0") && !version.startsWith("[") && !version.startsWith("(")) {
+ version = Macro.transform(featureRange, version);
+ }
+ registerMatchingFeatures(name, version != null ? new VersionRange(version) : VersionRange.ANY_VERSION);
+ }
+
+ public void registerMatchingFeatures(String name, VersionRange range) throws IOException {
+ for (Repository repo : repositories) {
+ Feature[] features;
+ try {
+ features = repo.getFeatures();
+ } catch (Exception e) {
+ // This should not happen as the repository has been loaded already
+ throw new IllegalStateException(e);
+ }
+ for (Feature f : features) {
+ if (name.equals(f.getName())) {
+ Version v = VersionTable.getVersion(f.getVersion());
+ if (range.contains(v)) {
+ featuresToRegister.add(f);
+ for (Dependency dep : f.getDependencies()) {
+ registerMatchingFeatures(dep.getName(), dep.getVersion());
+ }
+ for (BundleInfo bundle : f.getBundles()) {
+ downloadAndBuildResource(bundle.getLocation());
+ }
+ for (Conditional cond : f.getConditional()) {
+ Feature c = cond.asFeature(f.getName(), f.getVersion());
+ featuresToRegister.add(c);
+ for (BundleInfo bundle : c.getBundles()) {
+ downloadAndBuildResource(bundle.getLocation());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void buildRequirement(String requirement) {
+ try {
+ String location = REQ_PROTOCOL + requirement;
+ ResourceImpl resource = new ResourceImpl(location, "dummy", Version.emptyVersion);
+ for (Requirement req : ResourceBuilder.parseRequirement(resource, requirement)) {
+ resource.addRequirement(req);
+ }
+ resources.put(location, resource);
+ } catch (BundleException e) {
+ throw new IllegalArgumentException("Error parsing requirement: " + requirement, e);
+ }
+ }
+
+ public void downloadAndBuildResource(final String location) throws IOException {
+ if (!resources.containsKey(location)) {
+ downloader.download(location, new Downloader.DownloadCallback() {
+ @Override
+ public void downloaded(StreamProvider provider) throws Exception {
+ manageResource(location, provider);
+ }
+ });
+ }
+ }
+
+ private void manageResource(String location, StreamProvider provider) throws Exception {
+ if (!resources.containsKey(location)) {
+ Attributes attributes = getAttributes(location, provider);
+ Resource resource = createResource(location, attributes);
+ resources.put(location, resource);
+ providers.put(location, provider);
+ }
+ }
+
+ private Resource createResource(String uri, Attributes attributes) throws Exception {
+ Map<String, String> headers = new HashMap<String, String>();
+ for (Map.Entry attr : attributes.entrySet()) {
+ headers.put(attr.getKey().toString(), attr.getValue().toString());
+ }
+ try {
+ return ResourceBuilder.build(uri, headers);
+ } catch (BundleException e) {
+ throw new Exception("Unable to create resource for bundle " + uri, e);
+ }
+ }
+
+ protected Attributes getAttributes(String uri, StreamProvider provider) throws Exception {
+ InputStream is = provider.open();
+ try {
+ ZipInputStream zis = new ZipInputStream(is);
+ ZipEntry entry;
+ while ( (entry = zis.getNextEntry()) != null ) {
+ if ("META-INF/MANIFEST.MF".equals(entry.getName())) {
+ return new Manifest(zis).getMainAttributes();
+ }
+ }
+ } finally {
+ is.close();
+ }
+ throw new IllegalArgumentException("Resource " + uri + " does not contain a manifest");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java b/features/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
new file mode 100644
index 0000000..2d5dd98
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/deployment/Downloader.java
@@ -0,0 +1,35 @@
+/*
+ * 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.internal.deployment;
+
+import java.net.MalformedURLException;
+
+import org.apache.karaf.features.internal.util.MultiException;
+
+public interface Downloader {
+
+ void await() throws InterruptedException, MultiException;
+
+ void download(String location, DownloadCallback downloadCallback) throws MalformedURLException;
+
+ interface DownloadCallback {
+
+ void downloaded(StreamProvider provider) throws Exception;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java b/features/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
new file mode 100644
index 0000000..60a3dfc
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/deployment/StreamProvider.java
@@ -0,0 +1,26 @@
+/*
+ * 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.internal.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public interface StreamProvider {
+
+ InputStream open() throws IOException;
+
+}
[21/59] [abbrv] git commit: [KARAF-2852] Merge bundle/command into
bundle/core
Posted by gn...@apache.org.
[KARAF-2852] Merge bundle/command into bundle/core
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/d0180939
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/d0180939
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/d0180939
Branch: refs/heads/master
Commit: d01809398ab4943c9d1944da3bd6e68a37268ba1
Parents: 999f497
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 21:59:03 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 15:59:24 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
bundle/command/NOTICE | 71 ----
bundle/command/pom.xml | 113 -------
.../karaf/bundle/command/BundleCommand.java | 69 ----
.../command/BundleCommandWithConfirmation.java | 37 ---
.../karaf/bundle/command/BundlesCommand.java | 79 -----
.../command/BundlesCommandWithConfirmation.java | 62 ----
.../karaf/bundle/command/Capabilities.java | 239 -------------
.../apache/karaf/bundle/command/Classes.java | 63 ----
.../org/apache/karaf/bundle/command/Diag.java | 51 ---
.../karaf/bundle/command/DynamicImport.java | 46 ---
.../apache/karaf/bundle/command/FindClass.java | 68 ----
.../apache/karaf/bundle/command/Headers.java | 333 -------------------
.../org/apache/karaf/bundle/command/Info.java | 79 -----
.../apache/karaf/bundle/command/Install.java | 81 -----
.../bundle/command/ListBundleServices.java | 116 -------
.../karaf/bundle/command/ListBundles.java | 176 ----------
.../apache/karaf/bundle/command/LoadTest.java | 192 -----------
.../apache/karaf/bundle/command/Refresh.java | 43 ---
.../karaf/bundle/command/Requirements.java | 177 ----------
.../apache/karaf/bundle/command/Resolve.java | 39 ---
.../apache/karaf/bundle/command/Restart.java | 62 ----
.../karaf/bundle/command/ShowBundleTree.java | 245 --------------
.../org/apache/karaf/bundle/command/Start.java | 32 --
.../apache/karaf/bundle/command/StartLevel.java | 64 ----
.../org/apache/karaf/bundle/command/Stop.java | 44 ---
.../apache/karaf/bundle/command/Uninstall.java | 36 --
.../org/apache/karaf/bundle/command/Update.java | 48 ---
.../org/apache/karaf/bundle/command/Watch.java | 128 -------
.../karaf/bundle/command/bundletree/Node.java | 159 ---------
.../karaf/bundle/command/bundletree/Tree.java | 100 ------
.../wikidoc/AnsiPrintingWikiVisitor.java | 58 ----
.../bundle/command/wikidoc/WikiParser.java | 86 -----
.../bundle/command/wikidoc/WikiVisitor.java | 29 --
.../src/main/resources/OSGI-INF/bundle.info | 32 --
.../karaf/bundle/command/ListServicesTest.java | 61 ----
.../karaf/bundle/command/TestBundleFactory.java | 104 ------
.../bundle/command/bundletree/TreeTest.java | 135 --------
.../bundle/command/wikidoc/WikiParserTest.java | 94 ------
bundle/core/pom.xml | 8 +
.../karaf/bundle/command/BundleCommand.java | 69 ++++
.../command/BundleCommandWithConfirmation.java | 37 +++
.../karaf/bundle/command/BundlesCommand.java | 79 +++++
.../command/BundlesCommandWithConfirmation.java | 62 ++++
.../karaf/bundle/command/Capabilities.java | 239 +++++++++++++
.../apache/karaf/bundle/command/Classes.java | 63 ++++
.../org/apache/karaf/bundle/command/Diag.java | 51 +++
.../karaf/bundle/command/DynamicImport.java | 46 +++
.../apache/karaf/bundle/command/FindClass.java | 68 ++++
.../apache/karaf/bundle/command/Headers.java | 333 +++++++++++++++++++
.../org/apache/karaf/bundle/command/Info.java | 79 +++++
.../apache/karaf/bundle/command/Install.java | 81 +++++
.../bundle/command/ListBundleServices.java | 116 +++++++
.../karaf/bundle/command/ListBundles.java | 176 ++++++++++
.../apache/karaf/bundle/command/LoadTest.java | 192 +++++++++++
.../apache/karaf/bundle/command/Refresh.java | 43 +++
.../karaf/bundle/command/Requirements.java | 177 ++++++++++
.../apache/karaf/bundle/command/Resolve.java | 39 +++
.../apache/karaf/bundle/command/Restart.java | 62 ++++
.../karaf/bundle/command/ShowBundleTree.java | 245 ++++++++++++++
.../org/apache/karaf/bundle/command/Start.java | 32 ++
.../apache/karaf/bundle/command/StartLevel.java | 64 ++++
.../org/apache/karaf/bundle/command/Stop.java | 44 +++
.../apache/karaf/bundle/command/Uninstall.java | 36 ++
.../org/apache/karaf/bundle/command/Update.java | 48 +++
.../org/apache/karaf/bundle/command/Watch.java | 128 +++++++
.../karaf/bundle/command/bundletree/Node.java | 159 +++++++++
.../karaf/bundle/command/bundletree/Tree.java | 100 ++++++
.../wikidoc/AnsiPrintingWikiVisitor.java | 58 ++++
.../bundle/command/wikidoc/WikiParser.java | 86 +++++
.../bundle/command/wikidoc/WikiVisitor.java | 29 ++
.../karaf/bundle/command/ListServicesTest.java | 61 ++++
.../karaf/bundle/command/TestBundleFactory.java | 104 ++++++
.../bundle/command/bundletree/TreeTest.java | 135 ++++++++
.../bundle/command/wikidoc/WikiParserTest.java | 94 ++++++
bundle/pom.xml | 1 -
76 files changed, 3443 insertions(+), 3653 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/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 fde555c..2bc3ec4 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -121,7 +121,6 @@
<feature name="bundle" description="Provide Bundle support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.bundle/org.apache.karaf.bundle.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.bundle/org.apache.karaf.bundle.command/${project.version}</bundle>
</feature>
<feature name="config" description="Provide OSGi ConfigAdmin support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/NOTICE
----------------------------------------------------------------------
diff --git a/bundle/command/NOTICE b/bundle/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/bundle/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/d0180939/bundle/command/pom.xml
----------------------------------------------------------------------
diff --git a/bundle/command/pom.xml b/bundle/command/pom.xml
deleted file mode 100644
index d856d04..0000000
--- a/bundle/command/pom.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?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.bundle</groupId>
- <artifactId>bundle</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.bundle.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Bundle :: Commands</name>
- <description>Provides shell commands to manipulate OSGi bundles.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.bundle</groupId>
- <artifactId>org.apache.karaf.bundle.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.gogo.runtime</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </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>
- <Export-Package>!*</Export-Package>
- <Private-Package>
- org.apache.karaf.bundle.command*,
- org.apache.felix.utils.version;-split-package:=merge-first,
- org.apache.felix.utils.manifest;-split-package:=merge-first
- </Private-Package>
- <Karaf-Commands>org.apache.karaf.bundle.command.*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java
deleted file mode 100644
index dce0ca8..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.bundle.core.BundleService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/**
- * Unique bundle command.
- */
-public abstract class BundleCommand implements Action {
-
- @Argument(index = 0, name = "id", description = "The bundle ID or name or name/version", required = true, multiValued = false)
- String id;
-
- boolean defaultAllBundles = true;
-
- @Reference
- BundleService bundleService;
-
- @Reference
- BundleContext bundleContext;
-
- public BundleCommand(boolean defaultAllBundles) {
- this.defaultAllBundles = defaultAllBundles;
- }
-
- public Object execute() throws Exception {
- return doExecute(true);
- }
-
- protected Object doExecute(boolean force) throws Exception {
- Bundle bundle = bundleService.getBundle(id, defaultAllBundles);
- if (bundle != null) {
- if (force || !ShellUtil.isASystemBundle(bundleContext, bundle)) {
- doExecute(bundle);
- } else {
- System.err.println("Access to system bundle " + id + " is discouraged. You may override with -f");
- }
- }
- return null;
- }
-
- protected abstract void doExecute(Bundle bundle) throws Exception;
-
- public void setBundleService(BundleService bundleService) {
- this.bundleService = bundleService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
deleted file mode 100644
index c07a357..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.shell.api.action.Option;
-
-/**
- * Unique bundle command with confirmation while accessing system bundle.
- */
-public abstract class BundleCommandWithConfirmation extends BundleCommand {
-
- @Option(name = "--force", aliases = {"-f"}, description = "Forces the command to execute", required = false, multiValued = false)
- boolean force;
-
- public BundleCommandWithConfirmation() {
- super(true);
- }
-
- public Object execute() throws Exception {
- return doExecute(force);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
deleted file mode 100644
index ff4dd53..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.List;
-
-import org.apache.karaf.bundle.core.BundleService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-public abstract class BundlesCommand implements Action {
-
- @Argument(index = 0, name = "ids", description = "The list of bundle (identified by IDs or name or name/version) separated by whitespaces", required = false, multiValued = true)
- List<String> ids;
-
- boolean defaultAllBundles = true;
-
- @Reference
- BundleContext bundleContext;
-
- @Reference
- BundleService bundleService;
-
- public BundlesCommand(boolean defaultAllBundles) {
- this.defaultAllBundles = defaultAllBundles;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- @Override
- public Object execute() throws Exception {
- doExecute(true);
- return null;
- }
-
- protected Object doExecute(boolean force) throws Exception {
- List<Bundle> bundles = bundleService.selectBundles(ids, defaultAllBundles);
- if (!force) {
- assertNoSystemBundles(bundles);
- }
- doExecute(bundles);
- return null;
- }
-
- private void assertNoSystemBundles(List<Bundle> bundles) {
- for (Bundle bundle : bundles) {
- if (ShellUtil.isASystemBundle(bundleContext, bundle)) {
- throw new RuntimeException("Access to system bundle " + bundle.getBundleId() + " denied. You can override with -f");
- }
- }
- }
-
- protected abstract void doExecute(List<Bundle> bundles) throws Exception;
-
- public void setBundleService(BundleService bundleService) {
- this.bundleService = bundleService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java
deleted file mode 100644
index 271fc42..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/BundlesCommandWithConfirmation.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.support.MultiException;
-import org.osgi.framework.Bundle;
-
-/**
- * Command related to bundles requiring read-write access to the bundle (including system bundle).
- */
-public abstract class BundlesCommandWithConfirmation extends BundlesCommand {
-
- @Option(name = "--force", aliases = {"-f"}, description = "Forces the command to execute", required = false, multiValued = false)
- boolean force;
-
- protected String errorMessage = "Unable to execute command on bundle ";
-
- public BundlesCommandWithConfirmation() {
- super(false);
- }
-
- protected Object doExecute() throws Exception {
- doExecute(force);
- return null;
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- if (bundles.isEmpty()) {
- System.err.println("No bundles specified.");
- return;
- }
- List<Exception> exceptions = new ArrayList<Exception>();
- for (Bundle bundle : bundles) {
- try {
- executeOnBundle(bundle);
- } catch (Exception e) {
- exceptions.add(new Exception(errorMessage + bundle.getBundleId() + ": " + e.getMessage(), e));
- }
- }
- MultiException.throwIf("Error executing command on bundles", exceptions);
- }
-
- protected abstract void executeOnBundle(Bundle bundle) throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Capabilities.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
deleted file mode 100644
index de83a1d..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Capabilities.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-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.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-@Command(scope = "bundle", name = "capabilities", description = "Displays OSGi capabilities of a given bundles.")
-@Service
-public class Capabilities extends BundlesCommand {
- public static final String NONSTANDARD_SERVICE_NAMESPACE = "service";
-
- private static final String EMPTY_MESSAGE = "[EMPTY]";
- private static final String UNUSED_MESSAGE = "[UNUSED]";
-
- @Option(name = "--namespace")
- String namespace = "*";
-
- public Capabilities() {
- super(true);
- }
-
- @Override
- protected void doExecute(List<Bundle> bundles) throws Exception {
- boolean separatorNeeded = false;
- Pattern ns = Pattern.compile(namespace.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*"));
- for (Bundle b : bundles)
- {
- if (separatorNeeded)
- {
- System.out.println("");
- }
-
- // Print out any matching generic capabilities.
- BundleWiring wiring = b.adapt(BundleWiring.class);
- if (wiring != null)
- {
- String title = b + " provides:";
- System.out.println(title);
- System.out.println(ShellUtil.getUnderlineString(title));
-
- // Print generic capabilities for matching namespaces.
- boolean matches = printMatchingCapabilities(wiring, ns);
-
- // Handle service capabilities separately, since they aren't part
- // of the generic model in OSGi.
- if (matchNamespace(ns, NONSTANDARD_SERVICE_NAMESPACE))
- {
- matches |= printServiceCapabilities(b);
- }
-
- // If there were no capabilities for the specified namespace,
- // then say so.
- if (!matches)
- {
- System.out.println(namespace + " " + EMPTY_MESSAGE);
- }
- }
- else
- {
- System.out.println("Bundle " + b.getBundleId() + " is not resolved.");
- }
- separatorNeeded = true;
- }
- }
-
- private static boolean printMatchingCapabilities(BundleWiring wiring, Pattern namespace)
- {
- List<BundleWire> wires = wiring.getProvidedWires(null);
- Map<BundleCapability, List<BundleWire>> aggregateCaps =
- aggregateCapabilities(namespace, wires);
- List<BundleCapability> allCaps = wiring.getCapabilities(null);
- boolean matches = false;
- for (BundleCapability cap : allCaps)
- {
- if (matchNamespace(namespace, cap.getNamespace()))
- {
- matches = true;
- List<BundleWire> dependents = aggregateCaps.get(cap);
- Object keyAttr =
- cap.getAttributes().get(cap.getNamespace());
- if (dependents != null)
- {
- String msg;
- if (keyAttr != null)
- {
- msg = cap.getNamespace()
- + "; "
- + keyAttr
- + " "
- + getVersionFromCapability(cap);
- }
- else
- {
- msg = cap.toString();
- }
- msg = msg + " required by:";
- System.out.println(msg);
- for (BundleWire wire : dependents)
- {
- System.out.println(" " + wire.getRequirerWiring().getBundle());
- }
- }
- else if (keyAttr != null)
- {
- System.out.println(cap.getNamespace()
- + "; "
- + cap.getAttributes().get(cap.getNamespace())
- + " "
- + getVersionFromCapability(cap)
- + " "
- + UNUSED_MESSAGE);
- }
- else
- {
- System.out.println(cap + " " + UNUSED_MESSAGE);
- }
- }
- }
- return matches;
- }
-
- private static Map<BundleCapability, List<BundleWire>> aggregateCapabilities(
- Pattern namespace, List<BundleWire> wires)
- {
- // Aggregate matching capabilities.
- Map<BundleCapability, List<BundleWire>> map =
- new HashMap<BundleCapability, List<BundleWire>>();
- for (BundleWire wire : wires)
- {
- if (matchNamespace(namespace, wire.getCapability().getNamespace()))
- {
- List<BundleWire> dependents = map.get(wire.getCapability());
- if (dependents == null)
- {
- dependents = new ArrayList<BundleWire>();
- map.put(wire.getCapability(), dependents);
- }
- dependents.add(wire);
- }
- }
- return map;
- }
-
- static boolean printServiceCapabilities(Bundle b)
- {
- boolean matches = false;
-
- try
- {
- ServiceReference<?>[] refs = b.getRegisteredServices();
-
- if ((refs != null) && (refs.length > 0))
- {
- matches = true;
- // Print properties for each service.
- for (ServiceReference<?> ref : refs)
- {
- // Print object class with "namespace".
- System.out.println(
- NONSTANDARD_SERVICE_NAMESPACE
- + "; "
- + ShellUtil.getValueString(ref.getProperty("objectClass"))
- + " with properties:");
- // Print service properties.
- String[] keys = ref.getPropertyKeys();
- for (String key : keys)
- {
- if (!key.equalsIgnoreCase(Constants.OBJECTCLASS))
- {
- Object v = ref.getProperty(key);
- System.out.println(" "
- + key + " = " + ShellUtil.getValueString(v));
- }
- }
- Bundle[] users = ref.getUsingBundles();
- if ((users != null) && (users.length > 0))
- {
- System.out.println(" Used by:");
- for (Bundle user : users)
- {
- System.out.println(" " + user);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- System.err.println(ex.toString());
- }
-
- return matches;
- }
-
- private static String getVersionFromCapability(BundleCapability c)
- {
- Object o = c.getAttributes().get(Constants.VERSION_ATTRIBUTE);
- if (o == null)
- {
- o = c.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- }
- return (o == null) ? "" : o.toString();
- }
-
- private static boolean matchNamespace(Pattern namespace, String actual)
- {
- return namespace.matcher(actual).matches();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Classes.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Classes.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Classes.java
deleted file mode 100644
index b0f80ff..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Classes.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.Collection;
-import java.util.List;
-
-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.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleWiring;
-
-@Command(scope = "bundle", name = "classes", description = "Displays a list of classes contained in the bundle")
-@Service
-public class Classes extends BundlesCommand {
-
- @Option(name = "-a", aliases={"--display-all-files"}, description="List all classes and files in the bundle", required = false, multiValued = false)
- boolean displayAllFiles;
-
- public Classes() {
- super(true);
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- for (Bundle bundle : bundles) {
- printResources(bundle);
- }
- }
-
- protected void printResources(Bundle bundle) {
- BundleWiring wiring = bundle.adapt(BundleWiring.class);
- if (wiring != null){
- Collection<String> resources;
- if (displayAllFiles){
- resources = wiring.listResources("/", null, BundleWiring.LISTRESOURCES_RECURSE);
- }else{
- resources = wiring.listResources("/", "*class", BundleWiring.LISTRESOURCES_RECURSE);
- }
- for (String resource:resources){
- System.out.println(resource);
- }
- } else {
- System.out.println("Bundle " + bundle.getBundleId() + " is not resolved.");
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Diag.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Diag.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Diag.java
deleted file mode 100644
index 1e8e11b..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Diag.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.List;
-
-import org.apache.karaf.bundle.core.BundleInfo;
-import org.apache.karaf.bundle.core.BundleState;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "diag", description = "Displays diagnostic information why a bundle is not Active")
-@Service
-public class Diag extends BundlesCommand {
-
- public Diag() {
- super(true);
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- for (Bundle bundle : bundles) {
- BundleInfo info = bundleService.getInfo(bundle);
- if (info.getState() == BundleState.Failure || info.getState() == BundleState.Waiting
- || info.getState() == BundleState.GracePeriod || info.getState() == BundleState.Installed) {
- String title = ShellUtil.getBundleName(bundle);
- System.out.println(title);
- System.out.println(ShellUtil.getUnderlineString(title));
- System.out.println("Status: " + info.getState().toString());
- System.out.println(this.bundleService.getDiag(bundle));
- System.out.println();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
deleted file mode 100644
index 74fc20a..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/DynamicImport.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-
-/**
- * Command for enabling/disabling debug logging on a bundle and calculating the difference in
- * wired imports.
- */
-@Command(scope = "bundle", name = "dynamic-import", description = "Enables/disables dynamic-import for a given bundle.")
-@Service
-public class DynamicImport extends BundleCommand {
-
- public DynamicImport() {
- super(true);
- }
-
- @Override
- protected void doExecute(Bundle bundle) throws Exception {
- if (bundleService.isDynamicImport(bundle)) {
- System.out.printf("Disabling dynamic imports on bundle %s%n", bundle);
- bundleService.disableDynamicImports(bundle);
- } else {
- System.out.printf("Enabling dynamic imports on bundle %s%n", bundle);
- bundleService.enableDynamicImports(bundle);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/FindClass.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/FindClass.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/FindClass.java
deleted file mode 100644
index 4a9fc75..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/FindClass.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.apache.karaf.bundle.command;
-
-/*
- * 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.
- */
-
-import java.util.Collection;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.wiring.BundleWiring;
-
-@Command(scope = "bundle", name = "find-class", description = "Locates a specified class in any deployed bundle")
-@Service
-public class FindClass implements Action {
-
- @Argument(index = 0, name = "className", description = "Class name or partial class name to be found", required = true, multiValued = false)
- String className;
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- findResource();
- return null;
- }
-
- protected void findResource() {
- Bundle[] bundles = bundleContext.getBundles();
- String filter = "*" + className + "*";
- for (Bundle bundle:bundles){
- BundleWiring wiring = bundle.adapt(BundleWiring.class);
- if (wiring != null){
- Collection<String> resources = wiring.listResources("/", filter, BundleWiring.LISTRESOURCES_RECURSE);
- if (resources.size() > 0){
- String title = ShellUtil.getBundleName(bundle);
- System.out.println("\n" + title);
- }
- for (String resource:resources){
- System.out.println(resource);
- }
- } else {
- System.out.println("Bundle " + bundle.getBundleId() + " is not resolved.");
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Headers.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Headers.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Headers.java
deleted file mode 100644
index 16083ff..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Headers.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.utils.manifest.Attribute;
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Directive;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-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.Terminal;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.fusesource.jansi.Ansi;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-
-@Command(scope = "bundle", name = "headers", description = "Displays OSGi headers of a given bundles.")
-@Service
-public class Headers extends BundlesCommand {
-
- protected final static String BUNDLE_PREFIX = "Bundle-";
- protected final static String PACKAGE_SUFFFIX = "-Package";
- protected final static String SERVICE_SUFFIX = "-Service";
- protected final static String CAPABILITY_SUFFIX = "-Capability";
- protected final static String IMPORT_PACKAGES_ATTRIB = "Import-Package";
- protected final static String REQUIRE_BUNDLE_ATTRIB = "Require-Bundle";
-
- @Option(name = "--indent", description = "Indentation method")
- int indent = -1;
-
- @Reference
- Terminal terminal;
-
- public Headers() {
- super(true);
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- for (Bundle bundle : bundles) {
- printHeaders(bundle);
- }
- }
-
- protected void printHeaders(Bundle bundle) throws Exception {
- String title = ShellUtil.getBundleName(bundle);
- System.out.println("\n" + title);
- System.out.println(ShellUtil.getUnderlineString(title));
- if (indent == 0) {
- Dictionary<String, String> dict = bundle.getHeaders();
- Enumeration<String> keys = dict.keys();
- while (keys.hasMoreElements()) {
- Object k = keys.nextElement();
- Object v = dict.get(k);
- System.out.println(k + " = " + ShellUtil.getValueString(v));
- }
- } else {
- System.out.println(generateFormattedOutput(bundle));
- }
- }
-
- protected String generateFormattedOutput(Bundle bundle) {
- StringBuilder output = new StringBuilder();
- Map<String, Object> otherAttribs = new HashMap<String, Object>();
- Map<String, Object> bundleAttribs = new HashMap<String, Object>();
- Map<String, Object> serviceAttribs = new HashMap<String, Object>();
- Map<String, Object> packagesAttribs = new HashMap<String, Object>();
- Dictionary<String, String> dict = bundle.getHeaders();
- Enumeration<String> keys = dict.keys();
-
- // do an initial loop and separate the attributes in different groups
- while (keys.hasMoreElements()) {
- String k = (String) keys.nextElement();
- Object v = dict.get(k);
- if (k.startsWith(BUNDLE_PREFIX)) {
- // starts with Bundle-xxx
- bundleAttribs.put(k, v);
- } else if (k.endsWith(SERVICE_SUFFIX) || k.endsWith(CAPABILITY_SUFFIX)) {
- // ends with xxx-Service
- serviceAttribs.put(k, v);
- } else if (k.endsWith(PACKAGE_SUFFFIX)) {
- // ends with xxx-Package
- packagesAttribs.put(k, v);
- } else if (k.endsWith(REQUIRE_BUNDLE_ATTRIB)) {
- // require bundle statement
- packagesAttribs.put(k, v);
- } else {
- // the remaining attribs
- otherAttribs.put(k, v);
- }
- }
-
- // we will display the formatted result like this:
- // Bundle-Name (ID)
- // -----------------------
- // all other attributes
- //
- // all Bundle attributes
- //
- // all Service attributes
- //
- // all Package attributes
- Iterator<Map.Entry<String, Object>> it = otherAttribs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, Object> e = it.next();
- output.append(String.format("%s = %s\n", e.getKey(), ShellUtil.getValueString(e.getValue())));
- }
- if (otherAttribs.size() > 0) {
- output.append('\n');
- }
-
- it = bundleAttribs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, Object> e = it.next();
- output.append(String.format("%s = %s\n", e.getKey(), ShellUtil.getValueString(e.getValue())));
- }
- if (bundleAttribs.size() > 0) {
- output.append('\n');
- }
-
- it = serviceAttribs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, Object> e = it.next();
- output.append(e.getKey());
- output.append(" = \n");
- formatHeader(ShellUtil.getValueString(e.getValue()), null, output, indent);
- output.append("\n");
- }
- if (serviceAttribs.size() > 0) {
- output.append('\n');
- }
-
- Map<String, ClauseFormatter> formatters = new HashMap<String, ClauseFormatter>();
- formatters.put(REQUIRE_BUNDLE_ATTRIB, new ClauseFormatter() {
- public void pre(Clause clause, StringBuilder output) {
- boolean isSatisfied = checkBundle(clause.getName(), clause.getAttribute("bundle-version"));
- Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED).a("");
- }
- public void post(Clause clause, StringBuilder output) {
- Ansi.ansi(output).reset().a("");
- }
- });
- formatters.put(IMPORT_PACKAGES_ATTRIB, new ClauseFormatter() {
- public void pre(Clause clause, StringBuilder output) {
- boolean isSatisfied = checkPackage(clause.getName(), clause.getAttribute("version"));
- boolean isOptional = "optional".equals(clause.getDirective("resolution"));
- Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED)
- .a(isSatisfied || isOptional ? Ansi.Attribute.INTENSITY_BOLD_OFF : Ansi.Attribute.INTENSITY_BOLD)
- .a("");
- }
- public void post(Clause clause, StringBuilder output) {
- Ansi.ansi(output).reset().a("");
- }
- });
-
- it = packagesAttribs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, Object> e = it.next();
- output.append(e.getKey());
- output.append(" = \n");
- formatHeader(ShellUtil.getValueString(e.getValue()), formatters.get(e.getKey()), output, indent);
- output.append("\n");
- }
- if (packagesAttribs.size() > 0) {
- output.append('\n');
- }
-
- return output.toString();
- }
-
- protected interface ClauseFormatter {
- void pre(Clause clause, StringBuilder output);
- void post(Clause clause, StringBuilder output);
- }
-
- protected void formatHeader(String header, ClauseFormatter formatter, StringBuilder builder, int indent) {
- Clause[] clauses = Parser.parseHeader(header);
- formatClauses(clauses, formatter, builder, indent);
- }
-
- protected void formatClauses(Clause[] clauses, ClauseFormatter formatter, StringBuilder builder, int indent) {
- boolean first = true;
- for (Clause clause : clauses) {
- if (first) {
- first = false;
- } else {
- builder.append(",\n");
- }
- formatClause(clause, formatter, builder, indent);
- }
- }
-
- protected void formatClause(Clause clause, ClauseFormatter formatter, StringBuilder builder, int indent) {
- builder.append("\t");
- if (formatter != null) {
- formatter.pre(clause, builder);
- }
- formatClause(clause, builder, indent);
- if (formatter != null) {
- formatter.post(clause, builder);
- }
- }
-
- protected int getTermWidth() {
- return terminal.getWidth();
-
- }
-
- protected void formatClause(Clause clause, StringBuilder builder, int indent) {
- if (indent < 0) {
- if (clause.toString().length() < getTermWidth() - 8) { // -8 for tabs
- indent = 1;
- } else {
- indent = 3;
- }
- }
- String name = clause.getName();
- Directive[] directives = clause.getDirectives();
- Attribute[] attributes = clause.getAttributes();
- Arrays.sort(directives, new Comparator<Directive>() {
- public int compare(Directive o1, Directive o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
- Arrays.sort(attributes, new Comparator<Attribute>() {
- public int compare(Attribute o1, Attribute o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
- builder.append(name);
- for (int i = 0; directives != null && i < directives.length; i++) {
- builder.append(";");
- if (indent > 1) {
- builder.append("\n\t\t");
- }
- builder.append(directives[i].getName()).append(":=");
- String v = directives[i].getValue();
- if (v.contains(",")) {
- if (indent > 2 && v.length() > 20) {
- v = v.replace(",", ",\n\t\t\t");
- }
- builder.append("\"").append(v).append("\"");
- } else {
- builder.append(v);
- }
- }
- for (int i = 0; attributes != null && i < attributes.length; i++) {
- builder.append(";");
- if (indent > 1) {
- builder.append("\n\t\t");
- }
- builder.append(attributes[i].getName()).append("=");
- String v = attributes[i].getValue();
- if (v.contains(",")) {
- if (indent > 2 && v.length() > 20) {
- v = v.replace(",", ",\n\t\t\t");
- }
- builder.append("\"").append(v).append("\"");
- } else {
- builder.append(v);
- }
- }
- }
-
-
- private boolean checkBundle(String bundleName, String version) {
- VersionRange vr = VersionRange.parseVersionRange(version);
- Bundle[] bundles = bundleContext.getBundles();
- for (int i = 0; (bundles != null) && (i < bundles.length); i++) {
- String sym = bundles[i].getSymbolicName();
- if ((sym != null) && sym.equals(bundleName)) {
- if (vr.contains(bundles[i].getVersion())) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean checkPackage(String packageName, String version) {
- VersionRange range = VersionRange.parseVersionRange(version);
- Bundle[] bundles = bundleContext.getBundles();
- for (int i = 0; (bundles != null) && (i < bundles.length); i++) {
- BundleWiring wiring = bundles[i].adapt(BundleWiring.class);
- List<BundleCapability> caps = wiring != null ? wiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE) : null;
- if (caps != null) {
- for (BundleCapability cap : caps) {
- String n = getAttribute(cap, BundleRevision.PACKAGE_NAMESPACE);
- String v = getAttribute(cap, Constants.VERSION_ATTRIBUTE);
- if (packageName.equals(n) && range.contains(VersionTable.getVersion(v))) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private String getAttribute(BundleCapability cap, String name) {
- Object obj = cap.getAttributes().get(name);
- return obj != null ? obj.toString() : null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Info.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Info.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Info.java
deleted file mode 100644
index 451ec87..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Info.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.List;
-
-import org.apache.karaf.bundle.command.wikidoc.AnsiPrintingWikiVisitor;
-import org.apache.karaf.bundle.command.wikidoc.WikiParser;
-import org.apache.karaf.bundle.command.wikidoc.WikiVisitor;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "info", description = "Displays detailed information of a given bundles.")
-@Service
-public class Info extends BundlesCommand {
-
- public Info() {
- super(true);
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- for (Bundle bundle : bundles) {
- printInfo(bundle);
- }
- }
-
- /**
- * <p>
- * Get the OSGI-INF/bundle.info entry from the bundle and display it.
- * </p>
- *
- * @param bundle the bundle.
- */
- protected void printInfo(Bundle bundle) {
- String title = ShellUtil.getBundleName(bundle);
- System.out.println("\n" + title);
- System.out.println(ShellUtil.getUnderlineString(title));
- URL bundleInfo = bundle.getEntry("OSGI-INF/bundle.info");
- if (bundleInfo != null) {
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new InputStreamReader(bundleInfo.openStream()));
- WikiVisitor visitor = new AnsiPrintingWikiVisitor(System.out);
- WikiParser parser = new WikiParser(visitor);
- parser.parse(reader);
- } catch (Exception e) {
- // ignore
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Install.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Install.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Install.java
deleted file mode 100644
index 11fba89..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Install.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.MultiException;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-@Command(scope = "bundle", name = "install", description = "Installs one or more bundles.")
-@Service
-public class Install implements Action {
-
- @Argument(index = 0, name = "urls", description = "Bundle URLs separated by whitespaces", required = true, multiValued = true)
- List<String> urls;
-
- @Option(name = "-s", aliases={"--start"}, description="Starts the bundles after installation", required = false, multiValued = false)
- boolean start;
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- List<Exception> exceptions = new ArrayList<Exception>();
- List<Bundle> bundles = new ArrayList<Bundle>();
- for (String url : urls) {
- try {
- bundles.add(bundleContext.installBundle(url, null));
- } catch (Exception e) {
- exceptions.add(new Exception("Unable to install bundle " + url, e));
- }
- }
- if (start) {
- for (Bundle bundle : bundles) {
- try {
- bundle.start();
- } catch (Exception e) {
- exceptions.add(new Exception("Unable to start bundle " + bundle.getLocation(), e));
- }
- }
- }
- if (bundles.size() == 1) {
- System.out.println("Bundle ID: " + bundles.get(0).getBundleId());
- } else {
- StringBuffer sb = new StringBuffer("Bundle IDs: ");
- for (Bundle bundle : bundles) {
- if (sb.length() > 0) {
- sb.append(", ");
- }
- sb.append(bundle.getBundleId());
- }
- System.out.println(sb);
- }
- MultiException.throwIf("Error installing bundles", exceptions);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
deleted file mode 100644
index 28f8264..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundleServices.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-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.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-@Command(scope = "bundle", name = "services", description = "Lists OSGi services per Bundle")
-@Service
-public class ListBundleServices extends BundlesCommand {
-
- @Option(name = "-a", aliases = {}, description = "Shows all services. (By default Karaf commands are hidden)", required = false, multiValued = false)
- boolean showAll;
-
- @Option(name = "-u", aliases = {}, description = "Shows the services each bundle uses. (By default the provided services are shown)", required = false, multiValued = false)
- boolean inUse;
-
- @Option(name = "-p", aliases = {}, description = "Shows the properties of the services", required = false, multiValued = false)
- boolean showProperties = false;
-
- Set<String> hidden = new HashSet<String>(Arrays.asList(new String[] {
- "org.apache.felix.service.command.Function",
- "org.apache.karaf.shell.console.Completer"
- }));
-
- public ListBundleServices() {
- super(true);
- }
-
- @Override
- protected void doExecute(List<Bundle> bundles) throws Exception {
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] refs = (inUse) ? bundle.getServicesInUse() : bundle.getRegisteredServices();
- printServices(bundle, refs, showProperties);
- }
- }
-
- private void printServices(Bundle bundle, ServiceReference<?>[] refs, boolean showProperties) {
- boolean headerPrinted = false;
- boolean needSeparator = false;
-
- if (refs == null) {
- return;
- }
-
- for (ServiceReference<?> serviceRef : refs) {
- String[] objectClass = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS);
-
- boolean print = showAll || !isCommandOrCompleter(objectClass);
-
- // Print header if we have not already done so.
- if (!headerPrinted) {
- headerPrinted = true;
- System.out.println("");
- String title = ShellUtil.getBundleName(bundle) + ((inUse) ? " uses:" : " provides:");
- System.out.println(title);
- System.out.println(ShellUtil.getUnderlineString(title));
- }
-
- if (print) {
- // Print service separator if necessary.
- if (needSeparator && showProperties) {
- System.out.println("----");
- }
-
- if (showProperties) {
- printProperties(serviceRef);
- } else {
- System.out.println(ShellUtil.getValueString(objectClass));
- }
-
- needSeparator = true;
- }
- }
- }
-
- private boolean isCommandOrCompleter(String[] objectClasses) {
- for (String objectClass : objectClasses) {
- if (hidden.contains(objectClass)) {
- return true;
- }
- }
- return false;
- }
-
- private void printProperties(ServiceReference<?> serviceRef) {
- for (String key : serviceRef.getPropertyKeys()) {
- System.out.println(key + " = " + ShellUtil.getValueString(serviceRef.getProperty(key)));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundles.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
deleted file mode 100644
index 107e578..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ListBundles.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.bundle.core.BundleInfo;
-import org.apache.karaf.bundle.core.BundleService;
-import org.apache.karaf.bundle.core.BundleState;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.startlevel.FrameworkStartLevel;
-
-@Command(scope = "bundle", name = "list", description = "Lists all installed bundles.")
-@Service
-public class ListBundles implements Action {
-
- @Option(name = "-l", aliases = {}, description = "Show the locations", required = false, multiValued = false)
- boolean showLoc;
-
- @Option(name = "-s", description = "Shows the symbolic name", required = false, multiValued = false)
- boolean showSymbolic;
-
- @Option(name = "-u", description = "Shows the update locations", required = false, multiValued = false)
- boolean showUpdate;
-
- @Option(name = "-t", valueToShowInHelp = "", description = "Specifies the bundle threshold; bundles with a start-level less than this value will not get printed out.", required = false, multiValued = false)
- int bundleLevelThreshold = -1;
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- BundleContext bundleContext;
-
- @Reference
- private BundleService bundleService;
-
- public void setBundleService(BundleService bundleService) {
- this.bundleService = bundleService;
- }
-
- @Override
- public Object execute() throws Exception {
- Bundle[] bundles = bundleContext.getBundles();
- if (bundles == null) {
- System.out.println("There are no installed bundles.");
- return null;
- }
-
- determineBundleLevelThreshold();
-
- // Display active start level.
- FrameworkStartLevel fsl = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class);
- if (fsl != null) {
- System.out.println("START LEVEL " + fsl.getStartLevel() + " , List Threshold: " + bundleLevelThreshold);
- }
-
- ShellTable table = new ShellTable();
- table.column("ID").alignRight();
- table.column("State");
- table.column("Lvl").alignRight();
- table.column("Version");
- table.column(getNameHeader());
-
- for (int i = 0; i < bundles.length; i++) {
- Bundle bundle = bundles[i];
- BundleInfo info = this.bundleService.getInfo(bundle);
- if (info.getStartLevel() >= bundleLevelThreshold) {
- String name = getNameToShow(info) + printFragments(info) + printHosts(info);
- String version = info.getVersion();
- table.addRow().addContent(info.getBundleId(), getStateString(info.getState()),
- info.getStartLevel(), version, name);
- }
- }
- table.print(System.out, !noFormat);
-
- return null;
- }
-
- private String getNameHeader() {
- String msg = "Name";
- if (showLoc) {
- msg = "Location";
- } else if (showSymbolic) {
- msg = "Symbolic name";
- } else if (showUpdate) {
- msg = "Update location";
- }
- return msg;
- }
-
- private void determineBundleLevelThreshold() {
- final String sbslProp = bundleContext.getProperty("karaf.systemBundlesStartLevel");
- if (sbslProp != null) {
- try {
- if (bundleLevelThreshold < 0) {
- bundleLevelThreshold = Integer.valueOf(sbslProp);
- }
- } catch (Exception ignore) {
- // ignore
- }
- }
- }
-
- private String printHosts(BundleInfo info) {
- if (info.getFragmentHosts().size() <= 0) {
- return "";
- }
- StringBuilder builder = new StringBuilder();
- builder.append(", Hosts: ");
- boolean first = true;
- for (Bundle host : info.getFragmentHosts()) {
- builder.append((first ? "" : ", ") + host.getBundleId());
- first = false;
- }
- return builder.toString();
- }
-
- private String printFragments(BundleInfo info) {
- if (info.getFragments().size() <= 0) {
- return "";
- }
- StringBuilder builder = new StringBuilder();
- builder.append(", Fragments: ");
- boolean first = true;
- for (Bundle host : info.getFragments()) {
- builder.append((first ? "" : ", ") + host.getBundleId());
- first = false;
- }
- return builder.toString();
- }
-
- private String getStateString(BundleState state) {
- return (state == null) ? "" : state.toString();
- }
-
- /**
- * Overwrite the default value is the user specifically requested to display
- * one or the other.
- *
- * @param info
- * @return
- */
- private String getNameToShow(BundleInfo info) {
- if (showLoc) {
- return info.getUpdateLocation();
- } else if (showSymbolic) {
- return info.getSymbolicName() == null ? "<no symbolic name>" : info.getSymbolicName();
- } else if (showUpdate) {
- return info.getUpdateLocation();
- } else {
- String name = (info.getName() == null) ? info.getSymbolicName() : info.getName();
- return (name == null) ? info.getUpdateLocation() : name;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/LoadTest.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
deleted file mode 100644
index 8ed318f..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/LoadTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.wiring.FrameworkWiring;
-
-@Command(scope = "bundle", name = "load-test", description = "Load test bundle lifecycle")
-@Service
-public class LoadTest implements Action {
-
- @Option(name = "--threads", description = "number of concurrent threads")
- int threads = 2;
-
- @Option(name = "--delay", description = "maximum delay between actions")
- int delay = 1;
-
- @Option(name = "--iterations", description = "number of iterations per thread")
- int iterations = 100;
-
- @Option(name = "--refresh", description = "percentage of bundle refresh vs restart")
- int refresh = 20;
-
- @Option(name = "--excludes", description = "List of bundles (ids or symbolic names) to exclude")
- List<String> excludes = Arrays.asList("0", "org.ops4j.pax.url.mvn", "org.ops4j.pax.logging.pax-logging-api", "org.ops4j.pax.logging.pax-logging-service");
-
- @Reference
- Session session;
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- if (!confirm(session)) {
- return null;
- }
- final BundleContext bundleContext = this.bundleContext.getBundle(0).getBundleContext();
- final FrameworkWiring wiring = bundleContext.getBundle().adapt(FrameworkWiring.class);
- final CountDownLatch latch = new CountDownLatch(threads);
- final Bundle[] bundles = bundleContext.getBundles();
- final AtomicBoolean[] locks = new AtomicBoolean[bundles.length];
- for (int b = 0; b < locks.length; b++) {
- locks[b] = new AtomicBoolean(true);
- // Avoid touching excluded bundles
- if (excludes.contains(Long.toString(bundles[b].getBundleId()))
- || excludes.contains(bundles[b].getSymbolicName())) {
- continue;
- }
- // Only touch active bundles
- if (bundles[b].getState() != Bundle.ACTIVE) {
- continue;
- }
- // Now set the lock to available
- locks[b].set(false);
- }
- for (int i = 0; i < threads; i++) {
- new Thread() {
- public void run() {
- try {
- Random rand = new Random();
- for (int j = 0; j < iterations; j++) {
- for (;;) {
- int b = rand.nextInt(bundles.length);
- if (locks[b].compareAndSet(false, true)) {
- try {
- // Only touch active bundles
- if (bundles[b].getState() != Bundle.ACTIVE) {
- continue;
- }
- if (rand.nextInt(100) < refresh) {
- try {
- bundles[b].update();
- final CountDownLatch latch = new CountDownLatch(1);
- wiring.refreshBundles(Collections.singletonList(bundles[b]), new FrameworkListener() {
- public void frameworkEvent(FrameworkEvent event) {
- latch.countDown();
- }
- });
- latch.await();
- } finally {
- while (true) {
- try {
- bundles[b].start(Bundle.START_TRANSIENT);
- break;
- } catch (Exception e) {
- Thread.sleep(1);
- }
- }
- }
- } else {
- try {
- bundles[b].stop(Bundle.STOP_TRANSIENT);
- } finally {
- while (true) {
- try {
- bundles[b].start(Bundle.START_TRANSIENT);
- break;
- } catch (Exception e) {
- Thread.sleep(1);
- }
- }
- }
- }
- Thread.sleep(rand.nextInt(delay));
- } catch (Exception e) {
- boolean ignore = false;
- if (e instanceof BundleException && e.getMessage() != null) {
- String msg = e.getMessage();
- if ("Cannot acquire global lock to update the bundle.".equals(msg) ||
- "Unable to acquire global lock for resolve.".equals(msg) ||
- msg.matches("Bundle .* cannot be update, since it is either starting or stopping.")) {
- ignore = true;
- }
- }
- if (!ignore) {
- e.printStackTrace();
- }
- } finally {
- locks[b].set(false);
- }
- }
- break;
- }
- }
- } catch (Throwable t) {
- t.printStackTrace();
- } finally {
- latch.countDown();
- }
- }
- }.start();
- }
- new Thread() {
- @Override
- public void run() {
- try {
- latch.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.err.println("Load test finished");
- }
- }.start();
- return null;
- }
-
- private boolean confirm(Session session) throws IOException {
- for (;;) {
- String msg = "You are about to perform a start/stop/refresh load test on bundles.\nDo you wish to continue (yes/no): ";
- String str = session.readLine(msg, null);
- if ("yes".equalsIgnoreCase(str)) {
- return true;
- }
- if ("no".equalsIgnoreCase(str)) {
- return false;
- }
- }
- }
-}
[06/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java b/features/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
new file mode 100644
index 0000000..0d5e83d
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/AggregateRepository.java
@@ -0,0 +1,55 @@
+/*
+ * 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.internal.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.service.repository.Repository;
+
+public class AggregateRepository implements Repository {
+
+ private final Collection<Repository> repositories;
+
+ public AggregateRepository(Collection<Repository> repositories) {
+ this.repositories = repositories;
+ }
+
+ @Override
+ public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
+ for (Requirement requirement : requirements) {
+ List<Capability> caps = new ArrayList<Capability>();
+ for (Repository repository : repositories) {
+ Map<Requirement, Collection<Capability>> resMap =
+ repository.findProviders(Collections.singleton(requirement));
+ Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
+ if (res != null) {
+ caps.addAll(res);
+ }
+ }
+ result.put(requirement, caps);
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java b/features/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
new file mode 100644
index 0000000..c4c0d16
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/BaseRepository.java
@@ -0,0 +1,86 @@
+/*
+ * 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.internal.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.features.internal.resolver.CapabilitySet;
+import org.apache.karaf.features.internal.resolver.RequirementImpl;
+import org.apache.karaf.features.internal.resolver.SimpleFilter;
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.service.repository.Repository;
+
+/**
+ */
+public class BaseRepository implements Repository {
+
+ protected final List<Resource> resources;
+ protected final Map<String, CapabilitySet> capSets;
+
+ public BaseRepository() {
+ this.resources = new ArrayList<Resource>();
+ this.capSets = new HashMap<String, CapabilitySet>();
+ }
+
+ protected void addResource(Resource resource) {
+ for (Capability cap : resource.getCapabilities(null)) {
+ String ns = cap.getNamespace();
+ CapabilitySet set = capSets.get(ns);
+ if (set == null) {
+ set = new CapabilitySet(Collections.singletonList(ns));
+ capSets.put(ns, set);
+ }
+ set.addCapability(cap);
+ }
+ resources.add(resource);
+ }
+
+ public List<Resource> getResources() {
+ return resources;
+ }
+
+ @Override
+ public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
+ for (Requirement requirement : requirements) {
+ CapabilitySet set = capSets.get(requirement.getNamespace());
+ if (set != null) {
+ SimpleFilter sf;
+ if (requirement instanceof RequirementImpl) {
+ sf = ((RequirementImpl) requirement).getFilter();
+ } else {
+ String filter = requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
+ sf = (filter != null)
+ ? SimpleFilter.parse(filter)
+ : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+ }
+ result.put(requirement, set.match(sf, true));
+ } else {
+ result.put(requirement, Collections.<Capability>emptyList());
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java b/features/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.java
new file mode 100644
index 0000000..7916821
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/CacheRepository.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.internal.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.service.repository.Repository;
+
+public class CacheRepository implements Repository {
+
+ private final Repository repository;
+ private final Map<Requirement, Collection<Capability>> cache =
+ new ConcurrentHashMap<Requirement, Collection<Capability>>();
+
+ public CacheRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ List<Requirement> missing = new ArrayList<Requirement>();
+ Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>();
+ for (Requirement requirement : requirements) {
+ Collection<Capability> caps = cache.get(requirement);
+ if (caps == null) {
+ missing.add(requirement);
+ } else {
+ result.put(requirement, caps);
+ }
+ }
+ Map<Requirement, Collection<Capability>> newCache = repository.findProviders(missing);
+ for (Requirement requirement : newCache.keySet()) {
+ cache.put(requirement, newCache.get(requirement));
+ result.put(requirement, newCache.get(requirement));
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java b/features/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
new file mode 100644
index 0000000..1aecef1
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/HttpMetadataProvider.java
@@ -0,0 +1,88 @@
+/*
+ * 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.internal.repository;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.karaf.features.internal.util.JsonReader;
+
+/**
+ */
+public class HttpMetadataProvider implements MetadataProvider {
+
+ public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
+ public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
+ public static final String GZIP = "gzip";
+
+ private final String url;
+ private long lastModified;
+ private Map<String, Map<String, String>> metadatas;
+
+ public HttpMetadataProvider(String url) {
+ this.url = url;
+ }
+
+ @Override
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ @Override
+ public Map<String, Map<String, String>> getMetadatas() {
+ try {
+ HttpURLConnection.setFollowRedirects(false);
+ HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
+ if (lastModified > 0) {
+ con.setIfModifiedSince(lastModified);
+ }
+ con.setRequestProperty(HEADER_ACCEPT_ENCODING, GZIP);
+ if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
+ lastModified = con.getLastModified();
+ InputStream is = con.getInputStream();
+ if (GZIP.equals(con.getHeaderField(HEADER_CONTENT_ENCODING))) {
+ is = new GZIPInputStream(is);
+ }
+ metadatas = verify(JsonReader.read(is));
+ } else if (con.getResponseCode() != HttpURLConnection.HTTP_NOT_MODIFIED) {
+ throw new IOException("Unexpected http response: "
+ + con.getResponseCode() + " " + con.getResponseMessage());
+ }
+ return metadatas;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Map<String, Map<String, String>> verify(Object value) {
+ Map<?,?> obj = Map.class.cast(value);
+ for (Map.Entry<?,?> entry : obj.entrySet()) {
+ String.class.cast(entry.getKey());
+ Map<?,?> child = Map.class.cast(entry.getValue());
+ for (Map.Entry<?,?> ce : child.entrySet()) {
+ String.class.cast(ce.getKey());
+ String.class.cast(ce.getValue());
+ }
+ }
+ return (Map<String, Map<String, String>>) obj;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java b/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
new file mode 100644
index 0000000..9ac54a1
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataProvider.java
@@ -0,0 +1,29 @@
+/*
+ * 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.internal.repository;
+
+import java.util.Map;
+
+/**
+ */
+public interface MetadataProvider {
+
+ long getLastModified();
+
+ Map<String, Map<String, String>> getMetadatas();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java b/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
new file mode 100644
index 0000000..2d4fbba
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/MetadataRepository.java
@@ -0,0 +1,43 @@
+/*
+ * 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.internal.repository;
+
+import java.util.Map;
+
+import org.apache.karaf.features.internal.resolver.ResourceBuilder;
+import org.osgi.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ */
+public class MetadataRepository extends BaseRepository {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetadataRepository.class);
+
+ public MetadataRepository(MetadataProvider provider) {
+ Map<String, Map<String, String>> metadatas = provider.getMetadatas();
+ for (Map.Entry<String, Map<String, String>> metadata : metadatas.entrySet()) {
+ try {
+ Resource resource = ResourceBuilder.build(metadata.getKey(), metadata.getValue());
+ addResource(resource);
+ } catch (Exception e) {
+ LOGGER.info("Unable to build resource for " + metadata.getKey(), e);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java b/features/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.java
new file mode 100644
index 0000000..f289c8d
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/repository/StaticRepository.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.internal.repository;
+
+import java.util.Collection;
+
+import org.osgi.resource.Resource;
+
+/**
+ */
+public class StaticRepository extends BaseRepository {
+
+ public StaticRepository(Collection<Resource> resources) {
+ for (Resource resource : resources) {
+ addResource(resource);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
new file mode 100644
index 0000000..0653398
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/BaseClause.java
@@ -0,0 +1,114 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.Map;
+
+import org.osgi.framework.Version;
+import org.osgi.resource.Resource;
+
+/**
+ */
+public abstract class BaseClause {
+
+ public abstract Resource getResource();
+
+ public abstract String getNamespace();
+
+ public abstract Map<String, String> getDirectives();
+
+ public abstract Map<String, Object> getAttributes();
+
+ @Override
+ public String toString() {
+ return toString(getResource(), getNamespace(), getAttributes(), getDirectives());
+ }
+
+ public static String toString(Resource res, String namespace, Map<String, Object> attrs, Map<String, String> dirs) {
+ StringBuilder sb = new StringBuilder();
+ if (res != null) {
+ sb.append("[").append(res).append("] ");
+ }
+ sb.append(namespace);
+ for (String key : attrs.keySet()) {
+ sb.append("; ");
+ append(sb, key, attrs.get(key), true);
+ }
+ for (String key : dirs.keySet()) {
+ sb.append("; ");
+ append(sb, key, dirs.get(key), false);
+ }
+ return sb.toString();
+ }
+
+ private static void append(StringBuilder sb, String key, Object val, boolean attribute) {
+ sb.append(key);
+ if (val instanceof Version) {
+ sb.append(":Version=");
+ sb.append(val);
+ } else if (val instanceof Long) {
+ sb.append(":Long=");
+ sb.append(val);
+ } else if (val instanceof Double) {
+ sb.append(":Double=");
+ sb.append(val);
+ } else if (val instanceof Iterable) {
+ Iterable it = (Iterable) val;
+ String scalar = null;
+ for (Object o : it) {
+ String ts;
+ if (o instanceof String) {
+ ts = "String";
+ } else if (o instanceof Long) {
+ ts = "Long";
+ } else if (o instanceof Double) {
+ ts = "Double";
+ } else if (o instanceof Version) {
+ ts = "Version";
+ } else {
+ throw new IllegalArgumentException("Unsupported scalar type: " + o);
+ }
+ if (scalar == null) {
+ scalar = ts;
+ } else if (!scalar.equals(ts)) {
+ throw new IllegalArgumentException("Unconsistent list type for attribute " + key);
+ }
+ }
+ sb.append(":List<").append(scalar).append(">=");
+ sb.append("\"");
+ boolean first = true;
+ for (Object o : it) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(",");
+ }
+ sb.append(o.toString().replace("\"", "\\\"").replace(",", "\\,"));
+ }
+ sb.append("\"");
+ } else {
+ sb.append(attribute ? "=" : ":=");
+ String s = val.toString();
+ if (s.matches("[0-9a-zA-Z_\\-.]*")) {
+ sb.append(s);
+ } else {
+ sb.append("\"").append(s.replace("\"", "\\\\")).append("\"");
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
new file mode 100644
index 0000000..ad4cc85
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/CandidateComparator.java
@@ -0,0 +1,129 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.Comparator;
+
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.resource.Capability;
+
+public class CandidateComparator implements Comparator<Capability>
+{
+ public int compare(Capability cap1, Capability cap2)
+ {
+ int c = 0;
+ // Always prefer system bundle
+ if (cap1 instanceof BundleCapability && !(cap2 instanceof BundleCapability)) {
+ c = -1;
+ } else if (!(cap1 instanceof BundleCapability) && cap2 instanceof BundleCapability) {
+ c = 1;
+ }
+ // Compare revision capabilities.
+ if ((c == 0) && cap1.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE))
+ {
+ c = ((Comparable) cap1.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE))
+ .compareTo(cap2.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE));
+ if (c == 0)
+ {
+ Version v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ Version v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ // Compare these in reverse order, since we want
+ // highest version to have priority.
+ c = compareVersions(v2, v1);
+ }
+ }
+ // Compare package capabilities.
+ else if ((c == 0) && cap1.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+ {
+ c = ((Comparable) cap1.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))
+ .compareTo(cap2.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
+ if (c == 0)
+ {
+ Version v1 = (!cap1.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap1.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ Version v2 = (!cap2.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap2.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ // Compare these in reverse order, since we want
+ // highest version to have priority.
+ c = compareVersions(v2, v1);
+ // if same version, rather compare on the bundle version
+ if (c == 0)
+ {
+ v1 = (!cap1.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap1.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ v2 = (!cap2.getAttributes().containsKey(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap2.getAttributes().get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ // Compare these in reverse order, since we want
+ // highest version to have priority.
+ c = compareVersions(v2, v1);
+ }
+ }
+ }
+ // Compare feature capabilities
+ else if ((c == 0) && cap1.getNamespace().equals(FeatureNamespace.FEATURE_NAMESPACE))
+ {
+ c = ((Comparable) cap1.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE))
+ .compareTo(cap2.getAttributes().get(FeatureNamespace.FEATURE_NAMESPACE));
+ if (c == 0)
+ {
+ Version v1 = (!cap1.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap1.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ Version v2 = (!cap2.getAttributes().containsKey(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE))
+ ? Version.emptyVersion
+ : (Version) cap2.getAttributes().get(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ // Compare these in reverse order, since we want
+ // highest version to have priority.
+ c = compareVersions(v2, v1);
+ }
+ }
+ return c;
+ }
+
+ private int compareVersions(Version v1, Version v2) {
+ int c = v1.getMajor() - v2.getMajor();
+ if (c != 0) {
+ return c;
+ }
+ c = v1.getMinor() - v2.getMinor();
+ if (c != 0) {
+ return c;
+ }
+ c = v1.getMicro() - v2.getMicro();
+ if (c != 0) {
+ return c;
+ }
+ String q1 = cleanQualifierForComparison(v1.getQualifier());
+ String q2 = cleanQualifierForComparison(v2.getQualifier());
+ return q1.compareTo(q2);
+ }
+
+ private String cleanQualifierForComparison(String qualifier) {
+ return qualifier.replaceAll("(redhat-[0-9]{3})([0-9]{3})", "$1-$2");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
new file mode 100644
index 0000000..bfe9b40
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilityImpl.java
@@ -0,0 +1,165 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+public class CapabilityImpl extends BaseClause implements Capability {
+
+ private final Resource m_resource;
+ private final String m_namespace;
+ private final Map<String, String> m_dirs;
+ private final Map<String, Object> m_attrs;
+ private final List<String> m_uses;
+ private final List<List<String>> m_includeFilter;
+ private final List<List<String>> m_excludeFilter;
+ private final Set<String> m_mandatory;
+
+ public CapabilityImpl(Capability capability) {
+ this(null, capability.getNamespace(), capability.getDirectives(), capability.getAttributes());
+ }
+
+ public CapabilityImpl(Resource resource, String namespace,
+ Map<String, String> dirs, Map<String, Object> attrs) {
+ m_namespace = namespace;
+ m_resource = resource;
+ m_dirs = dirs;
+ m_attrs = attrs;
+
+ // Find all export directives: uses, mandatory, include, and exclude.
+
+ List<String> uses = Collections.emptyList();
+ String value = m_dirs.get(Constants.USES_DIRECTIVE);
+ if (value != null) {
+ // Parse these uses directive.
+ StringTokenizer tok = new StringTokenizer(value, ",");
+ uses = new ArrayList<String>(tok.countTokens());
+ while (tok.hasMoreTokens()) {
+ uses.add(tok.nextToken().trim());
+ }
+ }
+ m_uses = uses;
+
+ value = m_dirs.get(Constants.INCLUDE_DIRECTIVE);
+ if (value != null) {
+ List<String> filters = ResourceBuilder.parseDelimitedString(value, ",");
+ m_includeFilter = new ArrayList<List<String>>(filters.size());
+ for (String filter : filters) {
+ List<String> substrings = SimpleFilter.parseSubstring(filter);
+ m_includeFilter.add(substrings);
+ }
+ } else {
+ m_includeFilter = null;
+ }
+
+ value = m_dirs.get(Constants.EXCLUDE_DIRECTIVE);
+ if (value != null) {
+ List<String> filters = ResourceBuilder.parseDelimitedString(value, ",");
+ m_excludeFilter = new ArrayList<List<String>>(filters.size());
+ for (String filter : filters) {
+ List<String> substrings = SimpleFilter.parseSubstring(filter);
+ m_excludeFilter.add(substrings);
+ }
+ } else {
+ m_excludeFilter = null;
+ }
+
+ Set<String> mandatory = Collections.emptySet();
+ value = m_dirs.get(Constants.MANDATORY_DIRECTIVE);
+ if (value != null) {
+ List<String> names = ResourceBuilder.parseDelimitedString(value, ",");
+ mandatory = new HashSet<String>(names.size());
+ for (String name : names) {
+ // If attribute exists, then record it as mandatory.
+ if (m_attrs.containsKey(name)) {
+ mandatory.add(name);
+ }
+ // Otherwise, report an error.
+ else {
+ throw new IllegalArgumentException("Mandatory attribute '" + name + "' does not exist.");
+ }
+ }
+ }
+ m_mandatory = mandatory;
+ }
+
+ public Resource getResource() {
+ return m_resource;
+ }
+
+ public String getNamespace() {
+ return m_namespace;
+ }
+
+ public Map<String, String> getDirectives() {
+ return m_dirs;
+ }
+
+ public Map<String, Object> getAttributes() {
+ return m_attrs;
+ }
+
+ public boolean isAttributeMandatory(String name) {
+ return !m_mandatory.isEmpty() && m_mandatory.contains(name);
+ }
+
+ public List<String> getUses() {
+ return m_uses;
+ }
+
+ public boolean isIncluded(String name) {
+ if ((m_includeFilter == null) && (m_excludeFilter == null)) {
+ return true;
+ }
+
+ // Get the class name portion of the target class.
+ String className = getClassName(name);
+
+ // If there are no include filters then all classes are included
+ // by default, otherwise try to find one match.
+ boolean included = (m_includeFilter == null);
+ for (int i = 0; !included && m_includeFilter != null && i < m_includeFilter.size(); i++) {
+ included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
+ }
+
+ // If there are no exclude filters then no classes are excluded
+ // by default, otherwise try to find one match.
+ boolean excluded = false;
+ for (int i = 0; (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size()); i++) {
+ excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
+ }
+ return included && !excluded;
+ }
+
+ private static String getClassName(String className) {
+ if (className == null) {
+ className = "";
+ }
+ return (className.lastIndexOf('.') < 0) ? "" : className.substring(className.lastIndexOf('.') + 1);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
new file mode 100644
index 0000000..4c5656d
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/CapabilitySet.java
@@ -0,0 +1,612 @@
+/*
+ * 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.internal.resolver;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+
+public class CapabilitySet
+{
+ private final Map<String, Map<Object, Set<Capability>>> m_indices;
+ private final Set<Capability> m_capSet = new HashSet<Capability>();
+
+public void dump()
+{
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+ {
+ boolean header1 = false;
+ for (Entry<Object, Set<Capability>> entry2 : entry.getValue().entrySet())
+ {
+ boolean header2 = false;
+ for (Capability cap : entry2.getValue())
+ {
+ if (!header1)
+ {
+ System.out.println(entry.getKey() + ":");
+ header1 = true;
+ }
+ if (!header2)
+ {
+ System.out.println(" " + entry2.getKey());
+ header2 = true;
+ }
+ System.out.println(" " + cap);
+ }
+ }
+ }
+}
+
+ public CapabilitySet(List<String> indexProps)
+ {
+ m_indices = new TreeMap<String, Map<Object, Set<Capability>>>();
+ for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
+ {
+ m_indices.put(
+ indexProps.get(i), new HashMap<Object, Set<Capability>>());
+ }
+ }
+
+ public void addCapability(Capability cap)
+ {
+ m_capSet.add(cap);
+
+ // Index capability.
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+ {
+ Object value = cap.getAttributes().get(entry.getKey());
+ if (value != null)
+ {
+ if (value.getClass().isArray())
+ {
+ value = convertArrayToList(value);
+ }
+
+ Map<Object, Set<Capability>> index = entry.getValue();
+
+ if (value instanceof Collection)
+ {
+ Collection c = (Collection) value;
+ for (Object o : c)
+ {
+ indexCapability(index, cap, o);
+ }
+ }
+ else
+ {
+ indexCapability(index, cap, value);
+ }
+ }
+ }
+ }
+
+ private void indexCapability(
+ Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+ {
+ Set<Capability> caps = index.get(capValue);
+ if (caps == null)
+ {
+ caps = new HashSet<Capability>();
+ index.put(capValue, caps);
+ }
+ caps.add(cap);
+ }
+
+ public void removeCapability(Capability cap)
+ {
+ if (m_capSet.remove(cap))
+ {
+ for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+ {
+ Object value = cap.getAttributes().get(entry.getKey());
+ if (value != null)
+ {
+ if (value.getClass().isArray())
+ {
+ value = convertArrayToList(value);
+ }
+
+ Map<Object, Set<Capability>> index = entry.getValue();
+
+ if (value instanceof Collection)
+ {
+ Collection c = (Collection) value;
+ for (Object o : c)
+ {
+ deindexCapability(index, cap, o);
+ }
+ }
+ else
+ {
+ deindexCapability(index, cap, value);
+ }
+ }
+ }
+ }
+ }
+
+ private void deindexCapability(
+ Map<Object, Set<Capability>> index, Capability cap, Object value)
+ {
+ Set<Capability> caps = index.get(value);
+ if (caps != null)
+ {
+ caps.remove(cap);
+ if (caps.isEmpty())
+ {
+ index.remove(value);
+ }
+ }
+ }
+
+ public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
+ {
+ Set<Capability> matches = match(m_capSet, sf);
+ return (obeyMandatory)
+ ? matchMandatory(matches, sf)
+ : matches;
+ }
+
+ private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
+ {
+ Set<Capability> matches = new HashSet<Capability>();
+
+ if (sf.getOperation() == SimpleFilter.MATCH_ALL)
+ {
+ matches.addAll(caps);
+ }
+ else if (sf.getOperation() == SimpleFilter.AND)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For AND we calculate the intersection of each subfilter.
+ // We can short-circuit the AND operation if there are no
+ // remaining capabilities.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
+ {
+ matches = match(caps, sfs.get(i));
+ caps = matches;
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.OR)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matches.addAll(match(caps, sfs.get(i)));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.NOT)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ matches.addAll(caps);
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matches.removeAll(match(caps, sfs.get(i)));
+ }
+ }
+ else
+ {
+ Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
+ if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
+ {
+ Set<Capability> existingCaps = index.get(sf.getValue());
+ if (existingCaps != null)
+ {
+ matches.addAll(existingCaps);
+ matches.retainAll(caps);
+ }
+ }
+ else
+ {
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+ {
+ Capability cap = it.next();
+ Object lhs = cap.getAttributes().get(sf.getName());
+ if (lhs != null)
+ {
+ if (compare(lhs, sf.getValue(), sf.getOperation()))
+ {
+ matches.add(cap);
+ }
+ }
+ }
+ }
+ }
+
+ return matches;
+ }
+
+ public static boolean matches(Capability cap, SimpleFilter sf)
+ {
+ return matchesInternal(cap, sf) && matchMandatory(cap, sf);
+ }
+
+ private static boolean matchesInternal(Capability cap, SimpleFilter sf)
+ {
+ boolean matched = true;
+
+ if (sf.getOperation() == SimpleFilter.MATCH_ALL)
+ {
+ matched = true;
+ }
+ else if (sf.getOperation() == SimpleFilter.AND)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For AND we calculate the intersection of each subfilter.
+ // We can short-circuit the AND operation if there are no
+ // remaining capabilities.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; matched && (i < sfs.size()); i++)
+ {
+ matched = matchesInternal(cap, sfs.get(i));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.OR)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ matched = false;
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; !matched && (i < sfs.size()); i++)
+ {
+ matched = matchesInternal(cap, sfs.get(i));
+ }
+ }
+ else if (sf.getOperation() == SimpleFilter.NOT)
+ {
+ // Evaluate each subfilter against the remaining capabilities.
+ // For OR we calculate the union of each subfilter.
+ List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+ for (int i = 0; i < sfs.size(); i++)
+ {
+ matched = !(matchesInternal(cap, sfs.get(i)));
+ }
+ }
+ else
+ {
+ matched = false;
+ Object lhs = cap.getAttributes().get(sf.getName());
+ if (lhs != null)
+ {
+ matched = compare(lhs, sf.getValue(), sf.getOperation());
+ }
+ }
+
+ return matched;
+ }
+
+ private static Set<Capability> matchMandatory(
+ Set<Capability> caps, SimpleFilter sf)
+ {
+ for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+ {
+ Capability cap = it.next();
+ if (!matchMandatory(cap, sf))
+ {
+ it.remove();
+ }
+ }
+ return caps;
+ }
+
+ private static boolean matchMandatory(Capability cap, SimpleFilter sf)
+ {
+ if (cap instanceof CapabilityImpl) {
+ for (Entry<String, Object> entry : cap.getAttributes().entrySet())
+ {
+ if (((CapabilityImpl) cap).isAttributeMandatory(entry.getKey())
+ && !matchMandatoryAttribute(entry.getKey(), sf))
+ {
+ return false;
+ }
+ }
+ } else {
+ String value = cap.getDirectives().get(Constants.MANDATORY_DIRECTIVE);
+ if (value != null) {
+ List<String> names = ResourceBuilder.parseDelimitedString(value, ",");
+ for (Entry<String, Object> entry : cap.getAttributes().entrySet())
+ {
+ if (names.contains(entry.getKey())
+ && !matchMandatoryAttribute(entry.getKey(), sf))
+ {
+ return false;
+ }
+ }
+ }
+
+ }
+ return true;
+ }
+
+ private static boolean matchMandatoryAttribute(String attrName, SimpleFilter sf)
+ {
+ if ((sf.getName() != null) && sf.getName().equals(attrName))
+ {
+ return true;
+ }
+ else if (sf.getOperation() == SimpleFilter.AND)
+ {
+ List list = (List) sf.getValue();
+ for (int i = 0; i < list.size(); i++)
+ {
+ SimpleFilter sf2 = (SimpleFilter) list.get(i);
+ if ((sf2.getName() != null)
+ && sf2.getName().equals(attrName))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static final Class<?>[] STRING_CLASS = new Class[] { String.class };
+
+ private static boolean compare(Object lhs, Object rhsUnknown, int op)
+ {
+ if (lhs == null)
+ {
+ return false;
+ }
+
+ // If this is a PRESENT operation, then just return true immediately
+ // since we wouldn't be here if the attribute wasn't present.
+ if (op == SimpleFilter.PRESENT)
+ {
+ return true;
+ }
+
+ // If the type is comparable, then we can just return the
+ // result immediately.
+ if (lhs instanceof Comparable)
+ {
+ // Spec says SUBSTRING is false for all types other than string.
+ if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+ {
+ return false;
+ }
+
+ Object rhs;
+ if (op == SimpleFilter.SUBSTRING)
+ {
+ rhs = rhsUnknown;
+ }
+ else
+ {
+ try
+ {
+ rhs = coerceType(lhs, (String) rhsUnknown);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ switch (op)
+ {
+ case SimpleFilter.EQ :
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) == 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ case SimpleFilter.GTE :
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) >= 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ case SimpleFilter.LTE :
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) <= 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ case SimpleFilter.APPROX :
+ return compareApproximate(((Comparable) lhs), rhs);
+ case SimpleFilter.SUBSTRING :
+ return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
+ default:
+ throw new RuntimeException(
+ "Unknown comparison operator: " + op);
+ }
+ }
+ // Booleans do not implement comparable, so special case them.
+ else if (lhs instanceof Boolean)
+ {
+ Object rhs;
+ try
+ {
+ rhs = coerceType(lhs, (String) rhsUnknown);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+
+ switch (op)
+ {
+ case SimpleFilter.EQ :
+ case SimpleFilter.GTE :
+ case SimpleFilter.LTE :
+ case SimpleFilter.APPROX :
+ return (lhs.equals(rhs));
+ default:
+ throw new RuntimeException(
+ "Unknown comparison operator: " + op);
+ }
+ }
+
+ // If the LHS is not a comparable or boolean, check if it is an
+ // array. If so, convert it to a list so we can treat it as a
+ // collection.
+ if (lhs.getClass().isArray())
+ {
+ lhs = convertArrayToList(lhs);
+ }
+
+ // If LHS is a collection, then call compare() on each element
+ // of the collection until a match is found.
+ if (lhs instanceof Collection)
+ {
+ for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); )
+ {
+ if (compare(iter.next(), rhsUnknown, op))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // Spec says SUBSTRING is false for all types other than string.
+ if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+ {
+ return false;
+ }
+
+ // Since we cannot identify the LHS type, then we can only perform
+ // equality comparison.
+ try
+ {
+ return lhs.equals(coerceType(lhs, (String) rhsUnknown));
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ private static boolean compareApproximate(Object lhs, Object rhs)
+ {
+ if (rhs instanceof String)
+ {
+ return removeWhitespace((String) lhs)
+ .equalsIgnoreCase(removeWhitespace((String) rhs));
+ }
+ else if (rhs instanceof Character)
+ {
+ return Character.toLowerCase(((Character) lhs))
+ == Character.toLowerCase(((Character) rhs));
+ }
+ return lhs.equals(rhs);
+ }
+
+ private static String removeWhitespace(String s)
+ {
+ StringBuffer sb = new StringBuffer(s.length());
+ for (int i = 0; i < s.length(); i++)
+ {
+ if (!Character.isWhitespace(s.charAt(i)))
+ {
+ sb.append(s.charAt(i));
+ }
+ }
+ return sb.toString();
+ }
+
+ private static Object coerceType(Object lhs, String rhsString) throws Exception
+ {
+ // If the LHS expects a string, then we can just return
+ // the RHS since it is a string.
+ if (lhs.getClass() == rhsString.getClass())
+ {
+ return rhsString;
+ }
+
+ // Try to convert the RHS type to the LHS type by using
+ // the string constructor of the LHS class, if it has one.
+ Object rhs = null;
+ try
+ {
+ // The Character class is a special case, since its constructor
+ // does not take a string, so handle it separately.
+ if (lhs instanceof Character)
+ {
+ rhs = new Character(rhsString.charAt(0));
+ }
+ else
+ {
+ // Spec says we should trim number types.
+ if ((lhs instanceof Number) || (lhs instanceof Boolean))
+ {
+ rhsString = rhsString.trim();
+ }
+ Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
+ ctor.setAccessible(true);
+ rhs = ctor.newInstance(new Object[] { rhsString });
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(
+ "Could not instantiate class "
+ + lhs.getClass().getName()
+ + " from string constructor with argument '"
+ + rhsString + "' because " + ex);
+ }
+
+ return rhs;
+ }
+
+ /**
+ * This is an ugly utility method to convert an array of primitives
+ * to an array of primitive wrapper objects. This method simplifies
+ * processing LDAP filters since the special case of primitive arrays
+ * can be ignored.
+ * @param array An array of primitive types.
+ * @return An corresponding array using pritive wrapper objects.
+ **/
+ private static List convertArrayToList(Object array)
+ {
+ int len = Array.getLength(array);
+ List list = new ArrayList(len);
+ for (int i = 0; i < len; i++)
+ {
+ list.add(Array.get(array, i));
+ }
+ return list;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
new file mode 100644
index 0000000..e211618
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureNamespace.java
@@ -0,0 +1,72 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.List;
+
+import org.osgi.framework.Version;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Resource;
+
+/**
+ */
+public final class FeatureNamespace extends Namespace {
+
+ public static final String FEATURE_NAMESPACE = "karaf.feature";
+
+ public static final String CAPABILITY_VERSION_ATTRIBUTE = "version";
+
+ /**
+ * The attribute value identifying the resource
+ * {@link org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi bundle.
+ *
+ * @see org.osgi.framework.namespace.IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ */
+ public static final String TYPE_FEATURE = "karaf.feature";
+
+ public static String getName(Resource resource)
+ {
+ List<Capability> caps = resource.getCapabilities(null);
+ for (Capability cap : caps)
+ {
+ if (cap.getNamespace().equals(FEATURE_NAMESPACE))
+ {
+ return cap.getAttributes().get(FEATURE_NAMESPACE).toString();
+ }
+ }
+ return null;
+ }
+
+ public static Version getVersion(Resource resource)
+ {
+ List<Capability> caps = resource.getCapabilities(null);
+ for (Capability cap : caps)
+ {
+ if (cap.getNamespace().equals(FEATURE_NAMESPACE))
+ {
+ return (Version)
+ cap.getAttributes().get(CAPABILITY_VERSION_ATTRIBUTE);
+ }
+ }
+ return null;
+ }
+
+
+ private FeatureNamespace() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
new file mode 100644
index 0000000..88f08ae
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/FeatureResource.java
@@ -0,0 +1,121 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.Conditional;
+import org.apache.karaf.features.Dependency;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.internal.util.Macro;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+/**
+*/
+public class FeatureResource extends ResourceImpl {
+
+ private final Feature feature;
+
+ public static Resource build(Feature feature, Conditional conditional, String featureRange, Map<String, Resource> locToRes) throws BundleException {
+ Feature fcond = conditional.asFeature(feature.getName(), feature.getVersion());
+ FeatureResource resource = (FeatureResource) build(fcond, featureRange, locToRes);
+ for (Dependency dep : conditional.getCondition()) {
+ addDependency(resource, dep, featureRange);
+ }
+ org.apache.karaf.features.internal.model.Dependency dep = new org.apache.karaf.features.internal.model.Dependency();
+ dep.setName(feature.getName());
+ dep.setVersion(feature.getVersion());
+ addDependency(resource, dep, featureRange);
+ return resource;
+ }
+
+ public static Resource build(Feature feature, String featureRange, Map<String, Resource> locToRes) throws BundleException {
+ FeatureResource resource = new FeatureResource(feature);
+ Map<String, String> dirs = new HashMap<String, String>();
+ Map<String, Object> attrs = new HashMap<String, Object>();
+ attrs.put(FeatureNamespace.FEATURE_NAMESPACE, feature.getName());
+ attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, VersionTable.getVersion(feature.getVersion()));
+ resource.addCapability(new CapabilityImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
+ for (BundleInfo info : feature.getBundles()) {
+ if (!info.isDependency()) {
+ Resource res = locToRes.get(info.getLocation());
+ if (res == null) {
+ throw new IllegalStateException("Resource not found for url " + info.getLocation());
+ }
+ List<Capability> caps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (caps.size() != 1) {
+ throw new IllegalStateException("Resource does not have a single " + IdentityNamespace.IDENTITY_NAMESPACE + " capability");
+ }
+ dirs = new HashMap<String, String>();
+ attrs = new HashMap<String, Object>();
+ attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, caps.get(0).getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
+ attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+ attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange((Version) caps.get(0).getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE), true));
+ resource.addRequirement(new RequirementImpl(resource, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs));
+ }
+ }
+ for (Dependency dep : feature.getDependencies()) {
+ addDependency(resource, dep, featureRange);
+ }
+ for (org.apache.karaf.features.Capability cap : feature.getCapabilities()) {
+ resource.addCapabilities(ResourceBuilder.parseCapability(resource, cap.getValue()));
+ }
+ for (org.apache.karaf.features.Requirement req : feature.getRequirements()) {
+ resource.addRequirements(ResourceBuilder.parseRequirement(resource, req.getValue()));
+ }
+ return resource;
+ }
+
+ protected static void addDependency(FeatureResource resource, Dependency dep, String featureRange) {
+ Map<String, String> dirs;
+ Map<String, Object> attrs;
+ String name = dep.getName();
+ String version = dep.getVersion();
+ if (version.equals("0.0.0")) {
+ version = null;
+ } else if (!version.startsWith("[") && !version.startsWith("(")) {
+ version = Macro.transform(featureRange, version);
+ }
+ dirs = new HashMap<String, String>();
+ attrs = new HashMap<String, Object>();
+ attrs.put(FeatureNamespace.FEATURE_NAMESPACE, name);
+ if (version != null) {
+ attrs.put(FeatureNamespace.CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(version));
+ }
+ resource.addRequirement(new RequirementImpl(resource, FeatureNamespace.FEATURE_NAMESPACE, dirs, attrs));
+ }
+
+ public FeatureResource(Feature feature) {
+ super(feature.getName(), FeatureNamespace.TYPE_FEATURE, VersionTable.getVersion(feature.getVersion()));
+ this.feature = feature;
+ }
+
+ public Feature getFeature() {
+ return feature;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
new file mode 100644
index 0000000..cdc00d1
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/IdentityCapability.java
@@ -0,0 +1,63 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+class IdentityCapability extends BaseClause implements Capability
+{
+ private final Resource m_resource;
+ private final Map<String, String> m_dirs;
+ private final Map<String, Object> m_attrs;
+
+ public IdentityCapability(Resource resource, String name, String type, Version version)
+ {
+ m_resource = resource;
+ m_dirs = new HashMap<String, String>();
+ m_attrs = new HashMap<String, Object>();
+ m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
+ m_attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type);
+ m_attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version);
+ }
+
+ public String getNamespace()
+ {
+ return IdentityNamespace.IDENTITY_NAMESPACE;
+ }
+
+ public Map<String, String> getDirectives()
+ {
+ return m_dirs;
+ }
+
+ public Map<String, Object> getAttributes()
+ {
+ return m_attrs;
+ }
+
+ public Resource getResource()
+ {
+ return m_resource;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
new file mode 100644
index 0000000..a4ef775
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/RequirementImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.Map;
+
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class RequirementImpl extends BaseClause implements Requirement {
+ private final Resource m_resource;
+ private final String m_namespace;
+ private final SimpleFilter m_filter;
+ private final boolean m_optional;
+ private final Map<String, String> m_dirs;
+ private final Map<String, Object> m_attrs;
+
+ public RequirementImpl(
+ Resource resource, String namespace,
+ Map<String, String> dirs, Map<String, Object> attrs, SimpleFilter filter) {
+ m_resource = resource;
+ m_namespace = namespace;
+ m_dirs = dirs;
+ m_attrs = attrs;
+ m_filter = filter;
+ // Find resolution import directives.
+ m_optional = Constants.RESOLUTION_OPTIONAL.equals(m_dirs.get(Constants.RESOLUTION_DIRECTIVE));
+ }
+
+ public RequirementImpl(
+ Resource resource, String namespace,
+ Map<String, String> dirs, Map<String, Object> attrs) {
+ this(resource, namespace, dirs, attrs, SimpleFilter.convert(attrs));
+ }
+
+ public String getNamespace() {
+ return m_namespace;
+ }
+
+ public Map<String, String> getDirectives() {
+ return m_dirs;
+ }
+
+ public Map<String, Object> getAttributes() {
+ return m_attrs;
+ }
+
+ public Resource getResource() {
+ return m_resource;
+ }
+
+ public boolean matches(Capability cap) {
+ return CapabilitySet.matches(cap, getFilter());
+ }
+
+ public boolean isOptional() {
+ return m_optional;
+ }
+
+ public SimpleFilter getFilter() {
+ return m_filter;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
new file mode 100644
index 0000000..e2ff793
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResolveContextImpl.java
@@ -0,0 +1,102 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wiring;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolveContext;
+
+/**
+*/
+public class ResolveContextImpl extends ResolveContext {
+
+ private final Set<Resource> mandatory;
+ private final Set<Resource> optional;
+ private final Repository repository;
+ private final Map<Resource, Wiring> wirings;
+ private final boolean resolveOptional;
+
+ private final CandidateComparator candidateComparator = new CandidateComparator();
+
+ public ResolveContextImpl(Set<Resource> mandatory,
+ Set<Resource> optional,
+ Repository repository,
+ boolean resolveOptional) {
+ this.mandatory = mandatory;
+ this.optional = optional;
+ this.repository = repository;
+ this.wirings = new HashMap<Resource, Wiring>();
+ this.resolveOptional = resolveOptional;
+ }
+
+ @Override
+ public Collection<Resource> getMandatoryResources() {
+ return mandatory;
+ }
+
+ @Override
+ public Collection<Resource> getOptionalResources() {
+ return optional;
+ }
+
+ @Override
+ public List<Capability> findProviders(Requirement requirement) {
+ List<Capability> caps = new ArrayList<Capability>();
+ Map<Requirement, Collection<Capability>> resMap =
+ repository.findProviders(Collections.singleton(requirement));
+ Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
+ if (res != null) {
+ caps.addAll(res);
+ }
+ Collections.sort(caps, candidateComparator);
+ return caps;
+ }
+ @Override
+ public int insertHostedCapability(List capabilities, HostedCapability hostedCapability) {
+ for (int i=0; i < capabilities.size(); i++) {
+ Capability cap = (Capability) capabilities.get(i);
+ if (candidateComparator.compare(hostedCapability, cap) <= 0) {
+ capabilities.add(i, hostedCapability);
+ return i;
+ }
+ }
+ capabilities.add(hostedCapability);
+ return capabilities.size() - 1;
+ }
+ @Override
+ public boolean isEffective(Requirement requirement) {
+ return resolveOptional ||
+ !Constants.RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(Constants.RESOLUTION_DIRECTIVE));
+ }
+ @Override
+ public Map<Resource, Wiring> getWirings() {
+ return wirings;
+ }
+}
[42/59] [abbrv] git commit: [KARAF-2852] Merge system/core and
system/command
Posted by gn...@apache.org.
[KARAF-2852] Merge system/core and system/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/0a100d76
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/0a100d76
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/0a100d76
Branch: refs/heads/master
Commit: 0a100d76c881f6bd7e63c983f624d145180f609d
Parents: 149822e
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 08:57:14 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:30 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
system/NOTICE | 71 +++++
system/command/NOTICE | 71 -----
system/command/pom.xml | 87 -------
.../karaf/system/commands/FrameworkOptions.java | 73 ------
.../org/apache/karaf/system/commands/Name.java | 51 ----
.../apache/karaf/system/commands/Shutdown.java | 104 --------
.../karaf/system/commands/StartLevel.java | 49 ----
.../karaf/system/commands/SystemProperty.java | 157 -----------
.../apache/karaf/system/commands/Version.java | 38 ---
.../src/main/resources/OSGI-INF/bundle.info | 20 --
system/core/NOTICE | 71 -----
system/core/pom.xml | 106 --------
.../org/apache/karaf/system/FrameworkType.java | 19 --
.../org/apache/karaf/system/SystemService.java | 130 ----------
.../system/internal/SystemServiceImpl.java | 238 -----------------
.../karaf/system/internal/osgi/Activator.java | 38 ---
.../karaf/system/management/SystemMBean.java | 157 -----------
.../management/internal/SystemMBeanImpl.java | 259 -------------------
.../src/main/resources/OSGI-INF/bundle.info | 16 --
.../system/internal/SystemServiceImplTest.java | 53 ----
.../src/test/resources/etc/system.properties | 22 --
system/pom.xml | 89 ++++++-
.../org/apache/karaf/system/FrameworkType.java | 19 ++
.../org/apache/karaf/system/SystemService.java | 130 ++++++++++
.../karaf/system/commands/FrameworkOptions.java | 73 ++++++
.../org/apache/karaf/system/commands/Name.java | 51 ++++
.../apache/karaf/system/commands/Shutdown.java | 104 ++++++++
.../karaf/system/commands/StartLevel.java | 49 ++++
.../karaf/system/commands/SystemProperty.java | 157 +++++++++++
.../apache/karaf/system/commands/Version.java | 38 +++
.../system/internal/SystemServiceImpl.java | 238 +++++++++++++++++
.../karaf/system/internal/osgi/Activator.java | 38 +++
.../karaf/system/management/SystemMBean.java | 157 +++++++++++
.../management/internal/SystemMBeanImpl.java | 259 +++++++++++++++++++
system/src/main/resources/OSGI-INF/bundle.info | 16 ++
.../system/internal/SystemServiceImplTest.java | 53 ++++
system/src/test/resources/etc/system.properties | 22 ++
38 files changed, 1556 insertions(+), 1768 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/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 90c38db..fae3b4f 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -165,7 +165,6 @@
<feature name="system" description="Provide System support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.system/org.apache.karaf.system.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.system/org.apache.karaf.system.command/${project.version}</bundle>
</feature>
<feature name="http" version="${project.version}" resolver="(obr)" description="Implementation of the OSGI HTTP Service">
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/NOTICE
----------------------------------------------------------------------
diff --git a/system/NOTICE b/system/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/system/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/0a100d76/system/command/NOTICE
----------------------------------------------------------------------
diff --git a/system/command/NOTICE b/system/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/system/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/0a100d76/system/command/pom.xml
----------------------------------------------------------------------
diff --git a/system/command/pom.xml b/system/command/pom.xml
deleted file mode 100644
index 3eeaa19..0000000
--- a/system/command/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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.system</groupId>
- <artifactId>system</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.system.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: System :: Shell Commands</name>
- <description>
- This bundle provides Karaf shell commands to manipulate system service (shutdown container, etc).
- </description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.system</groupId>
- <artifactId>org.apache.karaf.system.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </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>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java b/system/command/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java
deleted file mode 100644
index 9e16a7d..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.system.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.system.FrameworkType;
-import org.apache.karaf.system.SystemService;
-
-/**
- * Command for enabling/disabling debug logging on the OSGi framework
- */
-@Command(scope = "system", name = "framework", description = "OSGi Framework options.")
-@Service
-public class FrameworkOptions implements Action {
-
- @Option(name = "-debug", aliases={"--enable-debug"}, description="Enable debug for the OSGi framework", required = false, multiValued = false)
- boolean debug;
-
- @Option(name = "-nodebug", aliases={"--disable-debug"}, description="Disable debug for the OSGi framework", required = false, multiValued = false)
- boolean nodebug;
-
- @Argument(name = "framework", required = false, description = "Name of the OSGi framework to use")
- String framework;
-
- @Reference
- SystemService systemService;
-
- @Override
- public Object execute() throws Exception {
-
- if (!debug^nodebug && framework == null) {
- System.out.printf("Current OSGi framework is %s%n", systemService.getFramework().name());
- return null;
- }
- if (framework != null) {
- FrameworkType frameworkType = FrameworkType.valueOf(framework);
- systemService.setFramework(frameworkType);
- System.out.println("Changed OSGi framework to " + frameworkType.toString().toLowerCase() + ". Karaf needs to be restarted to make the change effective");
- }
- if (debug) {
- FrameworkType frameworkType = systemService.getFramework();
- System.out.printf("Enabling debug for OSGi framework (%s)%n", frameworkType.name());
- systemService.setFrameworkDebug(true);
- }
- if (nodebug) {
- FrameworkType frameworkType = systemService.getFramework();
- System.out.printf("Disabling debug for OSGi framework (%s)%n", frameworkType.name());
- systemService.setFrameworkDebug(false);
- }
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/Name.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/Name.java b/system/command/src/main/java/org/apache/karaf/system/commands/Name.java
deleted file mode 100644
index a716d82..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/Name.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.system.commands;
-
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.system.SystemService;
-
-/**
- * Command to shut down Karaf container.
- */
-@Command(scope = "system", name = "name", description = "Show or change Karaf instance name.")
-@Service
-public class Name implements Action {
-
- @Argument(name = "name", index = 0, description = "New name for the instance", required = false, multiValued = false)
- String name;
-
- @Reference
- SystemService systemService;
-
- @Override
- public Object execute() throws Exception {
- if (name == null) {
- System.out.println(systemService.getName());
- } else {
- systemService.setName(name);
- System.out.println("Instance name changed to " + name + ". Restart needed for this to take effect.");
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/Shutdown.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/Shutdown.java b/system/command/src/main/java/org/apache/karaf/system/commands/Shutdown.java
deleted file mode 100644
index b8b4b41..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/Shutdown.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.system.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-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.Session;
-import org.apache.karaf.system.SystemService;
-
-/**
- * Command to shut down Karaf container.
- */
-@Command(scope = "system", name = "shutdown", description = "Shutdown Karaf.")
-@Service
-public class Shutdown implements Action {
-
- @Option(name = "-f", aliases = "--force", description = "Force the shutdown without confirmation message.", required = false, multiValued = false)
- boolean force = false;
-
- @Option(name = "-r", aliases = "--reboot", description = "Reboot the Karaf container.", required = false, multiValued = false)
- boolean reboot = false;
-
- @Option(name = "-h", aliases = "--halt", description = "Halt the Karaf container.", required = false, multiValued = false)
- boolean halt = false;
-
- @Option(name = "-c", aliases = {"--clean", "--clean-all", "-ca"}, description = "Force a clean restart by deleting the data directory")
- private boolean cleanAll;
-
- @Option(name = "-cc", aliases = {"--clean-cache", "-cc"}, description = "Force a clean restart by deleting the cache directory")
- private boolean cleanCache;
-
-
- @Argument(name = "time", index = 0, description = "Shutdown after a specified delay. The time argument can have different" +
- " formats. First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm" +
- " is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes" +
- " to wait. The word now is an alias for +0.", required = false, multiValued = false)
- String time;
-
- @Reference
- SystemService systemService;
-
- @Reference
- Session session;
-
- @Override
- public Object execute() throws Exception {
-
- if (force) {
- if (reboot) {
- systemService.reboot(time, determineSwipeType());
- } else {
- systemService.halt(time);
- }
- return null;
- }
-
- for (; ; ) {
- String karafName = System.getProperty("karaf.name");
- String msg;
- if (reboot) {
- msg = String.format("Confirm: reboot instance %s (yes/no): ", karafName);
- } else {
- msg = String.format("Confirm: halt instance %s (yes/no): ", karafName);
- }
- String str = session.readLine(msg, null);
- if (str.equalsIgnoreCase("yes")) {
- if (reboot) {
- systemService.reboot(time, determineSwipeType());
- } else {
- systemService.halt(time);
- }
- }
- return null;
- }
- }
-
- private SystemService.Swipe determineSwipeType() {
- if (cleanAll) {
- return SystemService.Swipe.ALL;
- } else if (cleanCache) {
- return SystemService.Swipe.CACHE;
- }
- return SystemService.Swipe.NONE;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/StartLevel.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/StartLevel.java b/system/command/src/main/java/org/apache/karaf/system/commands/StartLevel.java
deleted file mode 100644
index e91c15a..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/StartLevel.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.system.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.system.SystemService;
-
-/**
- * Get/set the system start level.
- */
-@Command(scope = "system", name = "start-level", description = "Gets or sets the system start level.")
-@Service
-public class StartLevel implements Action {
-
- @Argument(index = 0, name = "level", description = "The new system start level to set", required = false, multiValued = false)
- Integer level;
-
- @Reference
- SystemService systemService;
-
- @Override
- public Object execute() throws Exception {
- if (level == null) {
- System.out.println("Level " + systemService.getStartLevel());
- } else {
- systemService.setStartLevel(level);
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/SystemProperty.java b/system/command/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
deleted file mode 100644
index 37c2a1e..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.system.commands;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.system.SystemService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-
-/**
- * Command that allow access to system properties easily.
- */
-@Command(scope = "system", name = "property", description = "Get or set a system property.")
-@Service
-public class SystemProperty implements Action {
-
- @Option(name = "-p", aliases = {"--persistent"}, description = "Persist the new value to the etc/system.properties file")
- boolean persistent;
-
- @Option(name = "-f", aliases = {"--file-dump"}, description = "Dump all system properties in a file (in data folder)")
- boolean dumpToFile;
-
- @Option(name = "-u", aliases = {"--unset"}, description = "Show unset know properties with value unset")
- boolean unset;
-
- @Argument(index = 0, name = "key", required = false, description = "The system property name")
- String key;
-
- @Argument(index = 1, name = "value", required = false, description = "New value for the system property")
- String value;
-
- @Reference
- BundleContext bundleContext;
-
- @Reference
- SystemService systemService;
-
- @Override
- public Object execute() throws Exception {
- if (key == null && value == null) {
- Properties props = (Properties) System.getProperties().clone();
-
- String def = null;
- if (unset) {
- def = "unset";
- }
-
- setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def);
- setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def);
- setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def);
- setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def);
- setProperty(props, Constants.FRAMEWORK_LANGUAGE, def);
- setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def);
- setProperty(props, Constants.FRAMEWORK_OS_NAME, def);
- setProperty(props, Constants.FRAMEWORK_OS_VERSION, def);
- setProperty(props, Constants.FRAMEWORK_PROCESSOR, def);
- setProperty(props, Constants.FRAMEWORK_SECURITY, def);
- setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def);
- setProperty(props, Constants.FRAMEWORK_STORAGE, def);
- setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def);
- setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def);
- setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def);
- setProperty(props, Constants.FRAMEWORK_VENDOR, def);
- setProperty(props, Constants.FRAMEWORK_VERSION, def);
- setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def);
-
- setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def);
-
- if (dumpToFile) {
- PrintStream ps = new PrintStream(
- new File(
- bundleContext.getProperty("karaf.data"),
- "dump-properties-" + System.currentTimeMillis() + ".properties"
- )
- );
- ps.println("#Dump of the System and OSGi properties with the command system:property");
- ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date()));
- printOrderedProperties(props, ps);
- ps.flush();
- ps.close();
- } else {
- printOrderedProperties(props, System.out);
- }
-
- return null;
- }
-
- if (value != null) {
- systemService.setSystemProperty(key, value, persistent);
- } else {
- System.out.println(System.getProperty(key));
- }
-
- return null;
- }
-
- private void printOrderedProperties(Properties props, PrintStream out) {
- Set<Object> keys = props.keySet();
- Vector<String> order = new Vector<String>(keys.size());
- for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
- Object str = (Object) i.next();
- order.add((String) str);
- }
- Collections.sort(order);
- for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
- String key = (String) i.next();
- out.println(key + "=" + props.getProperty(key));
- }
- }
-
- private void setProperty(Properties props, String key, String def) {
- String val = bundleContext.getProperty(key);
- if (val == null && def != null) {
- props.setProperty(key, def);
- } else if (val != null) {
- props.setProperty(key, val);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/java/org/apache/karaf/system/commands/Version.java
----------------------------------------------------------------------
diff --git a/system/command/src/main/java/org/apache/karaf/system/commands/Version.java b/system/command/src/main/java/org/apache/karaf/system/commands/Version.java
deleted file mode 100644
index 9837aaa..0000000
--- a/system/command/src/main/java/org/apache/karaf/system/commands/Version.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.system.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.system.SystemService;
-
-@Command(scope = "system", name = "version", description = "Display the instance version")
-@Service
-public class Version implements Action {
-
- @Reference
- SystemService systemService;
-
- @Override
- public Object execute() throws Exception {
- System.out.println(systemService.getVersion());
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/system/command/src/main/resources/OSGI-INF/bundle.info b/system/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index c115593..0000000
--- a/system/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,20 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle contains all Karaf system shell commands.
-
-The following commands are available:
-* system:shutdown - Shutdown the Karaf container.
-* syste:start-level - Gets or sets the Karaf system start level.
-
-h1. See also
-
-Shutdown Karaf - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/NOTICE
----------------------------------------------------------------------
diff --git a/system/core/NOTICE b/system/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/system/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/0a100d76/system/core/pom.xml
----------------------------------------------------------------------
diff --git a/system/core/pom.xml b/system/core/pom.xml
deleted file mode 100644
index 61c68e0..0000000
--- a/system/core/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?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.system</groupId>
- <artifactId>system</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.system.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: System :: Core</name>
- <description>
- This bundle provides services to manipulate the Karaf container itself (system).
- </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.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </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>
- <Export-Package>
- org.apache.karaf.system,
- org.apache.karaf.system.management
- </Export-Package>
- <Private-Package>
- org.apache.karaf.system.internal,
- org.apache.karaf.system.internal.osgi,
- org.apache.karaf.system.management.internal,
- org.apache.karaf.util.tracker,
- org.apache.felix.utils.properties
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.system.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/FrameworkType.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/FrameworkType.java b/system/core/src/main/java/org/apache/karaf/system/FrameworkType.java
deleted file mode 100644
index 67720a7..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/FrameworkType.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed 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.system;
-
-public enum FrameworkType {
- felix,
- equinox
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/SystemService.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/SystemService.java b/system/core/src/main/java/org/apache/karaf/system/SystemService.java
deleted file mode 100644
index 2f53946..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/SystemService.java
+++ /dev/null
@@ -1,130 +0,0 @@
- /*
- * 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.system;
-
-/**
- * Describe a system service
- */
-public interface SystemService {
-
- /**
- * Types defining what to remove on a restart of Karaf
- */
- public enum Swipe {
- /** Delete nothing; simple restart */
- NONE,
- /** Delete only the cache; everything else remains */
- CACHE,
- /** Forces a clean restart by removing the working directory; this option is compatible to the former clean method. */
- ALL
- }
-
- /**
- * Halt the Karaf container.
- */
- void halt() throws Exception;
-
- /**
- * Halt the Karaf container.
- *
- * @param time shutdown delay. The time argument can have different formats.
- * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm
- * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes
- * to wait. The word now is an alias for +0.
- */
- void halt(String time) throws Exception;
-
- /**
- * Reboot the Karaf container.
- *
- * @throws Exception
- */
- void reboot() throws Exception;
-
- /**
- * Reboot the Karaf container.
- *
- * @param time reboot delay. The time argument can have different formats.
- * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm
- * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes
- * to wait. The word now is an alias for +0.
- * @param clean Force a clean restart by deleting the working directory.
- */
- void reboot(String time, Swipe clean) throws Exception;
-
- /**
- * Set the system start level.
- *
- * @param startLevel the new system start level.
- */
- void setStartLevel(int startLevel) throws Exception;
-
- /**
- * Get the system start level.
- *
- * @return the current system start level.
- */
- int getStartLevel() throws Exception;
-
- /**
- * Get the version of the current Karaf instance
- *
- * @return instance version
- */
- String getVersion();
-
- /**
- * Get the name of the current Karaf instance
- *
- * @return instance name
- */
- String getName();
-
- /**
- * Set the name of the Karaf instance
- *
- * @param name new instance name
- */
- void setName(String name);
-
- /**
- * Get the current OSGi framework in use.
- *
- * @return the name of the OSGi framework in use.
- * @throws Exception
- */
- FrameworkType getFramework();
-
- /**
- * change OSGi framework
- *
- * @param framework to use.
- */
- void setFramework(FrameworkType framework);
-
- /**
- * Enable or diable debgging
- * @param debug enable if true
- */
- void setFrameworkDebug(boolean debug);
-
- /**
- * Set a system property and persist to etc/system.properties
- * @param key
- */
- String setSystemProperty(String key, String value, boolean persist);
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java b/system/core/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
deleted file mode 100644
index 8fa5a38..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
-* 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.system.internal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-import org.apache.felix.utils.properties.Properties;
-import org.apache.karaf.system.FrameworkType;
-import org.apache.karaf.system.SystemService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.startlevel.FrameworkStartLevel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of the system service.
- */
-public class SystemServiceImpl implements SystemService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(SystemServiceImpl.class);
-
- private BundleContext bundleContext;
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public BundleContext getBundleContext() {
- return this.bundleContext;
- }
-
- public void halt() throws Exception {
- halt(null);
- }
-
- public void halt(String time) throws Exception {
- shutdown(timeToSleep(time));
- }
-
- public void reboot() throws Exception {
- reboot(null, Swipe.NONE);
- }
-
- public void reboot(String time, Swipe cleanup) throws Exception {
- reboot(timeToSleep(time), cleanup);
- }
-
- private void shutdown(final long sleep) {
- new Thread() {
- public void run() {
- try {
- sleepWithMsg(sleep, "Shutdown in " + sleep / 1000 / 60 + " minute(s)");
- getBundleContext().getBundle(0).stop();
- } catch (Exception e) {
- LOGGER.error("Halt error", e);
- }
- }
- }.start();
- }
-
- private void reboot(final long sleep, final Swipe clean) {
- new Thread() {
- public void run() {
- try {
- sleepWithMsg(sleep, "Reboot in " + sleep / 1000 / 60 + " minute(s)");
- System.setProperty("karaf.restart", "true");
- if (clean.equals(Swipe.ALL)) {
- System.setProperty("karaf.clean.all", "true");
- } else if (clean.equals(Swipe.CACHE)) {
- System.setProperty("karaf.clean.cache", "true");
- }
- bundleContext.getBundle(0).stop();
- } catch (Exception e) {
- LOGGER.error("Reboot error", e);
- }
- }
- }.start();
- }
-
- private void sleepWithMsg(final long sleep, String msg)
- throws InterruptedException {
- if (sleep > 0) {
- LOGGER.info(msg);
- System.err.println(msg);
- }
- Thread.sleep(sleep);
- }
-
- public void setStartLevel(int startLevel) throws Exception {
- getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).setStartLevel(startLevel);
- }
-
- public int getStartLevel() throws Exception {
- return getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
- }
-
- /**
- * Convert a time string to sleep period (in millisecond).
- *
- * @param time the time string.
- * @return the corresponding sleep period in millisecond.
- */
- private long timeToSleep(String time) throws Exception {
- long sleep = 0;
- if (time != null) {
- if (!time.equals("now")) {
- if (time.startsWith("+")) {
- // delay in number of minutes provided
- time = time.substring(1);
- try {
- sleep = Long.parseLong(time) * 60 * 1000;
- } catch (Exception e) {
- throw new IllegalArgumentException("Time " + time + " is not valid");
- }
- } else {
- // try to parse the date in hh:mm
- String[] strings = time.split(":");
- if (strings.length != 2) {
- throw new IllegalArgumentException("Time " + time + " is not valid");
- }
- GregorianCalendar currentDate = new GregorianCalendar();
- GregorianCalendar shutdownDate = new GregorianCalendar(currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE), Integer.parseInt(strings[0]), Integer.parseInt(strings[1]));
- if (shutdownDate.before(currentDate)) {
- shutdownDate.set(Calendar.DATE, shutdownDate.get(Calendar.DATE) + 1);
- }
- sleep = shutdownDate.getTimeInMillis() - currentDate.getTimeInMillis();
- }
- }
- }
- return sleep;
- }
-
- @Override
- public String getVersion() {
- return System.getProperty("karaf.version");
- }
-
- @Override
- public String getName() {
- return bundleContext.getProperty("karaf.name");
- }
-
- @Override
- public void setName(String name) {
- try {
- String karafEtc = bundleContext.getProperty("karaf.etc");
- File etcDir = new File(karafEtc);
- File syspropsFile = new File(etcDir, "system.properties");
- FileInputStream fis = new FileInputStream(syspropsFile);
- Properties props = new Properties();
- props.load(fis);
- fis.close();
- props.setProperty("karaf.name", name);
- FileOutputStream fos = new FileOutputStream(syspropsFile);
- props.store(fos, "");
- fos.close();
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- public FrameworkType getFramework() {
- if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) {
- return FrameworkType.felix;
- } else {
- return FrameworkType.equinox;
- }
- }
-
- private Properties loadProps() throws IOException {
- return new Properties(new File(System.getProperty("karaf.etc"), "config.properties"));
- }
-
- public void setFramework(FrameworkType framework) {
- if (framework == null) {
- return;
- }
- try {
- Properties properties = loadProps();
- properties.put("karaf.framework", framework.name());
- properties.save();
- } catch (IOException e) {
- throw new RuntimeException("Error setting framework: " + e.getMessage(), e);
- }
- }
-
- public void setFrameworkDebug(boolean debug) {
- try {
- Properties properties = loadProps();
- if (debug) {
- properties.put("felix.log.level", "4");
- properties.put("osgi.debug", "etc/equinox-debug.properties");
- } else {
- properties.remove("felix.log.level");
- properties.remove("osgi.debug");
- }
- // TODO populate the equinox-debug.properties file with the one provided in shell/dev module
- properties.save();
- } catch (IOException e) {
- throw new RuntimeException("Error settting framework debugging: " + e.getMessage(), e);
- }
- }
-
- @Override
- public String setSystemProperty(String key, String value, boolean persist) {
- if (persist) {
- try {
- String etc = System.getProperty("karaf.etc");
- Properties props = new Properties(new File(etc, "system.properties"));
- props.put(key, value);
- props.save();
- } catch (IOException e) {
- throw new RuntimeException("Error persisting system property", e);
- }
- }
- return System.setProperty(key, value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java b/system/core/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
deleted file mode 100644
index b7f8eab..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.system.internal.osgi;
-
-import org.apache.karaf.system.SystemService;
-import org.apache.karaf.system.internal.SystemServiceImpl;
-import org.apache.karaf.system.management.internal.SystemMBeanImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doStart() throws Exception {
- SystemServiceImpl systemService = new SystemServiceImpl();
- systemService.setBundleContext(bundleContext);
- register(SystemService.class, systemService);
-
- SystemMBeanImpl mbean = new SystemMBeanImpl();
- mbean.setBundleContext(bundleContext);
- mbean.setSystemService(systemService);
- registerMBean(mbean, "type=system");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/management/SystemMBean.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/management/SystemMBean.java b/system/core/src/main/java/org/apache/karaf/system/management/SystemMBean.java
deleted file mode 100644
index 5d9bdbc..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/management/SystemMBean.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.system.management;
-
-import javax.management.MBeanException;
-import java.util.Map;
-
-/**
- * Describe the system MBean.
- */
-public interface SystemMBean {
-
- /**
- * Stop the Karaf instance
- *
- * @throws Exception
- */
- void halt() throws MBeanException;
-
- /**
- * Stop the Karaf instance at a given time.
- *
- * @param time the time when to stop the Karaf instance.
- * @throws Exception
- */
- void halt(String time) throws MBeanException;
-
- /**
- * Reboot the Karaf instance.
- *
- * @throws Exception
- */
- void reboot() throws MBeanException;
-
- /**
- * Reboot the Karaf instance at a given time.
- *
- * @param time the time when to reboot the Karaf instance.
- * @throws Exception
- */
- void reboot(String time) throws MBeanException;
-
- /**
- * Reboot the Karaf instance at a given time and clean the cache.
- *
- * @param time the time when to reboot the Karaf instance.
- * @throws Exception
- */
- void rebootCleanCache(String time) throws MBeanException;
-
- /**
- * Reboot the Karaf instance at a given time and clean all working files.
- *
- * @param time the time when to reboot the Karaf instance.
- * @throws Exception
- */
- void rebootCleanAll(String time) throws MBeanException;
-
- /**
- * Set the system bundle start level.
- *
- * @param startLevel the new system bundle start level.
- * @throws Exception
- */
- void setStartLevel(int startLevel) throws MBeanException;
-
- /**
- * Get the current system bundle start level.
- *
- * @return the current system bundle start level.
- * @throws Exception
- */
- int getStartLevel() throws MBeanException;
-
- /**
- * Get the current OSGi framework in use.
- *
- * @return the name of the OSGi framework in use.
- * @throws Exception
- */
- String getFramework();
-
- /**
- * change OSGi framework
- *
- * @param framework to use.
- */
- void setFramework(String framework);
-
- /**
- * Enable or diable debgging
- * @param debug enable if true
- */
- void setFrameworkDebug(boolean debug);
-
- /**
- * Get the current Karaf instance name.
- *
- * @return the current Karaf instance name.
- */
- String getName();
-
- /**
- * Change Karaf instance name.
- *
- * @param name the new Karaf instance name.
- */
- void setName(String name);
-
- /**
- * Get the version of the current Karaf instance.
- *
- * @return the current Karaf instance version.
- */
- String getVersion();
-
- /**
- * Get all system properties.
- *
- * @param unset if true, display the OSGi properties even if they are not defined (with "undef" value).
- * @param dumpToFile if true, dump the properties into a file in the data folder.
- * @return the list of system properties.
- */
- Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException;
-
- /**
- * Get the value of a given system property.
- *
- * @param key the system property key.
- * @return the system property value.
- */
- String getProperty(String key);
-
- /**
- * Set the value of a system property.
- *
- * @param key the system property key.
- * @param value the new system property value.
- * @param persistent if true, persist the new value to the etc/system.properties file.
- */
- void setProperty(String key, String value, boolean persistent);
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
----------------------------------------------------------------------
diff --git a/system/core/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java b/system/core/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
deleted file mode 100644
index c0f34cd..0000000
--- a/system/core/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * 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.system.management.internal;
-
-import org.apache.karaf.system.FrameworkType;
-import org.apache.karaf.system.SystemService;
-import org.apache.karaf.system.management.SystemMBean;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import java.io.File;
-import java.io.PrintStream;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-/**
- * System MBean implementation.
- */
-public class SystemMBeanImpl extends StandardMBean implements SystemMBean {
-
- private SystemService systemService;
- private BundleContext bundleContext;
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public SystemMBeanImpl() throws NotCompliantMBeanException {
- super(SystemMBean.class);
- }
-
- public void setSystemService(SystemService systemService) {
- this.systemService = systemService;
- }
-
- public SystemService getSystemService() {
- return this.systemService;
- }
-
- public void halt() throws MBeanException {
- try {
- systemService.halt();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void halt(String time) throws MBeanException {
- try {
- systemService.halt(time);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void reboot() throws MBeanException {
- try {
- systemService.reboot();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void reboot(String time) throws MBeanException {
- try {
- systemService.reboot(time, SystemService.Swipe.NONE);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void rebootCleanCache(String time) throws MBeanException {
- try {
- systemService.reboot(time, SystemService.Swipe.CACHE);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void rebootCleanAll(String time) throws MBeanException {
- try {
- systemService.reboot(time, SystemService.Swipe.ALL);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void setStartLevel(int startLevel) throws MBeanException {
- try {
- systemService.setStartLevel(startLevel);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public int getStartLevel() throws MBeanException {
- try {
- return systemService.getStartLevel();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @Override
- public String getFramework() {
- return this.systemService.getFramework().toString();
- }
-
- @Override
- public void setFramework(String framework) {
- this.systemService.setFramework(FrameworkType.valueOf(framework.toLowerCase()));
- }
-
- @Override
- public void setFrameworkDebug(boolean debug) {
- this.systemService.setFrameworkDebug(debug);
- }
-
- @Override
- public String getName() {
- return this.systemService.getName();
- }
-
- @Override
- public void setName(String name) {
- if (name == null || name.trim().isEmpty()) {
- throw new IllegalArgumentException("Instance name can't be null or empty");
- }
- this.systemService.setName(name);
- }
-
- @Override
- public String getVersion() {
- return this.systemService.getVersion();
- }
-
- @Override
- public Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException {
- try {
- Map<String, String> result = new HashMap<String, String>();
-
- Properties props = (Properties) java.lang.System.getProperties().clone();
-
- String def = null;
- if (unset) {
- def = "unset";
- }
-
- setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def);
- setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def);
- setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def);
- setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def);
- setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def);
- setProperty(props, Constants.FRAMEWORK_LANGUAGE, def);
- setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def);
- setProperty(props, Constants.FRAMEWORK_OS_NAME, def);
- setProperty(props, Constants.FRAMEWORK_OS_VERSION, def);
- setProperty(props, Constants.FRAMEWORK_PROCESSOR, def);
- setProperty(props, Constants.FRAMEWORK_SECURITY, def);
- setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def);
- setProperty(props, Constants.FRAMEWORK_STORAGE, def);
- setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def);
- setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def);
- setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def);
- setProperty(props, Constants.FRAMEWORK_VENDOR, def);
- setProperty(props, Constants.FRAMEWORK_VERSION, def);
- setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def);
-
- setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def);
- setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def);
-
- if (dumpToFile) {
- PrintStream ps = new PrintStream(new File(bundleContext.getProperty("karaf.data"), "dump-properties-" + java.lang.System.currentTimeMillis() + ".properties"));
- ps.println("#Dump of the System and OSGi properties");
- ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date()));
- printOrderedProperties(props, ps);
- ps.flush();
- ps.close();
- } else {
- printOrderedProperties(props, result);
- }
-
- return result;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- private void printOrderedProperties(Properties props, PrintStream out) {
- Set<Object> keys = props.keySet();
- Vector<String> order = new Vector<String>(keys.size());
- for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
- Object str = (Object) i.next();
- order.add((String) str);
- }
- Collections.sort(order);
- for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
- String key = (String) i.next();
- out.println(key + "=" + props.getProperty(key));
- }
- }
-
- private void printOrderedProperties(Properties props, Map<String, String> result) {
- Set<Object> keys = props.keySet();
- Vector<String> order = new Vector<String>(keys.size());
- for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
- Object str = (Object) i.next();
- order.add((String) str);
- }
- Collections.sort(order);
- for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
- String key = (String) i.next();
- result.put(key, props.getProperty(key));
- }
- }
-
- private void setProperty(Properties props, String key, String def) {
- String val = bundleContext.getProperty(key);
- if (val == null && def != null) {
- props.setProperty(key, def);
- } else if (val != null) {
- props.setProperty(key, val);
- }
- }
-
- @Override
- public String getProperty(String key) {
- return java.lang.System.getProperty(key);
- }
-
- @Override
- public void setProperty(String key, String value, boolean persistent) {
- systemService.setSystemProperty(key, value, persistent);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/system/core/src/main/resources/OSGI-INF/bundle.info b/system/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index acca1c8..0000000
--- a/system/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,16 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides support of the system service, which control the Karaf container.
-
-h1. See also
-
-Shutdown - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
----------------------------------------------------------------------
diff --git a/system/core/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java b/system/core/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
deleted file mode 100644
index 2de4e1e..0000000
--- a/system/core/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-* 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.system.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-import org.apache.felix.utils.properties.Properties;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-/**
- * Implementation of the system service.
- */
-
-public class SystemServiceImplTest {
-
- private static final String NEW_NAME = "newName";
-
- @Test
- public void testSetName() throws URISyntaxException, IOException {
- SystemServiceImpl system = new SystemServiceImpl();
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- URL propUrl = this.getClass().getClassLoader().getResource("etc/system.properties");
- File propfile = new File(propUrl.toURI());
- EasyMock.expect(bundleContext.getProperty("karaf.etc")).andReturn(propfile.getParentFile().getParent() + "/etc");
- EasyMock.replay(bundleContext);
- system.setBundleContext(bundleContext);
- system.setName(NEW_NAME);
- EasyMock.verify(bundleContext);
- Properties props = new Properties(propfile);
- String nameAfter = props.getProperty("karaf.name");
- Assert.assertEquals(NEW_NAME, nameAfter);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/core/src/test/resources/etc/system.properties
----------------------------------------------------------------------
diff --git a/system/core/src/test/resources/etc/system.properties b/system/core/src/test/resources/etc/system.properties
deleted file mode 100644
index 6749fbb..0000000
--- a/system/core/src/test/resources/etc/system.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-#Comment
-karaf.name=oldName
-#Comment2
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/pom.xml
----------------------------------------------------------------------
diff --git a/system/pom.xml b/system/pom.xml
index 39ce101..59d338a 100644
--- a/system/pom.xml
+++ b/system/pom.xml
@@ -29,13 +29,86 @@
</parent>
<groupId>org.apache.karaf.system</groupId>
- <artifactId>system</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: System</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.system.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: System :: Core</name>
+ <description>
+ This bundle provides services to manipulate the Karaf container itself (system).
+ </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.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </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>
+ <Export-Package>
+ org.apache.karaf.system,
+ org.apache.karaf.system.management
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.system.commands,
+ org.apache.karaf.system.internal,
+ org.apache.karaf.system.internal.osgi,
+ org.apache.karaf.system.management.internal,
+ org.apache.karaf.util.tracker,
+ org.apache.felix.utils.properties
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.system.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/FrameworkType.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/FrameworkType.java b/system/src/main/java/org/apache/karaf/system/FrameworkType.java
new file mode 100644
index 0000000..67720a7
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/FrameworkType.java
@@ -0,0 +1,19 @@
+/*
+ * Licensed 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.system;
+
+public enum FrameworkType {
+ felix,
+ equinox
+}
[34/59] [abbrv] git commit: [KARAF-2852] Merge kar/core and
kar/command
Posted by gn...@apache.org.
[KARAF-2852] Merge kar/core and kar/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/f13d140c
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/f13d140c
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/f13d140c
Branch: refs/heads/master
Commit: f13d140c3a055686caa587883c74d987971b8e06
Parents: 886863a
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 23:07:47 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:01:24 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
kar/NOTICE | 71 ++++
kar/command/NOTICE | 71 ----
kar/command/pom.xml | 89 -----
.../karaf/kar/command/CreateKarCommand.java | 50 ---
.../karaf/kar/command/InstallKarCommand.java | 43 ---
.../karaf/kar/command/ListKarCommand.java | 52 ---
.../karaf/kar/command/UninstallKarCommand.java | 45 ---
.../kar/command/completers/KarCompleter.java | 50 ---
.../src/main/resources/OSGI-INF/bundle.info | 22 --
kar/core/NOTICE | 71 ----
kar/core/pom.xml | 118 ------
.../java/org/apache/karaf/kar/KarService.java | 80 ----
.../java/org/apache/karaf/kar/KarsMBean.java | 57 ---
.../karaf/kar/internal/FeatureDetector.java | 87 -----
.../java/org/apache/karaf/kar/internal/Kar.java | 203 ----------
.../karaf/kar/internal/KarServiceImpl.java | 382 -------------------
.../karaf/kar/internal/KarsMBeanImpl.java | 72 ----
.../karaf/kar/internal/osgi/Activator.java | 54 ---
.../src/main/resources/OSGI-INF/bundle.info | 19 -
kar/pom.xml | 102 ++++-
.../java/org/apache/karaf/kar/KarService.java | 80 ++++
.../java/org/apache/karaf/kar/KarsMBean.java | 57 +++
.../karaf/kar/command/CreateKarCommand.java | 50 +++
.../karaf/kar/command/InstallKarCommand.java | 43 +++
.../karaf/kar/command/ListKarCommand.java | 52 +++
.../karaf/kar/command/UninstallKarCommand.java | 45 +++
.../kar/command/completers/KarCompleter.java | 50 +++
.../karaf/kar/internal/FeatureDetector.java | 87 +++++
.../java/org/apache/karaf/kar/internal/Kar.java | 203 ++++++++++
.../karaf/kar/internal/KarServiceImpl.java | 382 +++++++++++++++++++
.../karaf/kar/internal/KarsMBeanImpl.java | 72 ++++
.../karaf/kar/internal/osgi/Activator.java | 54 +++
kar/src/main/resources/OSGI-INF/bundle.info | 19 +
34 files changed, 1359 insertions(+), 1574 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/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 af81c40..99554c2 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -195,7 +195,6 @@
<feature name="kar" description="Provide KAR (KARaf archive) support" version="${project.version}" resolver="(obr)">
<bundle start-level="30">mvn:org.apache.karaf.kar/org.apache.karaf.kar.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.kar/org.apache.karaf.kar.command/${project.version}</bundle>
</feature>
<feature name="webconsole" description="Base support of the Karaf WebConsole" version="${project.version}" resolver="(obr)">
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/NOTICE
----------------------------------------------------------------------
diff --git a/kar/NOTICE b/kar/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/kar/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/f13d140c/kar/command/NOTICE
----------------------------------------------------------------------
diff --git a/kar/command/NOTICE b/kar/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/kar/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/f13d140c/kar/command/pom.xml
----------------------------------------------------------------------
diff --git a/kar/command/pom.xml b/kar/command/pom.xml
deleted file mode 100644
index 220eec4..0000000
--- a/kar/command/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?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.kar</groupId>
- <artifactId>kar</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.kar.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: KAR :: Command</name>
- <description>This bundle provides a set of Karaf shell commands to manipulate KAR files.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.kar</groupId>
- <artifactId>org.apache.karaf.kar.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.command</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.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>
- <Export-Package>!*</Export-Package>
- <Karaf-Commands>org.apache.karaf.kar.command.*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java b/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
deleted file mode 100644
index a93706c..0000000
--- a/kar/command/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.kar.command;
-
-import java.util.List;
-
-import org.apache.karaf.features.command.completers.InstalledRepoNameCompleter;
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "kar", name = "create", description = "Create a kar file for a list of feature repos")
-@Service
-public class CreateKarCommand implements Action {
-
- @Argument(index = 0, name = "repoName", description = "Repository name. The kar will contain all features of the named repository by default", required = true, multiValued = false)
- @Completion(InstalledRepoNameCompleter.class)
- 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 = true)
- private List<String> features;
-
- @Reference
- private KarService karService;
-
- @Override
- public Object execute() throws Exception {
- karService.create(repoName, features, System.out);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/command/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java b/kar/command/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
deleted file mode 100644
index 806367a..0000000
--- a/kar/command/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.kar.command;
-
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-import java.net.URI;
-
-@Command(scope = "kar", name = "install", description = "Installs a KAR file.")
-@Service
-public class InstallKarCommand implements Action {
-
- @Argument(index = 0, name = "url", description = "The URL of the KAR file to install.", required = true, multiValued = false)
- private String url;
-
- @Reference
- private KarService karService;
-
- public Object execute() throws Exception {
- karService.install(new URI(url));
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/command/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java b/kar/command/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
deleted file mode 100644
index 98813ff..0000000
--- a/kar/command/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.kar.command;
-
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "kar", name = "list", description = "List the installed KAR files.")
-@Service
-public class ListKarCommand implements Action {
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private KarService karService;
-
- @Override
- public Object execute() throws Exception {
-
- ShellTable table = new ShellTable();
- table.column("KAR Name");
-
- for (String karName : karService.list()) {
- table.addRow().addContent(karName);
- }
-
- table.print(System.out, !noFormat);
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/command/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java b/kar/command/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
deleted file mode 100644
index 506bdb3..0000000
--- a/kar/command/src/main/java/org/apache/karaf/kar/command/UninstallKarCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.kar.command;
-
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.kar.command.completers.KarCompleter;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "kar", name = "uninstall", description = "Uninstall a KAR file.")
-@Service
-public class UninstallKarCommand implements Action {
-
- @Argument(index = 0, name = "name", description = "The name of the KAR file to uninstall.", required = true, multiValued = false)
- @Completion(KarCompleter.class)
- private String name;
-
- @Reference
- private KarService karService;
-
- @Override
- public Object execute() throws Exception {
- karService.uninstall(name);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
----------------------------------------------------------------------
diff --git a/kar/command/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java b/kar/command/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
deleted file mode 100644
index 539cfaf..0000000
--- a/kar/command/src/main/java/org/apache/karaf/kar/command/completers/KarCompleter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.kar.command.completers;
-
-import java.util.List;
-
-import org.apache.karaf.kar.KarService;
-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;
-
-/**
- * Completer on all installed KAR files.
- */
-@Service
-public class KarCompleter implements Completer {
-
- @Reference
- private KarService karService;
-
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- try {
- for (String karName : karService.list()) {
- delegate.getStrings().add(karName);
- }
- } catch (Exception e) {
- // ignore
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/kar/command/src/main/resources/OSGI-INF/bundle.info b/kar/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 79a21ae..0000000
--- a/kar/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,22 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides the shell commands to manipulate the KAR artifacts.
-
-Especially, the following commands are available:
-
-* kar:list
-* kar:install
-* kar:uninstall
-
-h1. See also
-
-KAR - section of the Karaf User Guide
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/NOTICE
----------------------------------------------------------------------
diff --git a/kar/core/NOTICE b/kar/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/kar/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/f13d140c/kar/core/pom.xml
----------------------------------------------------------------------
diff --git a/kar/core/pom.xml b/kar/core/pom.xml
deleted file mode 100644
index 92f30c8..0000000
--- a/kar/core/pom.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?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.kar</groupId>
- <artifactId>kar</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.kar.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: KAR :: Core</name>
- <description>This bundle provides core implementation of the KAR management service.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
- <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.ops4j.pax.swissbox</groupId>
- <artifactId>pax-swissbox-property</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </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>
- <Export-Package>
- org.apache.karaf.kar
- </Export-Package>
- <Private-Package>
- org.apache.karaf.kar.internal,
- org.apache.karaf.kar.internal.osgi,
- org.apache.karaf.util.maven,
- org.apache.karaf.util.tracker,
- org.apache.felix.utils.properties
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.kar.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/KarService.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/KarService.java b/kar/core/src/main/java/org/apache/karaf/kar/KarService.java
deleted file mode 100644
index 60acb77..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/KarService.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.kar;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.net.URI;
-import java.util.List;
-
-/**
- * The service managing KAR.
- */
-public interface KarService {
-
- /**
- * Install KAR from a given URI
- *
- * Resources will be copied to the karaf base dir
- * Repository contents will be copied to a subdir in the
- * karaf data directory
- *
- * @param karUri Uri of the kar to be installed
- * @throws Exception in case of installation failure.
- */
- void install(URI karUri) throws Exception;
-
- /**
- * Install a kar with manually given repository and
- * resource directories.
- *
- * @param karUri Uri of the kar to be installed
- * @param repoDir destination for the repository contents of the kar
- * @param resourceDir destination for the resource contents of the kar
- * @throws Exception
- */
- void install(URI karUri, File repoDir, File resourceDir) throws Exception;
-
- /**
- * Uninstall the given KAR
- *
- * @param name the name of the KAR
- * @throws Exception in case of failure
- */
- void uninstall(String name) throws Exception;
-
- /**
- * List the KAR stored in the data folder.
- *
- * @return the list of KAR stored.
- * @throws Exception in case of listing failure.
- */
- List<String> list() throws Exception;
-
- /**
- * Create a kar from the given feature and repo names.
- * Each named feature including all transitive deps will be added.
- * For each named repo all features in the repo and their transitive deps will be added.
- *
- * @param repoName
- * @param features
- * @param console
- */
- void create(String repoName, List<String> features, PrintStream console);
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/KarsMBean.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/KarsMBean.java b/kar/core/src/main/java/org/apache/karaf/kar/KarsMBean.java
deleted file mode 100644
index b1a86c9..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/KarsMBean.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.kar;
-
-import javax.management.MBeanException;
-import java.util.List;
-
-public interface KarsMBean {
-
- /**
- * List the installed KAR files.
- *
- * @return the list of KAR files.
- * @throws Exception in case of listing failure.
- */
- List<String> getKars() throws MBeanException;
-
- /**
- * Create a kar file for a list of feature repos
- *
- * @param repoName the name of features repository
- * @param features the features to include in the kar
- * @throws Exception in case of creation failure
- */
- void create(String repoName, List<String> features);
-
- /**
- * Install a KAR file from the given URL.
- *
- * @param url the JAR URL.
- * @throws Exception in case of installation failure.
- */
- void install(String url) throws MBeanException;
-
- /**
- * Uninstall a KAR file.
- *
- * @param name the name of the KAR file.
- * @throws Exception in case of uninstall failure.
- */
- void uninstall(String name) throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java b/kar/core/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
deleted file mode 100644
index aca1f53..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/internal/FeatureDetector.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.kar.internal;
-
-import java.io.File;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * Simple helper to determine if a file is a feature repo
- */
-class FeatureDetector {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(FeatureDetector.class);
-
- private DocumentBuilderFactory dbf;
-
- FeatureDetector() {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- }
- /**
- * Check if a file is a features XML.
- *
- * @param artifact the file to check.
- * @return true if the artifact is a features XML, false else.
- */
- boolean isFeaturesRepository(File artifact) {
- try {
- if (artifact.isFile() && artifact.getName().endsWith(".xml")) {
- Document doc = parse(artifact);
- String name = doc.getDocumentElement().getLocalName();
- String uri = doc.getDocumentElement().getNamespaceURI();
- if ("features".equals(name) && (uri == null || "".equals(uri) || uri.startsWith("http://karaf.apache.org/xmlns/features/v"))) {
- return true;
- }
- }
- } catch (Exception e) {
- LOGGER.debug("File '{}' is not a features file.", artifact.getName(), e);
- }
- return false;
- }
-
- /**
- * Parse a features XML.
- *
- * @param artifact the features XML to parse.
- * @return the parsed document.
- * @throws Exception in case of parsing failure.
- */
- private Document parse(File artifact) throws Exception {
- DocumentBuilder db = dbf.newDocumentBuilder();
- db.setErrorHandler(new ErrorHandler() {
- public void warning(SAXParseException exception) throws SAXException {
- }
- public void error(SAXParseException exception) throws SAXException {
- }
- public void fatalError(SAXParseException exception) throws SAXException {
- throw exception;
- }
- });
- return db.parse(artifact);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/internal/Kar.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/internal/Kar.java b/kar/core/src/main/java/org/apache/karaf/kar/internal/Kar.java
deleted file mode 100644
index 005cd17..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/internal/Kar.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.kar.internal;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.Attributes;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Representation of a Karaf Kar archive
- *
- * A Kar archive is a jar file with a special structure that can be used
- * to deploy feature repositories, maven repo contents and resources for the
- * karaf installation.
- *
- * meta-inf/Manifest:
- * Karaf-Feature-Start: (true|false) Controls if the features in the feature repos should be started on deploy
- * Karaf-Feature-Repos: (uri)* If present then only the given feature repo urls are added to karaf if it is not
- * present then the karaf file is scanned for repo files
- *
- * repository/
- * Everything below this directory is treated as a maven repository. On deploy the contents
- * will be copied to a directory below data. This directory will then be added to the
- * maven repos of pax url maven
- *
- * resource/
- * Everything below this directory will be copied to the karaf base dir on deploy
- *
- */
-public class Kar {
-
- public static final Logger LOGGER = LoggerFactory.getLogger(KarServiceImpl.class);
- public static final String MANIFEST_ATTR_KARAF_FEATURE_START = "Karaf-Feature-Start";
- public static final String MANIFEST_ATTR_KARAF_FEATURE_REPOS = "Karaf-Feature-Repos";
- private final URI karUri;
- private boolean shouldInstallFeatures;
- private List<URI> featureRepos;
-
- public Kar(URI karUri) {
- this.karUri = karUri;
- }
-
- /**
- * Extract a kar from a given URI into a repository dir and resource dir
- * and populate shouldInstallFeatures and featureRepos
- *
- * @param repoDir directory to write the repository contents of the kar to
- * @param resourceDir directory to write the resource contents of the kar to
- */
- public void extract(File repoDir, File resourceDir) {
- InputStream is = null;
- JarInputStream zipIs = null;
- FeatureDetector featureDetector = new FeatureDetector();
- this.featureRepos = new ArrayList<URI>();
- this.shouldInstallFeatures = true;
-
- try {
- is = karUri.toURL().openStream();
- repoDir.mkdirs();
-
- if (!repoDir.isDirectory()) {
- throw new RuntimeException("The KAR file " + karUri + " is already installed");
- }
-
- LOGGER.debug("Uncompress the KAR file {} into directory {}", karUri, repoDir);
- zipIs = new JarInputStream(is);
- boolean scanForRepos = true;
-
- Manifest manifest = zipIs.getManifest();
- if (manifest != null) {
- Attributes attr = manifest.getMainAttributes();
- String featureStartSt = (String)attr
- .get(new Attributes.Name(MANIFEST_ATTR_KARAF_FEATURE_START));
- if ("false".equals(featureStartSt)) {
- shouldInstallFeatures = false;
- }
- String featureReposAttr = (String)attr
- .get(new Attributes.Name(MANIFEST_ATTR_KARAF_FEATURE_REPOS));
- if (featureReposAttr != null) {
- featureRepos.add(new URI(featureReposAttr));
- scanForRepos = false;
- }
- }
-
- ZipEntry entry = zipIs.getNextEntry();
- while (entry != null) {
- if (entry.getName().startsWith("repository")) {
- String path = entry.getName().substring("repository/".length());
- File destFile = new File(repoDir, path);
- extract(zipIs, entry, destFile);
- if (scanForRepos && featureDetector.isFeaturesRepository(destFile)) {
- featureRepos.add(destFile.toURI());
- }
- }
-
- if (entry.getName().startsWith("resource")) {
- String path = entry.getName().substring("resource/".length());
- File destFile = new File(resourceDir, path);
- extract(zipIs, entry, destFile);
- }
- entry = zipIs.getNextEntry();
- }
- } catch (Exception e) {
- throw new RuntimeException("Error extracting kar file " + karUri + " into dir " + repoDir + ": " + e.getMessage(), e);
- } finally {
- closeStream(zipIs);
- closeStream(is);
- }
- }
-
- /**
- * Extract an entry from a KAR file
- *
- * @param is
- * @param zipEntry
- * @param dest
- * @return
- * @throws Exception
- */
- private static File extract(InputStream is, ZipEntry zipEntry, File dest) throws Exception {
- if (zipEntry.isDirectory()) {
- LOGGER.debug("Creating directory {}", dest.getName());
- dest.mkdirs();
- } else {
- dest.getParentFile().mkdirs();
- FileOutputStream out = new FileOutputStream(dest);
- copyStream(is, out);
- out.close();
- }
- return dest;
- }
-
- private static void closeStream(InputStream is) {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- LOGGER.warn("Error closing stream", e);
- }
- }
- }
-
- static long copyStream(InputStream input, OutputStream output) throws IOException {
- byte[] buffer = new byte[10000];
- long count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- public String getKarName() {
- try {
- String karName = new File(karUri.toURL().getFile()).getName();
- karName = karName.substring(0, karName.lastIndexOf("."));
- return karName;
- } catch (MalformedURLException e) {
- throw new RuntimeException("Invalid kar URI " + karUri, e);
- }
- }
-
- public URI getKarUri() {
- return karUri;
- }
-
- public boolean isShouldInstallFeatures() {
- return shouldInstallFeatures;
- }
-
- public List<URI> getFeatureRepos() {
- return featureRepos;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java b/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
deleted file mode 100644
index 0f86466..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * 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.kar.internal;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-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.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-
-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;
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.util.maven.Parser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of the KAR service.
- */
-public class KarServiceImpl implements KarService {
- private static final String FEATURE_CONFIG_FILE = "features.cfg";
- private static final Logger LOGGER = LoggerFactory.getLogger(KarServiceImpl.class);
-
- private File storage;
- private File base;
- private FeaturesService featuresService;
-
- private boolean noAutoRefreshBundles;
-
- public KarServiceImpl(String karafBase, FeaturesService featuresService) {
- this.base = new File(karafBase);
- this.storage = new File(this.base, "data" + File.separator + "kar");
- this.featuresService = featuresService;
- this.storage.mkdirs();
- if (!storage.isDirectory()) {
- throw new IllegalStateException("KAR storage " + storage + " is not a directory");
- }
- }
-
- @Override
- public void install(URI karUri) throws Exception {
- String karName = new Kar(karUri).getKarName();
- LOGGER.debug("Installing KAR {} from {}", karName, karUri);
- File karDir = new File(storage, karName);
- install(karUri, karDir, base);
- }
-
- @Override
- public void install(URI karUri, File repoDir, File resourceDir) throws Exception {
- Kar kar = new Kar(karUri);
- kar.extract(repoDir, resourceDir);
- writeToFile(kar.getFeatureRepos(), new File(repoDir, FEATURE_CONFIG_FILE));
- for (URI uri : kar.getFeatureRepos()) {
- addToFeaturesRepositories(uri);
- }
- if (kar.isShouldInstallFeatures()) {
- installFeatures(kar.getFeatureRepos());
- }
-
- }
-
-
- private List<URI> readFromFile(File repoListFile) {
- ArrayList<URI> uriList = new ArrayList<URI>();
- FileReader fr = null;
- try {
- fr = new FileReader(repoListFile);
- BufferedReader br = new BufferedReader(fr);
- String line;
- while ((line = br.readLine()) != null) {
- uriList.add(new URI(line));
- }
- } catch (Exception e) {
- throw new RuntimeException("Error reading repo list from file " + repoListFile.getAbsolutePath(), e);
- } finally {
- try {
- fr.close();
- } catch (IOException e) {
- LOGGER.warn("Error closing reader for file " + repoListFile, e);
- }
- }
- return uriList;
- }
-
- private void writeToFile(List<URI> featuresRepositoriesInKar, File repoListFile) {
- FileOutputStream fos = null;
- PrintStream ps = null;
- try {
- fos = new FileOutputStream(repoListFile);
- ps = new PrintStream(fos);
- for (URI uri : featuresRepositoriesInKar) {
- ps.println(uri);
- }
- ps.close();
- fos.close();
- } catch (Exception e) {
- throw new RuntimeException("Error writing feature repo list to file " + repoListFile.getAbsolutePath(), e);
- } finally {
- closeStream(ps);
- closeStream(fos);
- }
- }
-
- private void deleteRecursively(File dir) {
- if (dir.isDirectory()) {
- File[] children = dir.listFiles();
- for (File child : children) {
- deleteRecursively(child);
- }
- }
- dir.delete();
- }
-
- @Override
- public void uninstall(String karName) throws Exception {
- File karDir = new File(storage, karName);
-
- if (!karDir.exists()) {
- throw new IllegalArgumentException("The KAR " + karName + " is not installed");
- }
-
- List<URI> featuresRepositories = readFromFile(new File(karDir, FEATURE_CONFIG_FILE));
- uninstallFeatures(featuresRepositories);
- for (URI featuresRepository : featuresRepositories) {
- featuresService.removeRepository(featuresRepository);
- }
-
- deleteRecursively(karDir);
- }
-
- @Override
- public List<String> list() throws Exception {
- List<String> kars = new ArrayList<String>();
- for (File kar : storage.listFiles()) {
- if (kar.isDirectory()) {
- kars.add(kar.getName());
- }
- }
- return kars;
- }
-
-
-
- /**
- * Add an URI to the list of features repositories.
- *
- * @param uri the URI to add.
- * @throws Exception in case of add failure.
- */
- private void addToFeaturesRepositories(URI uri) throws Exception {
- try {
- featuresService.removeRepository(uri);
- featuresService.addRepository(uri);
- LOGGER.info("Added feature repository '{}'", uri);
- } catch (Exception e) {
- LOGGER.warn("Unable to add repository '{}'", uri, e);
- }
- }
-
- /**
- * Install all features contained in the list of features XML.
- *
- * @param featuresRepositories the list of features XML.
- */
- private void installFeatures(List<URI> featuresRepositories) throws Exception {
- for (Repository repository : featuresService.listRepositories()) {
- for (URI karFeatureRepoUri : featuresRepositories) {
- if (repository.getURI().equals(karFeatureRepoUri)) {
- try {
- for (Feature feature : repository.getFeatures()) {
- try {
- LOGGER.debug("noAutoRefreshBundles is " + isNoAutoRefreshBundles());
- if (isNoAutoRefreshBundles()) {
- featuresService.installFeature(feature, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
- } else {
- featuresService.installFeature(feature, EnumSet.noneOf(FeaturesService.Option.class));
- }
- } catch (Exception e) {
- LOGGER.warn("Unable to install Kar feature {}", feature.getName() + "/" + feature.getVersion(), e);
- }
- }
- } catch (Exception e) {
- LOGGER.warn("Can't get features for KAR {}", karFeatureRepoUri, e);
- }
- }
- }
- }
- }
-
- @Override
- public void create(String repoName, List<String> features, PrintStream console) {
- FileOutputStream fos = null;
- JarOutputStream jos = null;
- try {
- 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);
- Manifest manifest = createNonAutoStartManifest(repo.getURI());
- jos = new JarOutputStream(new BufferedOutputStream(fos, 100000), manifest);
-
- Map<URI, Integer> locationMap = new HashMap<URI, Integer>();
- copyResourceToJar(jos, repo.getURI(), locationMap);
-
- Map<String, Feature> featureMap = new HashMap<String, Feature>();
- for (Feature feature : repo.getFeatures()) {
- featureMap.put(feature.getName(), feature);
- }
-
- Set<Feature> featuresToCopy = getFeatures(featureMap, features, 1);
-
- for (Feature feature : featuresToCopy) {
- if (console != null)
- console.println("Adding feature " + feature.getName());
- copyFeatureToJar(jos, feature, locationMap);
- }
-
- if (console != null)
- console.println("Kar file created : " + karPath);
- } catch (Exception e) {
- throw new RuntimeException("Error creating kar: " + e.getMessage(), e);
- } finally {
- 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 ++));
- }
- }
- return featureSet;
- }
-
- private Manifest createNonAutoStartManifest(URI repoUri) throws UnsupportedEncodingException, IOException {
- String manifestSt = "Manifest-Version: 1.0\n" +
- Kar.MANIFEST_ATTR_KARAF_FEATURE_START +": false\n" +
- Kar.MANIFEST_ATTR_KARAF_FEATURE_REPOS + ": " + repoUri.toString() + "\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)
- throws URISyntaxException {
- for (BundleInfo bundleInfo : feature.getBundles()) {
- URI location = new URI(bundleInfo.getLocation());
- copyResourceToJar(jos, location, locationMap);
- }
- for (ConfigFileInfo configFileInfo : feature.getConfigurationFiles()) {
- URI location = new URI(configFileInfo.getLocation());
- copyResourceToJar(jos, location, locationMap);
- }
- }
-
- private void copyResourceToJar(JarOutputStream jos, URI location, Map<URI, Integer> locationMap) {
- if (locationMap.containsKey(location)) {
- return;
- }
- try {
- String noPrefixLocation = location.toString().substring(location.toString().lastIndexOf(":") + 1);
- Parser parser = new Parser(noPrefixLocation);
- InputStream is = location.toURL().openStream();
- String path = "repository/" + parser.getArtifactPath();
- jos.putNextEntry(new JarEntry(path));
- Kar.copyStream(is, jos);
- is.close();
- locationMap.put(location, 1);
- } catch (Exception e) {
- LOGGER.error("Error adding " + location, e);
- }
- }
-
- /**
- * Uninstall all features contained in the list of features XML.
- *
- * @param featuresRepositories the list of features XML.
- */
- private void uninstallFeatures(List<URI> featuresRepositories) throws Exception {
- for (Repository repository : featuresService.listRepositories()) {
- for (URI karFeatureRepoUri : featuresRepositories) {
- if (repository.getURI().equals(karFeatureRepoUri)) {
- try {
- for (Feature feature : repository.getFeatures()) {
- try {
- featuresService.uninstallFeature(feature.getName(), feature.getVersion());
- } catch (Exception e) {
- LOGGER.warn("Unable to uninstall Kar feature {}", feature.getName() + "/" + feature.getVersion(), e);
- }
- }
- } catch (Exception e) {
- LOGGER.warn("Can't get features for KAR {}", karFeatureRepoUri, e);
- }
- }
- }
- }
- }
-
- public boolean isNoAutoRefreshBundles() {
- return noAutoRefreshBundles;
- }
-
- public void setNoAutoRefreshBundles(boolean noAutoRefreshBundles) {
- this.noAutoRefreshBundles = noAutoRefreshBundles;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java b/kar/core/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
deleted file mode 100644
index b274e21..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/internal/KarsMBeanImpl.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.kar.internal;
-
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.kar.KarsMBean;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import java.net.URI;
-import java.util.List;
-
-public class KarsMBeanImpl extends StandardMBean implements KarsMBean {
-
- private KarService karService;
-
- public KarsMBeanImpl() throws NotCompliantMBeanException {
- super(KarsMBean.class);
- }
-
- public List<String> getKars() throws MBeanException {
- try {
- return karService.list();
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void create(String repoName, List<String> features) {
- karService.create(repoName, features, null);
- }
-
- public void install(String url) throws MBeanException {
- try {
- karService.install(new URI(url));
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void uninstall(String name) throws MBeanException {
- try {
- karService.uninstall(name);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public KarService getKarService() {
- return karService;
- }
-
- public void setKarService(KarService karService) {
- this.karService = karService;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/kar/core/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java b/kar/core/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java
deleted file mode 100644
index 05a1b59..0000000
--- a/kar/core/src/main/java/org/apache/karaf/kar/internal/osgi/Activator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.kar.internal.osgi;
-
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.kar.KarService;
-import org.apache.karaf.kar.internal.KarServiceImpl;
-import org.apache.karaf.kar.internal.KarsMBeanImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.osgi.service.cm.ManagedService;
-
-public class Activator extends BaseActivator implements ManagedService {
-
- @Override
- protected void doOpen() throws Exception {
- manage("org.apache.karaf.kar");
- trackService(FeaturesService.class);
- }
-
- protected void doStart() throws Exception {
- FeaturesService featuresService = getTrackedService(FeaturesService.class);
- if (featuresService == null) {
- return;
- }
-
- boolean noAutoRefreshBundles = getBoolean("noAutoRefreshBundles", false);
-
- KarServiceImpl karService = new KarServiceImpl(
- System.getProperty("karaf.base"),
- featuresService
- );
- karService.setNoAutoRefreshBundles(noAutoRefreshBundles);
- register(KarService.class, karService);
-
- KarsMBeanImpl mbean = new KarsMBeanImpl();
- mbean.setKarService(karService);
- registerMBean(mbean, "type=kar");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/kar/core/src/main/resources/OSGI-INF/bundle.info b/kar/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 7056453..0000000
--- a/kar/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,19 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle is the core implementation of the Karaf kar support.
-
-Karaf Archives (KAR) is an artifact (zip file) shipping a features XML and the associated bundles or configuration
-files.
-
-h1. See also
-
-KAR - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/pom.xml
----------------------------------------------------------------------
diff --git a/kar/pom.xml b/kar/pom.xml
index 44a8f77..78629f6 100644
--- a/kar/pom.xml
+++ b/kar/pom.xml
@@ -29,13 +29,99 @@
</parent>
<groupId>org.apache.karaf.kar</groupId>
- <artifactId>kar</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: KAR</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.kar.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: KAR :: Core</name>
+ <description>This bundle provides core implementation of the KAR management service.</description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <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.ops4j.pax.swissbox</groupId>
+ <artifactId>pax-swissbox-property</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </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>
+ <Export-Package>
+ org.apache.karaf.kar
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.kar.command,
+ org.apache.karaf.kar.command.completers,
+ org.apache.karaf.kar.internal,
+ org.apache.karaf.kar.internal.osgi,
+ org.apache.karaf.util.maven,
+ org.apache.karaf.util.tracker,
+ org.apache.felix.utils.properties
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.kar.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.kar.command.*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/KarService.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/KarService.java b/kar/src/main/java/org/apache/karaf/kar/KarService.java
new file mode 100644
index 0000000..60acb77
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/KarService.java
@@ -0,0 +1,80 @@
+/*
+ * 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.kar;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * The service managing KAR.
+ */
+public interface KarService {
+
+ /**
+ * Install KAR from a given URI
+ *
+ * Resources will be copied to the karaf base dir
+ * Repository contents will be copied to a subdir in the
+ * karaf data directory
+ *
+ * @param karUri Uri of the kar to be installed
+ * @throws Exception in case of installation failure.
+ */
+ void install(URI karUri) throws Exception;
+
+ /**
+ * Install a kar with manually given repository and
+ * resource directories.
+ *
+ * @param karUri Uri of the kar to be installed
+ * @param repoDir destination for the repository contents of the kar
+ * @param resourceDir destination for the resource contents of the kar
+ * @throws Exception
+ */
+ void install(URI karUri, File repoDir, File resourceDir) throws Exception;
+
+ /**
+ * Uninstall the given KAR
+ *
+ * @param name the name of the KAR
+ * @throws Exception in case of failure
+ */
+ void uninstall(String name) throws Exception;
+
+ /**
+ * List the KAR stored in the data folder.
+ *
+ * @return the list of KAR stored.
+ * @throws Exception in case of listing failure.
+ */
+ List<String> list() throws Exception;
+
+ /**
+ * Create a kar from the given feature and repo names.
+ * Each named feature including all transitive deps will be added.
+ * For each named repo all features in the repo and their transitive deps will be added.
+ *
+ * @param repoName
+ * @param features
+ * @param console
+ */
+ void create(String repoName, List<String> features, PrintStream console);
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/KarsMBean.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/KarsMBean.java b/kar/src/main/java/org/apache/karaf/kar/KarsMBean.java
new file mode 100644
index 0000000..b1a86c9
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/KarsMBean.java
@@ -0,0 +1,57 @@
+/*
+ * 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.kar;
+
+import javax.management.MBeanException;
+import java.util.List;
+
+public interface KarsMBean {
+
+ /**
+ * List the installed KAR files.
+ *
+ * @return the list of KAR files.
+ * @throws Exception in case of listing failure.
+ */
+ List<String> getKars() throws MBeanException;
+
+ /**
+ * Create a kar file for a list of feature repos
+ *
+ * @param repoName the name of features repository
+ * @param features the features to include in the kar
+ * @throws Exception in case of creation failure
+ */
+ void create(String repoName, List<String> features);
+
+ /**
+ * Install a KAR file from the given URL.
+ *
+ * @param url the JAR URL.
+ * @throws Exception in case of installation failure.
+ */
+ void install(String url) throws MBeanException;
+
+ /**
+ * Uninstall a KAR file.
+ *
+ * @param name the name of the KAR file.
+ * @throws Exception in case of uninstall failure.
+ */
+ void uninstall(String name) throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java b/kar/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
new file mode 100644
index 0000000..a93706c
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/command/CreateKarCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.kar.command;
+
+import java.util.List;
+
+import org.apache.karaf.features.command.completers.InstalledRepoNameCompleter;
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "kar", name = "create", description = "Create a kar file for a list of feature repos")
+@Service
+public class CreateKarCommand implements Action {
+
+ @Argument(index = 0, name = "repoName", description = "Repository name. The kar will contain all features of the named repository by default", required = true, multiValued = false)
+ @Completion(InstalledRepoNameCompleter.class)
+ 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 = true)
+ private List<String> features;
+
+ @Reference
+ private KarService karService;
+
+ @Override
+ public Object execute() throws Exception {
+ karService.create(repoName, features, System.out);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java b/kar/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
new file mode 100644
index 0000000..806367a
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/command/InstallKarCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.kar.command;
+
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+import java.net.URI;
+
+@Command(scope = "kar", name = "install", description = "Installs a KAR file.")
+@Service
+public class InstallKarCommand implements Action {
+
+ @Argument(index = 0, name = "url", description = "The URL of the KAR file to install.", required = true, multiValued = false)
+ private String url;
+
+ @Reference
+ private KarService karService;
+
+ public Object execute() throws Exception {
+ karService.install(new URI(url));
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f13d140c/kar/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java b/kar/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
new file mode 100644
index 0000000..98813ff
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/kar/command/ListKarCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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.kar.command;
+
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "kar", name = "list", description = "List the installed KAR files.")
+@Service
+public class ListKarCommand implements Action {
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ private KarService karService;
+
+ @Override
+ public Object execute() throws Exception {
+
+ ShellTable table = new ShellTable();
+ table.column("KAR Name");
+
+ for (String karName : karService.list()) {
+ table.addRow().addContent(karName);
+ }
+
+ table.print(System.out, !noFormat);
+
+ return null;
+ }
+
+}
[57/59] [abbrv] [KARAF-2852] Merge jndi/core and jndi/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
new file mode 100644
index 0000000..08e3912
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/AliasCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.jndi.command.completers.NamesCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jndi", name = "alias", description = "Create a JNDI alias on a given name.")
+@Service
+public class AliasCommand implements Action {
+
+ @Argument(index = 0, name = "name", description = "The JNDI name", required = true, multiValued = false)
+ @Completion(NamesCompleter.class)
+ String name;
+
+ @Argument(index = 1, name = "alias", description = "The JNDI alias", required = true, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String alias;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ jndiService.alias(name, alias);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/BindCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
new file mode 100644
index 0000000..b181762
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/BindCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.jndi.command.completers.ServicesIdCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jndi", name = "bind", description = "Bind an OSGi service in the JNDI context")
+@Service
+public class BindCommand implements Action {
+
+ @Argument(index = 0, name = "service", description = "The ID of the OSGi service to bind", required = true, multiValued = false)
+ @Completion(ServicesIdCompleter.class)
+ Long serviceId;
+
+ @Argument(index = 1, name = "name", description = "The JNDI name to bind the OSGi service", required = true, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String name;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ jndiService.bind(serviceId, name);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
new file mode 100644
index 0000000..2209479
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/ContextsCommand.java
@@ -0,0 +1,64 @@
+/*
+ * 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.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+import java.util.List;
+
+@Command(scope = "jndi", name = "contexts", description = "List the JNDI sub-contexts.")
+@Service
+public class ContextsCommand implements Action {
+
+ @Argument(index = 0, name = "context", description = "The base JNDI context", required = false, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String context;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ ShellTable table = new ShellTable();
+
+ table.column("JNDI Sub-Context");
+
+ List<String> contexts;
+ if (context == null) {
+ contexts = jndiService.contexts();
+ } else {
+ contexts = jndiService.contexts(context);
+ }
+
+ for (String c : contexts) {
+ table.addRow().addContent(c);
+ }
+
+ table.print(System.out);
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
new file mode 100644
index 0000000..86663bf
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/CreateCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jndi", name = "create", description = "Create a new JNDI sub-context.")
+@Service
+public class CreateCommand implements Action {
+
+ @Argument(index = 0, name = "context", description = "The JNDI sub-context name", required = true, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String context;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ jndiService.create(context);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
new file mode 100644
index 0000000..3cd3a40
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/DeleteCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jndi", name = "delete", description = "Delete a JNDI sub-context.")
+@Service
+public class DeleteCommand implements Action {
+
+ @Argument(index = 0, name = "context", description = "The JNDI sub-context name", required = true, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String context;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ jndiService.delete(context);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/NamesCommand.java
new file mode 100644
index 0000000..0345f11
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/NamesCommand.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.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.ContextsCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+import java.util.Map;
+
+@Command(scope = "jndi", name = "names", description = "List the JNDI names.")
+@Service
+public class NamesCommand implements Action {
+
+ @Argument(index = 0, name = "context", description = "The JNDI context to display the names", required = false, multiValued = false)
+ @Completion(ContextsCompleter.class)
+ String context;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ ShellTable table = new ShellTable();
+
+ table.column("JNDI Name");
+ table.column("Class Name");
+
+ Map<String, String> names;
+ if (context == null) {
+ names = jndiService.names();
+ } else {
+ names = jndiService.names(context);
+ }
+
+ for (String name : names.keySet()) {
+ table.addRow().addContent(name, names.get(name));
+ }
+
+ table.print(System.out);
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java b/jndi/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
new file mode 100644
index 0000000..b93c7b9
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/UnbindCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.jndi.command;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.command.completers.NamesCompleter;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jndi", name = "unbind", description = "Unbind a JNDI name.")
+@Service
+public class UnbindCommand implements Action {
+
+ @Argument(index = 0, name = "name", description = "The JNDI name to unbind", required = true, multiValued = false)
+ @Completion(NamesCompleter.class)
+ String name;
+
+ @Reference
+ JndiService jndiService;
+
+ @Override
+ public Object execute() throws Exception {
+ jndiService.unbind(name);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
new file mode 100644
index 0000000..8f2ac29
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ContextsCompleter.java
@@ -0,0 +1,60 @@
+/*
+ * 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.jndi.command.completers;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+import java.util.List;
+
+/**
+ * Completers on the JNDI contexts.
+ */
+@Service
+public class ContextsCompleter implements Completer {
+
+ @Reference
+ private JndiService jndiService;
+
+ @Override
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ List<String> contexts = jndiService.contexts();
+ for (String context : contexts) {
+ delegate.getStrings().add(context);
+ }
+ } catch (Exception e) {
+ // nothing to do
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ public JndiService getJndiService() {
+ return jndiService;
+ }
+
+ public void setJndiService(JndiService jndiService) {
+ this.jndiService = jndiService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.java
new file mode 100644
index 0000000..d94e3f4
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/NamesCompleter.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.jndi.command.completers;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+import java.util.List;
+
+/**
+ * Completer to the JNDI names.
+ */
+@Service
+public class NamesCompleter implements Completer {
+
+ @Reference
+ private JndiService jndiService;
+
+ @Override
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ try {
+ for (String name : jndiService.names().keySet()) {
+ delegate.getStrings().add(name);
+ }
+ } catch (Exception e) {
+ // nothing to do
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ public JndiService getJndiService() {
+ return jndiService;
+ }
+
+ public void setJndiService(JndiService jndiService) {
+ this.jndiService = jndiService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
new file mode 100644
index 0000000..c7cdb80
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/command/completers/ServicesIdCompleter.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jndi.command.completers;
+
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+import java.util.List;
+
+/**
+ * Completer on the OSGi services ID.
+ */
+@Service
+public class ServicesIdCompleter implements Completer {
+
+ @Reference
+ private BundleContext bundleContext;
+
+ @Override
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference[] references = bundle.getRegisteredServices();
+ if (references != null) {
+ for (ServiceReference reference : references) {
+ if (reference.getProperty(Constants.SERVICE_ID) != null) {
+ delegate.getStrings().add(reference.getProperty(Constants.SERVICE_ID).toString());
+ }
+ }
+ }
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java b/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
new file mode 100644
index 0000000..2433618
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiMBeanImpl.java
@@ -0,0 +1,122 @@
+/*
+ * 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.jndi.internal;
+
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.JndiMBean;
+
+import javax.management.MBeanException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of the JndiMBean
+ */
+public class JndiMBeanImpl implements JndiMBean {
+
+ private JndiService jndiService;
+
+ @Override
+ public Map<String, String> getNames() throws MBeanException {
+ try {
+ return this.jndiService.names();
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public List<String> getContexts() throws MBeanException {
+ try {
+ return this.jndiService.contexts();
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public Map<String, String> getNames(String context) throws MBeanException {
+ try {
+ return this.jndiService.names(context);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public List<String> getContexts(String context) throws MBeanException {
+ try {
+ return this.jndiService.contexts(context);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public void alias(String name, String alias) throws MBeanException {
+ try {
+ this.jndiService.alias(name, alias);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public void bind(Long serviceId, String name) throws MBeanException {
+ try {
+ this.jndiService.bind(serviceId, name);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public void unbind(String name) throws MBeanException {
+ try {
+ this.jndiService.unbind(name);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public void create(String context) throws MBeanException {
+ try {
+ this.jndiService.create(context);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ @Override
+ public void delete(String context) throws MBeanException {
+ try {
+ this.jndiService.delete(context);
+ } catch (Throwable t) {
+ throw new MBeanException(null, t.getMessage());
+ }
+ }
+
+ public JndiService getJndiService() {
+ return jndiService;
+ }
+
+ public void setJndiService(JndiService jndiService) {
+ this.jndiService = jndiService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java b/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
new file mode 100644
index 0000000..68d6b94
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/internal/JndiServiceImpl.java
@@ -0,0 +1,313 @@
+/*
+ * 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.jndi.internal;
+
+import org.apache.aries.proxy.ProxyManager;
+import org.apache.karaf.jndi.JndiService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+import javax.naming.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of the JNDI Service.
+ */
+public class JndiServiceImpl implements JndiService {
+
+ private BundleContext bundleContext;
+ private ProxyManager proxyManager;
+
+ private final static String OSGI_JNDI_CONTEXT_PREFIX = "osgi:service/";
+ private final static String OSGI_JNDI_SERVICE_PROPERTY = "osgi.jndi.service.name";
+
+ @Override
+ public Map<String, String> names() throws Exception {
+ Map<String, String> result = names("/");
+ result.putAll(names(OSGI_JNDI_CONTEXT_PREFIX));
+ return result;
+ }
+
+ @Override
+ public Map<String, String> names(String name) throws Exception {
+ Map<String, String> map = new HashMap<String, String>();
+ if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
+ // OSGi service binding
+ // make a lookup using directly the OSGi service
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] services = bundle.getRegisteredServices();
+ if (services != null) {
+ for (ServiceReference service : services) {
+ if (service.getProperty(OSGI_JNDI_SERVICE_PROPERTY) != null) {
+ Object actualService = bundleContext.getService(service);
+ if (proxyManager.isProxy(actualService)) {
+ actualService = proxyManager.unwrap(actualService).call();
+ }
+ map.put(OSGI_JNDI_CONTEXT_PREFIX + service.getProperty(OSGI_JNDI_SERVICE_PROPERTY), actualService.getClass().getName());
+ bundleContext.ungetService(service);
+ }
+ }
+ }
+ }
+ } else {
+ // "real" JNDI lookup
+ Context context = new InitialContext();
+ NamingEnumeration<NameClassPair> pairs = context.list(name);
+ while (pairs.hasMoreElements()) {
+ NameClassPair pair = pairs.nextElement();
+ Object o;
+ if (name != null) {
+ o = context.lookup(name + "/" + pair.getName());
+ } else {
+ o = context.lookup(pair.getName());
+ }
+ if (o instanceof Context) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("/" + pair.getName());
+ names((Context) o, sb, map);
+ } else {
+ map.put("/" + pair.getName(), pair.getClassName());
+ }
+ }
+ }
+ return map;
+ }
+
+ public List<String> contexts() throws Exception {
+ return contexts("/");
+ }
+
+ public List<String> contexts(String name) throws Exception {
+ List<String> contexts = new ArrayList<String>();
+ Context context = new InitialContext();
+ NamingEnumeration<NameClassPair> pairs = context.list(name);
+ while (pairs.hasMoreElements()) {
+ NameClassPair pair = pairs.nextElement();
+ Object o;
+ if (name != null) {
+ o = context.lookup(name + "/" + pair.getName());
+ } else {
+ o = context.lookup(pair.getName());
+ }
+ if (o instanceof Context) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("/" + pair.getName());
+ contexts((Context) o, sb, contexts);
+ }
+ }
+ return contexts;
+ }
+
+ private void contexts(Context context, StringBuilder sb, List<String> contexts) throws Exception {
+ NamingEnumeration list = context.listBindings("");
+ while (list.hasMore()) {
+ Binding item = (Binding) list.next();
+ String name = item.getName();
+ Object o = item.getObject();
+ if (o instanceof Context) {
+ if (((Context) o).list("").hasMoreElements()) {
+ sb.append("/").append(name);
+ contexts((Context) o, sb, contexts);
+ } else {
+ contexts.add(sb.toString() + "/" + name);
+ }
+ }
+ }
+ }
+
+ /**
+ * Recursively list a context/names
+ *
+ * @param ctx the startup context.
+ * @param sb the string builder where to construct the full qualified name.
+ * @param map the final map containing name/class name pairs.
+ * @throws Exception
+ */
+ private static final void names(Context ctx, StringBuilder sb, Map<String, String> map) throws Exception {
+ NamingEnumeration list = ctx.listBindings("");
+ while (list.hasMore()) {
+ Binding item = (Binding) list.next();
+ String className = item.getClassName();
+ String name = item.getName();
+ Object o = item.getObject();
+ if (o instanceof Context) {
+ sb.append("/").append(name);
+ names((Context) o, sb, map);
+ } else {
+ map.put(sb.toString() + "/" + name, className);
+ }
+ }
+ }
+
+ @Override
+ public void create(String name) throws Exception {
+ Context context = new InitialContext();
+ String[] splitted = name.split("/");
+ if (splitted.length > 0) {
+ for (int i = 0; i < splitted.length; i++) {
+ try {
+ Object o = context.lookup(splitted[i]);
+ if (!(o instanceof Context)) {
+ throw new NamingException("Name " + splitted[i] + " already exists");
+ }
+ } catch (NameNotFoundException e) {
+ context.createSubcontext(splitted[i]);
+ }
+ context = (Context) context.lookup(splitted[i]);
+ }
+ } else {
+ context.createSubcontext(name);
+ }
+ }
+
+ @Override
+ public void delete(String name) throws Exception {
+ Context context = new InitialContext();
+ context.destroySubcontext(name);
+ }
+
+ @Override
+ public void bind(long serviceId, String name) throws Exception {
+ Context context = new InitialContext();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] services = bundle.getRegisteredServices();
+ if (services != null) {
+ for (ServiceReference service : services) {
+ if (service.getProperty(Constants.SERVICE_ID) != null && ((Long) service.getProperty(Constants.SERVICE_ID)) == serviceId) {
+ Object actualService = bundleContext.getService(service);
+ if (proxyManager.isProxy(actualService)) {
+ actualService = proxyManager.unwrap(actualService).call();
+ }
+ try {
+ String[] splitted = name.split("/");
+ if (splitted.length > 0) {
+ for (int i = 0; i < splitted.length - 1; i++) {
+ try {
+ Object o = context.lookup(splitted[i]);
+ if (!(o instanceof Context)) {
+ throw new NamingException("Name " + splitted[i] + " already exists");
+ }
+ } catch (NameNotFoundException nnfe) {
+ context.createSubcontext(splitted[i]);
+ }
+ context = (Context) context.lookup(splitted[i]);
+ }
+ name = splitted[splitted.length - 1];
+ }
+ context.bind(name, actualService);
+ } finally {
+ bundleContext.ungetService(service);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void alias(String name, String alias) throws Exception {
+ Context context = new InitialContext();
+ if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
+ // get the object
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] services = bundle.getRegisteredServices();
+ if (services != null) {
+ for (ServiceReference service : services) {
+ if (service.getProperty(OSGI_JNDI_SERVICE_PROPERTY) != null && ((String) service.getProperty(OSGI_JNDI_SERVICE_PROPERTY)).equals(name.substring(OSGI_JNDI_CONTEXT_PREFIX.length()))) {
+ Object actualService = bundleContext.getService(service);
+ try {
+ if (proxyManager.isProxy(actualService)) {
+ actualService = proxyManager.unwrap(actualService).call();
+ }
+ String[] splitted = alias.split("/");
+ if (splitted.length > 0) {
+ for (int i = 0; i < splitted.length - 1; i++) {
+ try {
+ Object o = context.lookup(splitted[i]);
+ if (!(o instanceof Context)) {
+ throw new NamingException("Name " + splitted[i] + " already exists");
+ }
+ } catch (NameNotFoundException nnfe) {
+ context.createSubcontext(splitted[i]);
+ }
+ context = (Context) context.lookup(splitted[i]);
+ }
+ alias = splitted[splitted.length -1];
+ }
+ context.bind(alias, actualService);
+ } finally {
+ bundleContext.ungetService(service);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ Object object = context.lookup(name);
+ String[] splitted = alias.split("/");
+ if (splitted.length > 0) {
+ for (int i = 0; i < splitted.length - 1; i++) {
+ try {
+ Object o = context.lookup(splitted[i]);
+ if (!(o instanceof Context)) {
+ throw new NamingException("Name " + splitted[i] + " already exists");
+ }
+ } catch (NameNotFoundException nnfe) {
+ context.createSubcontext(splitted[i]);
+ }
+ context = (Context) context.lookup(splitted[i]);
+ }
+ alias = splitted[splitted.length - 1];
+ }
+ context.bind(alias, object);
+ }
+ }
+
+ @Override
+ public void unbind(String name) throws Exception {
+ InitialContext context = new InitialContext();
+ if (name.startsWith(OSGI_JNDI_CONTEXT_PREFIX)) {
+ throw new IllegalArgumentException("You can't unbind a name from the " + OSGI_JNDI_CONTEXT_PREFIX + " JNDI context.");
+ }
+ context.unbind(name);
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public ProxyManager getProxyManager() {
+ return proxyManager;
+ }
+
+ public void setProxyManager(ProxyManager proxyManager) {
+ this.proxyManager = proxyManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
----------------------------------------------------------------------
diff --git a/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml b/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
new file mode 100644
index 0000000..e6be3b1
--- /dev/null
+++ b/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+ -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+ default-activation="lazy">
+
+ <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]"/>
+
+ <bean id="karafInitialContextFactory" class="org.apache.karaf.jndi.KarafInitialContextFactory"/>
+
+ <reference id="proxyManager" interface="org.apache.aries.proxy.ProxyManager"/>
+
+ <service ref="karafInitialContextFactory" interface="javax.naming.spi.InitialContextFactory"/>
+
+ <bean id="jndiService" class="org.apache.karaf.jndi.internal.JndiServiceImpl">
+ <property name="bundleContext" ref="blueprintBundleContext"/>
+ <property name="proxyManager" ref="proxyManager"/>
+ </bean>
+
+ <service ref="jndiService" interface="org.apache.karaf.jndi.JndiService">
+ <service-properties>
+ <!-- bind the JNDI service itself in the JNDI context -->
+ <entry key="osgi.jndi.service.name" value="jndi"/>
+ </service-properties>
+ </service>
+
+ <!-- Management -->
+ <bean id="jndiMBeanImpl" class="org.apache.karaf.jndi.internal.JndiMBeanImpl">
+ <property name="jndiService" ref="jndiService"/>
+ </bean>
+
+ <service ref="jndiMBeanImpl" auto-export="interfaces">
+ <service-properties>
+ <entry key="jmx.objectname" value="org.apache.karaf:type=jndi,name=$[karaf.name]"/>
+ </service-properties>
+ </service>
+
+</blueprint>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/85c65dd6/jndi/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/jndi/src/main/resources/OSGI-INF/bundle.info b/jndi/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..4a7a606
--- /dev/null
+++ b/jndi/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,19 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle is the core implementation of the JNDI service support.
+
+JNDI allows to expose any OSGi services as JNDI names. Karaf JNDI also provides a set of commands and a MBean to list
+the current JNDI names, create JNDI aliases, ...
+
+h1. See also
+
+JNDI - section of the Karaf User Guide
[45/59] [abbrv] git commit: [KARAF-2852] Merge obr/core and
obr/command
Posted by gn...@apache.org.
[KARAF-2852] Merge obr/core and obr/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b0a20b83
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b0a20b83
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b0a20b83
Branch: refs/heads/master
Commit: b0a20b83891cbfd301bc3f13704285b34aba4311
Parents: d5ce026
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 09:26:03 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:45 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 2 -
obr/NOTICE | 71 +++++
obr/command/NOTICE | 71 -----
obr/command/pom.xml | 113 --------
.../apache/karaf/obr/command/AddUrlCommand.java | 39 ---
.../apache/karaf/obr/command/DeployCommand.java | 44 ---
.../apache/karaf/obr/command/FindCommand.java | 130 ---------
.../apache/karaf/obr/command/InfoCommand.java | 108 -------
.../apache/karaf/obr/command/ListCommand.java | 85 ------
.../karaf/obr/command/ListUrlCommand.java | 50 ----
.../karaf/obr/command/ObrCommandSupport.java | 281 -------------------
.../karaf/obr/command/RefreshUrlCommand.java | 63 -----
.../karaf/obr/command/RemoveUrlCommand.java | 54 ----
.../karaf/obr/command/ResolveCommand.java | 145 ----------
.../apache/karaf/obr/command/SourceCommand.java | 66 -----
.../apache/karaf/obr/command/StartCommand.java | 41 ---
.../apache/karaf/obr/command/util/FileUtil.java | 177 ------------
.../src/main/resources/OSGI-INF/bundle.info | 29 --
.../karaf/obr/command/ListCommandTest.java | 59 ----
obr/core/NOTICE | 71 -----
obr/core/pom.xml | 87 ------
.../org/apache/karaf/obr/core/ObrMBean.java | 37 ---
.../karaf/obr/core/internal/ObrMBeanImpl.java | 203 --------------
.../resources/OSGI-INF/blueprint/blueprint.xml | 34 ---
.../src/main/resources/OSGI-INF/bundle.info | 25 --
obr/pom.xml | 70 ++++-
.../apache/karaf/obr/command/AddUrlCommand.java | 39 +++
.../apache/karaf/obr/command/DeployCommand.java | 44 +++
.../apache/karaf/obr/command/FindCommand.java | 130 +++++++++
.../apache/karaf/obr/command/InfoCommand.java | 108 +++++++
.../apache/karaf/obr/command/ListCommand.java | 85 ++++++
.../karaf/obr/command/ListUrlCommand.java | 50 ++++
.../karaf/obr/command/ObrCommandSupport.java | 281 +++++++++++++++++++
.../karaf/obr/command/RefreshUrlCommand.java | 63 +++++
.../karaf/obr/command/RemoveUrlCommand.java | 54 ++++
.../karaf/obr/command/ResolveCommand.java | 145 ++++++++++
.../apache/karaf/obr/command/SourceCommand.java | 66 +++++
.../apache/karaf/obr/command/StartCommand.java | 41 +++
.../apache/karaf/obr/command/util/FileUtil.java | 177 ++++++++++++
.../org/apache/karaf/obr/core/ObrMBean.java | 37 +++
.../karaf/obr/core/internal/ObrMBeanImpl.java | 203 ++++++++++++++
.../resources/OSGI-INF/blueprint/blueprint.xml | 34 +++
obr/src/main/resources/OSGI-INF/bundle.info | 25 ++
43 files changed, 1715 insertions(+), 2022 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/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 4c2be08..e596a84 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -114,9 +114,7 @@
<bundle start-level="30">mvn:org.apache.felix/org.osgi.service.obr/${felix.obr.version}</bundle>
<bundle start-level="30">mvn:org.apache.felix/org.apache.felix.bundlerepository/${felix.bundlerepository.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.obr/org.apache.karaf.obr.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.obr/org.apache.karaf.obr.command/${project.version}</bundle>
<bundle start-level="30">mvn:org.ops4j.pax.url/pax-url-obr/${pax.url.version}/jar/uber</bundle>
- <bundle start-level="31">mvn:org.apache.karaf.features/org.apache.karaf.features.obr/${project.version}</bundle>
</feature>
<feature name="bundle" description="Provide Bundle support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/NOTICE
----------------------------------------------------------------------
diff --git a/obr/NOTICE b/obr/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/obr/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/b0a20b83/obr/command/NOTICE
----------------------------------------------------------------------
diff --git a/obr/command/NOTICE b/obr/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/obr/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/b0a20b83/obr/command/pom.xml
----------------------------------------------------------------------
diff --git a/obr/command/pom.xml b/obr/command/pom.xml
deleted file mode 100644
index 0c9457f..0000000
--- a/obr/command/pom.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?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.obr</groupId>
- <artifactId>obr</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.obr.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: OBR :: Command</name>
- <description>Shell commands to manipulate the OBR service</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.bundlerepository</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <Export-Package>
- !*
- </Export-Package>
- <Karaf-Commands>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
deleted file mode 100644
index 5aaf13a..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/AddUrlCommand.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.List;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "obr", name = "url-add", description = "Adds a list of repository URLs to the OBR service.")
-@Service
-public class AddUrlCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "urls", description = "Repository URLs to add to the OBR service separated by whitespaces", required = true, multiValued = true)
- List<String> urls;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- for (String url : urls) {
- admin.addRepository(url);
- }
- persistRepositoryList(admin);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/DeployCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
deleted file mode 100644
index a852c70..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/DeployCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.List;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.karaf.shell.api.action.Argument;
-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;
-
-@Command(scope = "obr", name = "deploy", description = "Deploys a list of bundles using OBR service.")
-@Service
-public class DeployCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "bundles", description = "List of bundle names to deploy (separated by whitespaces)", required = true, multiValued = true)
- protected List<String> bundles;
-
- @Option(name = "-s", aliases = { "--start" }, description = "Start the deployed bundles", required = false, multiValued = false)
- protected boolean start = false;
-
- @Option(name = "-d", aliases = { "--deployOptional" }, description = "Deploy optional bundles", required = false, multiValued = false)
- protected boolean deployOptional = false;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- doDeploy(admin, bundles, start, deployOptional);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/FindCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/FindCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/FindCommand.java
deleted file mode 100644
index fad967b..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/FindCommand.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.obr.command;
-
-import org.apache.felix.bundlerepository.Capability;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-import java.io.PrintStream;
-import java.lang.reflect.Array;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-@Command(scope = "obr", name = "find", description = "Find OBR bundles for a given filter.")
-@Service
-public class FindCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "requirements", description = "Requirement", required = true, multiValued = true)
- List<String> requirements;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- Resource[] resources = admin.discoverResources(parseRequirements(admin, requirements));
- if (resources == null)
- {
- System.err.println("No matching resources.");
- }
- else
- {
- for (int resIdx = 0; resIdx < resources.length; resIdx++)
- {
- if (resIdx > 0)
- {
- System.out.println("");
- }
- printResource(System.out, resources[resIdx]);
- }
- }
- }
-
- private void printResource(PrintStream out, Resource resource)
- {
- String name = resource.getPresentationName();
- if (name == null) {
- name = resource.getSymbolicName();
- }
-
- printUnderline(out, name.length());
- out.println(name);
- printUnderline(out, name .length());
-
- Map map = resource.getProperties();
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); )
- {
- Map.Entry entry = (Map.Entry) iter.next();
- if (entry.getValue().getClass().isArray())
- {
- out.println(entry.getKey() + ":");
- for (int j = 0; j < Array.getLength(entry.getValue()); j++)
- {
- out.println(" " + Array.get(entry.getValue(), j));
- }
- }
- else
- {
- out.println(entry.getKey() + ": " + entry.getValue());
- }
- }
-
- Requirement[] reqs = resource.getRequirements();
- if ((reqs != null) && (reqs.length > 0))
- {
- boolean hdr = false;
- for (int i = 0; i < reqs.length; i++)
- {
- if (!reqs[i].isOptional())
- {
- if (!hdr)
- {
- hdr = true;
- out.println("Requirements:");
- }
- out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
- }
- }
- hdr = false;
- for (int i = 0; i < reqs.length; i++)
- {
- if (reqs[i].isOptional())
- {
- if (!hdr)
- {
- hdr = true;
- out.println("Optional Requirements:");
- }
- out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
- }
- }
- }
-
- Capability[] caps = resource.getCapabilities();
- if ((caps != null) && (caps.length > 0))
- {
- out.println("Capabilities:");
- for (int i = 0; i < caps.length; i++)
- {
- out.println(" " + caps[i].getName() + ":" + caps[i].getPropertiesAsMap());
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/InfoCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
deleted file mode 100644
index bacc61b..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/InfoCommand.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.io.PrintStream;
-import java.lang.reflect.Array;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.bundlerepository.Capability;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "obr", name = "info", description = "Prints information about OBR bundles.")
-@Service
-public class InfoCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "bundles", description = "Specify bundles to query for information (separated by whitespaces)", required = true, multiValued = true)
- List<String> bundles;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- for (String bundle : bundles) {
- String[] target = getTarget(bundle);
- Resource[] resources = searchRepository(admin, target[0], target[1]);
- if (resources == null)
- {
- System.err.println("Unknown bundle and/or version: "
- + target[0]);
- }
- else
- {
- for (int resIdx = 0; resIdx < resources.length; resIdx++)
- {
- if (resIdx > 0)
- {
- System.out.println("");
- }
- printResource(System.out, resources[resIdx]);
- }
- }
- }
- }
-
- private void printResource(PrintStream out, Resource resource)
- {
- printUnderline(out, resource.getPresentationName().length());
- out.println(resource.getPresentationName());
- printUnderline(out, resource.getPresentationName().length());
-
- Map map = resource.getProperties();
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); )
- {
- Map.Entry entry = (Map.Entry) iter.next();
- if (entry.getValue().getClass().isArray())
- {
- out.println(entry.getKey() + ":");
- for (int j = 0; j < Array.getLength(entry.getValue()); j++)
- {
- out.println(" " + Array.get(entry.getValue(), j));
- }
- }
- else
- {
- out.println(entry.getKey() + ": " + entry.getValue());
- }
- }
-
- Requirement[] reqs = resource.getRequirements();
- if ((reqs != null) && (reqs.length > 0))
- {
- out.println("Requires:");
- for (int i = 0; i < reqs.length; i++)
- {
- out.println(" " + reqs[i].getName() + ":" + reqs[i].getFilter());
- }
- }
-
- Capability[] caps = resource.getCapabilities();
- if ((caps != null) && (caps.length > 0))
- {
- out.println("Capabilities:");
- for (int i = 0; i < caps.length; i++)
- {
- out.println(" " + caps[i].getName() + ":" + caps[i].getPropertiesAsMap());
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/ListCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/ListCommand.java
deleted file mode 100644
index 45db82f..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/ListCommand.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.List;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.shell.api.action.Argument;
-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 = "obr", name = "list", description = "Lists OBR bundles, optionally providing the given packages.")
-@Service
-public class ListCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "packages", description = "A list of packages separated by whitespaces.", required = false, multiValued = true)
- List<String> packages;
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Override
- void doExecute(RepositoryAdmin admin) throws Exception {
- StringBuilder substr = new StringBuilder();
-
- if (packages != null) {
- for (String packageName : packages) {
- substr.append(" ");
- substr.append(packageName);
- }
- }
-
- String query;
- if ((substr == null) || (substr.length() == 0)) {
- query = "(|(presentationname=*)(symbolicname=*))";
- } else {
- query = "(|(presentationname=*" + substr + "*)(symbolicname=*" + substr + "*))";
- }
- Resource[] resources = admin.discoverResources(query);
- int maxPName = 4;
- int maxSName = 13;
- int maxVersion = 7;
- for (Resource resource : resources) {
- maxPName = Math.max(maxPName, emptyIfNull(resource.getPresentationName()).length());
- maxSName = Math.max(maxSName, emptyIfNull(resource.getSymbolicName()).length());
- maxVersion = Math.max(maxVersion, emptyIfNull(resource.getVersion()).length());
- }
-
- ShellTable table = new ShellTable();
- table.column("Name");
- table.column("Symbolic Name");
- table.column("Version");
- table.emptyTableText("No matching bundles");
-
- for (Resource resource : resources) {
- table.addRow().addContent(emptyIfNull(resource.getPresentationName()),
- emptyIfNull(resource.getSymbolicName()),
- emptyIfNull(resource.getVersion()));
- }
-
- table.print(System.out, !noFormat);
- }
-
- private String emptyIfNull(Object st) {
- return st == null ? "" : st.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
deleted file mode 100644
index 1c07236..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/ListUrlCommand.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.obr.command;
-
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-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 = "obr", name = "url-list", description = "Displays the repository URLs currently associated with the OBR service.")
-@Service
-public class ListUrlCommand extends ObrCommandSupport {
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- protected void doExecute(RepositoryAdmin admin) {
-
- ShellTable table = new ShellTable();
- table.column("Index");
- table.column("OBR URL");
- table.emptyTableText("No OBR repository URL");
-
- Repository[] repos = admin.listRepositories();
- if (repos != null) {
- for (int i = 0; i < repos.length; i++) {
- table.addRow().addContent(i, repos[i].getURI());
- }
- }
-
- table.print(System.out, !noFormat);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java b/obr/command/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
deleted file mode 100644
index 5f038b4..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/ObrCommandSupport.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintStream;
-import java.util.List;
-
-import org.apache.felix.bundlerepository.Reason;
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resolver;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.Version;
-
-public abstract class ObrCommandSupport implements Action {
-
- protected static final char VERSION_DELIM = ',';
-
- @Reference
- private RepositoryAdmin repositoryAdmin;
-
- @Reference
- BundleContext bundleContext;
-
- public void setRepositoryAdmin(RepositoryAdmin repositoryAdmin) {
- this.repositoryAdmin = repositoryAdmin;
- }
-
- @Override
- public Object execute() throws Exception {
- doExecute(repositoryAdmin);
- return null;
- }
-
- abstract void doExecute(RepositoryAdmin admin) throws Exception;
-
- protected Resource[] searchRepository(RepositoryAdmin admin, String targetId, String targetVersion) throws InvalidSyntaxException {
- // Try to see if the targetId is a bundle ID.
- try {
- Bundle bundle = bundleContext.getBundle(Long.parseLong(targetId));
- targetId = bundle.getSymbolicName();
- } catch (NumberFormatException ex) {
- // It was not a number, so ignore.
- }
-
- // The targetId may be a bundle name or a bundle symbolic name,
- // so create the appropriate LDAP query.
- StringBuffer sb = new StringBuffer("(|(presentationname=");
- sb.append(targetId);
- sb.append(")(symbolicname=");
- sb.append(targetId);
- sb.append("))");
- if (targetVersion != null) {
- sb.insert(0, "(&");
- sb.append("(version=");
- sb.append(targetVersion);
- sb.append("))");
- }
- return admin.discoverResources(sb.toString());
- }
-
- public Resource selectNewestVersion(Resource[] resources) {
- int idx = -1;
- Version v = null;
- for (int i = 0; (resources != null) && (i < resources.length); i++) {
- if (i == 0) {
- idx = 0;
- v = resources[i].getVersion();
- } else {
- Version vtmp = resources[i].getVersion();
- if (vtmp.compareTo(v) > 0) {
- idx = i;
- v = vtmp;
- }
- }
- }
- return (idx < 0) ? null : resources[idx];
- }
-
- protected String[] getTarget(String bundle) {
- String[] target;
- int idx = bundle.indexOf(VERSION_DELIM);
- if (idx > 0) {
- target = new String[]{bundle.substring(0, idx), bundle.substring(idx + 1)};
- } else {
- target = new String[]{bundle, null};
- }
- return target;
- }
-
- protected void printUnderline(PrintStream out, int length) {
- for (int i = 0; i < length; i++) {
- out.print('-');
- }
- out.println("");
- }
-
- protected void doDeploy(RepositoryAdmin admin, List<String> bundles, boolean start, boolean deployOptional) throws Exception {
- Resolver resolver = admin.resolver();
- for (String bundle : bundles) {
- String[] target = getTarget(bundle);
- Resource resource = selectNewestVersion(searchRepository(admin, target[0], target[1]));
- if (resource != null) {
- resolver.add(resource);
- } else {
- System.err.println("Unknown bundle - " + target[0]);
- }
- }
- if ((resolver.getAddedResources() != null) &&
- (resolver.getAddedResources().length > 0)) {
- if (resolver.resolve(deployOptional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
- System.out.println("Target resource(s):");
- printUnderline(System.out, 19);
- Resource[] resources = resolver.getAddedResources();
- for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) {
- System.out.println(" " + resources[resIdx].getPresentationName()
- + " (" + resources[resIdx].getVersion() + ")");
- }
- resources = resolver.getRequiredResources();
- if ((resources != null) && (resources.length > 0)) {
- System.out.println("\nRequired resource(s):");
- printUnderline(System.out, 21);
- for (int resIdx = 0; resIdx < resources.length; resIdx++) {
- System.out.println(" " + resources[resIdx].getPresentationName()
- + " (" + resources[resIdx].getVersion() + ")");
- }
- }
- if (deployOptional) {
- resources = resolver.getOptionalResources();
- if ((resources != null) && (resources.length > 0)) {
- System.out.println("\nOptional resource(s):");
- printUnderline(System.out, 21);
- for (int resIdx = 0; resIdx < resources.length; resIdx++) {
- System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")");
- }
- }
- }
-
- try {
- System.out.print("\nDeploying...");
- resolver.deploy(start ? Resolver.START : 0);
- System.out.println("done.");
- } catch (IllegalStateException ex) {
- System.err.println(ex);
- }
- } else {
- Reason[] reqs = resolver.getUnsatisfiedRequirements();
- if ((reqs != null) && (reqs.length > 0)) {
- System.out.println("Unsatisfied requirement(s):");
- printUnderline(System.out, 27);
- for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) {
- System.out.println(" " + reqs[reqIdx].getRequirement().getFilter());
- System.out.println(" " + reqs[reqIdx].getResource().getPresentationName());
- }
- } else {
- System.out.println("Could not resolve targets.");
- }
- }
- }
-
- }
-
-
- protected Requirement parseRequirement(RepositoryAdmin admin, String req) throws InvalidSyntaxException {
- int p = req.indexOf(':');
- String name;
- String filter;
- if (p > 0) {
- name = req.substring(0, p);
- filter = req.substring(p + 1);
- } else {
- if (req.contains("package")) {
- name = "package";
- } else if (req.contains("service")) {
- name = "service";
- } else {
- name = "bundle";
- }
- filter = req;
- }
- if (!filter.startsWith("(")) {
- filter = "(" + filter + ")";
- }
- return admin.getHelper().requirement(name, filter);
- }
-
- protected Requirement[] parseRequirements(RepositoryAdmin admin, List<String> requirements) throws InvalidSyntaxException {
- Requirement[] reqs = new Requirement[requirements.size()];
- for (int i = 0; i < reqs.length; i++) {
- reqs[i] = parseRequirement(admin, requirements.get(i));
- }
- return reqs;
- }
-
- public static final String REPOSITORY_URL_PROP = "obr.repository.url";
-
- protected void persistRepositoryList(RepositoryAdmin admin) {
- try {
- StringBuilder sb = new StringBuilder();
- for (Repository repo : admin.listRepositories()) {
- if (sb.length() > 0) {
- sb.append(" ");
- }
- sb.append(repo.getURI());
- }
- File etc = new File(System.getProperty("karaf.etc"));
- File sys = new File(etc, "config.properties");
- File sysTmp = new File(etc, "config.properties.tmp");
-
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(sysTmp)));
- boolean modified = false;
- try {
- if (sys.exists()) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(sys)));
- try {
- String line = reader.readLine();
- while (line != null) {
- if (line.matches("obr\\.repository\\.url[:= ].*")) {
- modified = true;
- line = "obr.repository.url = " + sb.toString();
- }
- writer.write(line);
- writer.newLine();
- line = reader.readLine();
- }
- } finally {
- reader.close();
- }
- }
- if (!modified) {
- writer.newLine();
- writer.write("# ");
- writer.newLine();
- writer.write("# OBR Repository list");
- writer.newLine();
- writer.write("# ");
- writer.newLine();
- writer.write("obr.repository.url = " + sb.toString());
- writer.newLine();
- writer.newLine();
- }
- } finally {
- writer.close();
- }
-
- sys.delete();
- sysTmp.renameTo(sys);
-
- } catch (Exception e) {
- System.err.println("Error while persisting repository list");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
deleted file mode 100644
index 20a65ed..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/RefreshUrlCommand.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.List;
-
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.karaf.shell.api.action.Argument;
-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;
-
-@Command(scope = "obr", name = "url-refresh", description = "Reloads the repositories to obtain a fresh list of bundles.")
-@Service
-public class RefreshUrlCommand extends ObrCommandSupport {
-
- @Option(name = "-i", aliases = { "--index" }, description = "Use index to identify URL", required = false, multiValued = false)
- boolean useIndex;
-
- @Argument(index = 0, name = "ids", description = "Repository URLs (or indexes if you use -i) to refresh (leave empty for all)", required = false, multiValued = true)
- List<String> ids;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- if (ids != null && !ids.isEmpty()) {
- for (String id : ids) {
- if (useIndex) {
- Repository[] repos = admin.listRepositories();
- int index = Integer.parseInt(id);
- if (index >= 0 && index < repos.length) {
- admin.addRepository(repos[index].getURI());
- } else {
- System.err.println("Invalid index");
- }
- } else {
- admin.addRepository(id);
- }
- }
- } else {
- Repository[] repos = admin.listRepositories();
- if ((repos != null) && (repos.length > 0)) {
- for (int i = 0; i < repos.length; i++) {
- admin.addRepository(repos[i].getURI());
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java
deleted file mode 100644
index 2d41519..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/RemoveUrlCommand.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.List;
-
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.karaf.shell.api.action.Argument;
-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;
-
-@Command(scope = "obr", name = "url-remove", description = "Removes a list of repository URLs from the OBR service.")
-@Service
-public class RemoveUrlCommand extends ObrCommandSupport {
-
- @Option(name = "-i", aliases = { "--index" }, description = "Use index to identify URL", required = false, multiValued = false)
- boolean useIndex;
-
- @Argument(index = 0, name = "ids", description = "Repository URLs (or indexes if you use -i) to remove from OBR service", required = true, multiValued = true)
- List<String> ids;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- for (String id : ids) {
- if (useIndex) {
- Repository[] repos = admin.listRepositories();
- int index = Integer.parseInt(id);
- if (index >= 0 && index < repos.length) {
- admin.removeRepository(repos[index].getURI());
- } else {
- System.err.println("Invalid index");
- }
- } else {
- admin.removeRepository(id);
- }
- }
- persistRepositoryList(admin);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
deleted file mode 100644
index ab1bd04..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/ResolveCommand.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.felix.bundlerepository.Reason;
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resolver;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.shell.api.action.Argument;
-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;
-
-@Command(scope = "obr", name = "resolve", description = "Shows the resolution output for a given set of requirements.")
-@Service
-public class ResolveCommand extends ObrCommandSupport {
-
- @Option(name = "-w", aliases = "--why", description = "Display the reason of the inclusion of the resource")
- boolean why;
-
- @Option(name = "-l", aliases = "--no-local", description = "Ignore local resources during resolution")
- boolean noLocal;
-
- @Option(name = "--no-remote", description = "Ignore remote resources during resolution")
- boolean noRemote;
-
- @Option(name = "--deploy", description = "Deploy the selected bundles")
- boolean deploy;
-
- @Option(name = "--start", description = "Deploy and start the selected bundles")
- boolean start;
-
- @Option(name = "--optional", description = "Resolve optional dependencies")
- boolean optional;
-
- @Argument(index = 0, name = "requirements", description = "Requirements", required = true, multiValued = true)
- List<String> requirements;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- List<Repository> repositories = new ArrayList<Repository>();
- repositories.add(admin.getSystemRepository());
- if (!noLocal) {
- repositories.add(admin.getLocalRepository());
- }
- if (!noRemote) {
- repositories.addAll(Arrays.asList(admin.listRepositories()));
- }
- Resolver resolver = admin.resolver(repositories.toArray(new Repository[repositories.size()]));
- for (Requirement requirement : parseRequirements(admin, requirements)) {
- resolver.add(requirement);
- }
- if (resolver.resolve(optional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) {
- Resource[] resources;
- resources = resolver.getRequiredResources();
- if ((resources != null) && (resources.length > 0)) {
- System.out.println("Required resource(s):");
- printUnderline(System.out, 21);
- for (int resIdx = 0; resIdx < resources.length; resIdx++) {
- System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")");
- if (why) {
- Reason[] req = resolver.getReason(resources[resIdx]);
- for (int reqIdx = 0; req != null && reqIdx < req.length; reqIdx++) {
- if (!req[reqIdx].getRequirement().isOptional()) {
- Resource r = req[reqIdx].getResource();
- if (r != null) {
- System.out.println(" - " + r.getPresentationName() + " / " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
- } else {
- System.out.println(" - " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
- }
- }
- }
- }
- }
- }
- resources = resolver.getOptionalResources();
- if ((resources != null) && (resources.length > 0)) {
- System.out.println();
- System.out.println("Optional resource(s):");
- printUnderline(System.out, 21);
- for (int resIdx = 0; resIdx < resources.length; resIdx++) {
- System.out.println(" " + resources[resIdx].getPresentationName()
- + " (" + resources[resIdx].getVersion() + ")");
- if (why) {
- Reason[] req = resolver.getReason(resources[resIdx]);
- for (int reqIdx = 0; req != null && reqIdx < req.length; reqIdx++) {
- if (!req[reqIdx].getRequirement().isOptional()) {
- Resource r = req[reqIdx].getResource();
- if (r != null) {
- System.out.println(" - " + r.getPresentationName() + " / " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
- } else {
- System.out.println(" - " + req[reqIdx].getRequirement().getName() + ":" + req[reqIdx].getRequirement().getFilter());
- }
- }
- }
- }
- }
- }
- if (deploy || start) {
- try
- {
- System.out.print("\nDeploying...");
- resolver.deploy(start ? Resolver.START : 0);
- System.out.println("done.");
- }
- catch (IllegalStateException ex)
- {
- System.err.println(ex);
- }
- }
- } else {
- Reason[] reqs = resolver.getUnsatisfiedRequirements();
- if ((reqs != null) && (reqs.length > 0)) {
- System.out.println("Unsatisfied requirement(s):");
- printUnderline(System.out, 27);
- for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) {
- System.out.println(" " + reqs[reqIdx].getRequirement().getName() + ":" + reqs[reqIdx].getRequirement().getFilter());
- System.out.println(" " +reqs[reqIdx].getResource().getPresentationName());
- }
- } else {
- System.out.println("Could not resolve targets.");
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/SourceCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
deleted file mode 100644
index 161ba82..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/SourceCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.obr.command;
-
-import java.net.URI;
-import java.util.List;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.karaf.obr.command.util.FileUtil;
-import org.apache.karaf.shell.api.action.Argument;
-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;
-
-@Command(scope = "obr", name = "source", description = "Downloads the sources for an OBR bundle.")
-@Service
-public class SourceCommand extends ObrCommandSupport {
-
- @Option(name = "-x", aliases = {}, description = "Extract the archive", required = false, multiValued = false)
- boolean extract;
-
- @Argument(index = 0, name = "folder", description = "Local folder for storing sources", required = true, multiValued = false)
- String localDir;
-
- @Argument(index = 1, name = "bundles", description = "List of bundles to download the sources for", required = true, multiValued = true)
- List<String> bundles;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- for (String bundle : bundles) {
- String[] target = getTarget(bundle);
- Resource resource = selectNewestVersion(searchRepository(admin, target[0], target[1]));
- if (resource == null)
- {
- System.err.println("Unknown bundle and/or version: " + target[0]);
- }
- else
- {
- URI srcURL = (URI) resource.getProperties().get(Resource.SOURCE_URI);
- if (srcURL != null)
- {
- FileUtil.downloadSource(System.out, System.err, srcURL.toURL(), localDir, extract);
- }
- else
- {
- System.err.println("Missing source URL: " + target[0]);
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/StartCommand.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/StartCommand.java b/obr/command/src/main/java/org/apache/karaf/obr/command/StartCommand.java
deleted file mode 100644
index 0465bae..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/StartCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.obr.command;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.karaf.shell.api.action.Argument;
-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 java.util.List;
-
-@Command(scope = "obr", name = "start", description = "Deploys and starts a list of bundles using OBR.")
-@Service
-public class StartCommand extends ObrCommandSupport {
-
- @Argument(index = 0, name = "bundles", description = "List of bundles to deploy (separated by whitespaces)", required = true, multiValued = true)
- protected List<String> bundles;
-
- @Option(name = "-d", aliases = { "--deployOptional" }, description = "Deploy optional bundles", required = false, multiValued = false)
- protected boolean deployOptional = false;
-
- protected void doExecute(RepositoryAdmin admin) throws Exception {
- doDeploy(admin, bundles, true, deployOptional);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/obr/command/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java b/obr/command/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
deleted file mode 100644
index 26aa0bd..0000000
--- a/obr/command/src/main/java/org/apache/karaf/obr/command/util/FileUtil.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.obr.command.util;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-
-public class FileUtil
-{
- public static void downloadSource(
- PrintStream out, PrintStream err,
- URL srcURL, String dirStr, boolean extract)
- {
- // Get the file name from the URL.
- String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
- ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
- : srcURL.getFile();
-
- try
- {
- out.println("Connecting...");
-
- File dir = new File(dirStr);
- if (!dir.exists())
- {
- err.println("Destination directory does not exist.");
- }
- File file = new File(dir, fileName);
-
- OutputStream os = new FileOutputStream(file);
- URLConnection conn = srcURL.openConnection();
- int total = conn.getContentLength();
- InputStream is = conn.getInputStream();
-
- if (total > 0)
- {
- out.println("Downloading " + fileName
- + " ( " + total + " bytes ).");
- }
- else
- {
- out.println("Downloading " + fileName + ".");
- }
- byte[] buffer = new byte[4096];
- int count = 0;
- for (int len = is.read(buffer); len > 0; len = is.read(buffer))
- {
- count += len;
- os.write(buffer, 0, len);
- }
-
- os.close();
- is.close();
-
- if (extract)
- {
- is = new FileInputStream(file);
- JarInputStream jis = new JarInputStream(is);
- out.println("Extracting...");
- unjar(jis, dir);
- jis.close();
- file.delete();
- }
- }
- catch (Exception ex)
- {
- err.println(ex);
- }
- }
-
- public static void unjar(JarInputStream jis, File dir)
- throws IOException
- {
- // Reusable buffer.
- byte[] buffer = new byte[4096];
-
- // Loop through JAR entries.
- for (JarEntry je = jis.getNextJarEntry();
- je != null;
- je = jis.getNextJarEntry())
- {
- if (je.getName().startsWith("/"))
- {
- throw new IOException("JAR resource cannot contain absolute paths.");
- }
-
- File target = new File(dir, je.getName());
-
- // Check to see if the JAR entry is a directory.
- if (je.isDirectory())
- {
- if (!target.exists())
- {
- if (!target.mkdirs())
- {
- throw new IOException("Unable to create target directory: "
- + target);
- }
- }
- // Just continue since directories do not have content to copy.
- continue;
- }
-
- int lastIndex = je.getName().lastIndexOf('/');
- String name = (lastIndex >= 0) ?
- je.getName().substring(lastIndex + 1) : je.getName();
- String destination = (lastIndex >= 0) ?
- je.getName().substring(0, lastIndex) : "";
-
- // JAR files use '/', so convert it to platform separator.
- destination = destination.replace('/', File.separatorChar);
- copy(jis, dir, name, destination, buffer);
- }
- }
-
- public static void copy(
- InputStream is, File dir, String destName, String destDir, byte[] buffer)
- throws IOException
- {
- if (destDir == null)
- {
- destDir = "";
- }
-
- // Make sure the target directory exists and
- // that is actually a directory.
- File targetDir = new File(dir, destDir);
- if (!targetDir.exists())
- {
- if (!targetDir.mkdirs())
- {
- throw new IOException("Unable to create target directory: "
- + targetDir);
- }
- }
- else if (!targetDir.isDirectory())
- {
- throw new IOException("Target is not a directory: "
- + targetDir);
- }
-
- BufferedOutputStream bos = new BufferedOutputStream(
- new FileOutputStream(new File(targetDir, destName)));
- int count = 0;
- while ((count = is.read(buffer)) > 0)
- {
- bos.write(buffer, 0, count);
- }
- bos.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/obr/command/src/main/resources/OSGI-INF/bundle.info b/obr/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index cb73396..0000000
--- a/obr/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,29 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to manipulate the Karaf embedded OBR (OSGi Bundle Repository).
-
-The following commands are available:
-* obr:addUrl - Adds a list of repository URLs to the OBR service.
-* obr:deploy - Deploys a list of bundles using OBR service.
-* obr:find - Find OBR bundles for a given filter.
-* obr:info - Prints information about OBR bundles.
-* obr:list - Lists OBR bundles.
-* obr:listUrl - Displays the repository URLs currently associated with the OBR service.
-* obr:refreshUrl - Reloads the repositories to obtain a fresh list of bundles.
-* obr:removeUrl - Removes a list of repository URLs from the OBR service.
-* obr:resolve - Shows the resolution output for a given set of requirements.
-* obr:source - Downloads the sources for an OBR bundle.
-* obr:start - Deploys and starts a list of bundles using OBR.
-
-h1. See also
-
-Commands - and Provisioning - sections of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/command/src/test/java/org/apache/karaf/obr/command/ListCommandTest.java
----------------------------------------------------------------------
diff --git a/obr/command/src/test/java/org/apache/karaf/obr/command/ListCommandTest.java b/obr/command/src/test/java/org/apache/karaf/obr/command/ListCommandTest.java
deleted file mode 100644
index a4bbb17..0000000
--- a/obr/command/src/test/java/org/apache/karaf/obr/command/ListCommandTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.obr.command;
-
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.felix.bundlerepository.impl.ResourceImpl;
-import org.easymock.EasyMock;
-import org.easymock.IMocksControl;
-import org.junit.Test;
-
-public class ListCommandTest {
-
- /**
- * Show how the list of obr resources looks like
- * @throws Exception
- */
- @Test
- public void testList() throws Exception {
- IMocksControl control = EasyMock.createControl();
- RepositoryAdmin repoAdmin = control.createMock(RepositoryAdmin.class);
- ListCommand command = new ListCommand();
- command.setRepositoryAdmin(repoAdmin);
-
- Resource[] resources = new Resource[] {
- createResource("My bundle", "my.bundle", "1.0.0"),
- createResource("My other Bundle", "org.apache.mybundle", "2.0.1")
- };
- EasyMock.expect(repoAdmin.discoverResources("(|(presentationname=*)(symbolicname=*))")).
- andReturn(resources);
-
- control.replay();
- command.execute();
- control.verify();
- }
-
- private Resource createResource(String presentationName, String symbolicName, String version) {
- ResourceImpl r1 = new ResourceImpl();
- r1.put(Resource.PRESENTATION_NAME, presentationName);
- r1.put(Resource.SYMBOLIC_NAME, symbolicName);
- r1.put(Resource.VERSION, version);
- return r1;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/core/NOTICE
----------------------------------------------------------------------
diff --git a/obr/core/NOTICE b/obr/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/obr/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/b0a20b83/obr/core/pom.xml
----------------------------------------------------------------------
diff --git a/obr/core/pom.xml b/obr/core/pom.xml
deleted file mode 100644
index a9af4c3..0000000
--- a/obr/core/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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.obr</groupId>
- <artifactId>obr</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.obr.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: OBR :: Core</name>
- <description>OBR core services and MBeans</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.apache.felix</groupId>
- <artifactId>org.apache.felix.bundlerepository</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <includes>
- <include>**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>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>
- <Export-Package>
- org.apache.karaf.obr.core
- </Export-Package>
- <Private-Package>
- org.apache.karaf.obr.core.internal
- </Private-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/b0a20b83/obr/core/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
----------------------------------------------------------------------
diff --git a/obr/core/src/main/java/org/apache/karaf/obr/core/ObrMBean.java b/obr/core/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
deleted file mode 100644
index bf5ebcb..0000000
--- a/obr/core/src/main/java/org/apache/karaf/obr/core/ObrMBean.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.obr.core;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.TabularData;
-import java.util.List;
-
-/**
- * OBR MBean.
- */
-public interface ObrMBean {
-
- List<String> getUrls();
- TabularData getBundles() throws MBeanException;
-
- void addUrl(String url) throws MBeanException;
- void removeUrl(String url);
- void refreshUrl(String url) throws MBeanException;
-
- void deployBundle(String bundle) throws MBeanException;
- void deployBundle(String bundle, boolean start, boolean deployOptional) throws MBeanException;
-}
[40/59] [abbrv] git commit: [KARAF-2852] Merge service/command into
service/core
Posted by gn...@apache.org.
[KARAF-2852] Merge service/command into service/core
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/149822e9
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/149822e9
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/149822e9
Branch: refs/heads/master
Commit: 149822e903f5236ec48ce03af21dcfee8ade12b5
Parents: 91232f8
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 23:26:53 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:27 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
.../karaf/service/command/ListServices.java | 163 -------------------
.../service/command/ObjectClassCompleter.java | 58 -------
.../service/command/ObjectClassMatcher.java | 43 -----
.../org/apache/karaf/service/command/Wait.java | 86 ----------
.../service/command/ListServiceNamesTest.java | 34 ----
.../karaf/service/command/ListServicesTest.java | 35 ----
.../service/command/ObjectClassMatcherTest.java | 45 -----
.../service/command/TestBundleFactory.java | 104 ------------
service/core/pom.xml | 7 +
.../karaf/service/command/ListServices.java | 163 +++++++++++++++++++
.../service/command/ObjectClassCompleter.java | 58 +++++++
.../service/command/ObjectClassMatcher.java | 43 +++++
.../org/apache/karaf/service/command/Wait.java | 86 ++++++++++
.../service/command/ListServiceNamesTest.java | 34 ++++
.../karaf/service/command/ListServicesTest.java | 35 ++++
.../service/command/ObjectClassMatcherTest.java | 45 +++++
.../service/command/TestBundleFactory.java | 104 ++++++++++++
service/pom.xml | 1 -
19 files changed, 575 insertions(+), 570 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/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 ae6ab68..90c38db 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -161,7 +161,6 @@
<feature name="service" description="Provide Service support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.service/org.apache.karaf.service.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.service/org.apache.karaf.service.command/${project.version}</bundle>
</feature>
<feature name="system" description="Provide System support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/main/java/org/apache/karaf/service/command/ListServices.java
----------------------------------------------------------------------
diff --git a/service/command/src/main/java/org/apache/karaf/service/command/ListServices.java b/service/command/src/main/java/org/apache/karaf/service/command/ListServices.java
deleted file mode 100644
index caf546b..0000000
--- a/service/command/src/main/java/org/apache/karaf/service/command/ListServices.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.service.command;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-@Command(scope = "service", name = "list", description = "Lists OSGi services.")
-@Service
-public class ListServices implements Action {
-
- @Argument(index = 0, name = "objectClass", description = "Name of service objectClass to filter for", required = false,
- multiValued = false)
- @Completion(ObjectClassCompleter.class)
- String objectClass;
-
- @Option(name = "-a", aliases = {}, description = "Shows all services. (By default Karaf commands are hidden)", required = false, multiValued = false)
- boolean showAll;
-
- @Option(name = "-n", aliases = {}, description = "Shows only service class names", required = false, multiValued = false)
- boolean onlyNames;
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- if (onlyNames) {
- listNames();
- return null;
- }
- List<ServiceReference<?>> serviceRefs = new ArrayList<ServiceReference<?>>();
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] services = bundle.getRegisteredServices();
- if (services != null) {
- for (ServiceReference<?> ref : services) {
- String[] objectClasses = (String[])ref.getProperty(Constants.OBJECTCLASS);
- if (objectClass == null || ObjectClassMatcher.matchesAtLeastOneName(objectClasses, objectClass)) {
- serviceRefs.add(ref);
- }
- }
- }
- }
-
- Collections.sort(serviceRefs, new ServiceClassComparator());
-
- for (ServiceReference<?> serviceRef : serviceRefs) {
- if (showAll || !isCommand((String[])serviceRef.getProperty(Constants.OBJECTCLASS))) {
- printServiceRef(serviceRef);
- }
- }
- return null;
- }
-
- private void listNames() {
- Map<String, Integer> serviceNames = getServiceNamesMap(bundleContext);
- ArrayList<String> serviceNamesList = new ArrayList<String>(serviceNames.keySet());
- Collections.sort(serviceNamesList);
- for (String name : serviceNamesList) {
- System.out.println(name + " (" + serviceNames.get(name) + ")");
- }
- }
-
- public static Map<String, Integer> getServiceNamesMap(BundleContext bundleContext) {
- Map<String, Integer> serviceNames = new HashMap<String, Integer>();
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- ServiceReference<?>[] services = bundle.getRegisteredServices();
- if (services != null) {
- for (ServiceReference<?> serviceReference : services) {
- String[] names = (String[])serviceReference.getProperty(Constants.OBJECTCLASS);
- for (String name : names) {
- int curCount = (serviceNames.containsKey(name)) ? serviceNames.get(name) : 0;
- serviceNames.put(name, curCount + 1);
- }
- }
- }
- }
- return serviceNames;
- }
-
- private void printServiceRef(ServiceReference<?> serviceRef) {
- String[] objectClass = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS);
- String serviceClasses = ShellUtil.getValueString(objectClass);
- System.out.println(serviceClasses);
- System.out.println(ShellUtil.getUnderlineString(serviceClasses));
-
- printProperties(serviceRef);
-
- String bundleName = ShellUtil.getBundleName(serviceRef.getBundle());
- System.out.println("Provided by : ");
- System.out.println(" " + bundleName);
- if (serviceRef.getUsingBundles() != null) {
- System.out.println("Used by: ");
- for (Bundle bundle : serviceRef.getUsingBundles()) {
- System.out.println(" " + ShellUtil.getBundleName(bundle));
- }
- }
- System.out.println();
- }
-
- private boolean isCommand(String[] objectClasses) {
- for (String objectClass : objectClasses) {
- if (objectClass.equals("org.apache.felix.service.command.Function")) {
- return true;
- }
- }
- return false;
- }
-
- private void printProperties(ServiceReference<?> serviceRef) {
- for (String key : serviceRef.getPropertyKeys()) {
- if (!Constants.OBJECTCLASS.equals(key)) {
- System.out.println(" " + key + " = " + ShellUtil.getValueString(serviceRef.getProperty(key)));
- }
- }
- }
-
- public final class ServiceClassComparator implements Comparator<ServiceReference<?>> {
- @Override
- public int compare(ServiceReference<?> o1, ServiceReference<?> o2) {
- String[] classes1 = (String[])o1.getProperty(Constants.OBJECTCLASS);
- String[] classes2 = (String[])o2.getProperty(Constants.OBJECTCLASS);
- return classes1[0].compareTo(classes2[0]);
- }
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java
----------------------------------------------------------------------
diff --git a/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java b/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java
deleted file mode 100644
index 6b62b0c..0000000
--- a/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.service.command;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-import org.osgi.framework.BundleContext;
-
-@Service
-public class ObjectClassCompleter implements Completer {
-
- @Reference
- private BundleContext context;
-
- public void setContext(BundleContext context) {
- this.context = context;
- }
-
- @SuppressWarnings("rawtypes")
- @Override
- public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
- Map<String, Integer> serviceNamesMap = ListServices.getServiceNamesMap(context);
- Set<String> serviceNames = serviceNamesMap.keySet();
- List<String> strings = new ArrayList<String>();
- for (String name : serviceNames) {
- strings.add(ObjectClassMatcher.getShortName(name));
- }
- strings.addAll(serviceNames);
- return new StringsCompleter(strings).complete(session, commandLine, candidates);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
----------------------------------------------------------------------
diff --git a/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java b/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
deleted file mode 100644
index 9068aed..0000000
--- a/service/command/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.service.command;
-
-public class ObjectClassMatcher {
- private ObjectClassMatcher() {
- }
-
- static boolean matchesAtLeastOneName(String[] names, String pattern) {
- for (String objectClass : names) {
- if (matchesName(objectClass, pattern)) {
- return true;
- }
- }
- return false;
- }
-
- static boolean matchesName(String name, String pattern) {
- return name.equals(pattern) || getShortName(name).equals(pattern);
- }
-
- static String getShortName(String name) {
- int idx = name.lastIndexOf(".");
- if (idx + 1 > name.length()) {
- idx = 0;
- }
- return name.substring(idx + 1);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/main/java/org/apache/karaf/service/command/Wait.java
----------------------------------------------------------------------
diff --git a/service/command/src/main/java/org/apache/karaf/service/command/Wait.java b/service/command/src/main/java/org/apache/karaf/service/command/Wait.java
deleted file mode 100644
index 9a0d286..0000000
--- a/service/command/src/main/java/org/apache/karaf/service/command/Wait.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.service.command;
-
-import java.util.concurrent.TimeoutException;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * Command that can be used to wait for an OSGi service.
- */
-@Command(scope = "service", name = "wait", description = "Wait for a given OSGi service.")
-@Service
-public class Wait implements Action {
-
- @Option(name = "-e", aliases = { "--exception" }, description = "throw an exception if the service is not found after the timeout")
- boolean exception;
-
- @Option(name = "-t", aliases = { "--timeout" }, description = "timeout to wait for the service (in milliseconds, negative to not wait at all, zero to wait forever)")
- long timeout = 0;
-
- @Argument(name = "service", description="The service class or filter", required = true, multiValued = false)
- String service;
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- ServiceTracker<?,?> tracker = null;
- try {
- String filter = service;
- if (!filter.startsWith("(")) {
- if (!filter.contains("=")) {
- filter = Constants.OBJECTCLASS + "=" + filter;
- }
- filter = "(" + filter + ")";
- }
- Filter osgiFilter = FrameworkUtil.createFilter(filter);
- tracker = new ServiceTracker<Object, Object>(bundleContext, osgiFilter, null);
- tracker.open(true);
- Object svc = tracker.getService();
- if (timeout >= 0) {
- svc = tracker.waitForService(timeout);
- }
- if (exception && svc == null) {
- throw new TimeoutException("Can not find service '" + service + "' in the OSGi registry");
- }
- return svc != null;
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException("Invalid filter", e);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } finally {
- if (tracker != null) {
- tracker.close();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
----------------------------------------------------------------------
diff --git a/service/command/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java b/service/command/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
deleted file mode 100644
index 9f42147..0000000
--- a/service/command/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.service.command;
-import org.junit.Test;
-
-public class ListServiceNamesTest {
-
- public ListServiceNamesTest() {
-
- }
-
- @Test
- public void listAll() throws Exception {
- ListServices listServices = new ListServices();
- listServices.setBundleContext(new TestBundleFactory().createBundleContext());
- listServices.onlyNames = true;
- listServices.execute();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
----------------------------------------------------------------------
diff --git a/service/command/src/test/java/org/apache/karaf/service/command/ListServicesTest.java b/service/command/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
deleted file mode 100644
index 510de6c..0000000
--- a/service/command/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.service.command;
-
-import org.junit.Test;
-
-public class ListServicesTest {
-
- public ListServicesTest() {
-
- }
-
- @Test
- public void listAll() throws Exception {
- ListServices listServices = new ListServices();
- listServices.setBundleContext(new TestBundleFactory().createBundleContext());
- listServices.execute();
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
----------------------------------------------------------------------
diff --git a/service/command/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java b/service/command/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
deleted file mode 100644
index 296b591..0000000
--- a/service/command/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.service.command;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-public class ObjectClassMatcherTest {
-
- @Test
- public void testGetShortName() {
- Assert.assertEquals("TestClass", ObjectClassMatcher.getShortName("org.apache.TestClass"));
- Assert.assertEquals("", ObjectClassMatcher.getShortName("test."));
- Assert.assertEquals("TestClass", ObjectClassMatcher.getShortName("TestClass"));
- }
-
- @Test
- public void testMatchesName() {
- Assert.assertTrue(ObjectClassMatcher.matchesName("org.apache.TestClass", "TestClass"));
- Assert.assertTrue(ObjectClassMatcher.matchesName("TestClass", "TestClass"));
- }
-
- @Test
- public void testMatchesAtLeastOneName() {
- Assert.assertTrue(ObjectClassMatcher.matchesAtLeastOneName(new String[]{"other", "org.apache.TestClass"}, "TestClass"));
- Assert.assertFalse(ObjectClassMatcher.matchesAtLeastOneName(new String[]{"TestClass2"}, "TestClass"));
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/command/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
----------------------------------------------------------------------
diff --git a/service/command/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java b/service/command/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
deleted file mode 100644
index 3d83670..0000000
--- a/service/command/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.service.command;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class TestBundleFactory {
- ServiceReference<?> createServiceRef(Object ... keyProp) {
- ServiceReference<?> serviceRef = createMock(ServiceReference.class);
- if (keyProp.length % 2 != 0) {
- throw new IllegalArgumentException("");
- }
- Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
- int c = 0;
- while (c < keyProp.length) {
- String key = (String)keyProp[c++];
- Object value = (Object)keyProp[c++];
- keyPropMap.put(key, value);
- expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
- }
- expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new String[]{})).anyTimes();
- return serviceRef;
- }
-
- Bundle createBundle(long id, String name) {
- Bundle bundle = createMock(Bundle.class);
- expect(bundle.getBundleId()).andReturn(id).anyTimes();
- Dictionary<String, String> headers = new Hashtable<String, String>();
- headers.put(Constants.BUNDLE_NAME, name);
- expect(bundle.getHeaders()).andReturn(headers).anyTimes();
- return bundle;
- }
-
- private Bundle[] createBundles() {
- Bundle bundle1 = createBundle(1, "Bundle A");
- Bundle bundle2 = createBundle(2, "Bundle B");
- Bundle bundle3 = createBundle(3, "Bundle C");
-
- ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.MyService"},
- "key1", "value1");
- ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.OtherService"}, "key2", 1);
-
- addRegisteredServices(bundle1, ref1, ref2);
- addRegisteredServices(bundle2, ref2);
- expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
-
- expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
- addUsedServices(bundle2, ref1);
- addUsedServices(bundle3, ref1, ref2);
-
- expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, bundle3}).anyTimes();
- expect(ref2.getUsingBundles()).andReturn(new Bundle[]{bundle3}).anyTimes();
-
- replay(bundle1, bundle2, bundle3, ref1, ref2);
- return new Bundle[] { bundle1, bundle2, bundle3 };
- }
-
- private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
- expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
- }
-
- private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... refs) {
- expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
- for (ServiceReference<?> ref : refs) {
- expect(ref.getBundle()).andReturn(bundle);
- }
- }
-
- public BundleContext createBundleContext() {
- BundleContext bundleContext = createMock(BundleContext.class);
- Bundle[] bundles = createBundles();
- expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
- expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
- expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
- expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
- replay(bundleContext);
- return bundleContext;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/pom.xml
----------------------------------------------------------------------
diff --git a/service/core/pom.xml b/service/core/pom.xml
index e617fc3..4d10257 100644
--- a/service/core/pom.xml
+++ b/service/core/pom.xml
@@ -48,6 +48,11 @@
<artifactId>org.apache.karaf.util</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
</dependencies>
@@ -77,6 +82,7 @@
org.apache.karaf.service.core;-noimport:=true
</Export-Package>
<Private-Package>
+ org.apache.karaf.service.command,
org.apache.karaf.service.core.internal,
org.apache.karaf.service.core.internal.osgi,
org.apache.karaf.util.tracker
@@ -84,6 +90,7 @@
<Bundle-Activator>
org.apache.karaf.service.core.internal.osgi.Activator
</Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.service.command</Karaf-Commands>
</instructions>
</configuration>
</plugin>
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/main/java/org/apache/karaf/service/command/ListServices.java
----------------------------------------------------------------------
diff --git a/service/core/src/main/java/org/apache/karaf/service/command/ListServices.java b/service/core/src/main/java/org/apache/karaf/service/command/ListServices.java
new file mode 100644
index 0000000..caf546b
--- /dev/null
+++ b/service/core/src/main/java/org/apache/karaf/service/command/ListServices.java
@@ -0,0 +1,163 @@
+/*
+ * 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.service.command;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@Command(scope = "service", name = "list", description = "Lists OSGi services.")
+@Service
+public class ListServices implements Action {
+
+ @Argument(index = 0, name = "objectClass", description = "Name of service objectClass to filter for", required = false,
+ multiValued = false)
+ @Completion(ObjectClassCompleter.class)
+ String objectClass;
+
+ @Option(name = "-a", aliases = {}, description = "Shows all services. (By default Karaf commands are hidden)", required = false, multiValued = false)
+ boolean showAll;
+
+ @Option(name = "-n", aliases = {}, description = "Shows only service class names", required = false, multiValued = false)
+ boolean onlyNames;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ if (onlyNames) {
+ listNames();
+ return null;
+ }
+ List<ServiceReference<?>> serviceRefs = new ArrayList<ServiceReference<?>>();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] services = bundle.getRegisteredServices();
+ if (services != null) {
+ for (ServiceReference<?> ref : services) {
+ String[] objectClasses = (String[])ref.getProperty(Constants.OBJECTCLASS);
+ if (objectClass == null || ObjectClassMatcher.matchesAtLeastOneName(objectClasses, objectClass)) {
+ serviceRefs.add(ref);
+ }
+ }
+ }
+ }
+
+ Collections.sort(serviceRefs, new ServiceClassComparator());
+
+ for (ServiceReference<?> serviceRef : serviceRefs) {
+ if (showAll || !isCommand((String[])serviceRef.getProperty(Constants.OBJECTCLASS))) {
+ printServiceRef(serviceRef);
+ }
+ }
+ return null;
+ }
+
+ private void listNames() {
+ Map<String, Integer> serviceNames = getServiceNamesMap(bundleContext);
+ ArrayList<String> serviceNamesList = new ArrayList<String>(serviceNames.keySet());
+ Collections.sort(serviceNamesList);
+ for (String name : serviceNamesList) {
+ System.out.println(name + " (" + serviceNames.get(name) + ")");
+ }
+ }
+
+ public static Map<String, Integer> getServiceNamesMap(BundleContext bundleContext) {
+ Map<String, Integer> serviceNames = new HashMap<String, Integer>();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ ServiceReference<?>[] services = bundle.getRegisteredServices();
+ if (services != null) {
+ for (ServiceReference<?> serviceReference : services) {
+ String[] names = (String[])serviceReference.getProperty(Constants.OBJECTCLASS);
+ for (String name : names) {
+ int curCount = (serviceNames.containsKey(name)) ? serviceNames.get(name) : 0;
+ serviceNames.put(name, curCount + 1);
+ }
+ }
+ }
+ }
+ return serviceNames;
+ }
+
+ private void printServiceRef(ServiceReference<?> serviceRef) {
+ String[] objectClass = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS);
+ String serviceClasses = ShellUtil.getValueString(objectClass);
+ System.out.println(serviceClasses);
+ System.out.println(ShellUtil.getUnderlineString(serviceClasses));
+
+ printProperties(serviceRef);
+
+ String bundleName = ShellUtil.getBundleName(serviceRef.getBundle());
+ System.out.println("Provided by : ");
+ System.out.println(" " + bundleName);
+ if (serviceRef.getUsingBundles() != null) {
+ System.out.println("Used by: ");
+ for (Bundle bundle : serviceRef.getUsingBundles()) {
+ System.out.println(" " + ShellUtil.getBundleName(bundle));
+ }
+ }
+ System.out.println();
+ }
+
+ private boolean isCommand(String[] objectClasses) {
+ for (String objectClass : objectClasses) {
+ if (objectClass.equals("org.apache.felix.service.command.Function")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void printProperties(ServiceReference<?> serviceRef) {
+ for (String key : serviceRef.getPropertyKeys()) {
+ if (!Constants.OBJECTCLASS.equals(key)) {
+ System.out.println(" " + key + " = " + ShellUtil.getValueString(serviceRef.getProperty(key)));
+ }
+ }
+ }
+
+ public final class ServiceClassComparator implements Comparator<ServiceReference<?>> {
+ @Override
+ public int compare(ServiceReference<?> o1, ServiceReference<?> o2) {
+ String[] classes1 = (String[])o1.getProperty(Constants.OBJECTCLASS);
+ String[] classes2 = (String[])o2.getProperty(Constants.OBJECTCLASS);
+ return classes1[0].compareTo(classes2[0]);
+ }
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java
----------------------------------------------------------------------
diff --git a/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java b/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.java
new file mode 100644
index 0000000..6b62b0c
--- /dev/null
+++ b/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassCompleter.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.service.command;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.framework.BundleContext;
+
+@Service
+public class ObjectClassCompleter implements Completer {
+
+ @Reference
+ private BundleContext context;
+
+ public void setContext(BundleContext context) {
+ this.context = context;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
+ Map<String, Integer> serviceNamesMap = ListServices.getServiceNamesMap(context);
+ Set<String> serviceNames = serviceNamesMap.keySet();
+ List<String> strings = new ArrayList<String>();
+ for (String name : serviceNames) {
+ strings.add(ObjectClassMatcher.getShortName(name));
+ }
+ strings.addAll(serviceNames);
+ return new StringsCompleter(strings).complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
----------------------------------------------------------------------
diff --git a/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java b/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
new file mode 100644
index 0000000..9068aed
--- /dev/null
+++ b/service/core/src/main/java/org/apache/karaf/service/command/ObjectClassMatcher.java
@@ -0,0 +1,43 @@
+/*
+ * 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.service.command;
+
+public class ObjectClassMatcher {
+ private ObjectClassMatcher() {
+ }
+
+ static boolean matchesAtLeastOneName(String[] names, String pattern) {
+ for (String objectClass : names) {
+ if (matchesName(objectClass, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static boolean matchesName(String name, String pattern) {
+ return name.equals(pattern) || getShortName(name).equals(pattern);
+ }
+
+ static String getShortName(String name) {
+ int idx = name.lastIndexOf(".");
+ if (idx + 1 > name.length()) {
+ idx = 0;
+ }
+ return name.substring(idx + 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/main/java/org/apache/karaf/service/command/Wait.java
----------------------------------------------------------------------
diff --git a/service/core/src/main/java/org/apache/karaf/service/command/Wait.java b/service/core/src/main/java/org/apache/karaf/service/command/Wait.java
new file mode 100644
index 0000000..9a0d286
--- /dev/null
+++ b/service/core/src/main/java/org/apache/karaf/service/command/Wait.java
@@ -0,0 +1,86 @@
+/*
+ * 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.service.command;
+
+import java.util.concurrent.TimeoutException;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Command that can be used to wait for an OSGi service.
+ */
+@Command(scope = "service", name = "wait", description = "Wait for a given OSGi service.")
+@Service
+public class Wait implements Action {
+
+ @Option(name = "-e", aliases = { "--exception" }, description = "throw an exception if the service is not found after the timeout")
+ boolean exception;
+
+ @Option(name = "-t", aliases = { "--timeout" }, description = "timeout to wait for the service (in milliseconds, negative to not wait at all, zero to wait forever)")
+ long timeout = 0;
+
+ @Argument(name = "service", description="The service class or filter", required = true, multiValued = false)
+ String service;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ ServiceTracker<?,?> tracker = null;
+ try {
+ String filter = service;
+ if (!filter.startsWith("(")) {
+ if (!filter.contains("=")) {
+ filter = Constants.OBJECTCLASS + "=" + filter;
+ }
+ filter = "(" + filter + ")";
+ }
+ Filter osgiFilter = FrameworkUtil.createFilter(filter);
+ tracker = new ServiceTracker<Object, Object>(bundleContext, osgiFilter, null);
+ tracker.open(true);
+ Object svc = tracker.getService();
+ if (timeout >= 0) {
+ svc = tracker.waitForService(timeout);
+ }
+ if (exception && svc == null) {
+ throw new TimeoutException("Can not find service '" + service + "' in the OSGi registry");
+ }
+ return svc != null;
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Invalid filter", e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (tracker != null) {
+ tracker.close();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
----------------------------------------------------------------------
diff --git a/service/core/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java b/service/core/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
new file mode 100644
index 0000000..9f42147
--- /dev/null
+++ b/service/core/src/test/java/org/apache/karaf/service/command/ListServiceNamesTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.service.command;
+import org.junit.Test;
+
+public class ListServiceNamesTest {
+
+ public ListServiceNamesTest() {
+
+ }
+
+ @Test
+ public void listAll() throws Exception {
+ ListServices listServices = new ListServices();
+ listServices.setBundleContext(new TestBundleFactory().createBundleContext());
+ listServices.onlyNames = true;
+ listServices.execute();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
----------------------------------------------------------------------
diff --git a/service/core/src/test/java/org/apache/karaf/service/command/ListServicesTest.java b/service/core/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
new file mode 100644
index 0000000..510de6c
--- /dev/null
+++ b/service/core/src/test/java/org/apache/karaf/service/command/ListServicesTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.service.command;
+
+import org.junit.Test;
+
+public class ListServicesTest {
+
+ public ListServicesTest() {
+
+ }
+
+ @Test
+ public void listAll() throws Exception {
+ ListServices listServices = new ListServices();
+ listServices.setBundleContext(new TestBundleFactory().createBundleContext());
+ listServices.execute();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
----------------------------------------------------------------------
diff --git a/service/core/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java b/service/core/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
new file mode 100644
index 0000000..296b591
--- /dev/null
+++ b/service/core/src/test/java/org/apache/karaf/service/command/ObjectClassMatcherTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.service.command;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class ObjectClassMatcherTest {
+
+ @Test
+ public void testGetShortName() {
+ Assert.assertEquals("TestClass", ObjectClassMatcher.getShortName("org.apache.TestClass"));
+ Assert.assertEquals("", ObjectClassMatcher.getShortName("test."));
+ Assert.assertEquals("TestClass", ObjectClassMatcher.getShortName("TestClass"));
+ }
+
+ @Test
+ public void testMatchesName() {
+ Assert.assertTrue(ObjectClassMatcher.matchesName("org.apache.TestClass", "TestClass"));
+ Assert.assertTrue(ObjectClassMatcher.matchesName("TestClass", "TestClass"));
+ }
+
+ @Test
+ public void testMatchesAtLeastOneName() {
+ Assert.assertTrue(ObjectClassMatcher.matchesAtLeastOneName(new String[]{"other", "org.apache.TestClass"}, "TestClass"));
+ Assert.assertFalse(ObjectClassMatcher.matchesAtLeastOneName(new String[]{"TestClass2"}, "TestClass"));
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/core/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
----------------------------------------------------------------------
diff --git a/service/core/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java b/service/core/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
new file mode 100644
index 0000000..3d83670
--- /dev/null
+++ b/service/core/src/test/java/org/apache/karaf/service/command/TestBundleFactory.java
@@ -0,0 +1,104 @@
+/*
+ * 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.service.command;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class TestBundleFactory {
+ ServiceReference<?> createServiceRef(Object ... keyProp) {
+ ServiceReference<?> serviceRef = createMock(ServiceReference.class);
+ if (keyProp.length % 2 != 0) {
+ throw new IllegalArgumentException("");
+ }
+ Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
+ int c = 0;
+ while (c < keyProp.length) {
+ String key = (String)keyProp[c++];
+ Object value = (Object)keyProp[c++];
+ keyPropMap.put(key, value);
+ expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
+ }
+ expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new String[]{})).anyTimes();
+ return serviceRef;
+ }
+
+ Bundle createBundle(long id, String name) {
+ Bundle bundle = createMock(Bundle.class);
+ expect(bundle.getBundleId()).andReturn(id).anyTimes();
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put(Constants.BUNDLE_NAME, name);
+ expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+ return bundle;
+ }
+
+ private Bundle[] createBundles() {
+ Bundle bundle1 = createBundle(1, "Bundle A");
+ Bundle bundle2 = createBundle(2, "Bundle B");
+ Bundle bundle3 = createBundle(3, "Bundle C");
+
+ ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.MyService"},
+ "key1", "value1");
+ ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.OtherService"}, "key2", 1);
+
+ addRegisteredServices(bundle1, ref1, ref2);
+ addRegisteredServices(bundle2, ref2);
+ expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
+
+ expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
+ addUsedServices(bundle2, ref1);
+ addUsedServices(bundle3, ref1, ref2);
+
+ expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, bundle3}).anyTimes();
+ expect(ref2.getUsingBundles()).andReturn(new Bundle[]{bundle3}).anyTimes();
+
+ replay(bundle1, bundle2, bundle3, ref1, ref2);
+ return new Bundle[] { bundle1, bundle2, bundle3 };
+ }
+
+ private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
+ expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
+ }
+
+ private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... refs) {
+ expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
+ for (ServiceReference<?> ref : refs) {
+ expect(ref.getBundle()).andReturn(bundle);
+ }
+ }
+
+ public BundleContext createBundleContext() {
+ BundleContext bundleContext = createMock(BundleContext.class);
+ Bundle[] bundles = createBundles();
+ expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
+ expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
+ expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
+ expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
+ replay(bundleContext);
+ return bundleContext;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/149822e9/service/pom.xml
----------------------------------------------------------------------
diff --git a/service/pom.xml b/service/pom.xml
index de16f40..10efab4 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -35,7 +35,6 @@
<modules>
<module>core</module>
- <module>command</module>
<module>guard</module>
</modules>
[38/59] [abbrv] [KARAF-2852] Merge package/core and package/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java b/package/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..ea8ce1d
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
@@ -0,0 +1,34 @@
+/*
+ * 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.packages.core.internal.osgi;
+
+import org.apache.karaf.packages.core.PackageService;
+import org.apache.karaf.packages.core.internal.PackageServiceImpl;
+import org.apache.karaf.packages.core.internal.PackagesMBeanImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doStart() throws Exception {
+ PackageService packageService = new PackageServiceImpl(bundleContext);
+ register(PackageService.class, packageService);
+
+ PackagesMBeanImpl mbean = new PackagesMBeanImpl(packageService);
+ registerMBean(mbean, "type=package");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/package/src/main/resources/OSGI-INF/bundle.info b/package/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..b5747b7
--- /dev/null
+++ b/package/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,15 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+Services for handling packages
+
+h1. See also
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
----------------------------------------------------------------------
diff --git a/package/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java b/package/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
new file mode 100644
index 0000000..a9ab11b
--- /dev/null
+++ b/package/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.packages.core;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.karaf.packages.core.internal.PackagesMBeanImpl;
+import org.junit.Test;
+
+/**
+ * Checks that the PackagesMBean is valid and can be installed in the MBeanServer
+ *
+ */
+public class InstallMBeantest {
+
+ @Test
+ public void test() throws Exception {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ PackagesMBeanImpl pack = new PackagesMBeanImpl(null);
+ ObjectName oName = new ObjectName("org.apache.karaf:type=package,name=root");
+ server.registerMBean(pack, oName);
+ server.unregisterMBean(oName);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
----------------------------------------------------------------------
diff --git a/package/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java b/package/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
new file mode 100644
index 0000000..2ea1cf8
--- /dev/null
+++ b/package/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packages.core;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class PackageRequirementTest {
+
+ @Test
+ public void testGetPackageName() {
+ PackageRequirement req = new PackageRequirement("(&(osgi.wiring.package=org.osgi.service.useradmin)(version>=1.1.0))", false, null, false);
+ String packageName = req.getPackageName();
+ Assert.assertEquals("org.osgi.service.useradmin", packageName);
+ }
+
+}
[05/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
new file mode 100644
index 0000000..cb2c36a
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
@@ -0,0 +1,1129 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.utils.version.VersionRange;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class ResourceBuilder {
+
+ public static final String RESOLUTION_DYNAMIC = "dynamic";
+
+ public static Resource build(String uri, Map<String, String> headerMap)
+ throws BundleException {
+
+ // Verify that only manifest version 2 is specified.
+ String manifestVersion = getManifestVersion(headerMap);
+ if (manifestVersion == null || !manifestVersion.equals("2")) {
+ throw new BundleException("Unsupported 'Bundle-ManifestVersion' value: " + manifestVersion);
+ }
+
+ //
+ // Parse bundle version.
+ //
+
+ Version bundleVersion = Version.emptyVersion;
+ if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
+ bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
+ }
+
+ //
+ // Parse bundle symbolic name.
+ //
+
+ String bundleSymbolicName = null;
+ ParsedHeaderClause bundleCap = parseBundleSymbolicName(headerMap);
+ if (bundleCap == null) {
+ throw new BundleException("Bundle manifest must include bundle symbolic name");
+ }
+ bundleSymbolicName = (String) bundleCap.attrs.get(BundleRevision.BUNDLE_NAMESPACE);
+
+ // Now that we have symbolic name and version, create the resource
+ String type = headerMap.get(Constants.FRAGMENT_HOST) == null ? IdentityNamespace.TYPE_BUNDLE : IdentityNamespace.TYPE_FRAGMENT;
+ ResourceImpl resource = new ResourceImpl(bundleSymbolicName, type, bundleVersion);
+ if (uri != null) {
+ Map<String, Object> attrs = new HashMap<String, Object>();
+ attrs.put(UriNamespace.URI_NAMESPACE, uri);
+ resource.addCapability(new CapabilityImpl(resource, UriNamespace.URI_NAMESPACE, Collections.<String, String>emptyMap(), attrs));
+ }
+
+ // Add a bundle and host capability to all
+ // non-fragment bundles. A host capability is the same
+ // as a require capability, but with a different capability
+ // namespace. Bundle capabilities resolve required-bundle
+ // dependencies, while host capabilities resolve fragment-host
+ // dependencies.
+ if (headerMap.get(Constants.FRAGMENT_HOST) == null) {
+ // All non-fragment bundles have bundle capability.
+ resource.addCapability(new CapabilityImpl(resource, BundleRevision.BUNDLE_NAMESPACE, bundleCap.dirs, bundleCap.attrs));
+ // A non-fragment bundle can choose to not have a host capability.
+ String attachment = bundleCap.dirs.get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
+ attachment = (attachment == null) ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME : attachment;
+ if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
+ Map<String, Object> hostAttrs = new HashMap<String, Object>(bundleCap.attrs);
+ Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
+ hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
+ resource.addCapability(new CapabilityImpl(
+ resource, BundleRevision.HOST_NAMESPACE,
+ bundleCap.dirs,
+ hostAttrs));
+ }
+ }
+
+ //
+ // Parse Fragment-Host.
+ //
+
+ List<RequirementImpl> hostReqs = parseFragmentHost(resource, headerMap);
+
+ //
+ // Parse Require-Bundle
+ //
+
+ List<ParsedHeaderClause> rbClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_BUNDLE));
+ rbClauses = normalizeRequireClauses(rbClauses);
+ List<Requirement> rbReqs = convertRequires(rbClauses, resource);
+
+ //
+ // Parse Import-Package.
+ //
+
+ List<ParsedHeaderClause> importClauses = parseStandardHeader(headerMap.get(Constants.IMPORT_PACKAGE));
+ importClauses = normalizeImportClauses(importClauses);
+ List<Requirement> importReqs = convertImports(importClauses, resource);
+
+ //
+ // Parse DynamicImport-Package.
+ //
+
+ List<ParsedHeaderClause> dynamicClauses = parseStandardHeader(headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
+ dynamicClauses = normalizeDynamicImportClauses(dynamicClauses);
+ List<Requirement> dynamicReqs = convertImports(dynamicClauses, resource);
+
+ //
+ // Parse Require-Capability.
+ //
+
+ List<ParsedHeaderClause> requireClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_CAPABILITY));
+ requireClauses = normalizeRequireCapabilityClauses(requireClauses);
+ List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
+
+ //
+ // Parse Export-Package.
+ //
+
+ List<ParsedHeaderClause> exportClauses = parseStandardHeader(headerMap.get(Constants.EXPORT_PACKAGE));
+ exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
+ List<Capability> exportCaps = convertExports(exportClauses, resource);
+
+ //
+ // Parse Provide-Capability.
+ //
+
+ List<ParsedHeaderClause> provideClauses = parseStandardHeader(headerMap.get(Constants.PROVIDE_CAPABILITY));
+ provideClauses = normalizeProvideCapabilityClauses(provideClauses);
+ List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
+
+ //
+ // Parse Import-Service and Export-Service
+ // if Require-Capability and Provide-Capability are not set for services
+ //
+
+ boolean hasServiceReferenceCapability = false;
+ for (Capability cap : exportCaps) {
+ hasServiceReferenceCapability |= ServiceNamespace.SERVICE_NAMESPACE.equals(cap.getNamespace());
+ }
+ if (!hasServiceReferenceCapability) {
+ List<ParsedHeaderClause> exportServices = parseStandardHeader(headerMap.get(Constants.EXPORT_SERVICE));
+ List<Capability> caps = convertExportService(exportServices, resource);
+ provideCaps.addAll(caps);
+ }
+
+ boolean hasServiceReferenceRequirement = false;
+ for (Requirement req : requireReqs) {
+ hasServiceReferenceRequirement |= ServiceNamespace.SERVICE_NAMESPACE.equals(req.getNamespace());
+ }
+ if (!hasServiceReferenceRequirement) {
+ List<ParsedHeaderClause> importServices = parseStandardHeader(headerMap.get(Constants.IMPORT_SERVICE));
+ List<Requirement> reqs = convertImportService(importServices, resource);
+ requireReqs.addAll(reqs);
+ }
+
+ // Combine all capabilities.
+ resource.addCapabilities(exportCaps);
+ resource.addCapabilities(provideCaps);
+
+ // Combine all requirements.
+ resource.addRequirements(hostReqs);
+ resource.addRequirements(importReqs);
+ resource.addRequirements(rbReqs);
+ resource.addRequirements(requireReqs);
+ resource.addRequirements(dynamicReqs);
+
+ return resource;
+ }
+
+ public static List<Requirement> parseImport(Resource resource, String imports) throws BundleException {
+ List<ParsedHeaderClause> importClauses = parseStandardHeader(imports);
+ importClauses = normalizeImportClauses(importClauses);
+ List<Requirement> importReqs = convertImports(importClauses, resource);
+ return importReqs;
+ }
+
+ public static List<Requirement> parseRequirement(Resource resource, String requirement) throws BundleException {
+ List<ParsedHeaderClause> requireClauses = parseStandardHeader(requirement);
+ requireClauses = normalizeRequireCapabilityClauses(requireClauses);
+ List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);
+ return requireReqs;
+ }
+
+ public static List<Capability> parseExport(Resource resource, String bundleSymbolicName, Version bundleVersion, String exports) throws BundleException {
+ List<ParsedHeaderClause> exportClauses = parseStandardHeader(exports);
+ exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
+ List<Capability> exportCaps = convertExports(exportClauses, resource);
+ return exportCaps;
+ }
+
+ public static List<Capability> parseCapability(Resource resource, String capability) throws BundleException {
+ List<ParsedHeaderClause> provideClauses = parseStandardHeader(capability);
+ provideClauses = normalizeProvideCapabilityClauses(provideClauses);
+ List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);
+ return provideCaps;
+ }
+
+ @SuppressWarnings( "deprecation" )
+ private static List<ParsedHeaderClause> normalizeImportClauses(
+ List<ParsedHeaderClause> clauses)
+ throws BundleException {
+ // Verify that the values are equals if the package specifies
+ // both version and specification-version attributes.
+ Set<String> dupeSet = new HashSet<String>();
+ for (ParsedHeaderClause clause : clauses) {
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
+ Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null)) {
+ // Verify they are equal.
+ if (!((String) v).trim().equals(((String) sv).trim())) {
+ throw new IllegalArgumentException(
+ "Both version and specification-version are specified, but they are not equal.");
+ }
+ }
+
+ // Ensure that only the "version" attribute is used and convert
+ // it to the VersionRange type.
+ if ((v != null) || (sv != null)) {
+ clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
+ }
+
+ // If bundle version is specified, then convert its type to VersionRange.
+ v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if (v != null) {
+ clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
+ }
+
+ // Verify java.* is not imported, nor any duplicate imports.
+ for (String pkgName : clause.paths) {
+ if (!dupeSet.contains(pkgName)) {
+ // Verify that java.* packages are not imported.
+ if (pkgName.startsWith("java.")) {
+ throw new BundleException("Importing java.* packages not allowed: " + pkgName);
+ }
+ // The character "." has no meaning in the OSGi spec except
+ // when placed on the bundle class path. Some people, however,
+ // mistakenly think it means the default package when imported
+ // or exported. This is not correct. It is invalid.
+ else if (pkgName.equals(".")) {
+ throw new BundleException("Importing '.' is invalid.");
+ }
+ // Make sure a package name was specified.
+ else if (pkgName.length() == 0) {
+ throw new BundleException(
+ "Imported package names cannot be zero length.");
+ }
+ dupeSet.add(pkgName);
+ } else {
+ throw new BundleException("Duplicate import: " + pkgName);
+ }
+ }
+ }
+
+ return clauses;
+ }
+
+ private static List<Capability> convertExportService(List<ParsedHeaderClause> clauses, Resource resource) {
+ List<Capability> capList = new ArrayList<Capability>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String path : clause.paths) {
+ Map<String, String> dirs = new LinkedHashMap<String, String>();
+ dirs.put(ServiceNamespace.CAPABILITY_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
+ Map<String, Object> attrs = new LinkedHashMap<String, Object>();
+ attrs.put(Constants.OBJECTCLASS, path);
+ attrs.putAll(clause.attrs);
+ capList.add(new CapabilityImpl(
+ resource,
+ ServiceNamespace.SERVICE_NAMESPACE,
+ dirs,
+ attrs));
+ }
+ }
+ return capList;
+ }
+
+ private static List<Requirement> convertImportService(List<ParsedHeaderClause> clauses, Resource resource) throws BundleException {
+ try {
+ List<Requirement> reqList = new ArrayList<Requirement>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String path : clause.paths) {
+ String multiple = clause.dirs.get("multiple");
+ String avail = clause.dirs.get("availability");
+ String filter = (String) clause.attrs.get("filter");
+ Map<String, String> dirs = new LinkedHashMap<String, String>();
+ dirs.put(ServiceNamespace.REQUIREMENT_EFFECTIVE_DIRECTIVE, ServiceNamespace.EFFECTIVE_ACTIVE);
+ if ("optional".equals(avail)) {
+ dirs.put(ServiceNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, ServiceNamespace.RESOLUTION_OPTIONAL);
+ }
+ if ("true".equals(multiple)) {
+ dirs.put(ServiceNamespace.REQUIREMENT_CARDINALITY_DIRECTIVE, ServiceNamespace.CARDINALITY_MULTIPLE);
+ }
+ if (filter == null) {
+ filter = "(" + Constants.OBJECTCLASS + "=" + path + ")";
+ } else if (!filter.startsWith("(") && !filter.endsWith(")")) {
+ filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")(" + filter + "))";
+ } else {
+ filter = "(&(" + Constants.OBJECTCLASS + "=" + path + ")" + filter + ")";
+ }
+ dirs.put(ServiceNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
+ reqList.add(new RequirementImpl(
+ resource,
+ ServiceNamespace.SERVICE_NAMESPACE,
+ dirs,
+ Collections.<String, Object>emptyMap(),
+ SimpleFilter.parse(filter)));
+ }
+ }
+ return reqList;
+ } catch (Exception ex) {
+ throw new BundleException("Error creating requirement: " + ex, ex);
+ }
+ }
+
+ private static List<Requirement> convertImports(List<ParsedHeaderClause> clauses, Resource resource) {
+ // Now convert generic header clauses into requirements.
+ List<Requirement> reqList = new ArrayList<Requirement>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String path : clause.paths) {
+ // Prepend the package name to the array of attributes.
+ Map<String, Object> attrs = clause.attrs;
+ // Note that we use a linked hash map here to ensure the
+ // package attribute is first, which will make indexing
+ // more efficient.
+ // TODO: OSGi R4.3 - This is ordering is kind of hacky.
+ // Prepend the package name to the array of attributes.
+ Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
+ // We want this first from an indexing perspective.
+ newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
+ newAttrs.putAll(attrs);
+ // But we need to put it again to make sure it wasn't overwritten.
+ newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, path);
+
+ // Create filter now so we can inject filter directive.
+ SimpleFilter sf = SimpleFilter.convert(newAttrs);
+
+ // Inject filter directive.
+ // TODO: OSGi R4.3 - Can we insert this on demand somehow?
+ Map<String, String> dirs = clause.dirs;
+ Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
+ newDirs.putAll(dirs);
+ newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
+
+ // Create package requirement and add to requirement list.
+ reqList.add(
+ new RequirementImpl(
+ resource,
+ BundleRevision.PACKAGE_NAMESPACE,
+ newDirs,
+ Collections.<String, Object>emptyMap(),
+ sf));
+ }
+ }
+
+ return reqList;
+ }
+
+ @SuppressWarnings( "deprecation" )
+ private static List<ParsedHeaderClause> normalizeDynamicImportClauses(
+ List<ParsedHeaderClause> clauses)
+ throws BundleException {
+ // Verify that the values are equals if the package specifies
+ // both version and specification-version attributes.
+ for (ParsedHeaderClause clause : clauses) {
+ // Add the resolution directive to indicate that these are
+ // dynamic imports.
+ clause.dirs.put(Constants.RESOLUTION_DIRECTIVE, RESOLUTION_DYNAMIC);
+
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
+ Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null)) {
+ // Verify they are equal.
+ if (!((String) v).trim().equals(((String) sv).trim())) {
+ throw new IllegalArgumentException(
+ "Both version and specification-version are specified, but they are not equal.");
+ }
+ }
+
+ // Ensure that only the "version" attribute is used and convert
+ // it to the VersionRange type.
+ if ((v != null) || (sv != null)) {
+ clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
+ }
+
+ // If bundle version is specified, then convert its type to VersionRange.
+ v = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if (v != null) {
+ clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(v.toString()));
+ }
+
+ // Dynamic imports can have duplicates, so verify that java.*
+ // packages are not imported.
+ for (String pkgName : clause.paths) {
+ if (pkgName.startsWith("java.")) {
+ throw new BundleException("Dynamically importing java.* packages not allowed: " + pkgName);
+ } else if (!pkgName.equals("*") && pkgName.endsWith("*") && !pkgName.endsWith(".*")) {
+ throw new BundleException("Partial package name wild carding is not allowed: " + pkgName);
+ }
+ }
+ }
+
+ return clauses;
+ }
+
+ private static List<ParsedHeaderClause> normalizeRequireCapabilityClauses(
+ List<ParsedHeaderClause> clauses)
+ throws BundleException {
+
+ return clauses;
+ }
+
+ private static List<ParsedHeaderClause> normalizeProvideCapabilityClauses(
+ List<ParsedHeaderClause> clauses)
+ throws BundleException
+ {
+
+ // Convert attributes into specified types.
+ for (ParsedHeaderClause clause : clauses)
+ {
+ for (Map.Entry<String, String> entry : clause.types.entrySet())
+ {
+ String type = entry.getValue();
+ if (!type.equals("String"))
+ {
+ if (type.equals("Double"))
+ {
+ clause.attrs.put(
+ entry.getKey(),
+ new Double(clause.attrs.get(entry.getKey()).toString().trim()));
+ }
+ else if (type.equals("Version"))
+ {
+ clause.attrs.put(
+ entry.getKey(),
+ new Version(clause.attrs.get(entry.getKey()).toString().trim()));
+ }
+ else if (type.equals("Long"))
+ {
+ clause.attrs.put(
+ entry.getKey(),
+ new Long(clause.attrs.get(entry.getKey()).toString().trim()));
+ }
+ else if (type.startsWith("List"))
+ {
+ int startIdx = type.indexOf('<');
+ int endIdx = type.indexOf('>');
+ if (((startIdx > 0) && (endIdx <= startIdx))
+ || ((startIdx < 0) && (endIdx > 0)))
+ {
+ throw new BundleException(
+ "Invalid Provide-Capability attribute list type for '"
+ + entry.getKey()
+ + "' : "
+ + type);
+ }
+
+ String listType = "String";
+ if (endIdx > startIdx)
+ {
+ listType = type.substring(startIdx + 1, endIdx).trim();
+ }
+
+ List<String> tokens = parseDelimitedString(
+ clause.attrs.get(entry.getKey()).toString(), ",", false);
+ List<Object> values = new ArrayList<Object>(tokens.size());
+ for (String token : tokens)
+ {
+ if (listType.equals("String"))
+ {
+ values.add(token);
+ }
+ else if (listType.equals("Double"))
+ {
+ values.add(new Double(token.trim()));
+ }
+ else if (listType.equals("Version"))
+ {
+ values.add(new Version(token.trim()));
+ }
+ else if (listType.equals("Long"))
+ {
+ values.add(new Long(token.trim()));
+ }
+ else
+ {
+ throw new BundleException(
+ "Unknown Provide-Capability attribute list type for '"
+ + entry.getKey()
+ + "' : "
+ + type);
+ }
+ }
+ clause.attrs.put(
+ entry.getKey(),
+ values);
+ }
+ else
+ {
+ throw new BundleException(
+ "Unknown Provide-Capability attribute type for '"
+ + entry.getKey()
+ + "' : "
+ + type);
+ }
+ }
+ }
+ }
+
+ return clauses;
+ }
+
+ private static List<Requirement> convertRequireCapabilities(
+ List<ParsedHeaderClause> clauses, Resource resource)
+ throws BundleException {
+ // Now convert generic header clauses into requirements.
+ List<Requirement> reqList = new ArrayList<Requirement>();
+ for (ParsedHeaderClause clause : clauses) {
+ try {
+ String filterStr = clause.dirs.get(Constants.FILTER_DIRECTIVE);
+ SimpleFilter sf = (filterStr != null)
+ ? SimpleFilter.parse(filterStr)
+ : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+ for (String path : clause.paths) {
+ // Create requirement and add to requirement list.
+ reqList.add(new RequirementImpl(
+ resource, path, clause.dirs, clause.attrs, sf));
+ }
+ } catch (Exception ex) {
+ throw new BundleException("Error creating requirement: " + ex, ex);
+ }
+ }
+
+ return reqList;
+ }
+
+ private static List<Capability> convertProvideCapabilities(
+ List<ParsedHeaderClause> clauses, Resource resource)
+ throws BundleException {
+ List<Capability> capList = new ArrayList<Capability>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String path : clause.paths) {
+ if (path.startsWith("osgi.wiring.")) {
+// throw new BundleException("Manifest cannot use Provide-Capability for '" + path + "' namespace.");
+ }
+
+ // Create package capability and add to capability list.
+ capList.add(new CapabilityImpl(resource, path, clause.dirs, clause.attrs));
+ }
+ }
+
+ return capList;
+ }
+
+ @SuppressWarnings( "deprecation" )
+ private static List<ParsedHeaderClause> normalizeExportClauses(
+ List<ParsedHeaderClause> clauses,
+ String bsn, Version bv)
+ throws BundleException {
+ // Verify that "java.*" packages are not exported.
+ for (ParsedHeaderClause clause : clauses) {
+ // Verify that the named package has not already been declared.
+ for (String pkgName : clause.paths) {
+ // Verify that java.* packages are not exported.
+ if (pkgName.startsWith("java.")) {
+ throw new BundleException("Exporting java.* packages not allowed: " + pkgName);
+ }
+ // The character "." has no meaning in the OSGi spec except
+ // when placed on the bundle class path. Some people, however,
+ // mistakenly think it means the default package when imported
+ // or exported. This is not correct. It is invalid.
+ else if (pkgName.equals(".")) {
+ throw new BundleException("Exporing '.' is invalid.");
+ }
+ // Make sure a package name was specified.
+ else if (pkgName.length() == 0) {
+ throw new BundleException("Exported package names cannot be zero length.");
+ }
+ }
+
+ // Check for "version" and "specification-version" attributes
+ // and verify they are the same if both are specified.
+ Object v = clause.attrs.get(Constants.VERSION_ATTRIBUTE);
+ Object sv = clause.attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+ if ((v != null) && (sv != null)) {
+ // Verify they are equal.
+ if (!((String) v).trim().equals(((String) sv).trim())) {
+ throw new IllegalArgumentException("Both version and specification-version are specified, but they are not equal.");
+ }
+ }
+
+ // Always add the default version if not specified.
+ if ((v == null) && (sv == null)) {
+ v = Version.emptyVersion;
+ }
+
+ // Ensure that only the "version" attribute is used and convert
+ // it to the appropriate type.
+ if ((v != null) || (sv != null)) {
+ // Convert version attribute to type Version.
+ clause.attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+ v = (v == null) ? sv : v;
+ clause.attrs.put(Constants.VERSION_ATTRIBUTE, Version.parseVersion(v.toString()));
+ }
+
+ // Find symbolic name and version attribute, if present.
+ if (clause.attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
+ || clause.attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)) {
+ throw new BundleException("Exports must not specify bundle symbolic name or bundle version.");
+ }
+
+ // Now that we know that there are no bundle symbolic name and version
+ // attributes, add them since the spec says they are there implicitly.
+ clause.attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
+ clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
+ }
+
+ return clauses;
+ }
+
+ private static List<Capability> convertExports(
+ List<ParsedHeaderClause> clauses, Resource resource) {
+ List<Capability> capList = new ArrayList<Capability>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String pkgName : clause.paths) {
+ // Prepend the package name to the array of attributes.
+ Map<String, Object> attrs = clause.attrs;
+ Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
+ newAttrs.putAll(attrs);
+ newAttrs.put(BundleRevision.PACKAGE_NAMESPACE, pkgName);
+
+ // Create package capability and add to capability list.
+ capList.add(new CapabilityImpl(resource, BundleRevision.PACKAGE_NAMESPACE, clause.dirs, newAttrs));
+ }
+ }
+
+ return capList;
+ }
+
+ private static String getManifestVersion(Map<String, String> headerMap) {
+ String manifestVersion = headerMap.get(Constants.BUNDLE_MANIFESTVERSION);
+ return (manifestVersion == null) ? "1" : manifestVersion.trim();
+ }
+
+ private static List<ParsedHeaderClause> calculateImplicitImports(
+ List<BundleCapability> exports, List<ParsedHeaderClause> imports)
+ throws BundleException {
+ List<ParsedHeaderClause> clauseList = new ArrayList<ParsedHeaderClause>();
+
+ // Since all R3 exports imply an import, add a corresponding
+ // requirement for each existing export capability. Do not
+ // duplicate imports.
+ Map<String, String> map = new HashMap<String, String>();
+ // Add existing imports.
+ for (ParsedHeaderClause anImport : imports) {
+ for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
+ map.put(anImport.paths.get(pathIdx), anImport.paths.get(pathIdx));
+ }
+ }
+ // Add import requirement for each export capability.
+ for (BundleCapability export : exports) {
+ if (map.get(export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString()) == null) {
+ // Convert Version to VersionRange.
+ Object version = export.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+ ParsedHeaderClause clause = new ParsedHeaderClause();
+ if (version != null) {
+ clause.attrs.put(Constants.VERSION_ATTRIBUTE, VersionRange.parseVersionRange(version.toString()));
+ }
+ clause.paths.add((String) export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
+ clauseList.add(clause);
+ }
+ }
+
+ return clauseList;
+ }
+
+ private static List<Capability> calculateImplicitUses(
+ List<Capability> exports, List<ParsedHeaderClause> imports)
+ throws BundleException {
+ // Add a "uses" directive onto each export of R3 bundles
+ // that references every other import (which will include
+ // exports, since export implies import); this is
+ // necessary since R3 bundles assumed a single class space,
+ // but R4 allows for multiple class spaces.
+ String usesValue = "";
+ for (ParsedHeaderClause anImport : imports) {
+ for (int pathIdx = 0; pathIdx < anImport.paths.size(); pathIdx++) {
+ usesValue = usesValue
+ + ((usesValue.length() > 0) ? "," : "")
+ + anImport.paths.get(pathIdx);
+ }
+ }
+ for (int i = 0; i < exports.size(); i++) {
+ Map<String, String> dirs = new HashMap<String, String>(1);
+ dirs.put(Constants.USES_DIRECTIVE, usesValue);
+ exports.set(i, new CapabilityImpl(
+ exports.get(i).getResource(),
+ BundleRevision.PACKAGE_NAMESPACE,
+ dirs,
+ exports.get(i).getAttributes()));
+ }
+
+ return exports;
+ }
+
+ private static ParsedHeaderClause parseBundleSymbolicName(Map<String, String> headerMap)
+ throws BundleException {
+ List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
+ if (clauses.size() > 0) {
+ if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
+ throw new BundleException("Cannot have multiple symbolic names: " + headerMap.get(Constants.BUNDLE_SYMBOLICNAME));
+ }
+
+ // Get bundle version.
+ Version bundleVersion = Version.emptyVersion;
+ if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
+ bundleVersion = Version.parseVersion(headerMap.get(Constants.BUNDLE_VERSION));
+ }
+
+ // Create a require capability and return it.
+ ParsedHeaderClause clause = clauses.get(0);
+ String symName = clause.paths.get(0);
+ clause.attrs.put(BundleRevision.BUNDLE_NAMESPACE, symName);
+ clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
+ return clause;
+ }
+
+ return null;
+ }
+
+ private static List<RequirementImpl> parseFragmentHost(
+ Resource resource, Map<String, String> headerMap)
+ throws BundleException {
+ List<RequirementImpl> reqs = new ArrayList<RequirementImpl>();
+
+ List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.get(Constants.FRAGMENT_HOST));
+ if (clauses.size() > 0) {
+ // Make sure that only one fragment host symbolic name is specified.
+ if (clauses.size() > 1 || clauses.get(0).paths.size() > 1) {
+ throw new BundleException("Fragments cannot have multiple hosts: " + headerMap.get(Constants.FRAGMENT_HOST));
+ }
+
+ // If the bundle-version attribute is specified, then convert
+ // it to the proper type.
+ Object value = clauses.get(0).attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ value = (value == null) ? "0.0.0" : value;
+ clauses.get(0).attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
+
+ // Note that we use a linked hash map here to ensure the
+ // host symbolic name is first, which will make indexing
+ // more efficient.
+ // TODO: OSGi R4.3 - This is ordering is kind of hacky.
+ // Prepend the host symbolic name to the map of attributes.
+ Map<String, Object> attrs = clauses.get(0).attrs;
+ Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
+ // We want this first from an indexing perspective.
+ newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
+ newAttrs.putAll(attrs);
+ // But we need to put it again to make sure it wasn't overwritten.
+ newAttrs.put(BundleRevision.HOST_NAMESPACE, clauses.get(0).paths.get(0));
+
+ // Create filter now so we can inject filter directive.
+ SimpleFilter sf = SimpleFilter.convert(newAttrs);
+
+ // Inject filter directive.
+ // TODO: OSGi R4.3 - Can we insert this on demand somehow?
+ Map<String, String> dirs = clauses.get(0).dirs;
+ Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
+ newDirs.putAll(dirs);
+ newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
+
+ reqs.add(new RequirementImpl(
+ resource, BundleRevision.HOST_NAMESPACE,
+ newDirs,
+ newAttrs));
+ }
+
+ return reqs;
+ }
+
+ private static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses) {
+ // Convert bundle version attribute to VersionRange type.
+ for (ParsedHeaderClause clause : clauses) {
+ Object value = clause.attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if (value != null) {
+ clause.attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, VersionRange.parseVersionRange(value.toString()));
+ }
+ }
+
+ return clauses;
+ }
+
+ private static List<Requirement> convertRequires(List<ParsedHeaderClause> clauses, Resource resource) {
+ List<Requirement> reqList = new ArrayList<Requirement>();
+ for (ParsedHeaderClause clause : clauses) {
+ for (String path : clause.paths) {
+ // Prepend the bundle symbolic name to the array of attributes.
+ Map<String, Object> attrs = clause.attrs;
+ // Note that we use a linked hash map here to ensure the
+ // symbolic name attribute is first, which will make indexing
+ // more efficient.
+ // TODO: OSGi R4.3 - This is ordering is kind of hacky.
+ // Prepend the symbolic name to the array of attributes.
+ Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
+ // We want this first from an indexing perspective.
+ newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
+ newAttrs.putAll(attrs);
+ // But we need to put it again to make sure it wasn't overwritten.
+ newAttrs.put(BundleRevision.BUNDLE_NAMESPACE, path);
+
+ // Create filter now so we can inject filter directive.
+ SimpleFilter sf = SimpleFilter.convert(newAttrs);
+
+ // Inject filter directive.
+ // TODO: OSGi R4.3 - Can we insert this on demand somehow?
+ Map<String, String> dirs = clause.dirs;
+ Map<String, String> newDirs = new HashMap<String, String>(dirs.size() + 1);
+ newDirs.putAll(dirs);
+ newDirs.put(Constants.FILTER_DIRECTIVE, sf.toString());
+
+ // Create package requirement and add to requirement list.
+ reqList.add(new RequirementImpl(resource, BundleRevision.BUNDLE_NAMESPACE, newDirs, newAttrs));
+ }
+ }
+
+ return reqList;
+ }
+
+ private static final char EOF = (char) -1;
+
+ private static char charAt(int pos, String headers, int length)
+ {
+ if (pos >= length)
+ {
+ return EOF;
+ }
+ return headers.charAt(pos);
+ }
+
+ private static final int CLAUSE_START = 0;
+ private static final int PARAMETER_START = 1;
+ private static final int KEY = 2;
+ private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
+ private static final int ARGUMENT = 8;
+ private static final int VALUE = 16;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private static List<ParsedHeaderClause> parseStandardHeader(String header)
+ {
+ List<ParsedHeaderClause> clauses = new ArrayList<ParsedHeaderClause>();
+ if (header == null)
+ {
+ return clauses;
+ }
+ ParsedHeaderClause clause = null;
+ String key = null;
+ Map targetMap = null;
+ int state = CLAUSE_START;
+ int currentPosition = 0;
+ int startPosition = 0;
+ int length = header.length();
+ boolean quoted = false;
+ boolean escaped = false;
+
+ char currentChar = EOF;
+ do
+ {
+ currentChar = charAt(currentPosition, header, length);
+ switch (state)
+ {
+ case CLAUSE_START:
+ clause = new ParsedHeaderClause();
+ clauses.add(clause);
+ state = PARAMETER_START;
+ case PARAMETER_START:
+ startPosition = currentPosition;
+ state = KEY;
+ case KEY:
+ switch (currentChar)
+ {
+ case ':':
+ case '=':
+ key = header.substring(startPosition, currentPosition).trim();
+ startPosition = currentPosition + 1;
+ targetMap = clause.attrs;
+ state = currentChar == ':' ? DIRECTIVE_OR_TYPEDATTRIBUTE : ARGUMENT;
+ break;
+ case EOF:
+ case ',':
+ case ';':
+ clause.paths.add(header.substring(startPosition, currentPosition).trim());
+ state = currentChar == ',' ? CLAUSE_START : PARAMETER_START;
+ break;
+ default:
+ break;
+ }
+ currentPosition++;
+ break;
+ case DIRECTIVE_OR_TYPEDATTRIBUTE:
+ switch(currentChar)
+ {
+ case '=':
+ if (startPosition != currentPosition)
+ {
+ clause.types.put(key, header.substring(startPosition, currentPosition).trim());
+ }
+ else
+ {
+ targetMap = clause.dirs;
+ }
+ state = ARGUMENT;
+ startPosition = currentPosition + 1;
+ break;
+ default:
+ break;
+ }
+ currentPosition++;
+ break;
+ case ARGUMENT:
+ if (currentChar == '\"')
+ {
+ quoted = true;
+ currentPosition++;
+ }
+ else
+ {
+ quoted = false;
+ }
+ if (!Character.isWhitespace(currentChar)) {
+ state = VALUE;
+ }
+ else {
+ currentPosition++;
+ }
+ break;
+ case VALUE:
+ if (escaped)
+ {
+ escaped = false;
+ }
+ else
+ {
+ if (currentChar == '\\' )
+ {
+ escaped = true;
+ }
+ else if (quoted && currentChar == '\"')
+ {
+ quoted = false;
+ }
+ else if (!quoted)
+ {
+ String value = null;
+ switch(currentChar)
+ {
+ case EOF:
+ case ';':
+ case ',':
+ value = header.substring(startPosition, currentPosition).trim();
+ if (value.startsWith("\"") && value.endsWith("\""))
+ {
+ value = value.substring(1, value.length() - 1);
+ }
+ if (targetMap.put(key, value) != null)
+ {
+ throw new IllegalArgumentException(
+ "Duplicate '" + key + "' in: " + header);
+ }
+ state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ currentPosition++;
+ break;
+ default:
+ break;
+ }
+ } while ( currentChar != EOF);
+
+ if (state > PARAMETER_START)
+ {
+ throw new IllegalArgumentException("Unable to parse header: " + header);
+ }
+ return clauses;
+ }
+
+ public static List<String> parseDelimitedString(String value, String delim)
+ {
+ return parseDelimitedString(value, delim, true);
+ }
+
+ /**
+ * Parses delimited string and returns an array containing the tokens. This
+ * parser obeys quotes, so the delimiter character will be ignored if it is
+ * inside of a quote. This method assumes that the quote character is not
+ * included in the set of delimiter characters.
+ * @param value the delimited string to parse.
+ * @param delim the characters delimiting the tokens.
+ * @return a list of string or an empty list if there are none.
+ **/
+ public static List<String> parseDelimitedString(String value, String delim, boolean trim)
+ {
+ if (value == null)
+ {
+ value = "";
+ }
+
+ List<String> list = new ArrayList();
+
+ int CHAR = 1;
+ int DELIMITER = 2;
+ int STARTQUOTE = 4;
+ int ENDQUOTE = 8;
+
+ StringBuffer sb = new StringBuffer();
+
+ int expecting = (CHAR | DELIMITER | STARTQUOTE);
+
+ boolean isEscaped = false;
+ for (int i = 0; i < value.length(); i++)
+ {
+ char c = value.charAt(i);
+
+ boolean isDelimiter = (delim.indexOf(c) >= 0);
+
+ if (!isEscaped && (c == '\\'))
+ {
+ isEscaped = true;
+ continue;
+ }
+
+ if (isEscaped)
+ {
+ sb.append(c);
+ }
+ else if (isDelimiter && ((expecting & DELIMITER) > 0))
+ {
+ if (trim)
+ {
+ list.add(sb.toString().trim());
+ }
+ else
+ {
+ list.add(sb.toString());
+ }
+ sb.delete(0, sb.length());
+ expecting = (CHAR | DELIMITER | STARTQUOTE);
+ }
+ else if ((c == '"') && ((expecting & STARTQUOTE) > 0))
+ {
+ sb.append(c);
+ expecting = CHAR | ENDQUOTE;
+ }
+ else if ((c == '"') && ((expecting & ENDQUOTE) > 0))
+ {
+ sb.append(c);
+ expecting = (CHAR | STARTQUOTE | DELIMITER);
+ }
+ else if ((expecting & CHAR) > 0)
+ {
+ sb.append(c);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid delimited string: " + value);
+ }
+
+ isEscaped = false;
+ }
+
+ if (sb.length() > 0)
+ {
+ if (trim)
+ {
+ list.add(sb.toString().trim());
+ }
+ else
+ {
+ list.add(sb.toString());
+ }
+ }
+
+ return list;
+ }
+
+
+ static class ParsedHeaderClause {
+ public final List<String> paths = new ArrayList<String>();
+ public final Map<String, String> dirs = new LinkedHashMap<String, String>();
+ public final Map<String, Object> attrs = new LinkedHashMap<String, Object>();
+ public final Map<String, String> types = new LinkedHashMap<String, String>();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
new file mode 100644
index 0000000..18e0dc3
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/ResourceImpl.java
@@ -0,0 +1,110 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+/**
+ */
+public class ResourceImpl implements Resource {
+
+ private final List<Capability> m_caps;
+ private final List<Requirement> m_reqs;
+
+ public ResourceImpl(String name, Version version) {
+ this(name, IdentityNamespace.TYPE_BUNDLE, version);
+ }
+
+ public ResourceImpl(String name, String type, Version version)
+ {
+ m_caps = new ArrayList<Capability>();
+ m_caps.add(0, new IdentityCapability(this, name, type, version));
+ m_reqs = new ArrayList<Requirement>();
+ }
+
+ public void addCapability(Capability capability) {
+ assert capability.getResource() == this;
+ m_caps.add(capability);
+ }
+
+ public void addCapabilities(Iterable<? extends Capability> capabilities) {
+ for (Capability cap : capabilities) {
+ addCapability(cap);
+ }
+ }
+
+ public void addRequirement(Requirement requirement) {
+ assert requirement.getResource() == this;
+ m_reqs.add(requirement);
+ }
+
+ public void addRequirements(Iterable<? extends Requirement> requirements) {
+ for (Requirement req : requirements) {
+ addRequirement(req);
+ }
+ }
+
+ public List<Capability> getCapabilities(String namespace)
+ {
+ List<Capability> result = m_caps;
+ if (namespace != null)
+ {
+ result = new ArrayList<Capability>();
+ for (Capability cap : m_caps)
+ {
+ if (cap.getNamespace().equals(namespace))
+ {
+ result.add(cap);
+ }
+ }
+ }
+ return result;
+ }
+
+ public List<Requirement> getRequirements(String namespace)
+ {
+ List<Requirement> result = m_reqs;
+ if (namespace != null)
+ {
+ result = new ArrayList<Requirement>();
+ for (Requirement req : m_reqs)
+ {
+ if (req.getNamespace().equals(namespace))
+ {
+ result.add(req);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ Capability cap = getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
+ return cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE) + "/"
+ + cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
new file mode 100644
index 0000000..4fe3bf8
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/ServiceNamespace.java
@@ -0,0 +1,30 @@
+/*
+ * 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.internal.resolver;
+
+import org.osgi.resource.Namespace;
+
+/**
+ */
+public final class ServiceNamespace extends Namespace {
+
+ public static final String SERVICE_NAMESPACE = "service-reference";
+
+ private ServiceNamespace() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
new file mode 100644
index 0000000..ae10441
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
@@ -0,0 +1,649 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.felix.utils.version.VersionRange;
+
+public class SimpleFilter
+{
+ public static final int MATCH_ALL = 0;
+ public static final int AND = 1;
+ public static final int OR = 2;
+ public static final int NOT = 3;
+ public static final int EQ = 4;
+ public static final int LTE = 5;
+ public static final int GTE = 6;
+ public static final int SUBSTRING = 7;
+ public static final int PRESENT = 8;
+ public static final int APPROX = 9;
+
+ private final String m_name;
+ private final Object m_value;
+ private final int m_op;
+
+ public SimpleFilter(String attr, Object value, int op)
+ {
+ m_name = attr;
+ m_value = value;
+ m_op = op;
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+
+ public Object getValue()
+ {
+ return m_value;
+ }
+
+ public int getOperation()
+ {
+ return m_op;
+ }
+
+ public String toString()
+ {
+ String s = null;
+ switch (m_op)
+ {
+ case AND:
+ s = "(&" + toString((List) m_value) + ")";
+ break;
+ case OR:
+ s = "(|" + toString((List) m_value) + ")";
+ break;
+ case NOT:
+ s = "(!" + toString((List) m_value) + ")";
+ break;
+ case EQ:
+ s = "(" + m_name + "=" + toEncodedString(m_value) + ")";
+ break;
+ case LTE:
+ s = "(" + m_name + "<=" + toEncodedString(m_value) + ")";
+ break;
+ case GTE:
+ s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
+ break;
+ case SUBSTRING:
+ s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
+ break;
+ case PRESENT:
+ s = "(" + m_name + "=*)";
+ break;
+ case APPROX:
+ s = "(" + m_name + "~=" + toEncodedString(m_value) + ")";
+ break;
+ case MATCH_ALL:
+ s = "(*)";
+ break;
+ }
+ return s;
+ }
+
+ private static String toString(List list)
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < list.size(); i++)
+ {
+ sb.append(list.get(i).toString());
+ }
+ return sb.toString();
+ }
+
+ private static String toDecodedString(String s, int startIdx, int endIdx)
+ {
+ StringBuffer sb = new StringBuffer(endIdx - startIdx);
+ boolean escaped = false;
+ for (int i = 0; i < (endIdx - startIdx); i++)
+ {
+ char c = s.charAt(startIdx + i);
+ if (!escaped && (c == '\\'))
+ {
+ escaped = true;
+ }
+ else
+ {
+ escaped = false;
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ private static String toEncodedString(Object o)
+ {
+ if (o instanceof String)
+ {
+ String s = (String) o;
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < s.length(); i++)
+ {
+ char c = s.charAt(i);
+ if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
+ {
+ sb.append('\\');
+ }
+ sb.append(c);
+ }
+
+ o = sb.toString();
+ }
+
+ return o.toString();
+ }
+
+ public static SimpleFilter parse(String filter)
+ {
+ int idx = skipWhitespace(filter, 0);
+
+ if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
+ {
+ throw new IllegalArgumentException("Null or empty filter.");
+ }
+ else if (filter.charAt(idx) != '(')
+ {
+ throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
+ }
+
+ SimpleFilter sf = null;
+ List stack = new ArrayList();
+ boolean isEscaped = false;
+ while (idx < filter.length())
+ {
+ if (sf != null)
+ {
+ throw new IllegalArgumentException(
+ "Only one top-level operation allowed: " + filter);
+ }
+
+ if (!isEscaped && (filter.charAt(idx) == '('))
+ {
+ // Skip paren and following whitespace.
+ idx = skipWhitespace(filter, idx + 1);
+
+ if (filter.charAt(idx) == '&')
+ {
+ int peek = skipWhitespace(filter, idx + 1);
+ if (filter.charAt(peek) == '(')
+ {
+ idx = peek - 1;
+ stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
+ }
+ else
+ {
+ stack.add(0, new Integer(idx));
+ }
+ }
+ else if (filter.charAt(idx) == '|')
+ {
+ int peek = skipWhitespace(filter, idx + 1);
+ if (filter.charAt(peek) == '(')
+ {
+ idx = peek - 1;
+ stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
+ }
+ else
+ {
+ stack.add(0, new Integer(idx));
+ }
+ }
+ else if (filter.charAt(idx) == '!')
+ {
+ int peek = skipWhitespace(filter, idx + 1);
+ if (filter.charAt(peek) == '(')
+ {
+ idx = peek - 1;
+ stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
+ }
+ else
+ {
+ stack.add(0, new Integer(idx));
+ }
+ }
+ else
+ {
+ stack.add(0, new Integer(idx));
+ }
+ }
+ else if (!isEscaped && (filter.charAt(idx) == ')'))
+ {
+ Object top = stack.remove(0);
+ if (top instanceof SimpleFilter)
+ {
+ if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+ {
+ ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
+ }
+ else
+ {
+ sf = (SimpleFilter) top;
+ }
+ }
+ else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+ {
+ ((List) ((SimpleFilter) stack.get(0)).m_value).add(
+ SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx));
+ }
+ else
+ {
+ sf = SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx);
+ }
+ }
+ else if (!isEscaped && (filter.charAt(idx) == '\\'))
+ {
+ isEscaped = true;
+ }
+ else
+ {
+ isEscaped = false;
+ }
+
+ idx = skipWhitespace(filter, idx + 1);
+ }
+
+ if (sf == null)
+ {
+ throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
+ }
+
+ return sf;
+ }
+
+ private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
+ {
+ final String opChars = "=<>~";
+
+ // Determine the ending index of the attribute name.
+ int attrEndIdx = startIdx;
+ for (int i = 0; i < (endIdx - startIdx); i++)
+ {
+ char c = filter.charAt(startIdx + i);
+ if (opChars.indexOf(c) >= 0)
+ {
+ break;
+ }
+ else if (!Character.isWhitespace(c))
+ {
+ attrEndIdx = startIdx + i + 1;
+ }
+ }
+ if (attrEndIdx == startIdx)
+ {
+ throw new IllegalArgumentException(
+ "Missing attribute name: " + filter.substring(startIdx, endIdx));
+ }
+ String attr = filter.substring(startIdx, attrEndIdx);
+
+ // Skip the attribute name and any following whitespace.
+ startIdx = skipWhitespace(filter, attrEndIdx);
+
+ // Determine the operator type.
+ int op = -1;
+ switch (filter.charAt(startIdx))
+ {
+ case '=':
+ op = EQ;
+ startIdx++;
+ break;
+ case '<':
+ if (filter.charAt(startIdx + 1) != '=')
+ {
+ throw new IllegalArgumentException(
+ "Unknown operator: " + filter.substring(startIdx, endIdx));
+ }
+ op = LTE;
+ startIdx += 2;
+ break;
+ case '>':
+ if (filter.charAt(startIdx + 1) != '=')
+ {
+ throw new IllegalArgumentException(
+ "Unknown operator: " + filter.substring(startIdx, endIdx));
+ }
+ op = GTE;
+ startIdx += 2;
+ break;
+ case '~':
+ if (filter.charAt(startIdx + 1) != '=')
+ {
+ throw new IllegalArgumentException(
+ "Unknown operator: " + filter.substring(startIdx, endIdx));
+ }
+ op = APPROX;
+ startIdx += 2;
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown operator: " + filter.substring(startIdx, endIdx));
+ }
+
+ // Parse value.
+ Object value = toDecodedString(filter, startIdx, endIdx);
+
+ // Check if the equality comparison is actually a substring
+ // or present operation.
+ if (op == EQ)
+ {
+ String valueStr = filter.substring(startIdx, endIdx);
+ List<String> values = parseSubstring(valueStr);
+ if ((values.size() == 2)
+ && (values.get(0).length() == 0)
+ && (values.get(1).length() == 0))
+ {
+ op = PRESENT;
+ }
+ else if (values.size() > 1)
+ {
+ op = SUBSTRING;
+ value = values;
+ }
+ }
+
+ return new SimpleFilter(attr, value, op);
+ }
+
+ public static List<String> parseSubstring(String value)
+ {
+ List<String> pieces = new ArrayList();
+ StringBuffer ss = new StringBuffer();
+ // int kind = SIMPLE; // assume until proven otherwise
+ boolean wasStar = false; // indicates last piece was a star
+ boolean leftstar = false; // track if the initial piece is a star
+ boolean rightstar = false; // track if the final piece is a star
+
+ int idx = 0;
+
+ // We assume (sub)strings can contain leading and trailing blanks
+ boolean escaped = false;
+ loop: for (;;)
+ {
+ if (idx >= value.length())
+ {
+ if (wasStar)
+ {
+ // insert last piece as "" to handle trailing star
+ rightstar = true;
+ }
+ else
+ {
+ pieces.add(ss.toString());
+ // accumulate the last piece
+ // note that in the case of
+ // (cn=); this might be
+ // the string "" (!=null)
+ }
+ ss.setLength(0);
+ break loop;
+ }
+
+ // Read the next character and account for escapes.
+ char c = value.charAt(idx++);
+ if (!escaped && (c == '*'))
+ {
+ // If we have successive '*' characters, then we can
+ // effectively collapse them by ignoring succeeding ones.
+ if (!wasStar)
+ {
+ if (ss.length() > 0)
+ {
+ pieces.add(ss.toString()); // accumulate the pieces
+ // between '*' occurrences
+ }
+ ss.setLength(0);
+ // if this is a leading star, then track it
+ if (pieces.isEmpty())
+ {
+ leftstar = true;
+ }
+ wasStar = true;
+ }
+ }
+ else if (!escaped && (c == '\\'))
+ {
+ escaped = true;
+ }
+ else
+ {
+ escaped = false;
+ wasStar = false;
+ ss.append(c);
+ }
+ }
+ if (leftstar || rightstar || pieces.size() > 1)
+ {
+ // insert leading and/or trailing "" to anchor ends
+ if (rightstar)
+ {
+ pieces.add("");
+ }
+ if (leftstar)
+ {
+ pieces.add(0, "");
+ }
+ }
+ return pieces;
+ }
+
+ public static String unparseSubstring(List<String> pieces)
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < pieces.size(); i++)
+ {
+ if (i > 0)
+ {
+ sb.append("*");
+ }
+ sb.append(toEncodedString(pieces.get(i)));
+ }
+ return sb.toString();
+ }
+
+ public static boolean compareSubstring(List<String> pieces, String s)
+ {
+ // Walk the pieces to match the string
+ // There are implicit stars between each piece,
+ // and the first and last pieces might be "" to anchor the match.
+ // assert (pieces.length > 1)
+ // minimal case is <string>*<string>
+
+ boolean result = true;
+ int len = pieces.size();
+
+ // Special case, if there is only one piece, then
+ // we must perform an equality test.
+ if (len == 1)
+ {
+ return s.equals(pieces.get(0));
+ }
+
+ // Otherwise, check whether the pieces match
+ // the specified string.
+
+ int index = 0;
+
+ loop: for (int i = 0; i < len; i++)
+ {
+ String piece = pieces.get(i);
+
+ // If this is the first piece, then make sure the
+ // string starts with it.
+ if (i == 0)
+ {
+ if (!s.startsWith(piece))
+ {
+ result = false;
+ break loop;
+ }
+ }
+
+ // If this is the last piece, then make sure the
+ // string ends with it.
+ if (i == (len - 1))
+ {
+ if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
+ {
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ break loop;
+ }
+
+ // If this is neither the first or last piece, then
+ // make sure the string contains it.
+ if ((i > 0) && (i < (len - 1)))
+ {
+ index = s.indexOf(piece, index);
+ if (index < 0)
+ {
+ result = false;
+ break loop;
+ }
+ }
+
+ // Move string index beyond the matching piece.
+ index += piece.length();
+ }
+
+ return result;
+ }
+
+ private static int skipWhitespace(String s, int startIdx)
+ {
+ int len = s.length();
+ while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
+ {
+ startIdx++;
+ }
+ return startIdx;
+ }
+
+ /**
+ * Converts a attribute map to a filter. The filter is created by iterating
+ * over the map's entry set. If ordering of attributes is important (e.g.,
+ * for hitting attribute indices), then the map's entry set should iterate
+ * in the desired order. Equality testing is assumed for all attribute types
+ * other than version ranges, which are handled appropriated. If the attribute
+ * map is empty, then a filter that matches anything is returned.
+ * @param attrs Map of attributes to convert to a filter.
+ * @return A filter corresponding to the attributes.
+ */
+ public static SimpleFilter convert(Map<String, Object> attrs)
+ {
+ // Rather than building a filter string to be parsed into a SimpleFilter,
+ // we will just create the parsed SimpleFilter directly.
+
+ List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
+
+ for (Entry<String, Object> entry : attrs.entrySet())
+ {
+ if (entry.getValue() instanceof VersionRange)
+ {
+ VersionRange vr = (VersionRange) entry.getValue();
+ if (!vr.isOpenFloor())
+ {
+ filters.add(
+ new SimpleFilter(
+ entry.getKey(),
+ vr.getFloor().toString(),
+ SimpleFilter.GTE));
+ }
+ else
+ {
+ SimpleFilter not =
+ new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
+ ((List) not.getValue()).add(
+ new SimpleFilter(
+ entry.getKey(),
+ vr.getFloor().toString(),
+ SimpleFilter.LTE));
+ filters.add(not);
+ }
+
+ if (vr.getCeiling() != null)
+ {
+ if (!vr.isOpenCeiling())
+ {
+ filters.add(
+ new SimpleFilter(
+ entry.getKey(),
+ vr.getCeiling().toString(),
+ SimpleFilter.LTE));
+ }
+ else
+ {
+ SimpleFilter not =
+ new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
+ ((List) not.getValue()).add(
+ new SimpleFilter(
+ entry.getKey(),
+ vr.getCeiling().toString(),
+ SimpleFilter.GTE));
+ filters.add(not);
+ }
+ }
+ }
+ else
+ {
+ List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
+ if (values.size() > 1)
+ {
+ filters.add(
+ new SimpleFilter(
+ entry.getKey(),
+ values,
+ SimpleFilter.SUBSTRING));
+ }
+ else
+ {
+ filters.add(
+ new SimpleFilter(
+ entry.getKey(),
+ values.get(0),
+ SimpleFilter.EQ));
+ }
+ }
+ }
+
+ SimpleFilter sf = null;
+
+ if (filters.size() == 1)
+ {
+ sf = filters.get(0);
+ }
+ else if (attrs.size() > 1)
+ {
+ sf = new SimpleFilter(null, filters, SimpleFilter.AND);
+ }
+ else if (filters.isEmpty())
+ {
+ sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+ }
+
+ return sf;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
new file mode 100644
index 0000000..2f4a1f3
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/Slf4jResolverLog.java
@@ -0,0 +1,49 @@
+/*
+ * 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.internal.resolver;
+
+import org.slf4j.Logger;
+
+/**
+ */
+public class Slf4jResolverLog extends org.apache.felix.resolver.Logger {
+
+ private final Logger logger;
+
+ public Slf4jResolverLog(Logger logger) {
+ super(LOG_DEBUG);
+ this.logger = logger;
+ }
+
+ @Override
+ protected void doLog(int level, String msg, Throwable throwable) {
+ switch (level) {
+ case LOG_ERROR:
+ logger.error(msg, throwable);
+ break;
+ case LOG_WARNING:
+ logger.warn(msg, throwable);
+ break;
+ case LOG_INFO:
+ logger.info(msg, throwable);
+ break;
+ case LOG_DEBUG:
+ logger.debug(msg, throwable);
+ break;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java b/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
new file mode 100644
index 0000000..b5158bf
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/resolver/UriNamespace.java
@@ -0,0 +1,47 @@
+/*
+ * 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.internal.resolver;
+
+import java.util.List;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Resource;
+
+/**
+ */
+public final class UriNamespace extends Namespace {
+
+ public static final String URI_NAMESPACE = "karaf.uri";
+
+ public static String getUri(Resource resource)
+ {
+ List<Capability> caps = resource.getCapabilities(null);
+ for (Capability cap : caps)
+ {
+ if (cap.getNamespace().equals(UriNamespace.URI_NAMESPACE))
+ {
+ return cap.getAttributes().get(UriNamespace.URI_NAMESPACE).toString();
+ }
+ }
+ return null;
+ }
+
+
+ private UriNamespace() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/Artifact.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/Artifact.java b/features/src/main/java/org/apache/karaf/features/internal/service/Artifact.java
new file mode 100644
index 0000000..44e9a7c
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/Artifact.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.internal.service;
+
+import java.net.URI;
+
+/**
+ * Simple abstraction of a maven artifact to avoid external deps
+ */
+public class Artifact {
+ String groupId;
+ String artifactId;
+ String version;
+ String extension;
+ String classifier;
+
+ public Artifact(String coords) {
+ String[] coordsAr = coords.split(":");
+ if (coordsAr.length != 5) {
+ throw new IllegalArgumentException("Maven URL " + coords + " is malformed or not complete");
+ }
+ this.groupId = coordsAr[0];
+ this.artifactId = coordsAr[1];
+ this.version = coordsAr[4];
+ this.extension = coordsAr[2];
+ this.classifier = coordsAr[3];
+ }
+
+ public Artifact(String coords, String version) {
+ this(coords);
+ this.version = version;
+ }
+
+ public URI getMavenUrl(String version) {
+ String uriSt = "mvn:" + this.groupId + "/" + this.artifactId + "/" + version + "/" + this.extension + "/" + this.classifier;
+ try {
+ return new URI(uriSt);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
[36/59] [abbrv] [KARAF-2852] Merge log/core and log/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
deleted file mode 100644
index 80155a0..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Copied from log4j
- */
-// Contributors: Arndt Schoenewald <ar...@ibm23093i821.mc.schoenewald.de>
-/**
- Formats a {@link Date} in the format "yyyy-MM-dd HH:mm:ss,SSS" for example
- "1999-11-27 15:49:37,459".
-
- <p>Refer to the <a
- href=http://www.cl.cam.ac.uk/~mgk25/iso-time.html>summary of the
- International Standard Date and Time Notation</a> for more
- information on this format.
-
- @since 0.7.5
-*/
-public class ISO8601DateFormat extends AbsoluteTimeDateFormat {
-
- public
- ISO8601DateFormat() {
- }
-
- public
- ISO8601DateFormat(TimeZone timeZone) {
- super(timeZone);
- }
-
- static private long lastTime;
- static private char[] lastTimeString = new char[20];
-
- /**
- Appends a date in the format "YYYY-mm-dd HH:mm:ss,SSS"
- to <code>sbuf</code>. For example: "1999-11-27 15:49:37,459".
-
- @param sbuf the <code>StringBuffer</code> to write to
- */
- public
- StringBuffer format(Date date, StringBuffer sbuf,
- FieldPosition fieldPosition) {
-
- long now = date.getTime();
- int millis = (int)(now % 1000);
-
- if ((now - millis) != lastTime) {
- // We reach this point at most once per second
- // across all threads instead of each time format()
- // is called. This saves considerable CPU time.
-
- calendar.setTime(date);
-
- int start = sbuf.length();
-
- int year = calendar.get(Calendar.YEAR);
- sbuf.append(year);
-
- String month;
- switch(calendar.get(Calendar.MONTH)) {
- case Calendar.JANUARY: month = "-01-"; break;
- case Calendar.FEBRUARY: month = "-02-"; break;
- case Calendar.MARCH: month = "-03-"; break;
- case Calendar.APRIL: month = "-04-"; break;
- case Calendar.MAY: month = "-05-"; break;
- case Calendar.JUNE: month = "-06-"; break;
- case Calendar.JULY: month = "-07-"; break;
- case Calendar.AUGUST: month = "-08-"; break;
- case Calendar.SEPTEMBER: month = "-09-"; break;
- case Calendar.OCTOBER: month = "-10-"; break;
- case Calendar.NOVEMBER: month = "-11-"; break;
- case Calendar.DECEMBER: month = "-12-"; break;
- default: month = "-NA-"; break;
- }
- sbuf.append(month);
-
- int day = calendar.get(Calendar.DAY_OF_MONTH);
- if(day < 10)
- sbuf.append('0');
- sbuf.append(day);
-
- sbuf.append(' ');
-
- int hour = calendar.get(Calendar.HOUR_OF_DAY);
- if(hour < 10) {
- sbuf.append('0');
- }
- sbuf.append(hour);
- sbuf.append(':');
-
- int mins = calendar.get(Calendar.MINUTE);
- if(mins < 10) {
- sbuf.append('0');
- }
- sbuf.append(mins);
- sbuf.append(':');
-
- int secs = calendar.get(Calendar.SECOND);
- if(secs < 10) {
- sbuf.append('0');
- }
- sbuf.append(secs);
-
- sbuf.append(',');
-
- // store the time string for next time to avoid recomputation
- sbuf.getChars(start, sbuf.length(), lastTimeString, 0);
- lastTime = now - millis;
- }
- else {
- sbuf.append(lastTimeString);
- }
-
-
- if (millis < 100)
- sbuf.append('0');
- if (millis < 10)
- sbuf.append('0');
-
- sbuf.append(millis);
- return sbuf;
- }
-
- /**
- This method does not do anything but return <code>null</code>.
- */
- public
- Date parse(java.lang.String s, ParsePosition pos) {
- return null;
- }
-}
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java
deleted file mode 100644
index 0d91e8c..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-/**
- <p>PatternConverter is an abtract class that provides the
- formatting functionality that derived classes need.
-
- <p>Conversion specifiers in a conversion patterns are parsed to
- individual PatternConverters. Each of which is responsible for
- converting a logging event in a converter specific manner.
-
- @since 0.8.2
- */
-public abstract class PatternConverter {
- public PatternConverter next;
- int min = -1;
- int max = 0x7FFFFFFF;
- boolean leftAlign = false;
-
- protected
- PatternConverter() { }
-
- protected
- PatternConverter(FormattingInfo fi) {
- min = fi.min;
- max = fi.max;
- leftAlign = fi.leftAlign;
- }
-
- /**
- Derived pattern converters must override this method in order to
- convert conversion specifiers in the correct way.
- */
- abstract
- protected
- String convert(PaxLoggingEvent event);
-
- /**
- A template method for formatting in a converter specific way.
- */
- public
- void format(StringBuffer sbuf, PaxLoggingEvent e) {
- String s = convert(e);
-
- if(s == null) {
- if(0 < min)
- spacePad(sbuf, min);
- return;
- }
-
- int len = s.length();
-
- if(len > max)
- sbuf.append(s.substring(len-max));
- else if(len < min) {
- if(leftAlign) {
- sbuf.append(s);
- spacePad(sbuf, min-len);
- }
- else {
- spacePad(sbuf, min-len);
- sbuf.append(s);
- }
- }
- else
- sbuf.append(s);
- }
-
- static String[] SPACES = {" ", " ", " ", " ", //1,2,4,8 spaces
- " ", // 16 spaces
- " " }; // 32 spaces
-
- /**
- Fast space padding method.
- */
- public
- void spacePad(StringBuffer sbuf, int length) {
- while(length >= 32) {
- sbuf.append(SPACES[5]);
- length -= 32;
- }
-
- for(int i = 4; i >= 0; i--) {
- if((length & (1<<i)) != 0) {
- sbuf.append(SPACES[i]);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
deleted file mode 100644
index f61b278..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Map;
-
-import org.apache.log4j.spi.LoggingEvent;
-import org.ops4j.pax.logging.spi.PaxLocationInfo;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-/**
- * Copied from log4j
- */
-/**
- Most of the work of the {@link org.apache.log4j.PatternLayout} class
- is delegated to the PatternParser class.
-
- @since 0.8.2
-*/
-public class PatternParser {
-
- private static final String LINE_SEP = System.getProperty("line.separator");
-
- private static final char ESCAPE_CHAR = '%';
-
- private static final int LITERAL_STATE = 0;
- private static final int CONVERTER_STATE = 1;
- private static final int MINUS_STATE = 2;
- private static final int DOT_STATE = 3;
- private static final int MIN_STATE = 4;
- private static final int MAX_STATE = 5;
-
- static final int FULL_LOCATION_CONVERTER = 1000;
- static final int METHOD_LOCATION_CONVERTER = 1001;
- static final int CLASS_LOCATION_CONVERTER = 1002;
- static final int LINE_LOCATION_CONVERTER = 1003;
- static final int FILE_LOCATION_CONVERTER = 1004;
-
- static final int RELATIVE_TIME_CONVERTER = 2000;
- static final int THREAD_CONVERTER = 2001;
- static final int LEVEL_CONVERTER = 2002;
- static final int NDC_CONVERTER = 2003;
- static final int MESSAGE_CONVERTER = 2004;
-
- int state;
- protected StringBuffer currentLiteral = new StringBuffer(32);
- protected int patternLength;
- protected int i;
- PatternConverter head;
- PatternConverter tail;
- protected FormattingInfo formattingInfo = new FormattingInfo();
- protected String pattern;
-
- public
- PatternParser(String pattern) {
- this.pattern = pattern;
- patternLength = pattern.length();
- state = LITERAL_STATE;
- }
-
- private
- void addToList(PatternConverter pc) {
- if(head == null) {
- head = tail = pc;
- } else {
- tail.next = pc;
- tail = pc;
- }
- }
-
- protected
- String extractOption() {
- if((i < patternLength) && (pattern.charAt(i) == '{')) {
- int end = pattern.indexOf('}', i);
- if (end > i) {
- String r = pattern.substring(i + 1, end);
- i = end+1;
- return r;
- }
- }
- return null;
- }
-
-
- /**
- The option is expected to be in decimal and positive. In case of
- error, zero is returned. */
- protected
- int extractPrecisionOption() {
- String opt = extractOption();
- int r = 0;
- if(opt != null) {
- try {
- r = Integer.parseInt(opt);
- if(r <= 0) {
- //LogLog.error("Precision option (" + opt + ") isn't a positive integer.");
- r = 0;
- }
- }
- catch (NumberFormatException e) {
- //LogLog.error("Category option \""+opt+"\" not a decimal integer.", e);
- }
- }
- return r;
- }
-
- public
- PatternConverter parse() {
- char c;
- i = 0;
- while(i < patternLength) {
- c = pattern.charAt(i++);
- switch(state) {
- case LITERAL_STATE:
- // In literal state, the last char is always a literal.
- if(i == patternLength) {
- currentLiteral.append(c);
- continue;
- }
- if(c == ESCAPE_CHAR) {
- // peek at the next char.
- switch(pattern.charAt(i)) {
- case ESCAPE_CHAR:
- currentLiteral.append(c);
- i++; // move pointer
- break;
- case 'n':
- currentLiteral.append(LINE_SEP);
- i++; // move pointer
- break;
- default:
- if(currentLiteral.length() != 0) {
- addToList(new LiteralPatternConverter(
- currentLiteral.toString()));
- //LogLog.debug("Parsed LITERAL converter: \""
- // +currentLiteral+"\".");
- }
- currentLiteral.setLength(0);
- currentLiteral.append(c); // append %
- state = CONVERTER_STATE;
- formattingInfo.reset();
- }
- }
- else {
- currentLiteral.append(c);
- }
- break;
- case CONVERTER_STATE:
- currentLiteral.append(c);
- switch(c) {
- case '-':
- formattingInfo.leftAlign = true;
- break;
- case '.':
- state = DOT_STATE;
- break;
- default:
- if(c >= '0' && c <= '9') {
- formattingInfo.min = c - '0';
- state = MIN_STATE;
- }
- else
- finalizeConverter(c);
- } // switch
- break;
- case MIN_STATE:
- currentLiteral.append(c);
- if(c >= '0' && c <= '9')
- formattingInfo.min = formattingInfo.min*10 + (c - '0');
- else if(c == '.')
- state = DOT_STATE;
- else {
- finalizeConverter(c);
- }
- break;
- case DOT_STATE:
- currentLiteral.append(c);
- if(c >= '0' && c <= '9') {
- formattingInfo.max = c - '0';
- state = MAX_STATE;
- }
- else {
- //LogLog.error("Error occured in position "+i+".\n Was expecting digit, instead got char \""+c+"\".");
- state = LITERAL_STATE;
- }
- break;
- case MAX_STATE:
- currentLiteral.append(c);
- if(c >= '0' && c <= '9')
- formattingInfo.max = formattingInfo.max*10 + (c - '0');
- else {
- finalizeConverter(c);
- state = LITERAL_STATE;
- }
- break;
- } // switch
- } // while
- if(currentLiteral.length() != 0) {
- addToList(new LiteralPatternConverter(currentLiteral.toString()));
- //LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
- }
- return head;
- }
-
- protected
- void finalizeConverter(char c) {
- PatternConverter pc = null;
- switch(c) {
- case 'c':
- pc = new CategoryPatternConverter(formattingInfo,
- extractPrecisionOption());
- //LogLog.debug("CATEGORY converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'C':
- pc = new ClassNamePatternConverter(formattingInfo,
- extractPrecisionOption());
- //LogLog.debug("CLASS_NAME converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'd':
- String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT;
- DateFormat df;
- String dOpt = extractOption();
- if(dOpt != null)
- dateFormatStr = dOpt;
-
- if(dateFormatStr.equalsIgnoreCase(
- AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT))
- df = new ISO8601DateFormat();
- else if(dateFormatStr.equalsIgnoreCase(
- AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT))
- df = new AbsoluteTimeDateFormat();
- else if(dateFormatStr.equalsIgnoreCase(
- AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT))
- df = new DateTimeDateFormat();
- else {
- try {
- df = new SimpleDateFormat(dateFormatStr);
- }
- catch (IllegalArgumentException e) {
- //LogLog.error("Could not instantiate SimpleDateFormat with " + dateFormatStr, e);
- df = new ISO8601DateFormat();
- }
- }
- pc = new DatePatternConverter(formattingInfo, df);
- //LogLog.debug("DATE converter {"+dateFormatStr+"}.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'F':
- pc = new LocationPatternConverter(formattingInfo,
- FILE_LOCATION_CONVERTER);
- //LogLog.debug("File name converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- /*case 'l':
- pc = new LocationPatternConverter(formattingInfo,
- FULL_LOCATION_CONVERTER);
- //LogLog.debug("Location converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;*/
- case 'L':
- pc = new LocationPatternConverter(formattingInfo,
- LINE_LOCATION_CONVERTER);
- //LogLog.debug("LINE NUMBER converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'm':
- pc = new BasicPatternConverter(formattingInfo, MESSAGE_CONVERTER);
- //LogLog.debug("MESSAGE converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'M':
- pc = new LocationPatternConverter(formattingInfo,
- METHOD_LOCATION_CONVERTER);
- //LogLog.debug("METHOD converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'p':
- pc = new BasicPatternConverter(formattingInfo, LEVEL_CONVERTER);
- //LogLog.debug("LEVEL converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 'r':
- pc = new BasicPatternConverter(formattingInfo,
- RELATIVE_TIME_CONVERTER);
- //LogLog.debug("RELATIVE time converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- case 't':
- pc = new BasicPatternConverter(formattingInfo, THREAD_CONVERTER);
- //LogLog.debug("THREAD converter.");
- //formattingInfo.dump();
- currentLiteral.setLength(0);
- break;
- /*case 'u':
- if(i < patternLength) {
- char cNext = pattern.charAt(i);
- if(cNext >= '0' && cNext <= '9') {
- pc = new UserFieldPatternConverter(formattingInfo, cNext - '0');
- LogLog.debug("USER converter ["+cNext+"].");
- formattingInfo.dump();
- currentLiteral.setLength(0);
- i++;
- }
- else
- LogLog.error("Unexpected char" +cNext+" at position "+i);
- }
- break;*/
- /*case 'x':
- pc = new BasicPatternConverter(formattingInfo, NDC_CONVERTER);
- //LogLog.debug("NDC converter.");
- currentLiteral.setLength(0);
- break;*/
- case 'X':
- String xOpt = extractOption();
- pc = new MDCPatternConverter(formattingInfo, xOpt);
- currentLiteral.setLength(0);
- break;
- default:
- //LogLog.error("Unexpected char [" +c+"] at position "+i+" in conversion patterrn.");
- pc = new LiteralPatternConverter(currentLiteral.toString());
- currentLiteral.setLength(0);
- }
-
- addConverter(pc);
- }
-
- protected
- void addConverter(PatternConverter pc) {
- currentLiteral.setLength(0);
- // Add the pattern converter to the list.
- addToList(pc);
- // Next pattern is assumed to be a literal.
- state = LITERAL_STATE;
- // Reset formatting info
- formattingInfo.reset();
- }
-
- // ---------------------------------------------------------------------
- // PatternConverters
- // ---------------------------------------------------------------------
-
- private static class BasicPatternConverter extends PatternConverter {
- int type;
-
- BasicPatternConverter(FormattingInfo formattingInfo, int type) {
- super(formattingInfo);
- this.type = type;
- }
-
- public
- String convert(PaxLoggingEvent event) {
- switch(type) {
- case RELATIVE_TIME_CONVERTER:
- return (Long.toString(event.getTimeStamp() - LoggingEvent.getStartTime()));
- case THREAD_CONVERTER:
- return event.getThreadName();
- case LEVEL_CONVERTER:
- return event.getLevel().toString();
- // case NDC_CONVERTER:
- //return event.getNDC();
- case MESSAGE_CONVERTER: {
- return event.getRenderedMessage();
- }
- default: return null;
- }
- }
- }
-
- private static class LiteralPatternConverter extends PatternConverter {
- private String literal;
-
- LiteralPatternConverter(String value) {
- literal = value;
- }
-
- public
- final
- void format(StringBuffer sbuf, LoggingEvent event) {
- sbuf.append(literal);
- }
-
- public
- String convert(PaxLoggingEvent event) {
- return literal;
- }
- }
-
- private static class DatePatternConverter extends PatternConverter {
- private DateFormat df;
- private Date date;
-
- DatePatternConverter(FormattingInfo formattingInfo, DateFormat df) {
- super(formattingInfo);
- date = new Date();
- this.df = df;
- }
-
- public
- String convert(PaxLoggingEvent event) {
- date.setTime(event.getTimeStamp());
- String converted = null;
- try {
- converted = df.format(date);
- }
- catch (Exception ex) {
- //LogLog.error("Error occured while converting date.", ex);
- }
- return converted;
- }
- }
-
- private class LocationPatternConverter extends PatternConverter {
- int type;
-
- LocationPatternConverter(FormattingInfo formattingInfo, int type) {
- super(formattingInfo);
- this.type = type;
- }
-
- public
- String convert(PaxLoggingEvent event) {
- PaxLocationInfo locationInfo = event.getLocationInformation();
- switch(type) {
- /*case FULL_LOCATION_CONVERTER:
- return locationInfo.fullInfo;*/
- case METHOD_LOCATION_CONVERTER:
- return locationInfo.getMethodName();
- case LINE_LOCATION_CONVERTER:
- return locationInfo.getLineNumber();
- case FILE_LOCATION_CONVERTER:
- return locationInfo.getFileName();
- default: return null;
- }
- }
- }
-
- private static abstract class NamedPatternConverter extends PatternConverter {
- int precision;
-
- NamedPatternConverter(FormattingInfo formattingInfo, int precision) {
- super(formattingInfo);
- this.precision = precision;
- }
-
- abstract
- String getFullyQualifiedName(PaxLoggingEvent event);
-
- public
- String convert(PaxLoggingEvent event) {
- String n = getFullyQualifiedName(event);
- if(precision <= 0)
- return n;
- else {
- int len = n.length();
-
- // We substract 1 from 'len' when assigning to 'end' to avoid out of
- // bounds exception in return r.substring(end+1, len). This can happen if
- // precision is 1 and the category name ends with a dot.
- int end = len -1 ;
- for(int i = precision; i > 0; i--) {
- end = n.lastIndexOf('.', end-1);
- if(end == -1)
- return n;
- }
- return n.substring(end+1, len);
- }
- }
- }
-
- private class ClassNamePatternConverter extends NamedPatternConverter {
-
- ClassNamePatternConverter(FormattingInfo formattingInfo, int precision) {
- super(formattingInfo, precision);
- }
-
- String getFullyQualifiedName(PaxLoggingEvent event) {
- return event.getLocationInformation().getClassName();
- }
- }
-
- private class CategoryPatternConverter extends NamedPatternConverter {
-
- CategoryPatternConverter(FormattingInfo formattingInfo, int precision) {
- super(formattingInfo, precision);
- }
-
- String getFullyQualifiedName(PaxLoggingEvent event) {
- return event.getLoggerName();
- }
- }
-
- private class MDCPatternConverter extends PatternConverter {
- String key;
-
- MDCPatternConverter(FormattingInfo formattingInfo, String key) {
- super(formattingInfo);
- this.key = key;
- }
-
- public
- String convert(PaxLoggingEvent event) {
- if (key == null) {
- StringBuffer buf = new StringBuffer("{");
- Map properties = event.getProperties();
- if (properties.size() > 0) {
- Object[] keys = properties.keySet().toArray();
- Arrays.sort(keys);
- for (int i = 0; i < keys.length; i++) {
- buf.append('{');
- buf.append(keys[i]);
- buf.append(',');
- buf.append(properties.get(keys[i]));
- buf.append('}');
- }
- }
- buf.append('}');
- return buf.toString();
- } else {
- Object val = event.getProperties().get(key);
- if(val == null) {
- return null;
- } else {
- return val.toString();
- }
- }
- }
-
- }
-}
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
deleted file mode 100644
index 2e8c4d8..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.log.core.internal.osgi;
-
-import java.util.Hashtable;
-
-import org.apache.karaf.log.core.LogEventFormatter;
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.log.core.internal.LogEventFormatterImpl;
-import org.apache.karaf.log.core.internal.LogMBeanImpl;
-import org.apache.karaf.log.core.internal.LogServiceImpl;
-import org.apache.karaf.log.core.internal.LruList;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.ops4j.pax.logging.spi.PaxAppender;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ManagedService;
-
-public class Activator extends BaseActivator implements ManagedService {
-
- @Override
- protected void doOpen() throws Exception {
- manage("org.apache.karaf.log");
- trackService(ConfigurationAdmin.class);
- }
-
- protected void doStart() throws Exception {
- ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
- if (configurationAdmin == null) {
- return;
- }
-
- int size = getInt("size", 500);
- String pattern = getString("pattern", "%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n");
- String fatalColor = getString("fatalColor", "31");
- String errorColor = getString("errorColor", "31");
- String warnColor = getString("warnColor", "35");
- String infoColor = getString("infoColor", "36");
- String debugColor = getString("debugColor", "39");
- String traceColor = getString("traceColor", "39");
-
- LruList events = new LruList(size);
- Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put("org.ops4j.pax.logging.appender.name", "VmLogAppender");
- register(PaxAppender.class, events, props);
-
- LogEventFormatterImpl formatter = new LogEventFormatterImpl();
- formatter.setPattern(pattern);
- formatter.setFatalColor(fatalColor);
- formatter.setErrorColor(errorColor);
- formatter.setWarnColor(warnColor);
- formatter.setInfoColor(infoColor);
- formatter.setDebugColor(debugColor);
- formatter.setTraceColor(traceColor);
- register(LogEventFormatter.class, formatter);
-
- LogServiceImpl logService = new LogServiceImpl(configurationAdmin, events);
- register(LogService.class, logService);
-
- LogMBeanImpl securityMBean = new LogMBeanImpl(logService);
- registerMBean(securityMBean, "type=log");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/log/core/src/main/resources/OSGI-INF/bundle.info b/log/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 2bd45bd..0000000
--- a/log/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,24 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-The log mbean management bundle exposes a Log MBean that can be used with any JMX client (for instance JConsole).
-
-The Log MBean allows quite the same actions that can be performed using log:* commands:
- * display()
- * display(logger)
- * get()
- * get(logger)
- * set(level)
- * list(level, logger)
-
-h1. See also
-
- * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
----------------------------------------------------------------------
diff --git a/log/core/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java b/log/core/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
deleted file mode 100644
index 73459d3..0000000
--- a/log/core/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.log.core.internal;
-
-import java.util.Hashtable;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.log.core.LogMBean;
-import org.apache.karaf.log.core.LogService;
-import org.easymock.EasyMock;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-/**
- * Test cases for {@link SetLogLevel}
- */
-@SuppressWarnings("unchecked")
-public class SetLogLevelTest extends TestCase {
-
- private static final String ROOT_LOGGER = "log4j.rootLogger";
- private static final String PACKAGE_LOGGER = "log4j.logger.org.apache.karaf.test";
-
- private LogService logService;
- private LogMBean logMBean;
- @SuppressWarnings("rawtypes")
- private Hashtable properties;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- properties = new Hashtable<String, String>();
- final Configuration configuration = EasyMock.createMock(Configuration.class);
- EasyMock.expect(configuration.getProperties()).andReturn(properties);
- configuration.update(properties);
- ConfigurationAdmin configAdmin = EasyMock.createMock(ConfigurationAdmin.class);
- EasyMock.expect(configAdmin.getConfiguration(LogServiceImpl.CONFIGURATION_PID, null)).andReturn(configuration);
- logService = new LogServiceImpl(configAdmin, new LruList(100));
- logMBean = new LogMBeanImpl(logService);
- EasyMock.replay(configAdmin);
- EasyMock.replay(configuration);
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testInvalidLogLevel() throws Exception {
- try {
- logMBean.setLevel("INVALID");
- fail("Exception expected");
- } catch(IllegalArgumentException e) {
- // Expected
- }
- }
-
- public void testSetLogLevel() throws Exception {
- logMBean.setLevel("org.apache.karaf.test", "INFO");
- assertEquals("INFO", properties.get(PACKAGE_LOGGER));
- }
-
- public void testSetRootLogLevel() throws Exception {
- logMBean.setLevel("INFO");
- assertEquals("INFO", properties.get(ROOT_LOGGER));
- }
-
- public void testSetLogLevelLowerCase() throws Exception {
- logMBean.setLevel("org.apache.karaf.test", "info");
- assertEquals("INFO", properties.get(PACKAGE_LOGGER));
- }
-
- public void testSetRootLogLevelLowerCase() throws Exception {
- logMBean.setLevel("info");
- assertEquals("INFO", properties.get(ROOT_LOGGER));
- }
-
- public void testChangeLogLevel() throws Exception {
- properties.put(PACKAGE_LOGGER, "DEBUG");
- logMBean.setLevel("org.apache.karaf.test", "INFO");
- assertEquals("INFO", properties.get(PACKAGE_LOGGER));
- }
-
- public void testChangeRootLogLevel() throws Exception {
- properties.put(ROOT_LOGGER, "DEBUG");
- logMBean.setLevel("INFO");
- assertEquals("INFO", properties.get(ROOT_LOGGER));
- }
-
- public void testChangeLogLevelWithAppender() throws Exception {
- properties.put(PACKAGE_LOGGER, "DEBUG, APPENDER1");
- logMBean.setLevel("org.apache.karaf.test", "INFO");
- assertEquals("INFO, APPENDER1", properties.get(PACKAGE_LOGGER));
- }
-
- public void testChangeRootLogLevelWithAppender() throws Exception {
- properties.put(ROOT_LOGGER, "DEBUG, APPENDER1");
- logMBean.setLevel("INFO");
- assertEquals("INFO, APPENDER1", properties.get(ROOT_LOGGER));
- }
-
- public void testUnsetLogLevel() throws Exception {
- properties.put(PACKAGE_LOGGER, "DEBUG");
- logMBean.setLevel("org.apache.karaf.test", "DEFAULT");
- assertFalse("Configuration for logger org.apache.karaf.test has been removed", properties.containsKey(PACKAGE_LOGGER));
- }
-
- public void testUnsetRootLogLevel() throws Exception {
- properties.put(ROOT_LOGGER, "INFO");
- logMBean.setLevel("org.apache.karaf.test", "DEFAULT");
- assertEquals("Configuration for root logger should not be removed", "INFO", properties.get(ROOT_LOGGER));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/pom.xml
----------------------------------------------------------------------
diff --git a/log/pom.xml b/log/pom.xml
index 9106544..5dec97a 100644
--- a/log/pom.xml
+++ b/log/pom.xml
@@ -29,13 +29,94 @@
</parent>
<groupId>org.apache.karaf.log</groupId>
- <artifactId>log</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Log</name>
+ <artifactId>org.apache.karaf.log.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Log :: Core</name>
+ <description>Core Seervices and JMX MBean to manipulate the Karaf log layer</description>
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../../etc/appended-resources/</appendedResourcesDirectory>
+ </properties>
-</project>
\ No newline at end of file
+ <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.ops4j.pax.logging</groupId>
+ <artifactId>pax-logging-service</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.logging</groupId>
+ <artifactId>pax-logging-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>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>
+ <Export-Package>
+ org.apache.karaf.log.core
+ </Export-Package>
+ <Import-Package>
+ *
+ </Import-Package>
+ <Private-Package>
+ org.apache.karaf.log.command,
+ org.apache.karaf.log.core.internal,
+ org.apache.karaf.log.core.internal.layout,
+ org.apache.karaf.log.core.internal.osgi,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.log.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>
+ org.apache.karaf.log.command*
+ </Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/ClearLog.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/ClearLog.java b/log/src/main/java/org/apache/karaf/log/command/ClearLog.java
new file mode 100644
index 0000000..75a48d6
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/ClearLog.java
@@ -0,0 +1,41 @@
+/*
+ * 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.log.command;
+
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * Clear the last log entries.
+ */
+@Command(scope = "log", name = "clear", description = "Clear log entries.")
+@Service
+public class ClearLog implements Action {
+
+ @Reference
+ LogService logService;
+
+ @Override
+ public Object execute() throws Exception {
+ logService.clearEvents();
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/DisplayException.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/DisplayException.java b/log/src/main/java/org/apache/karaf/log/command/DisplayException.java
new file mode 100644
index 0000000..52a2661
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/DisplayException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.log.command;
+
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+@Command(scope = "log", name = "exception-display", description = "Displays the last occurred exception from the log.")
+@Service
+public class DisplayException implements Action {
+
+ @Argument(index = 0, name = "logger", description = "The name of the logger. This can be ROOT, ALL, or the name of a logger specified in the org.ops4j.pax.logger.cfg file.", required = false, multiValued = false)
+ String logger;
+
+ @Reference
+ LogService logService;
+
+ @Override
+ public Object execute() throws Exception {
+ PaxLoggingEvent throwableEvent = logService.getLastException(logger);
+ if (throwableEvent != null) {
+ for (String r : throwableEvent.getThrowableStrRep()) {
+ System.out.println(r);
+ }
+ System.out.println();
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/DisplayLog.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/DisplayLog.java b/log/src/main/java/org/apache/karaf/log/command/DisplayLog.java
new file mode 100644
index 0000000..813eea5
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/DisplayLog.java
@@ -0,0 +1,83 @@
+/*
+ * 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.log.command;
+
+import java.io.PrintStream;
+
+import org.apache.karaf.log.core.LogEventFormatter;
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+/**
+ * Displays the last log entries
+ */
+@Command(scope = "log", name = "display", description = "Displays log entries.")
+@Service
+public class DisplayLog implements Action {
+
+ @Option(name = "-n", aliases = {}, description="Number of entries to display", required = false, multiValued = false)
+ int entries;
+
+ @Option(name = "-p", aliases = {}, description="Pattern for formatting the output", required = false, multiValued = false)
+ String overridenPattern;
+
+ @Option(name = "--no-color", description="Disable syntax coloring of log events", required = false, multiValued = false)
+ boolean noColor;
+
+ @Argument(index = 0, name = "logger", description = "The name of the logger. This can be ROOT, ALL, or the name of a logger specified in the org.ops4j.pax.logger.cfg file.", required = false, multiValued = false)
+ String logger;
+
+ @Reference
+ LogService logService;
+
+ @Reference
+ LogEventFormatter formatter;
+
+ @Override
+ public Object execute() throws Exception {
+
+ final PrintStream out = System.out;
+
+ Iterable<PaxLoggingEvent> le = logService.getEvents(entries == 0 ? Integer.MAX_VALUE : entries);
+ for (PaxLoggingEvent event : le) {
+ printEvent(out, event);
+ }
+ out.println();
+ return null;
+ }
+
+ protected boolean checkIfFromRequestedLog(PaxLoggingEvent event) {
+ return (event.getLoggerName().lastIndexOf(logger)>=0) ? true : false;
+ }
+
+ protected void printEvent(final PrintStream out, PaxLoggingEvent event) {
+ if ((logger != null) &&
+ (event != null)&&
+ (checkIfFromRequestedLog(event))) {
+ out.append(formatter.format(event, overridenPattern, noColor));
+ }
+ else if ((event != null)&&(logger == null)){
+ out.append(formatter.format(event, overridenPattern, noColor));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/GetLogLevel.java b/log/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
new file mode 100644
index 0000000..83e5003
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
@@ -0,0 +1,63 @@
+/*
+ * 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.log.command;
+
+import java.util.Map;
+
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+/**
+ * Get the log level
+ */
+@Command(scope = "log", name = "get", description = "Shows the currently set log level.")
+@Service
+public class GetLogLevel implements Action {
+
+ @Argument(index = 0, name = "logger", description = "The name of the logger, ALL or ROOT (default)", required = false, multiValued = false)
+ String logger;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ LogService logService;
+
+ @Override
+ public Object execute() throws Exception {
+ Map<String, String> loggers = logService.getLevel(logger);
+
+ ShellTable table = new ShellTable();
+ table.column("Logger");
+ table.column("Level");
+
+ for (String logger : loggers.keySet()) {
+ table.addRow().addContent(logger, loggers.get(logger));
+ }
+
+ table.print(System.out, !noFormat);
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/LogEntry.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/LogEntry.java b/log/src/main/java/org/apache/karaf/log/command/LogEntry.java
new file mode 100644
index 0000000..d7c17a9
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/LogEntry.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.log.command;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.service.log.LogService;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Command(scope = "log", name = "log", description = "Log a message.")
+@Service
+public class LogEntry implements Action {
+
+ @Argument(index = 0, name = "message", description = "The message to log", required = true, multiValued = false)
+ private String message;
+
+ @Option(name = "--level", aliases = {"-l"}, description = "The level the message will be logged at", required = false, multiValued = false)
+ @Completion(value = StringsCompleter.class, values = { "DEBUG", "INFO", "WARNING", "ERROR" })
+ private String level = "INFO";
+
+ @Reference
+ LogService logService;
+
+ private final Map<String,Integer> mappings = new HashMap<String,Integer>();
+
+ public LogEntry() {
+ mappings.put("ERROR", 1);
+ mappings.put("WARNING", 2);
+ mappings.put("INFO", 3);
+ mappings.put("DEBUG", 4);
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ logService.log(toLevel(level.toUpperCase()), message);
+ return null;
+ }
+
+ private int toLevel(String logLevel) {
+ Integer level = mappings.get(logLevel);
+ if(level == null) {
+ level = 3;
+ }
+ return level;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/LogTail.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/LogTail.java b/log/src/main/java/org/apache/karaf/log/command/LogTail.java
new file mode 100644
index 0000000..bf2801e
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/LogTail.java
@@ -0,0 +1,129 @@
+/*
+ * 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.log.command;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
+import org.ops4j.pax.logging.spi.PaxAppender;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+@Command(scope = "log", name = "tail", description = "Continuously display log entries. Use ctrl-c to quit this command")
+@Service
+public class LogTail extends DisplayLog {
+
+ @Reference
+ Session session;
+
+ @Reference
+ LogService logService;
+
+ private ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+ @Override
+ public Object execute() throws Exception {
+ PrintEventThread printThread = new PrintEventThread();
+ executorService.execute(printThread);
+ new Thread(new ReadKeyBoardThread(this, Thread.currentThread())).start();
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ Thread.sleep(200);
+ } catch (java.lang.InterruptedException e) {
+ break;
+ }
+ }
+ printThread.abort();
+ executorService.shutdownNow();
+ return null;
+ }
+
+ class ReadKeyBoardThread implements Runnable {
+ private LogTail logTail;
+ private Thread sessionThread;
+ public ReadKeyBoardThread(LogTail logtail, Thread thread) {
+ this.logTail = logtail;
+ this.sessionThread = thread;
+ }
+ public void run() {
+ for (;;) {
+ try {
+ int c = this.logTail.session.getKeyboard().read();
+ if (c < 0) {
+ this.sessionThread.interrupt();
+ break;
+ }
+ } catch (IOException e) {
+ break;
+ }
+
+ }
+ }
+ }
+
+ class PrintEventThread implements Runnable {
+
+ PrintStream out = System.out;
+ boolean doDisplay = true;
+
+ public void run() {
+ Iterable<PaxLoggingEvent> le = logService.getEvents(entries == 0 ? Integer.MAX_VALUE : entries);
+ for (PaxLoggingEvent event : le) {
+ if (event != null) {
+ printEvent(out, event);
+ }
+ }
+ // Tail
+ final BlockingQueue<PaxLoggingEvent> queue = new LinkedBlockingQueue<PaxLoggingEvent>();
+ PaxAppender appender = new PaxAppender() {
+ public void doAppend(PaxLoggingEvent event) {
+ queue.add(event);
+ }
+ };
+ try {
+ logService.addAppender(appender);
+
+ while (doDisplay) {
+ PaxLoggingEvent event = queue.take();
+ if (event != null) {
+ printEvent(out, event);
+ }
+ }
+ } catch (InterruptedException e) {
+ // Ignore
+ } finally {
+ logService.removeAppender(appender);
+ }
+ out.println();
+
+ }
+
+ public void abort() {
+ doDisplay = false;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/command/SetLogLevel.java b/log/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
new file mode 100644
index 0000000..b1145b4
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
@@ -0,0 +1,52 @@
+/*
+ * 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.log.command;
+
+
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+/**
+ * Set the log level for a given logger
+ */
+@Command(scope = "log", name = "set", description = "Sets the log level.")
+@Service
+public class SetLogLevel implements Action {
+
+ @Argument(index = 0, name = "level", description = "The log level to set (TRACE, DEBUG, INFO, WARN, ERROR) or DEFAULT to unset", required = true, multiValued = false)
+ @Completion(value = StringsCompleter.class, values = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "DEFAULT" })
+ String level;
+
+ @Argument(index = 1, name = "logger", description = "Logger name or ROOT (default)", required = false, multiValued = false)
+ String logger;
+
+ @Reference
+ LogService logService;
+
+ @Override
+ public Object execute() throws Exception {
+ logService.setLevel(logger, level);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/Level.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/Level.java b/log/src/main/java/org/apache/karaf/log/core/Level.java
new file mode 100644
index 0000000..a83396f
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/Level.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.log.core;
+
+/**
+ * Enumeration of available log levels for the log:set command and
+ * the command completer
+ */
+public enum Level {
+
+ TRACE,
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ DEFAULT;
+
+ /**
+ * Convert the list of values into a String array
+ *
+ * @return all the values as a String array
+ */
+ public static String[] strings() {
+ String[] values = new String[values().length];
+ for (int i = 0 ; i < values.length ; i++) {
+ values[i] = values()[i].name();
+ }
+ return values;
+ }
+
+ /**
+ * Check if the string value represents the default level
+ *
+ * @param level the level value
+ * @return <code>true</code> if the value represents the {@link #DEFAULT} level
+ */
+ public static boolean isDefault(String level) {
+ return valueOf(level).equals(DEFAULT);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java b/log/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
new file mode 100644
index 0000000..71fe275
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
@@ -0,0 +1,25 @@
+/*
+ * 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.log.core;
+
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+public interface LogEventFormatter {
+
+ public abstract String format(PaxLoggingEvent event, String overridenPattern, boolean noColor);
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/LogMBean.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/LogMBean.java b/log/src/main/java/org/apache/karaf/log/core/LogMBean.java
new file mode 100644
index 0000000..ad5006f
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/LogMBean.java
@@ -0,0 +1,32 @@
+/*
+ * 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.log.core;
+
+import java.util.Map;
+
+/**
+ * Log MBean.
+ */
+public interface LogMBean {
+
+ String getLevel();
+ Map<String, String> getLevel(String logger);
+
+ void setLevel(String level);
+ void setLevel(String logger, String level);
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/LogService.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/LogService.java b/log/src/main/java/org/apache/karaf/log/core/LogService.java
new file mode 100644
index 0000000..ae9f678
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/LogService.java
@@ -0,0 +1,38 @@
+/*
+ * 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.log.core;
+
+import org.ops4j.pax.logging.spi.PaxAppender;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+import java.util.Map;
+
+public interface LogService {
+
+ String getLevel();
+ void setLevel(String level);
+
+ Map<String, String> getLevel(String logger);
+ void setLevel(String logger, String level);
+
+ void clearEvents();
+ Iterable<PaxLoggingEvent> getEvents();
+ Iterable<PaxLoggingEvent> getEvents(int maxNum);
+ PaxLoggingEvent getLastException(String logger);
+ void addAppender(PaxAppender appender);
+ void removeAppender(PaxAppender appender);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
new file mode 100644
index 0000000..0ba1f3e
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
@@ -0,0 +1,157 @@
+/*
+ * 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.log.core.internal;
+
+import org.apache.karaf.log.core.LogEventFormatter;
+import org.apache.karaf.log.core.internal.layout.PatternConverter;
+import org.apache.karaf.log.core.internal.layout.PatternParser;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+public class LogEventFormatterImpl implements LogEventFormatter {
+
+ protected String pattern;
+ protected String fatalColor;
+ protected String errorColor;
+ protected String warnColor;
+ protected String infoColor;
+ protected String debugColor;
+ protected String traceColor;
+
+ private static final String FATAL = "fatal";
+ private static final String ERROR = "error";
+ private static final String WARN = "warn";
+ private static final String INFO = "info";
+ private static final String DEBUG = "debug";
+ private static final String TRACE = "trace";
+
+ private static final char FIRST_ESC_CHAR = 27;
+ private static final char SECOND_ESC_CHAR = '[';
+ private static final char COMMAND_CHAR = 'm';
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ public String getFatalColor() {
+ return fatalColor;
+ }
+
+ public void setFatalColor(String fatalColor) {
+ this.fatalColor = fatalColor;
+ }
+
+ public String getErrorColor() {
+ return errorColor;
+ }
+
+ public void setErrorColor(String errorColor) {
+ this.errorColor = errorColor;
+ }
+
+ public String getWarnColor() {
+ return warnColor;
+ }
+
+ public void setWarnColor(String warnColor) {
+ this.warnColor = warnColor;
+ }
+
+ public String getInfoColor() {
+ return infoColor;
+ }
+
+ public void setInfoColor(String infoColor) {
+ this.infoColor = infoColor;
+ }
+
+ public String getDebugColor() {
+ return debugColor;
+ }
+
+ public void setDebugColor(String debugColor) {
+ this.debugColor = debugColor;
+ }
+
+ public String getTraceColor() {
+ return traceColor;
+ }
+
+ public void setTraceColor(String traceColor) {
+ this.traceColor = traceColor;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.karaf.log.core.internal.LogEventFormatter#format(org.ops4j.pax.logging.spi.PaxLoggingEvent, java.lang.String, boolean)
+ */
+ @Override
+ public String format(PaxLoggingEvent event, String overridenPattern, boolean noColor) {
+ final PatternConverter cnv = new PatternParser(overridenPattern != null ? overridenPattern : pattern).parse();
+ String color = getColor(event, noColor);
+ StringBuffer sb = new StringBuffer();
+ sb.setLength(0);
+ if (color != null) {
+ sb.append(FIRST_ESC_CHAR);
+ sb.append(SECOND_ESC_CHAR);
+ sb.append(color);
+ sb.append(COMMAND_CHAR);
+ }
+ for (PatternConverter pc = cnv; pc != null; pc = pc.next) {
+ pc.format(sb, event);
+ }
+ if (event.getThrowableStrRep() != null) {
+ for (String r : event.getThrowableStrRep()) {
+ sb.append(r).append('\n');
+ }
+ }
+ if (color != null) {
+ sb.append(FIRST_ESC_CHAR);
+ sb.append(SECOND_ESC_CHAR);
+ sb.append("0");
+ sb.append(COMMAND_CHAR);
+ }
+ return sb.toString();
+ }
+
+ private String getColor(PaxLoggingEvent event, boolean noColor) {
+ String color = null;
+ if (!noColor && event != null && event.getLevel() != null && event.getLevel().toString() != null) {
+ String lvl = event.getLevel().toString().toLowerCase();
+ if (FATAL.equals(lvl)) {
+ color = fatalColor;
+ } else if (ERROR.equals(lvl)) {
+ color = errorColor;
+ } else if (WARN.equals(lvl)) {
+ color = warnColor;
+ } else if (INFO.equals(lvl)) {
+ color = infoColor;
+ } else if (DEBUG.equals(lvl)) {
+ color = debugColor;
+ } else if (TRACE.equals(lvl)) {
+ color = traceColor;
+ }
+ if (color != null && color.length() == 0) {
+ color = null;
+ }
+ }
+ return color;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java
new file mode 100644
index 0000000..49ccbf6
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.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.log.core.internal;
+
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+
+import org.apache.karaf.log.core.LogMBean;
+import org.apache.karaf.log.core.LogService;
+
+import java.util.Map;
+
+/**
+ * Implementation of the LogMBean.
+ */
+public class LogMBeanImpl extends StandardMBean implements LogMBean {
+
+ private final LogService logService;
+
+ public LogMBeanImpl(LogService logService) throws NotCompliantMBeanException {
+ super(LogMBean.class);
+ this.logService = logService;
+ }
+
+ @Override
+ public String getLevel() {
+ return logService.getLevel();
+ }
+
+ @Override
+ public Map<String, String> getLevel(String logger) {
+ return logService.getLevel(logger);
+ }
+
+ @Override
+ public void setLevel(String level) {
+ this.logService.setLevel(level);
+ }
+
+ @Override
+ public void setLevel(String logger, String level) {
+ this.logService.setLevel(logger, level);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
new file mode 100644
index 0000000..4751873
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
@@ -0,0 +1,261 @@
+/*
+ * 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.log.core.internal;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.karaf.log.core.Level;
+import org.apache.karaf.log.core.LogService;
+import org.ops4j.pax.logging.spi.PaxAppender;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class LogServiceImpl implements LogService {
+
+ static final String CONFIGURATION_PID = "org.ops4j.pax.logging";
+ static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger";
+ static final String LOGGER_PREFIX = "log4j.logger.";
+ static final String ALL_LOGGER = "ALL";
+ static final String ROOT_LOGGER = "ROOT";
+
+ private final ConfigurationAdmin configAdmin;
+ private final LruList events;
+
+ public LogServiceImpl(ConfigurationAdmin configAdmin, LruList events) {
+ this.configAdmin = configAdmin;
+ this.events = events;
+ }
+
+ public String getLevel() {
+ return getLevel(null).get(ROOT_LOGGER);
+ }
+
+ public Map<String, String> getLevel(String logger) {
+ Configuration cfg;
+ try {
+ cfg = configAdmin.getConfiguration(CONFIGURATION_PID, null);
+ } catch (IOException e) {
+ throw new RuntimeException("Error retrieving Log information from config admin", e);
+ }
+ @SuppressWarnings("rawtypes")
+ Dictionary props = cfg.getProperties();
+
+ if (ROOT_LOGGER.equalsIgnoreCase(logger)) {
+ logger = null;
+ }
+
+ Map<String, String> loggers = new TreeMap<String, String>();
+
+ if (ALL_LOGGER.equalsIgnoreCase(logger)) {
+ String root = getLevelFromProperty((String) props.get(ROOT_LOGGER_PREFIX));
+ loggers.put("ROOT", root);
+ for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
+ String prop = (String) e.nextElement();
+ if (prop.startsWith(LOGGER_PREFIX)) {
+ String val = getLevelFromProperty((String) props.get(prop));
+ loggers.put(prop.substring(LOGGER_PREFIX.length()), val);
+ }
+ }
+ return loggers;
+ }
+
+ String l = logger;
+ String val;
+ for (;;) {
+ String prop;
+ if (l == null) {
+ prop = ROOT_LOGGER_PREFIX;
+ } else {
+ prop = LOGGER_PREFIX + l;
+ }
+ val = (String) props.get(prop);
+ val = getLevelFromProperty(val);
+ if (val != null || l == null) {
+ break;
+ }
+ int idx = l.lastIndexOf('.');
+ if (idx < 0) {
+ l = null;
+ } else {
+ l = l.substring(0, idx);
+ }
+ }
+
+ if (logger == null)
+ logger = ROOT_LOGGER;
+
+ loggers.put(logger, val);
+
+ return loggers;
+ }
+
+ public void setLevel(String level) {
+ setLevel(null, level);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setLevel(String logger, String level) {
+ if (ROOT_LOGGER.equalsIgnoreCase(logger)) {
+ logger = null;
+ }
+
+ // make sure both uppercase and lowercase levels are supported
+ level = level.toUpperCase();
+
+ // check if the level is valid
+ Level.valueOf(level);
+
+ if (Level.isDefault(level) && logger == null) {
+ throw new IllegalStateException("Can not unset the ROOT logger");
+ }
+
+ Configuration cfg = getConfiguration();
+ Dictionary props = cfg.getProperties();
+
+ String val;
+ String prop;
+ if (logger == null) {
+ prop = ROOT_LOGGER_PREFIX;
+ } else {
+ prop = LOGGER_PREFIX + logger;
+ }
+
+ val = (String) props.get(prop);
+ if (Level.isDefault(level)) {
+ if (val != null) {
+ val = val.trim();
+ int idx = val.indexOf(",");
+ if (idx < 0) {
+ val = null;
+ } else {
+ val = val.substring(idx);
+ }
+ }
+ } else {
+ if (val == null) {
+ val = level;
+ } else {
+ val = val.trim();
+ int idx = val.indexOf(",");
+ if (idx < 0) {
+ val = level;
+ } else {
+ val = level + val.substring(idx);
+ }
+ }
+ }
+ if (val == null) {
+ props.remove(prop);
+ } else {
+ props.put(prop, val);
+ }
+ try {
+ cfg.update(props);
+ } catch (IOException e) {
+ throw new RuntimeException("Error writing log config to config admin", e);
+ }
+ }
+
+ private boolean checkIfFromRequestedLog(PaxLoggingEvent event, String logger) {
+ return (event.getLoggerName().lastIndexOf(logger) >= 0) ? true : false;
+ }
+
+ private String getLevelFromProperty(String prop) {
+ if (prop == null) {
+ return null;
+ } else {
+ String val = prop.trim();
+ int idx = val.indexOf(",");
+ if (idx == 0) {
+ val = null;
+ } else if (idx > 0) {
+ val = val.substring(0, idx);
+ }
+ return val;
+ }
+ }
+
+ private Configuration getConfiguration() {
+ try {
+ return configAdmin.getConfiguration(CONFIGURATION_PID, null);
+ } catch (IOException e) {
+ throw new RuntimeException("Error retrieving Log information from config admin", e);
+ }
+ }
+
+ @Override
+ public Iterable<PaxLoggingEvent> getEvents() {
+ return events.getElements();
+ }
+
+ @Override
+ public Iterable<PaxLoggingEvent> getEvents(int maxNum) {
+ return events.getElements(maxNum);
+ }
+
+ @Override
+ public void clearEvents() {
+ events.clear();
+ }
+
+ @Override
+ public PaxLoggingEvent getLastException(String logger) {
+ PaxLoggingEvent throwableEvent = null;
+ Iterable<PaxLoggingEvent> le = getEvents();
+ for (PaxLoggingEvent event : le) {
+ // if this is an exception, and the log is the same as the requested log,
+ // then save this exception and continue iterating from oldest to newest
+ if ((event.getThrowableStrRep() != null)
+ &&(logger != null)
+ &&(checkIfFromRequestedLog(event, logger))) {
+ throwableEvent = event;
+ // Do not break, as we iterate from the oldest to the newest event
+ } else if ((event.getThrowableStrRep() != null)&&(logger == null)) {
+ // now check if there has been no log passed in, and if this is an exception
+ // then save this exception and continue iterating from oldest to newest
+ throwableEvent = event;
+ }
+ }
+
+ return throwableEvent;
+ }
+
+ @Override
+ public void addAppender(PaxAppender appender) {
+ events.addAppender(appender);
+ }
+
+ @Override
+ public void removeAppender(PaxAppender appender) {
+ events.removeAppender(appender);
+ }
+
+ public Level convertToLevel(String level) {
+ level = level.toUpperCase();
+ Level res = Level.valueOf(level);
+ if (res == null) {
+ throw new IllegalArgumentException("level must be set to TRACE, DEBUG, INFO, WARN or ERROR (or DEFAULT to unset it)");
+ }
+ return res;
+ }
+
+}
[11/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Overrides.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
deleted file mode 100644
index 233a8a2..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.utils.version.VersionRange;
-import org.osgi.framework.Version;
-import org.osgi.resource.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.felix.resolver.Util.getSymbolicName;
-import static org.apache.felix.resolver.Util.getVersion;
-
-/**
- * Helper class to deal with overriden bundles at feature installation time.
- */
-public class Overrides {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(Overrides.class);
-
- protected static final String OVERRIDE_RANGE = "range";
-
- /**
- * Compute a list of bundles to install, taking into account overrides.
- *
- * The file containing the overrides will be loaded from the given url.
- * Blank lines and lines starting with a '#' will be ignored, all other lines
- * are considered as urls to override bundles.
- *
- * The list of resources to resolve will be scanned and for each bundle,
- * if a bundle override matches that resource, it will be used instead.
- *
- * Matching is done on bundle symbolic name (they have to be the same)
- * and version (the bundle override version needs to be greater than the
- * resource to be resolved, and less than the next minor version. A range
- * directive can be added to the override url in which case, the matching
- * will succeed if the resource to be resolved is within the given range.
- *
- * @param resources the list of resources to resolve
- * @param overrides list of bundle overrides
- */
- public static void override(Map<String, Resource> resources, Collection<String> overrides) {
- // Do override replacement
- for (Clause override : Parser.parseClauses(overrides.toArray(new String[overrides.size()]))) {
- String url = override.getName();
- String vr = override.getAttribute(OVERRIDE_RANGE);
- Resource over = resources.get(url);
- if (over == null) {
- // Ignore invalid overrides
- continue;
- }
- for (String uri : new ArrayList<String>(resources.keySet())) {
- Resource res = resources.get(uri);
- if (getSymbolicName(res).equals(getSymbolicName(over))) {
- VersionRange range;
- if (vr == null) {
- // default to micro version compatibility
- Version v1 = getVersion(res);
- Version v2 = new Version(v1.getMajor(), v1.getMinor() + 1, 0);
- range = new VersionRange(false, v1, v2, true);
- } else {
- range = VersionRange.parseVersionRange(vr);
- }
- // The resource matches, so replace it with the overridden resource
- // if the override is actually a newer version than what we currently have
- if (range.contains(getVersion(over)) && getVersion(res).compareTo(getVersion(over)) < 0) {
- resources.put(uri, over);
- }
- }
- }
- }
- }
-
- public static Set<String> loadOverrides(String overridesUrl) {
- Set<String> overrides = new HashSet<String>();
- try {
- if (overridesUrl != null) {
- InputStream is = new URL(overridesUrl).openStream();
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- String line;
- while ((line = reader.readLine()) != null) {
- line = line.trim();
- if (!line.isEmpty() && !line.startsWith("#")) {
- overrides.add(line);
- }
- }
- } finally {
- is.close();
- }
- }
- } catch (Exception e) {
- LOGGER.debug("Unable to load overrides bundles list", e);
- }
- return overrides;
- }
-
- public static String extractUrl(String override) {
- Clause[] cs = Parser.parseClauses(new String[] { override });
- if (cs.length != 1) {
- throw new IllegalStateException("Override contains more than one clause: " + override);
- }
- return cs[0].getName();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
deleted file mode 100644
index 4bf1502..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.net.URI;
-
-import org.apache.karaf.features.Repository;
-import org.apache.karaf.features.internal.model.Features;
-import org.apache.karaf.features.internal.model.JaxbUtil;
-
-/**
- * The repository implementation.
- */
-public class RepositoryImpl implements Repository {
-
- private final URI uri;
- private Features features;
-
- public RepositoryImpl(URI uri) {
- this.uri = uri;
- }
-
- public URI getURI() {
- return uri;
- }
-
- public String getName() {
- // TODO: catching this exception is ugly
- try {
- load();
- } catch (IOException e) {
- throw new RuntimeException("Unable to load repository", e);
- }
- return features.getName();
- }
-
- public URI[] getRepositories() throws Exception {
- load();
- URI[] result = new URI[features.getRepository().size()];
- for (int i = 0; i < features.getRepository().size(); i++) {
- String uri = features.getRepository().get(i);
- uri = uri.trim();
- result[i] = URI.create(uri);
- }
- return result;
- }
-
- public org.apache.karaf.features.Feature[] getFeatures() throws Exception {
- load();
- return features.getFeature().toArray(new org.apache.karaf.features.Feature[features.getFeature().size()]);
- }
-
-
- public void load() throws IOException {
- if (features == null) {
- try {
- InputStream inputStream = uri.toURL().openStream();
- inputStream = new FilterInputStream(inputStream) {
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (Thread.currentThread().isInterrupted()) {
- throw new InterruptedIOException();
- }
- return super.read(b, off, len);
- }
- };
- try {
- features = JaxbUtil.unmarshal(inputStream, false);
- } finally {
- inputStream.close();
- }
- } catch (IllegalArgumentException e) {
- throw (IOException) new IOException(e.getMessage() + " : " + uri).initCause(e);
- } catch (Exception e) {
- throw (IOException) new IOException(e.getMessage() + " : " + uri).initCause(e);
- }
- }
- }
-
- @Override
- public boolean isValid() {
- throw new UnsupportedOperationException();
- }
-}
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
deleted file mode 100644
index e9ecece..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.internal.service;
-
-
-import org.apache.karaf.features.internal.resolver.RequirementImpl;
-import org.apache.karaf.features.internal.resolver.SimpleFilter;
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-public class RequirementSort {
-
- /**
- * Sorts {@link Resource} based on their {@link Requirement}s and {@link Capability}s.
- * @param resources
- * @return
- */
- public static <T extends Resource> Collection<T> sort(Collection<T> resources) {
- Set<T> sorted = new LinkedHashSet<T>();
- Set<T> visited = new LinkedHashSet<T>();
- for (T r : resources) {
- visit(r, resources, visited, sorted);
- }
- return sorted;
- }
-
-
- private static <T extends Resource> void visit(T resource, Collection<T> resources, Set<T> visited, Set<T> sorted) {
- if (visited.contains(resource)) {
- return;
- }
- visited.add(resource);
- for (T r : collectDependencies(resource, resources)) {
- visit(r, resources, visited, sorted);
- }
- sorted.add(resource);
- }
-
- /**
- * Finds the dependencies of the current resource.
- * @param resource
- * @param allResources
- * @return
- */
- private static <T extends Resource> Set<T> collectDependencies(T resource, Collection<T> allResources) {
- Set<T> result = new LinkedHashSet<T>();
- List<Requirement> requirements = resource.getRequirements(null);
- for (Requirement requirement : requirements) {
- boolean isSatisfied = false;
- for (Resource r : result) {
- for (Capability capability : r.getCapabilities(null)) {
- if (isSatisfied(requirement, capability)) {
- isSatisfied = true;
- break;
- }
- }
- }
-
- for (T r : allResources) {
- if (!isSatisfied) {
- for (Capability capability : r.getCapabilities(null)) {
- if (isSatisfied(requirement, capability)) {
- result.add(r);
- break;
- }
- }
- }
- }
- }
- return result;
- }
-
- private static boolean isSatisfied(Requirement requirement, Capability capability) {
- RequirementImpl br;
- if (requirement instanceof RequirementImpl) {
- br = (RequirementImpl) requirement;
- } else {
- String filter = requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
- SimpleFilter sf = (filter != null)
- ? SimpleFilter.parse(filter)
- : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- br = new RequirementImpl(null, requirement.getNamespace(), requirement.getDirectives(), requirement.getAttributes(), sf);
- }
- return br.matches(capability);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
deleted file mode 100644
index d1f16b9..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.apache.karaf.features.internal.deployment.Downloader;
-import org.apache.karaf.features.internal.deployment.StreamProvider;
-import org.apache.karaf.features.internal.util.MultiException;
-
-public class SimpleDownloader implements Downloader {
-
- private final MultiException exception = new MultiException("Error");
-
- @Override
- public void await() throws InterruptedException, MultiException {
- exception.throwIfExceptions();
- }
-
- @Override
- public void download(final String location, final DownloadCallback downloadCallback) throws MalformedURLException {
- final URL url = new URL(location);
- try {
- downloadCallback.downloaded(new StreamProvider() {
- @Override
- public InputStream open() throws IOException {
- return url.openStream();
- }
- });
- } catch (Exception e) {
- exception.addException(e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
deleted file mode 100644
index c84f4e0..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/State.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class State {
-
- public final AtomicBoolean bootDone = new AtomicBoolean();
- public final Set<String> repositories = new TreeSet<String>();
- public final Set<String> features = new TreeSet<String>();
- public final Set<String> installedFeatures = new TreeSet<String>();
- public final Set<Long> managedBundles = new TreeSet<Long>();
- public final Map<String, Long> bundleChecksums = new HashMap<String, Long>();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
deleted file mode 100644
index ac54ab0..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.karaf.features.Feature;
-
-public abstract class StateStorage {
-
- public void load(State state) throws IOException {
- state.repositories.clear();
- state.features.clear();
- state.installedFeatures.clear();
- state.managedBundles.clear();
- InputStream is = getInputStream();
- if (is != null) {
- try {
- Properties props = new Properties();
- props.load(is);
- state.bootDone.set(loadBool(props, "bootDone"));
- state.repositories.addAll(loadSet(props, "repositories."));
- state.features.addAll(loadSet(props, "features."));
- state.installedFeatures.addAll(loadSet(props, "installed."));
- state.managedBundles.addAll(toLongSet(loadSet(props, "managed.")));
- state.bundleChecksums.putAll(toStringLongMap(loadMap(props, "checksums.")));
- } finally {
- close(is);
- }
- }
- }
-
- public void save(State state) throws IOException {
- OutputStream os = getOutputStream();
- if (os != null) {
- try {
- Properties props = new Properties();
- saveBool(props, "bootDone", state.bootDone.get());
- saveSet(props, "repositories.", state.repositories);
- saveSet(props, "features.", state.features);
- saveSet(props, "installed.", state.installedFeatures);
- saveSet(props, "managed.", toStringSet(state.managedBundles));
- saveMap(props, "checksums.", toStringStringMap(state.bundleChecksums));
- props.store(os, "FeaturesService State");
- } finally {
- close(os);
- }
- }
- }
-
- protected abstract InputStream getInputStream() throws IOException;
- protected abstract OutputStream getOutputStream() throws IOException;
-
- protected boolean loadBool(Properties props, String key) {
- return Boolean.parseBoolean(props.getProperty(key));
- }
-
- protected void saveBool(Properties props, String key, boolean val) {
- props.setProperty(key, Boolean.toString(val));
- }
-
- protected Set<String> toStringSet(Set<Long> set) {
- Set<String> ns = new TreeSet<String>();
- for (long l : set) {
- ns.add(Long.toString(l));
- }
- return ns;
- }
-
- protected Set<Long> toLongSet(Set<String> set) {
- Set<Long> ns = new TreeSet<Long>();
- for (String s : set) {
- ns.add(Long.parseLong(s));
- }
- return ns;
- }
-
- protected void saveSet(Properties props, String prefix, Set<String> set) {
- List<String> l = new ArrayList<String>(set);
- props.put(prefix + "count", Integer.toString(l.size()));
- for (int i = 0; i < l.size(); i++) {
- props.put(prefix + "item." + i, l.get(i));
- }
- }
-
- protected Set<String> loadSet(Properties props, String prefix) {
- Set<String> l = new HashSet<String>();
- String countStr = (String) props.get(prefix + "count");
- if (countStr != null) {
- int count = Integer.parseInt(countStr);
- for (int i = 0; i < count; i++) {
- l.add((String) props.get(prefix + "item." + i));
- }
- }
- return l;
- }
-
- protected Map<String, String> toStringStringMap(Map<String, Long> map) {
- Map<String, String> nm = new HashMap<String, String>();
- for (Map.Entry<String, Long> entry : map.entrySet()) {
- nm.put(entry.getKey(), Long.toString(entry.getValue()));
- }
- return nm;
- }
-
- protected Map<String, Long> toStringLongMap(Map<String, String> map) {
- Map<String, Long> nm = new HashMap<String, Long>();
- for (Map.Entry<String, String> entry : map.entrySet()) {
- nm.put(entry.getKey(), Long.parseLong(entry.getValue()));
- }
- return nm;
- }
-
-
- protected void saveMap(Properties props, String prefix, Map<String, String> map) {
- List<Map.Entry<String, String>> l = new ArrayList<Map.Entry<String, String>>(map.entrySet());
- props.put(prefix + "count", Integer.toString(l.size()));
- for (int i = 0; i < l.size(); i++) {
- props.put(prefix + "key." + i, l.get(i).getKey());
- props.put(prefix + "val." + i, l.get(i).getValue());
- }
- }
-
- protected Map<String, String> loadMap(Properties props, String prefix) {
- Map<String, String> l = new HashMap<String, String>();
- String countStr = (String) props.get(prefix + "count");
- if (countStr != null) {
- int count = Integer.parseInt(countStr);
- for (int i = 0; i < count; i++) {
- String key = (String) props.get(prefix + "key." + i);
- String val = (String) props.get(prefix + "val." + i);
- l.put(key, val);
- }
- }
- return l;
- }
-
-
- protected void close(Closeable closeable) {
- if (closeable != null) {
- try {
- closeable.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java
deleted file mode 100644
index 19fc706..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.internal.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.CRC32;
-
-public class ChecksumUtils {
-
- private ChecksumUtils() {
- }
-
- /**
- * Compute a cheksum for the file or directory that consists of the name, length and the last modified date
- * for a file and its children in case of a directory
- *
- * @param is the input stream
- * @return a checksum identifying any change
- */
- public static long checksum(InputStream is) throws IOException
- {
- try {
- CRC32 crc = new CRC32();
- byte[] buffer = new byte[8192];
- int l;
- while ((l = is.read(buffer)) > 0) {
- crc.update(buffer, 0, l);
- }
- return crc.getValue();
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
deleted file mode 100644
index a53d8a5..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * 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.internal.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- */
-public class JsonReader {
-
- public static Object read(Reader reader) throws IOException {
- return new JsonReader(reader).parse();
- }
-
- public static Object read(InputStream is) throws IOException {
- return new JsonReader(new InputStreamReader(is)).parse();
- }
-
- //
- // Implementation
- //
-
- private final Reader reader;
- private final StringBuilder recorder;
- private int current;
- private int line = 1;
- private int column = 0;
-
- JsonReader(Reader reader) {
- this.reader = reader;
- recorder = new StringBuilder();
- }
-
- public Object parse() throws IOException {
- read();
- skipWhiteSpace();
- Object result = readValue();
- skipWhiteSpace();
- if (!endOfText()) {
- throw error("Unexpected character");
- }
- return result;
- }
-
- private Object readValue() throws IOException {
- switch (current) {
- case 'n':
- return readNull();
- case 't':
- return readTrue();
- case 'f':
- return readFalse();
- case '"':
- return readString();
- case '[':
- return readArray();
- case '{':
- return readObject();
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return readNumber();
- default:
- throw expected("value");
- }
- }
-
- private Collection<?> readArray() throws IOException {
- read();
- Collection<Object> array = new ArrayList<Object>();
- skipWhiteSpace();
- if (readChar(']')) {
- return array;
- }
- do {
- skipWhiteSpace();
- array.add(readValue());
- skipWhiteSpace();
- } while (readChar(','));
- if (!readChar(']')) {
- throw expected("',' or ']'");
- }
- return array;
- }
-
- private Map<String, Object> readObject() throws IOException {
- read();
- Map<String, Object> object = new HashMap<String, Object>();
- skipWhiteSpace();
- if (readChar('}')) {
- return object;
- }
- do {
- skipWhiteSpace();
- String name = readName();
- skipWhiteSpace();
- if (!readChar(':')) {
- throw expected("':'");
- }
- skipWhiteSpace();
- object.put(name, readValue());
- skipWhiteSpace();
- } while (readChar(','));
- if (!readChar('}')) {
- throw expected("',' or '}'");
- }
- return object;
- }
-
- private Object readNull() throws IOException {
- read();
- readRequiredChar('u');
- readRequiredChar('l');
- readRequiredChar('l');
- return null;
- }
-
- private Boolean readTrue() throws IOException {
- read();
- readRequiredChar('r');
- readRequiredChar('u');
- readRequiredChar('e');
- return Boolean.TRUE;
- }
-
- private Boolean readFalse() throws IOException {
- read();
- readRequiredChar('a');
- readRequiredChar('l');
- readRequiredChar('s');
- readRequiredChar('e');
- return Boolean.FALSE;
- }
-
- private void readRequiredChar(char ch) throws IOException {
- if (!readChar(ch)) {
- throw expected("'" + ch + "'");
- }
- }
-
- private String readString() throws IOException {
- read();
- recorder.setLength(0);
- while (current != '"') {
- if (current == '\\') {
- readEscape();
- } else if (current < 0x20) {
- throw expected("valid string character");
- } else {
- recorder.append((char) current);
- read();
- }
- }
- read();
- return recorder.toString();
- }
-
- private void readEscape() throws IOException {
- read();
- switch (current) {
- case '"':
- case '/':
- case '\\':
- recorder.append((char) current);
- break;
- case 'b':
- recorder.append('\b');
- break;
- case 'f':
- recorder.append('\f');
- break;
- case 'n':
- recorder.append('\n');
- break;
- case 'r':
- recorder.append('\r');
- break;
- case 't':
- recorder.append('\t');
- break;
- case 'u':
- char[] hexChars = new char[4];
- for (int i = 0; i < 4; i++) {
- read();
- if (!isHexDigit(current)) {
- throw expected("hexadecimal digit");
- }
- hexChars[i] = (char) current;
- }
- recorder.append((char) Integer.parseInt(String.valueOf(hexChars), 16));
- break;
- default:
- throw expected("valid escape sequence");
- }
- read();
- }
-
- private Number readNumber() throws IOException {
- recorder.setLength(0);
- readAndAppendChar('-');
- int firstDigit = current;
- if (!readAndAppendDigit()) {
- throw expected("digit");
- }
- if (firstDigit != '0') {
- while (readAndAppendDigit()) {
- }
- }
- readFraction();
- readExponent();
- return Double.parseDouble(recorder.toString());
- }
-
- private boolean readFraction() throws IOException {
- if (!readAndAppendChar('.')) {
- return false;
- }
- if (!readAndAppendDigit()) {
- throw expected("digit");
- }
- while (readAndAppendDigit()) {
- }
- return true;
- }
-
- private boolean readExponent() throws IOException {
- if (!readAndAppendChar('e') && !readAndAppendChar('E')) {
- return false;
- }
- if (!readAndAppendChar('+')) {
- readAndAppendChar('-');
- }
- if (!readAndAppendDigit()) {
- throw expected("digit");
- }
- while (readAndAppendDigit()) {
- }
- return true;
- }
-
- private String readName() throws IOException {
- if (current != '"') {
- throw expected("name");
- }
- readString();
- return recorder.toString();
- }
-
- private boolean readAndAppendChar(char ch) throws IOException {
- if (current != ch) {
- return false;
- }
- recorder.append(ch);
- read();
- return true;
- }
-
- private boolean readChar(char ch) throws IOException {
- if (current != ch) {
- return false;
- }
- read();
- return true;
- }
-
- private boolean readAndAppendDigit() throws IOException {
- if (!isDigit(current)) {
- return false;
- }
- recorder.append((char) current);
- read();
- return true;
- }
-
- private void skipWhiteSpace() throws IOException {
- while (isWhiteSpace(current) && !endOfText()) {
- read();
- }
- }
-
- private void read() throws IOException {
- if (endOfText()) {
- throw error("Unexpected end of input");
- }
- column++;
- if (current == '\n') {
- line++;
- column = 0;
- }
- current = reader.read();
- }
-
- private boolean endOfText() {
- return current == -1;
- }
-
- private IOException expected(String expected) {
- if (endOfText()) {
- return error("Unexpected end of input");
- }
- return error("Expected " + expected);
- }
-
- private IOException error(String message) {
- return new IOException(message + " at " + line + ":" + column);
- }
-
- private static boolean isWhiteSpace(int ch) {
- return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
- }
-
- private static boolean isDigit(int ch) {
- return ch >= '0' && ch <= '9';
- }
-
- private static boolean isHexDigit(int ch) {
- return ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F';
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
deleted file mode 100644
index cba27fb..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.internal.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- */
-public class JsonWriter {
-
- public static void write(Writer writer, Object value) throws IOException {
- if (value instanceof Map) {
- writeObject(writer, (Map) value);
- } else if (value instanceof Collection) {
- writeArray(writer, (Collection) value);
- } else if (value instanceof Number) {
- writeNumber(writer, (Number) value);
- } else if (value instanceof String) {
- writeString(writer, (String) value);
- } else if (value instanceof Boolean) {
- writeBoolean(writer, (Boolean) value);
- } else if (value == null) {
- writeNull(writer);
- } else {
- throw new IllegalArgumentException("Unsupported value: " + value);
- }
- }
-
- private static void writeObject(Writer writer, Map<?, ?> value) throws IOException {
- writer.append('{');
- boolean first = true;
- for (Map.Entry entry : value.entrySet()) {
- if (!first) {
- writer.append(',');
- } else {
- first = false;
- }
- writeString(writer, (String) entry.getKey());
- writer.append(':');
- write(writer, entry.getValue());
- }
- writer.append('}');
- }
-
- private static void writeString(Writer writer, String value) throws IOException {
- writer.append('"');
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- switch (c) {
- case '\"':
- case '\\':
- case '\b':
- case '\f':
- case '\n':
- case '\r':
- case '\t':
- writer.append('\\');
- writer.append(c);
- break;
- default:
- if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
- String s = Integer.toHexString(c);
- writer.append('\\');
- writer.append('u');
- for (int j = s.length(); j < 4; j++) {
- writer.append('0');
- }
- writer.append(s);
- } else {
- writer.append(c);
- }
- break;
- }
- }
- writer.append('"');
- }
-
- private static void writeNumber(Writer writer, Number value) throws IOException {
- writer.append(value.toString());
- }
-
- private static void writeBoolean(Writer writer, Boolean value) throws IOException {
- writer.append(Boolean.toString(value));
- }
-
- private static void writeArray(Writer writer, Collection<?> value) throws IOException {
- writer.append('[');
- boolean first = true;
- for (Object obj : value) {
- if (!first) {
- writer.append(',');
- } else {
- first = false;
- }
- write(writer, obj);
- }
- writer.append(']');
- }
-
- private static void writeNull(Writer writer) throws IOException {
- writer.append("null");
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/util/Macro.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/Macro.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/Macro.java
deleted file mode 100644
index d30b7b5..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/Macro.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.internal.util;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.felix.utils.version.VersionTable;
-import org.osgi.framework.Version;
-
-public class Macro {
-
- public static String transform(String macro, String value) {
- if (macro.startsWith("${") && macro.endsWith("}")) {
- String[] args = macro.substring(2, macro.length() - 1).split(";");
- if ("version".equals(args[0])) {
- if (args.length != 2) {
- throw new IllegalArgumentException("Invalid syntax for macro: " + macro);
- }
- return version(args[1], VersionTable.getVersion(value));
- } else if ("range".equals(args[0])) {
- if (args.length != 2) {
- throw new IllegalArgumentException("Invalid syntax for macro: " + macro);
- }
- return range(args[1], VersionTable.getVersion(value));
- } else {
- throw new IllegalArgumentException("Unknown macro: " + macro);
- }
- }
- return value;
- }
-
- /**
- * Modify a version to set a version policy. Thed policy is a mask that is
- * mapped to a version.
- *
- * <pre>
- * + increment
- * - decrement
- * = maintain
- * ˜ discard
- *
- * ==+ = maintain major, minor, increment micro, discard qualifier
- * ˜˜˜= = just get the qualifier
- * version="[${version;==;${@}},${version;=+;${@}})"
- * </pre>
- *
- * @param args
- * @return
- */
- final static String MASK_STRING = "[\\-+=~0123456789]{0,3}[=~]?";
-
- static String version(String mask, Version version) {
- StringBuilder sb = new StringBuilder();
- String del = "";
-
- for (int i = 0; i < mask.length(); i++) {
- char c = mask.charAt(i);
- String result = null;
- if (c != '~') {
- if (i > 3) {
- throw new IllegalArgumentException("Version mask can only specify 3 digits");
- } else if (i == 3) {
- result = version.getQualifier();
- if (result.isEmpty()) {
- result = null;
- }
- } else if (Character.isDigit(c)) {
- // Handle masks like +00, =+0
- result = String.valueOf(c);
- } else {
- int x = 0;
- switch (i) {
- case 0: x = version.getMajor(); break;
- case 1: x = version.getMinor(); break;
- case 2: x = version.getMicro(); break;
- }
- switch (c) {
- case '+' :
- x++;
- break;
- case '-' :
- x--;
- break;
- case '=' :
- break;
- }
- result = Integer.toString(x);
- }
- if (result != null) {
- sb.append(del);
- del = ".";
- sb.append(result);
- }
- }
- }
- return sb.toString();
- }
-
- /**
- * Schortcut for version policy
- *
- * <pre>
- * -provide-policy : ${policy;[==,=+)}
- * -consume-policy : ${policy;[==,+)}
- * </pre>
- *
- * @param args
- * @return
- */
-
- static Pattern RANGE_MASK = Pattern.compile("(\\[|\\()(" + MASK_STRING + "),(" + MASK_STRING + ")(\\]|\\))");
-
- static String range(String spec, Version version) {
- Matcher m = RANGE_MASK.matcher(spec);
- m.matches();
- String floor = m.group(1);
- String floorMask = m.group(2);
- String ceilingMask = m.group(3);
- String ceiling = m.group(4);
-
- String left = version(floorMask, version);
- String right = version(ceilingMask, version);
-
- return floor + left + "," + right + ceiling;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/MultiException.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
deleted file mode 100644
index 36af452..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.internal.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("serial")
-public class MultiException extends Exception {
-
- private List<Exception> exceptions = new ArrayList<Exception>();
-
- public MultiException(String message) {
- super(message);
- }
-
- public MultiException(String message, List<Exception> exceptions) {
- super(message);
- this.exceptions = exceptions;
- }
-
- public void addException(Exception e) {
- exceptions.add(e);
- }
-
- public void throwIfExceptions() throws MultiException {
- if (!exceptions.isEmpty()) {
- throw this;
- }
- }
-
- public Throwable[] getCauses() {
- return exceptions.toArray(new Throwable[exceptions.size()]);
- }
-
- @Override
- public void printStackTrace()
- {
- super.printStackTrace();
- for (Exception e : exceptions) {
- e.printStackTrace();
- }
- }
-
-
- /* ------------------------------------------------------------------------------- */
- /**
- * @see Throwable#printStackTrace(java.io.PrintStream)
- */
- @Override
- public void printStackTrace(PrintStream out)
- {
- super.printStackTrace(out);
- for (Exception e : exceptions) {
- e.printStackTrace(out);
- }
- }
-
- @Override
- public void printStackTrace(PrintWriter out)
- {
- super.printStackTrace(out);
- for (Exception e : exceptions) {
- e.printStackTrace(out);
- }
- }
-
- public static void throwIf(String message, List<Exception> exceptions) throws MultiException {
- if (exceptions != null && !exceptions.isEmpty()) {
- StringBuilder sb = new StringBuilder(message);
- sb.append(":");
- for (Exception e : exceptions) {
- sb.append("\n\t");
- sb.append(e.getMessage());
- }
- throw new MultiException(sb.toString(), exceptions);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java b/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
deleted file mode 100644
index 6afbbed..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.management;
-
-import javax.management.openmbean.TabularData;
-
-public interface FeaturesServiceMBean {
-
- TabularData getFeatures() throws Exception;
-
- TabularData getRepositories() throws Exception;
-
- void addRepository(String url) throws Exception;
-
- void addRepository(String url, boolean install) throws Exception;
-
- void removeRepository(String url) throws Exception;
-
- void removeRepository(String url, boolean uninstall) throws Exception;
-
- void installFeature(String name) throws Exception;
-
- void installFeature(String name, boolean noRefresh) throws Exception;
-
- void installFeature(String name, boolean noRefresh, boolean noStart) throws Exception;
-
- void installFeature(String name, String version) throws Exception;
-
- void installFeature(String name, String version, boolean noRefresh) throws Exception;
-
- void installFeature(String name, String version, boolean noRefresh, boolean noStart) throws Exception;
-
- TabularData infoFeature(String name) throws Exception;
-
- TabularData infoFeature(String name, String version) throws Exception;
-
- void uninstallFeature(String name) throws Exception;
-
- void uninstallFeature(String name, boolean noRefresh) throws Exception;
-
- void uninstallFeature(String name, String version) throws Exception;
-
- void uninstallFeature(String name, String version, boolean noRefresh) throws Exception;
-
- String FEATURE_NAME = "Name";
-
- String FEATURE_VERSION = "Version";
-
- String FEATURE_DEPENDENCIES = "Dependencies";
-
- String FEATURE_BUNDLES = "Bundles";
-
- String FEATURE_CONFIGURATIONS = "Configurations";
-
- String FEATURE_CONFIGURATIONFILES = "Configuration Files";
-
- String FEATURE_INSTALLED = "Installed";
-
- String FEATURE_CONFIG_PID = "Pid";
- String FEATURE_CONFIG_ELEMENTS = "Elements";
- String FEATURE_CONFIG_ELEMENT_KEY = "Key";
- String FEATURE_CONFIG_ELEMENT_VALUE = "Value";
-
- String FEATURE_CONFIG_FILES_ELEMENTS = "Files";
-
- /**
- * The type of the event which is emitted for features events
- */
- String FEATURE_EVENT_TYPE = "org.apache.karaf.features.featureEvent";
-
- String FEATURE_EVENT_EVENT_TYPE = "Type";
-
- String FEATURE_EVENT_EVENT_TYPE_INSTALLED = "Installed";
-
- String FEATURE_EVENT_EVENT_TYPE_UNINSTALLED = "Uninstalled";
-
- /**
- * The item names in the CompositeData representing a feature
- */
- String[] FEATURE = { FEATURE_NAME, FEATURE_VERSION, FEATURE_DEPENDENCIES, FEATURE_BUNDLES,
- FEATURE_CONFIGURATIONS, FEATURE_CONFIGURATIONFILES, FEATURE_INSTALLED };
-
- String[] FEATURE_IDENTIFIER = { FEATURE_NAME, FEATURE_VERSION };
-
- String[] FEATURE_CONFIG = { FEATURE_CONFIG_PID, FEATURE_CONFIG_ELEMENTS };
-
- String[] FEATURE_CONFIG_FILES = { FEATURE_CONFIG_FILES_ELEMENTS };
-
- String[] FEATURE_CONFIG_ELEMENT = { FEATURE_CONFIG_ELEMENT_KEY, FEATURE_CONFIG_ELEMENT_VALUE };
-
- /**
- * The item names in the CompositeData representing the event raised for
- * feature events within the OSGi container by this bean
- */
- String[] FEATURE_EVENT = { FEATURE_NAME, FEATURE_VERSION, FEATURE_EVENT_EVENT_TYPE };
-
-
- String REPOSITORY_NAME = "Name";
-
- String REPOSITORY_URI = "Uri";
-
- String REPOSITORY_REPOSITORIES = "Repositories";
-
- String REPOSITORY_FEATURES = "Features";
-
- /**
- * The type of the event which is emitted for repositories events
- */
- String REPOSITORY_EVENT_TYPE = "org.apache.karaf.features.repositoryEvent";
-
- String REPOSITORY_EVENT_EVENT_TYPE = "Type";
-
- String REPOSITORY_EVENT_EVENT_TYPE_ADDED = "Added";
-
- String REPOSITORY_EVENT_EVENT_TYPE_REMOVED = "Removed";
-
- /**
- * The item names in the CompositeData representing a feature
- */
- String[] REPOSITORY = { REPOSITORY_NAME, REPOSITORY_URI, REPOSITORY_REPOSITORIES, REPOSITORY_FEATURES };
-
- /**
- * The item names in the CompositeData representing the event raised for
- * feature events within the OSGi container by this bean
- */
- String[] REPOSITORY_EVENT = { REPOSITORY_URI, REPOSITORY_EVENT_EVENT_TYPE };
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java b/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
deleted file mode 100644
index 54fa3c0..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * 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.management.codec;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularDataSupport;
-
-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.management.FeaturesServiceMBean;
-
-public class JmxFeature {
-
- /**
- * The CompositeType which represents a single feature
- */
- public final static CompositeType FEATURE;
-
- /**
- * The TabularType which represents a list of features
- */
- public final static TabularType FEATURE_TABLE;
-
- public final static CompositeType FEATURE_IDENTIFIER;
-
- public final static TabularType FEATURE_IDENTIFIER_TABLE;
-
- public final static CompositeType FEATURE_CONFIG_ELEMENT;
-
- public final static TabularType FEATURE_CONFIG_ELEMENT_TABLE;
-
- public final static CompositeType FEATURE_CONFIG;
-
- public final static TabularType FEATURE_CONFIG_TABLE;
-
- public final static CompositeType FEATURE_CONFIG_FILES;
-
- public final static TabularType FEATURE_CONFIG_FILES_TABLE;
-
- private final CompositeData data;
-
- public JmxFeature(Feature feature, boolean installed) {
- try {
- String[] itemNames = FeaturesServiceMBean.FEATURE;
- Object[] itemValues = new Object[itemNames.length];
- itemValues[0] = feature.getName();
- itemValues[1] = feature.getVersion();
- itemValues[2] = getDependencyIdentifierTable(feature.getDependencies());
- itemValues[3] = getBundleUris(feature.getBundles());
- itemValues[4] = getConfigTable(feature.getConfigurations());
- itemValues[5] = getConfigFileList(feature.getConfigurationFiles());
- itemValues[6] = installed;
- data = new CompositeDataSupport(FEATURE, itemNames, itemValues);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Cannot form feature open data", e);
- }
- }
-
- public CompositeData asCompositeData() {
- return data;
- }
-
- public static TabularData tableFrom(Collection<JmxFeature> features) {
- TabularDataSupport table = new TabularDataSupport(FEATURE_TABLE);
- for (JmxFeature feature : features) {
- table.put(feature.asCompositeData());
- }
- return table;
- }
-
- private static TabularData getDependencyIdentifierTable(List<Dependency> features) throws OpenDataException {
- TabularDataSupport table = new TabularDataSupport(FEATURE_IDENTIFIER_TABLE);
- Set<String> featureSet = new HashSet<String>();
- for (Dependency feature : features) {
- if (featureSet.contains(feature.getName() + feature.getVersion())) {
- continue;
- } else {
- featureSet.add(feature.getName() + feature.getVersion());
- }
- String[] itemNames = new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION };
- Object[] itemValues = new Object[] { feature.getName(), feature.getVersion() };
- CompositeData ident = new CompositeDataSupport(FEATURE_IDENTIFIER, itemNames, itemValues);
- table.put(ident);
- }
- return table;
- }
-
- static String[] getBundleUris(List<BundleInfo> infos) {
- String[] array = new String[infos.size()];
- for (int i = 0; i < array.length; i++) {
- array[i] = infos.get(i).getLocation();
- }
- return array;
- }
-
- static TabularData getConfigTable(Map<String, Map<String, String>> configs) throws OpenDataException {
- TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_TABLE);
- for (Map.Entry<String, Map<String, String>> entry : configs.entrySet()) {
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG;
- Object[] itemValues = new Object[2];
- itemValues[0] = entry.getKey();
- itemValues[1] = getConfigElementTable(entry.getValue());
- CompositeData config = new CompositeDataSupport(FEATURE_CONFIG, itemNames, itemValues);
- table.put(config);
- }
- return table;
- }
-
- static TabularData getConfigFileList(List<ConfigFileInfo> configFiles) throws OpenDataException {
- TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_FILES_TABLE);
- for (ConfigFileInfo configFile : configFiles) {
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_FILES;
- Object[] itemValues = { configFile.getFinalname() };
- CompositeData config = new CompositeDataSupport(FEATURE_CONFIG_FILES, itemNames, itemValues);
- table.put(config);
- }
- return table;
- }
-
- static TabularData getConfigElementTable(Map<String, String> config) throws OpenDataException {
- TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_ELEMENT_TABLE);
- for (Map.Entry<String, String> entry : config.entrySet()) {
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT;
- Object[] itemValues = { entry.getKey(), entry.getValue() };
- CompositeData element = new CompositeDataSupport(FEATURE_CONFIG_ELEMENT, itemNames, itemValues);
- table.put(element);
- }
- return table;
- }
-
-
- static {
- FEATURE_IDENTIFIER = createFeatureIdentifierType();
- FEATURE_IDENTIFIER_TABLE = createFeatureIdentifierTableType();
- FEATURE_CONFIG_ELEMENT = createFeatureConfigElementType();
- FEATURE_CONFIG_ELEMENT_TABLE = createFeatureConfigElementTableType();
- FEATURE_CONFIG = createFeatureConfigType();
- FEATURE_CONFIG_TABLE = createFeatureConfigTableType();
- FEATURE_CONFIG_FILES = createFeatureConfigFilesType();
- FEATURE_CONFIG_FILES_TABLE = createFeatureConfigFilesTableType();
- FEATURE = createFeatureType();
- FEATURE_TABLE = createFeatureTableType();
- }
-
- private static CompositeType createFeatureIdentifierType() {
- try {
- String description = "This type identify a Karaf features";
- String[] itemNames = FeaturesServiceMBean.FEATURE_IDENTIFIER;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
-
- itemDescriptions[0] = "The id of the feature";
- itemDescriptions[1] = "The version of the feature";
-
- return new CompositeType("FeatureIdentifier", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build featureIdentifier type", e);
- }
- }
-
- private static TabularType createFeatureIdentifierTableType() {
- try {
- return new TabularType("Features", "The table of featureIdentifiers",
- FEATURE_IDENTIFIER, new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION });
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build featureIdentifier table type", e);
- }
- }
-
- private static CompositeType createFeatureConfigElementType() {
- try {
- String description = "This type encapsulates Karaf feature config element";
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
-
- itemDescriptions[0] = "The key";
- itemDescriptions[1] = "The value";
-
- return new CompositeType("ConfigElement", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build configElement type", e);
- }
- }
-
- private static TabularType createFeatureConfigElementTableType() {
- try {
- return new TabularType("ConfigElement", "The table of configurations elements",
- FEATURE_CONFIG_ELEMENT, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT_KEY});
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build feature table type", e);
- }
- }
-
- private static CompositeType createFeatureConfigType() {
- try {
- String description = "This type encapsulates Karaf feature config";
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = FEATURE_CONFIG_ELEMENT_TABLE;
-
- itemDescriptions[0] = "The PID of the config";
- itemDescriptions[1] = "The configuration elements";
-
- return new CompositeType("Config", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build configElement type", e);
- }
- }
-
- private static CompositeType createFeatureConfigFilesType() {
- try {
- String description = "This type encapsulates Karaf feature config files";
- String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_FILES;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
-
- itemDescriptions[0] = "The configuration file";
-
- return new CompositeType("Config", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build configElement type", e);
- }
- }
-
- private static TabularType createFeatureConfigTableType() {
- try {
- return new TabularType("Features", "The table of configurations",
- FEATURE_CONFIG, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_PID});
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build feature table type", e);
- }
- }
-
- private static TabularType createFeatureConfigFilesTableType() {
- try {
- return new TabularType("Features", "The table of configuration files",
- FEATURE_CONFIG_FILES, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_FILES_ELEMENTS });
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build feature table type", e);
- }
- }
-
- private static CompositeType createFeatureType() {
- try {
- String description = "This type encapsulates Karaf features";
- String[] itemNames = FeaturesServiceMBean.FEATURE;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
- itemTypes[2] = FEATURE_IDENTIFIER_TABLE;
- itemTypes[3] = new ArrayType(1, SimpleType.STRING);
- itemTypes[4] = FEATURE_CONFIG_TABLE;
- itemTypes[5] = FEATURE_CONFIG_FILES_TABLE;
- itemTypes[6] = SimpleType.BOOLEAN;
-
- itemDescriptions[0] = "The name of the feature";
- itemDescriptions[1] = "The version of the feature";
- itemDescriptions[2] = "The feature dependencies";
- itemDescriptions[3] = "The feature bundles";
- itemDescriptions[4] = "The feature configurations";
- itemDescriptions[5] = "The feature configuration files";
- itemDescriptions[6] = "Whether the feature is installed";
-
- return new CompositeType("Feature", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build feature type", e);
- }
- }
-
- private static TabularType createFeatureTableType() {
- try {
- return new TabularType("Features", "The table of all features",
- FEATURE, new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION });
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build feature table type", e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java b/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
deleted file mode 100644
index 81f446b..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.management.codec;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-
-import org.apache.karaf.features.FeatureEvent;
-import org.apache.karaf.features.management.FeaturesServiceMBean;
-
-public class JmxFeatureEvent {
-
- public static final CompositeType FEATURE_EVENT;
-
- private final CompositeData data;
-
- public JmxFeatureEvent(FeatureEvent event) {
- try {
- String[] itemNames = FeaturesServiceMBean.FEATURE_EVENT;
- Object[] itemValues = new Object[itemNames.length];
- itemValues[0] = event.getFeature().getName();
- itemValues[1] = event.getFeature().getVersion();
- switch (event.getType()) {
- case FeatureInstalled: itemValues[2] = FeaturesServiceMBean.FEATURE_EVENT_EVENT_TYPE_INSTALLED; break;
- case FeatureUninstalled: itemValues[2] = FeaturesServiceMBean.FEATURE_EVENT_EVENT_TYPE_UNINSTALLED; break;
- default: throw new IllegalStateException("Unsupported event type: " + event.getType());
- }
- data = new CompositeDataSupport(FEATURE_EVENT, itemNames, itemValues);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Cannot form feature event open data", e);
- }
- }
-
- public CompositeData asCompositeData() {
- return data;
- }
-
- static {
- FEATURE_EVENT = createFeatureEventType();
- }
-
- private static CompositeType createFeatureEventType() {
- try {
- String description = "This type identify a Karaf feature event";
- String[] itemNames = FeaturesServiceMBean.FEATURE_EVENT;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
- itemTypes[2] = SimpleType.STRING;
-
- itemDescriptions[0] = "The id of the feature";
- itemDescriptions[1] = "The version of the feature";
- itemDescriptions[2] = "The type of the event";
-
- return new CompositeType("FeatureEvent", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build featureEvent type", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java b/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
deleted file mode 100644
index fee1ab2..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.management.codec;
-
-import java.util.Collection;
-import java.util.Arrays;
-import java.net.URI;
-import java.util.List;
-
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.TabularType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.CompositeDataSupport;
-
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.Repository;
-import org.apache.karaf.features.management.FeaturesServiceMBean;
-
-public class JmxRepository {
-
- public final static CompositeType REPOSITORY;
-
- public final static TabularType REPOSITORY_TABLE;
-
- private final CompositeData data;
-
- public JmxRepository(Repository repository) {
- try {
- String[] itemNames = FeaturesServiceMBean.REPOSITORY;
- Object[] itemValues = new Object[itemNames.length];
- itemValues[0] = repository.getName();
- itemValues[1] = repository.getURI().toString();
- itemValues[2] = toStringArray(repository.getRepositories());
- itemValues[3] = getFeatureIdentifierTable(Arrays.asList(repository.getFeatures()));
- data = new CompositeDataSupport(REPOSITORY, itemNames, itemValues);
- } catch (Exception e) {
- throw new IllegalStateException("Cannot form repository open data", e);
- }
- }
-
- public CompositeData asCompositeData() {
- return data;
- }
-
- public static TabularData tableFrom(Collection<JmxRepository> repositories) {
- TabularDataSupport table = new TabularDataSupport(REPOSITORY_TABLE);
- for (JmxRepository repository : repositories) {
- table.put(repository.asCompositeData());
- }
- return table;
- }
-
- private static String[] toStringArray(URI[] uris) {
- if (uris == null) {
- return null;
- }
- String[] res = new String[uris.length];
- for (int i = 0; i < res.length; i++) {
- res[i] = uris[i].toString();
- }
- return res;
- }
-
- static TabularData getFeatureIdentifierTable(List<Feature> features) throws OpenDataException {
- TabularDataSupport table = new TabularDataSupport(JmxFeature.FEATURE_IDENTIFIER_TABLE);
- for (Feature feature : features) {
- String[] itemNames = new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION };
- Object[] itemValues = new Object[] { feature.getName(), feature.getVersion() };
- CompositeData ident = new CompositeDataSupport(JmxFeature.FEATURE_IDENTIFIER, itemNames, itemValues);
- table.put(ident);
- }
- return table;
- }
-
- static {
- REPOSITORY = createRepositoryType();
- REPOSITORY_TABLE = createRepositoryTableType();
- }
-
- private static CompositeType createRepositoryType() {
- try {
- String description = "This type identify a Karaf repository";
- String[] itemNames = FeaturesServiceMBean.REPOSITORY;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
- itemTypes[2] = new ArrayType(1, SimpleType.STRING);
- itemTypes[3] = JmxFeature.FEATURE_IDENTIFIER_TABLE;
-
- itemDescriptions[0] = "The name of the repository";
- itemDescriptions[1] = "The uri of the repository";
- itemDescriptions[2] = "The dependent repositories";
- itemDescriptions[3] = "The list of included features";
-
- return new CompositeType("Repository", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build repository type", e);
- }
- }
-
- private static TabularType createRepositoryTableType() {
- try {
- return new TabularType("Features", "The table of repositories",
- REPOSITORY, new String[] { FeaturesServiceMBean.REPOSITORY_URI });
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build repository table type", e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java b/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
deleted file mode 100644
index e00e85d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.management.codec;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-
-import org.apache.karaf.features.RepositoryEvent;
-import org.apache.karaf.features.management.FeaturesServiceMBean;
-
-public class JmxRepositoryEvent {
-
- public static final CompositeType REPOSITORY_EVENT;
-
- private final CompositeData data;
-
- public JmxRepositoryEvent(RepositoryEvent event) {
- try {
- String[] itemNames = FeaturesServiceMBean.REPOSITORY_EVENT;
- Object[] itemValues = new Object[itemNames.length];
- itemValues[0] = event.getRepository().getURI().toString();
- switch (event.getType()) {
- case RepositoryAdded: itemValues[1] = FeaturesServiceMBean.REPOSITORY_EVENT_EVENT_TYPE_ADDED; break;
- case RepositoryRemoved: itemValues[1] = FeaturesServiceMBean.REPOSITORY_EVENT_EVENT_TYPE_REMOVED; break;
- default: throw new IllegalStateException("Unsupported event type: " + event.getType());
- }
- data = new CompositeDataSupport(REPOSITORY_EVENT, itemNames, itemValues);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Cannot form repository event open data", e);
- }
- }
-
- public CompositeData asCompositeData() {
- return data;
- }
-
- static {
- REPOSITORY_EVENT = createRepositoryEventType();
- }
-
- private static CompositeType createRepositoryEventType() {
- try {
- String description = "This type identify a Karaf repository event";
- String[] itemNames = FeaturesServiceMBean.REPOSITORY_EVENT;
- OpenType[] itemTypes = new OpenType[itemNames.length];
- String[] itemDescriptions = new String[itemNames.length];
- itemTypes[0] = SimpleType.STRING;
- itemTypes[1] = SimpleType.STRING;
-
- itemDescriptions[0] = "The uri of the repository";
- itemDescriptions[1] = "The type of event";
-
- return new CompositeType("RepositoryEvent", description, itemNames,
- itemDescriptions, itemTypes);
- } catch (OpenDataException e) {
- throw new IllegalStateException("Unable to build repositoryEvent type", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/OSGI-INF/bundle.info b/features/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index d5b4180..0000000
--- a/features/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,20 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle is the core implementation of the Karaf features support.
-
-Karaf provides a simple, yet flexible, way to provision applications or "features". Such a mechanism is mainly
-provided by a set of commands available in the features shell. The provisioning system uses xml "repositories"
-that define a set of features.
-
-h1. See also
-
-Provisioning - section of the Karaf User Guide
[47/59] [abbrv] [KARAF-2852] Merge wrapper/core and wrapper/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
new file mode 100644
index 0000000..8737547
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/PumpStreamHandler.java
@@ -0,0 +1,246 @@
+/*
+ * 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.wrapper.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+//
+// Based on Apache Ant 1.6.5
+//
+
+/**
+ * Copies standard output and error of children streams to standard output and error of the parent.
+ */
+public class PumpStreamHandler {
+
+ private final InputStream in;
+
+ private final OutputStream out;
+
+ private final OutputStream err;
+
+ private final String name;
+
+ private StreamPumper outputPump;
+
+ private StreamPumper errorPump;
+
+ private StreamPumper inputPump;
+
+ //
+ // NOTE: May want to use a ThreadPool here, 3 threads per/pair seems kinda expensive :-(
+ //
+
+ public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err, String name) {
+ assert in != null;
+ assert out != null;
+ assert err != null;
+ assert name != null;
+
+ this.in = in;
+ this.out = out;
+ this.err = err;
+ this.name = name;
+ }
+
+ public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err) {
+ this(in, out, err, "<unknown>");
+ }
+
+ public PumpStreamHandler(final OutputStream out, final OutputStream err) {
+ this(null, out, err);
+ }
+
+ public PumpStreamHandler(final OutputStream outAndErr) {
+ this(outAndErr, outAndErr);
+ }
+
+ /**
+ * Set the input stream from which to read the standard output of the child.
+ */
+ public void setChildOutputStream(final InputStream in) {
+ assert in != null;
+
+ createChildOutputPump(in, out);
+ }
+
+ /**
+ * Set the input stream from which to read the standard error of the child.
+ */
+ public void setChildErrorStream(final InputStream in) {
+ assert in != null;
+
+ if (err != null) {
+ createChildErrorPump(in, err);
+ }
+ }
+
+ /**
+ * Set the output stream by means of which input can be sent to the child.
+ */
+ public void setChildInputStream(final OutputStream out) {
+ assert out != null;
+
+ if (in != null) {
+ inputPump = createInputPump(in, out, true);
+ } else {
+ try {
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Attach to a child streams from the given process.
+ *
+ * @param p The process to attach to.
+ */
+ public void attach(final Process p) {
+ assert p != null;
+
+ setChildInputStream(p.getOutputStream());
+ setChildOutputStream(p.getInputStream());
+ setChildErrorStream(p.getErrorStream());
+ }
+
+ /**
+ * Start pumping the streams.
+ */
+ public void start() {
+ if (outputPump != null) {
+ Thread thread = new Thread(outputPump);
+ thread.setDaemon(true);
+ thread.setName("Output pump for " + this.name);
+ thread.start();
+ }
+
+ if (errorPump != null) {
+ Thread thread = new Thread(errorPump);
+ thread.setDaemon(true);
+ thread.setName("Error pump for " + this.name);
+ thread.start();
+ }
+
+ if (inputPump != null) {
+ Thread thread = new Thread(inputPump);
+ thread.setDaemon(true);
+ thread.setName("Input pump for " + this.name);
+ thread.start();
+ }
+ }
+
+ /**
+ * Stop pumping the streams.
+ */
+ public void stop() {
+ if (outputPump != null) {
+ try {
+ outputPump.stop();
+ outputPump.waitFor();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ if (errorPump != null) {
+ try {
+ errorPump.stop();
+ errorPump.waitFor();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ if (inputPump != null) {
+ inputPump.stop();
+ }
+
+ try {
+ err.flush();
+ } catch (IOException e) {
+ }
+ try {
+ out.flush();
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Create the pump to handle child output.
+ */
+ protected void createChildOutputPump(final InputStream in, final OutputStream out) {
+ assert in != null;
+ assert out != null;
+
+ outputPump = createPump(in, out);
+ }
+
+ /**
+ * Create the pump to handle error output.
+ */
+ protected void createChildErrorPump(final InputStream in, final OutputStream out) {
+ assert in != null;
+ assert out != null;
+
+ errorPump = createPump(in, out);
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the given output stream.
+ */
+ protected StreamPumper createPump(final InputStream in, final OutputStream out) {
+ assert in != null;
+ assert out != null;
+
+ return createPump(in, out, false);
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the
+ * given output stream.
+ *
+ * @param in The input stream to copy from.
+ * @param out The output stream to copy to.
+ * @param closeWhenExhausted If true close the inputstream.
+ * @return A thread object that does the pumping.
+ */
+ protected StreamPumper createPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
+ assert in != null;
+ assert out != null;
+
+ StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
+ return pumper;
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the
+ * given output stream. Used for standard input.
+ */
+ protected StreamPumper createInputPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
+ assert in != null;
+ assert out != null;
+
+ StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
+ pumper.setAutoflush(true);
+ return pumper;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
new file mode 100644
index 0000000..330d8fc
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/StreamPumper.java
@@ -0,0 +1,195 @@
+/*
+ * 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.wrapper.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+//
+// Based on Apache Ant 1.6.5
+//
+
+/**
+ * Copies all data from an input stream to an output stream.
+ */
+public class StreamPumper implements Runnable {
+
+ private InputStream in;
+
+ private OutputStream out;
+
+ private volatile boolean finish;
+
+ private volatile boolean finished;
+
+ private boolean closeWhenExhausted;
+
+ private boolean autoflush;
+
+ private Exception exception;
+
+ private int bufferSize = 128;
+
+ private boolean started;
+
+ /**
+ * Create a new stream pumper.
+ *
+ * @param in Input stream to read data from
+ * @param out Output stream to write data to.
+ * @param closeWhenExhausted If true, the output stream will be closed when
+ * the input is exhausted.
+ */
+ public StreamPumper(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
+ assert in != null;
+ assert out != null;
+
+ this.in = in;
+ this.out = out;
+ this.closeWhenExhausted = closeWhenExhausted;
+ }
+
+ /**
+ * Create a new stream pumper.
+ *
+ * @param in Input stream to read data from
+ * @param out Output stream to write data to.
+ */
+ public StreamPumper(final InputStream in, final OutputStream out) {
+ this(in, out, false);
+ }
+
+ /**
+ * Set whether data should be flushed through to the output stream.
+ *
+ * @param autoflush If true, push through data; if false, let it be buffered
+ */
+ public void setAutoflush(boolean autoflush) {
+ this.autoflush = autoflush;
+ }
+
+ /**
+ * Copies data from the input stream to the output stream.
+ * <p/>
+ * Terminates as soon as the input stream is closed or an error occurs.
+ */
+ public void run() {
+ synchronized (this) {
+ started = true;
+ }
+ finished = false;
+ finish = false;
+
+ final byte[] buf = new byte[bufferSize];
+
+ int length;
+ try {
+ while ((length = in.read(buf)) > 0 && !finish) {
+ out.write(buf, 0, length);
+ if (autoflush) {
+ out.flush();
+ }
+ }
+ out.flush();
+ } catch (Exception e) {
+ synchronized (this) {
+ exception = e;
+ }
+ } finally {
+ if (closeWhenExhausted) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+ finished = true;
+
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Tells whether the end of the stream has been reached.
+ *
+ * @return true If the stream has been exhausted.
+ */
+ public boolean isFinished() {
+ return finished;
+ }
+
+ /**
+ * This method blocks until the stream pumper finishes.
+ *
+ * @see #isFinished()
+ */
+ public synchronized void waitFor() throws InterruptedException {
+ while (!isFinished()) {
+ wait();
+ }
+ }
+
+ /**
+ * Set the size in bytes of the read buffer.
+ *
+ * @param bufferSize the buffer size to use.
+ * @throws IllegalStateException if the StreamPumper is already running.
+ */
+ public synchronized void setBufferSize(final int bufferSize) {
+ if (started) {
+ throw new IllegalStateException("Cannot set buffer size on a running StreamPumper");
+ }
+
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Get the size in bytes of the read buffer.
+ *
+ * @return The size of the read buffer.
+ */
+ public synchronized int getBufferSize() {
+ return bufferSize;
+ }
+
+ /**
+ * Get the exception encountered, if any.
+ *
+ * @return The Exception encountered; or null if there was none.
+ */
+ public synchronized Exception getException() {
+ return exception;
+ }
+
+ /**
+ * Stop the pumper as soon as possible.
+ * <p/>
+ * Note that it may continue to block on the input stream
+ * but it will really stop the thread as soon as it gets EOF
+ * or any byte, and it will be marked as finished.
+ */
+ public synchronized void stop() {
+ finish = true;
+
+ notifyAll();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
new file mode 100644
index 0000000..ad4aa4a
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/WrapperServiceImpl.java
@@ -0,0 +1,450 @@
+/*
+ * 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.wrapper.internal;
+
+import org.apache.karaf.wrapper.WrapperService;
+import org.fusesource.jansi.Ansi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Default implementation of the wrapper service.
+ */
+public class WrapperServiceImpl implements WrapperService {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(WrapperServiceImpl.class);
+
+ public void install() throws Exception {
+ install("karaf", "karaf", "", "AUTO_START");
+ }
+
+ public File[] install(String name, String displayName, String description, String startType) throws Exception {
+
+ File base = new File(System.getProperty("karaf.base"));
+ File etc = new File(System.getProperty("karaf.etc"));
+ File bin = new File(base, "bin");
+ File lib = new File(base, "lib");
+
+ if (name == null) {
+ name = base.getName();
+ }
+
+ HashMap<String, String> props = new HashMap<String, String>();
+ props.put("${java.home}", System.getenv("JAVA_HOME"));
+ props.put("${karaf.home}", System.getProperty("karaf.home"));
+ props.put("${karaf.base}", base.getPath());
+ props.put("${karaf.data}", System.getProperty("karaf.data"));
+ props.put("${karaf.etc}", System.getProperty("karaf.etc"));
+ props.put("${name}", name);
+ props.put("${displayName}", displayName);
+ props.put("${description}", description);
+ props.put("${startType}", startType);
+
+ String os = System.getProperty("os.name", "Unknown");
+ File serviceFile = null;
+ File wrapperConf = null;
+ if (os.startsWith("Win")) {
+ String arch = System.getProperty("os.arch");
+ if (arch.equalsIgnoreCase("amd64") || arch.equalsIgnoreCase("x86_64")) {
+ mkdir(bin);
+
+ copyResourceTo(new File(bin, name + "-wrapper.exe"), "windows64/karaf-wrapper.exe", false);
+
+ serviceFile = new File(bin, name + "-service.bat");
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+
+ copyFilteredResourceTo(wrapperConf, "windows64/karaf-wrapper.conf", props);
+ copyFilteredResourceTo(serviceFile, "windows64/karaf-service.bat", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "wrapper.dll"), "windows64/wrapper.dll", false);
+ } else {
+ mkdir(bin);
+
+ copyResourceTo(new File(bin, name + "-wrapper.exe"), "windows/karaf-wrapper.exe", false);
+
+ serviceFile = new File(bin, name + "-service.bat");
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+
+ copyFilteredResourceTo(wrapperConf, "windows/karaf-wrapper.conf", props);
+ copyFilteredResourceTo(serviceFile, "windows/karaf-service.bat", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "wrapper.dll"), "windows/wrapper.dll", false);
+ }
+ } else if (os.startsWith("Mac OS X")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "macosx/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ File plistConf = new File(bin, "org.apache.karaf."+ name + ".plist");
+ copyFilteredResourceTo(plistConf, "macosx/org.apache.karaf.KARAF.plist", props);
+
+ mkdir(lib);
+
+ copyResourceTo(new File(lib, "libwrapper.jnilib"), "macosx/libwrapper.jnilib", false);
+ } else if (os.startsWith("Linux")) {
+ String arch = System.getProperty("os.arch");
+ if (arch.equalsIgnoreCase("amd64") || arch.equalsIgnoreCase("x86_64")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "linux64/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "linux64/libwrapper.so", false);
+ } else {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "linux/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "linux/libwrapper.so", false);
+ }
+ } else if (os.startsWith("AIX")) {
+ String arch = System.getProperty("os.arch");
+ if (arch.equalsIgnoreCase("ppc64")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "aix/ppc64/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.a"), "aix/ppc64/libwrapper.a", false);
+ } else {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "aix/ppc32/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.a"), "aix/ppc32/libwrapper.a", false);
+ }
+ } else if (os.startsWith("Solaris") || os.startsWith("SunOS")) {
+ String arch = System.getProperty("os.arch");
+ if (arch.equalsIgnoreCase("sparc")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "solaris/sparc64/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "solaris/sparc64/libwrapper.so", false);
+ } else if (arch.equalsIgnoreCase("x86")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "solaris/x86/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "solaris/x86/libwrapper.so", false);
+ } else if (arch.equalsIgnoreCase("x86_64")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "solaris/x86_64/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "solaris/x86_64/libwrapper.so", false);
+ } else {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "solaris/sparc32/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.so"), "solaris/sparc32/libwrapper.so", false);
+ }
+ } else if (os.startsWith("HP-UX") || os.startsWith("HPUX")) {
+ mkdir(bin);
+
+ File file = new File(bin, name + "-wrapper");
+ copyResourceTo(file, "hpux/parisc64/karaf-wrapper", false);
+ chmod(file, "a+x");
+
+ serviceFile = new File(bin, name + "-service");
+ copyFilteredResourceTo(serviceFile, "unix/karaf-service", props);
+ chmod(serviceFile, "a+x");
+
+ wrapperConf = new File(etc, name + "-wrapper.conf");
+ copyFilteredResourceTo(wrapperConf, "unix/karaf-wrapper.conf", props);
+
+ mkdir(lib);
+ copyResourceTo(new File(lib, "libwrapper.sl"), "hpux/parisc64/libwrapper.sl", false);
+ } else {
+ throw new IllegalStateException("Your operating system '" + os + "' is not currently supported.");
+ }
+
+ // install the wrapper jar to the lib directory
+ mkdir(lib);
+ copyResourceTo(new File(lib, "karaf-wrapper.jar"), "all/karaf-wrapper.jar", false);
+ mkdir(etc);
+
+ createJar(new File(lib, "karaf-wrapper-main.jar"), "org/apache/karaf/wrapper/internal/Main.class");
+
+ File[] wrapperPaths = new File[2];
+ wrapperPaths[0] = wrapperConf;
+ wrapperPaths[1] = serviceFile;
+
+ return wrapperPaths;
+ }
+
+ private void mkdir(File file) {
+ if (!file.exists()) {
+ LOGGER.info("Creating missing directory: {}", file.getPath());
+ System.out.println(Ansi.ansi().a("Creating missing directory: ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(file.getPath()).a(Ansi.Attribute.RESET).toString());
+ file.mkdirs();
+ }
+ }
+
+ private void copyResourceTo(File outFile, String resource, boolean text) throws Exception {
+ if (!outFile.exists()) {
+ LOGGER.info("Creating file: {}", outFile.getPath());
+ System.out.println(Ansi.ansi().a("Creating file: ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
+ InputStream is = WrapperServiceImpl.class.getResourceAsStream(resource);
+ if (is == null) {
+ throw new IllegalArgumentException("Resource " + resource + " doesn't exist");
+ }
+ try {
+ if (text) {
+ // read it line at a time so what we can use the platform line ending when we write it out
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ LOGGER.info("writing: {}", line);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } else {
+ // binary resource so just write it out the way it came in
+ FileOutputStream out = new FileOutputStream(outFile);
+ try {
+ int c = 0;
+ while ((c = is.read()) >= 0) {
+ out.write(c);
+ }
+ } finally {
+ safeClose(out);
+ }
+ }
+ } finally {
+ safeClose(is);
+ }
+ } else {
+ LOGGER.warn("File already exists. Move it out of the way if you wish to recreate it: {}", outFile.getPath());
+ System.out.println(Ansi.ansi()
+ .fg(Ansi.Color.RED).a("File already exists").a(Ansi.Attribute.RESET)
+ .a(". Move it out of the way if you wish to recreate it: ").a(outFile.getPath()).toString());
+ }
+ }
+
+ private void copyFilteredResourceTo(File outFile, String resource, HashMap<String, String> props) throws Exception {
+ if (!outFile.exists()) {
+ LOGGER.info("Creating file: {}", outFile.getPath());
+ System.out.println(Ansi.ansi().a("Creating file: ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
+ InputStream is = WrapperServiceImpl.class.getResourceAsStream(resource);
+ if (is == null) {
+ throw new IllegalArgumentException("Resource " + resource + " doesn't exist");
+ }
+ try {
+ // read it line at a time so that we can use the platform line ending when we write it out
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ line = filter(line, props);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(is);
+ }
+ } else {
+ LOGGER.warn("File already exists. Move it out of the way if you wish to recreate it: {}", outFile.getPath());
+ System.out.println(Ansi.ansi()
+ .fg(Ansi.Color.RED).a("File already exists").a(Ansi.Attribute.RESET)
+ .a(". Move it out of the way if you wish to recreate it: ").a(outFile.getPath()).toString());
+ }
+ }
+
+ private void safeClose(InputStream is) throws IOException {
+ if (is == null)
+ return;
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ // nothing to do
+ }
+ }
+
+ private void safeClose(OutputStream is) throws IOException {
+ if (is == null)
+ return;
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ // nothing to do
+ }
+ }
+
+ private String filter(String line, HashMap<String, String> props) {
+ for (Map.Entry<String, String> i : props.entrySet()) {
+ int p1 = line.indexOf(i.getKey());
+ if (p1 >= 0) {
+ String l1 = line.substring(0, p1);
+ String l2 = line.substring(p1 + i.getKey().length());
+ line = l1 + i.getValue() + l2;
+ }
+ }
+ return line;
+ }
+
+ private int chmod(File serviceFile, String mode) throws Exception {
+ ProcessBuilder builder = new ProcessBuilder();
+ builder.command("chmod", mode, serviceFile.getCanonicalPath());
+ Process p = builder.start();
+
+ PumpStreamHandler handler = new PumpStreamHandler(System.in, System.out, System.err);
+ handler.attach(p);
+ handler.start();
+ int status = p.waitFor();
+ handler.stop();
+ return status;
+ }
+
+ private void createJar(File outFile, String resource) throws Exception {
+ if (!outFile.exists()) {
+ LOGGER.info("Creating file: {}", outFile.getPath());
+ System.out.println(Ansi.ansi().a("Creating file: ")
+ .a(Ansi.Attribute.INTENSITY_BOLD).a(outFile.getPath()).a(Ansi.Attribute.RESET).toString());
+ InputStream is = getClass().getClassLoader().getResourceAsStream(resource);
+ if (is == null) {
+ throw new IllegalStateException("Resource " + resource + " not found!");
+ }
+ try {
+ JarOutputStream jar = new JarOutputStream(new FileOutputStream(outFile));
+ int idx = resource.indexOf('/');
+ while (idx > 0) {
+ jar.putNextEntry(new ZipEntry(resource.substring(0, idx)));
+ jar.closeEntry();
+ idx = resource.indexOf('/', idx + 1);
+ }
+ jar.putNextEntry(new ZipEntry(resource));
+ int c;
+ while ((c = is.read()) >= 0) {
+ jar.write(c);
+ }
+ jar.closeEntry();
+ jar.close();
+ } finally {
+ safeClose(is);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
new file mode 100644
index 0000000..0cb8242
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/internal/osgi/Activator.java
@@ -0,0 +1,36 @@
+/*
+ * 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.wrapper.internal.osgi;
+
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.wrapper.WrapperService;
+import org.apache.karaf.wrapper.internal.WrapperServiceImpl;
+import org.apache.karaf.wrapper.management.internal.WrapperMBeanImpl;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doStart() throws Exception {
+ WrapperService wrapperService = new WrapperServiceImpl();
+ register(WrapperService.class, wrapperService);
+
+ WrapperMBeanImpl wrapperMBean = new WrapperMBeanImpl();
+ wrapperMBean.setWrapperService(wrapperService);
+ registerMBean(wrapperMBean, "type=wrapper");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java b/wrapper/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
new file mode 100644
index 0000000..937bfe2
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/management/WrapperMBean.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wrapper.management;
+
+import javax.management.MBeanException;
+import java.io.File;
+
+/**
+ * Describe the WrapperMBean.
+ */
+public interface WrapperMBean {
+
+ /**
+ * Install the service wrapper.
+ *
+ * @throws MBeanException in case of installation failure.
+ */
+ void install() throws MBeanException;
+
+ /**
+ * Install the service wrapper.
+ *
+ * @param name the service name.
+ * @param displayName the service display name.
+ * @param description the service description.
+ * @param startType the start type.
+ * @return the wrapper configuration (index 0) and service files (index 1).
+ * @throws MBeanException in case of installation failure.
+ */
+ File[] install(String name, String displayName, String description, String startType) throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java
----------------------------------------------------------------------
diff --git a/wrapper/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java b/wrapper/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.java
new file mode 100644
index 0000000..1523015
--- /dev/null
+++ b/wrapper/src/main/java/org/apache/karaf/wrapper/management/internal/WrapperMBeanImpl.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.wrapper.management.internal;
+
+import org.apache.karaf.wrapper.WrapperService;
+import org.apache.karaf.wrapper.management.WrapperMBean;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import java.io.File;
+
+/**
+ * Implementation of the wrapper MBean.
+ */
+public class WrapperMBeanImpl extends StandardMBean implements WrapperMBean {
+
+ private WrapperService wrapperService;
+
+ public WrapperMBeanImpl() throws NotCompliantMBeanException {
+ super(WrapperMBean.class);
+ }
+
+ public void setWrapperService(WrapperService wrapperService) {
+ this.wrapperService = wrapperService;
+ }
+
+ public WrapperService getWrapperService() {
+ return this.wrapperService;
+ }
+
+ public void install() throws MBeanException {
+ try {
+ wrapperService.install();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public File[] install(String name, String displayName, String description, String startType) throws MBeanException {
+ try {
+ return wrapperService.install(name, displayName, description, startType);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/META-INF/services/org/apache/karaf/shell/commands b/wrapper/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
new file mode 100644
index 0000000..73b329d
--- /dev/null
+++ b/wrapper/src/main/resources/META-INF/services/org/apache/karaf/shell/commands
@@ -0,0 +1,18 @@
+##---------------------------------------------------------------------------
+## 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.
+##---------------------------------------------------------------------------
+org.apache.karaf.wrapper.internal.WrapperServiceImpl
+org.apache.karaf.wrapper.commands.Install
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/OSGI-INF/bundle.info b/wrapper/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..8462cc5
--- /dev/null
+++ b/wrapper/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,16 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle provides support of the service wrapper, which allows for starting/stopping Karaf as a system service.
+
+h1. See also
+
+Service Wrapper - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper
new file mode 100755
index 0000000..5215c2e
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a
new file mode 100755
index 0000000..4bcc342
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc32/libwrapper.a differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper
new file mode 100755
index 0000000..6ba0351
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a
new file mode 100755
index 0000000..b569e3f
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/aix/ppc64/libwrapper.a differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar
new file mode 100644
index 0000000..4db355b
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/all/karaf-wrapper.jar differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper
new file mode 100755
index 0000000..ad883d7
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl
new file mode 100755
index 0000000..08adc52
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/hpux/parisc64/libwrapper.sl differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper
new file mode 100644
index 0000000..7e00645
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so
new file mode 100644
index 0000000..2cc4ab3
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper
new file mode 100644
index 0000000..3128b95
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so
new file mode 100644
index 0000000..24197bf
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/linux64/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper
new file mode 100644
index 0000000..0165db0
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib
new file mode 100644
index 0000000..6356705
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/libwrapper.jnilib differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
new file mode 100644
index 0000000..1c18918
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/macosx/org.apache.karaf.KARAF.plist
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+ -->
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ProcessType</key>
+ <string>Background</string>
+ <key>KeepAlive</key>
+ <false/>
+ <key>Label</key>
+ <string>org.apache.karaf.KARAF</string>
+ <key>ProgramArguments</key>
+ <array>
+ <!-- path to your KARAF-service wrapper -->
+ <string>${karaf.home}/bin/${name}-service</string>
+ <string>console</string>
+ </array>
+ <key>RunAtLoad</key>
+ <true/>
+</dict>
+</plist>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper
new file mode 100755
index 0000000..7cac208
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so
new file mode 100755
index 0000000..4093262
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc32/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper
new file mode 100755
index 0000000..91257c6
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so
new file mode 100755
index 0000000..008bef6
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/sparc64/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper
new file mode 100755
index 0000000..bdec254
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so
new file mode 100755
index 0000000..963ff49
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper
new file mode 100755
index 0000000..6bd165e
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/karaf-wrapper differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so
new file mode 100755
index 0000000..0d52ffa
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/solaris/x86_64/libwrapper.so differ
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
new file mode 100644
index 0000000..a7ca8bb
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-service
@@ -0,0 +1,557 @@
+#! /bin/sh
+
+# ------------------------------------------------------------------------
+# 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.
+# ------------------------------------------------------------------------
+
+# If require, set the JAVA_HOME to launch the wrapper
+#
+#JAVA_HOME=
+#
+
+# Application
+APP_NAME="${name}"
+APP_LONG_NAME="${displayName}"
+
+# Wrapper
+WRAPPER_CMD="${karaf.base}/bin/${APP_NAME}-wrapper"
+WRAPPER_CONF="${karaf.etc}/${APP_NAME}-wrapper.conf"
+
+# Priority at which to run the wrapper. See "man nice" for valid priorities.
+# nice is only used if a priority is specified.
+PRIORITY=
+
+# Location of the data folder.
+DATADIR="${karaf.data}"
+
+# Location of the pid file.
+PIDDIR="${karaf.data}"
+
+# If uncommented, causes the Wrapper to be shutdown using an anchor file.
+# When launched with the 'start' command, it will also ignore all INT and
+# TERM signals.
+#IGNORE_SIGNALS=true
+
+# If specified, the Wrapper will be run as the specified user.
+# IMPORTANT - Make sure that the user has the required privileges to write
+# the PID file and wrapper.log files. Failure to be able to write the log
+# file will cause the Wrapper to exit without any way to write out an error
+# message.
+# NOTE - This will set the user which is used to run the Wrapper as well as
+# the JVM and is not useful in situations where a privileged resource or
+# port needs to be allocated prior to the user being changed.
+#RUN_AS_USER=
+
+# The following two lines are used by the chkconfig command. Change as is
+# appropriate for your application. They should remain commented.
+# chkconfig: 2345 20 80
+# description: ${displayName}
+
+# Do not modify anything beyond this point
+#-----------------------------------------------------------------------------
+
+# Get the fully qualified path to the script
+case $0 in
+ /*)
+ SCRIPT="$0"
+ ;;
+ *)
+ PWD=`pwd`
+ SCRIPT="$PWD/$0"
+ ;;
+esac
+
+# Resolve the true real path without any sym links.
+CHANGED=true
+while [ "X$CHANGED" != "X" ]
+do
+ # Change spaces to ":" so the tokens can be parsed.
+ SCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'`
+ # Get the real path to this script, resolving any symbolic links
+ TOKENS=`echo $SCRIPT | sed -e 's;/; ;g'`
+ REALPATH=
+ for C in $TOKENS; do
+ REALPATH="$REALPATH/$C"
+ while [ -h "$REALPATH" ] ; do
+ LS="`ls -ld "$REALPATH"`"
+ LINK="`expr "$LS" : '.*-> \(.*\)$'`"
+ if expr "$LINK" : '/.*' > /dev/null; then
+ REALPATH="$LINK"
+ else
+ REALPATH="`dirname "$REALPATH"`""/$LINK"
+ fi
+ done
+ done
+ # Change ":" chars back to spaces.
+ REALPATH=`echo $REALPATH | sed -e 's;:; ;g'`
+
+ if [ "$REALPATH" = "$SCRIPT" ]
+ then
+ CHANGED=""
+ else
+ SCRIPT="$REALPATH"
+ fi
+done
+
+# Change the current directory to the location of the script
+cd "`dirname "$REALPATH"`"
+REALDIR=`pwd`
+
+# If the PIDDIR is relative, set its value relative to the full REALPATH to avoid problems if
+# the working directory is later changed.
+FIRST_CHAR=`echo $PIDDIR | cut -c1,1`
+if [ "$FIRST_CHAR" != "/" ]
+then
+ PIDDIR=$REALDIR/$PIDDIR
+fi
+# Same test for WRAPPER_CMD
+FIRST_CHAR=`echo $WRAPPER_CMD | cut -c1,1`
+if [ "$FIRST_CHAR" != "/" ]
+then
+ WRAPPER_CMD=$REALDIR/$WRAPPER_CMD
+fi
+# Same test for WRAPPER_CONF
+FIRST_CHAR=`echo $WRAPPER_CONF | cut -c1,1`
+if [ "$FIRST_CHAR" != "/" ]
+then
+ WRAPPER_CONF=$REALDIR/$WRAPPER_CONF
+fi
+
+# Process ID
+ANCHORFILE="$PIDDIR/$APP_NAME.anchor"
+PIDFILE="$PIDDIR/$APP_NAME.pid"
+LOCKDIR="/var/lock/subsys"
+LOCKFILE="$LOCKDIR/$APP_NAME"
+pid=""
+
+# Resolve the location of the 'ps' command
+PSEXE="/usr/bin/ps"
+if [ ! -x $PSEXE ]
+then
+ PSEXE="/bin/ps"
+ if [ ! -x $PSEXE ]
+ then
+ echo "Unable to locate 'ps'."
+ echo "Please report this message along with the location of the command on your system."
+ exit 1
+ fi
+fi
+
+# Resolve the os
+DIST_OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]`
+case "$DIST_OS" in
+ 'sunos')
+ DIST_OS="solaris"
+ ;;
+ 'hp-ux' | 'hp-ux64')
+ DIST_OS="hpux"
+ ;;
+ 'darwin')
+ DIST_OS="macosx"
+ ;;
+ 'unix_sv')
+ DIST_OS="unixware"
+ ;;
+esac
+
+# Resolve the architecture
+DIST_ARCH=`uname -p | tr [:upper:] [:lower:] | tr -d [:blank:]`
+if [ "$DIST_ARCH" = "unknown" ]
+then
+ DIST_ARCH=`uname -m | tr [:upper:] [:lower:] | tr -d [:blank:]`
+fi
+case "$DIST_ARCH" in
+ 'amd64' | 'ia32' | 'ia64' | 'i386' | 'i486' | 'i586' | 'i686' | 'x86_64')
+ DIST_ARCH="x86"
+ ;;
+ 'ip27')
+ DIST_ARCH="mips"
+ ;;
+ 'power' | 'powerpc' | 'power_pc' | 'ppc64')
+ DIST_ARCH="ppc"
+ ;;
+ 'pa_risc' | 'pa-risc')
+ DIST_ARCH="parisc"
+ ;;
+ 'sun4u' | 'sparcv9')
+ DIST_ARCH="sparc"
+ ;;
+ '9000/800')
+ DIST_ARCH="parisc"
+ ;;
+esac
+
+# Decide on the wrapper binary to use.
+# If a 32-bit wrapper binary exists then it will work on 32 or 64 bit
+# platforms, if the 64-bit binary exists then the distribution most
+# likely wants to use long names. Otherwise, look for the default.
+# For macosx, we also want to look for universal binaries.
+WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
+if [ -x $WRAPPER_TEST_CMD ]
+then
+ WRAPPER_CMD="$WRAPPER_TEST_CMD"
+else
+ if [ "$DIST_OS" = "macosx" ]
+ then
+ WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-32"
+ if [ -x $WRAPPER_TEST_CMD ]
+ then
+ WRAPPER_CMD="$WRAPPER_TEST_CMD"
+ else
+ WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
+ if [ -x $WRAPPER_TEST_CMD ]
+ then
+ WRAPPER_CMD="$WRAPPER_TEST_CMD"
+ else
+ WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-64"
+ if [ -x $WRAPPER_TEST_CMD ]
+ then
+ WRAPPER_CMD="$WRAPPER_TEST_CMD"
+ else
+ if [ ! -x $WRAPPER_CMD ]
+ then
+ echo "Unable to locate any of the following binaries:"
+ echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
+ echo " $WRAPPER_CMD-$DIST_OS-universal-32"
+ echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
+ echo " $WRAPPER_CMD-$DIST_OS-universal-64"
+ echo " $WRAPPER_CMD"
+ exit 1
+ fi
+ fi
+ fi
+ fi
+ else
+ WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
+ if [ -x $WRAPPER_TEST_CMD ]
+ then
+ WRAPPER_CMD="$WRAPPER_TEST_CMD"
+ else
+ if [ ! -x $WRAPPER_CMD ]
+ then
+ echo "Unable to locate any of the following binaries:"
+ echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
+ echo " $WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
+ echo " $WRAPPER_CMD"
+ exit 1
+ fi
+ fi
+ fi
+fi
+
+# Build the nice clause
+if [ "X$PRIORITY" = "X" ]
+then
+ CMDNICE=""
+else
+ CMDNICE="nice -$PRIORITY"
+fi
+
+# Build the anchor file clause.
+if [ "X$IGNORE_SIGNALS" = "X" ]
+then
+ ANCHORPROP=
+ IGNOREPROP=
+else
+ ANCHORPROP=wrapper.anchorfile=$ANCHORFILE
+ IGNOREPROP=wrapper.ignore_signals=TRUE
+fi
+
+# Build the lock file clause. Only create a lock file if the lock directory exists on this platform.
+if [ -d $LOCKDIR ]
+then
+ LOCKPROP=wrapper.lockfile=$LOCKFILE
+else
+ LOCKPROP=
+fi
+
+checkUser() {
+ # Check the configured user. If necessary rerun this script as the desired user.
+ if [ "X$RUN_AS_USER" != "X" ]
+ then
+ # Resolve the location of the 'id' command
+ IDEXE="/usr/xpg4/bin/id"
+ if [ ! -x $IDEXE ]
+ then
+ IDEXE="/usr/bin/id"
+ if [ ! -x $IDEXE ]
+ then
+ echo "Unable to locate 'id'."
+ echo "Please report this message along with the location of the command on your system."
+ exit 1
+ fi
+ fi
+
+ if [ "`$IDEXE -u -n`" = "$RUN_AS_USER" ]
+ then
+ # Already running as the configured user. Avoid password prompts by not calling su.
+ RUN_AS_USER=""
+ fi
+ fi
+ if [ "X$RUN_AS_USER" != "X" ]
+ then
+ # If LOCKPROP and $RUN_AS_USER are defined then the new user will most likely not be
+ # able to create the lock file. The Wrapper will be able to update this file once it
+ # is created but will not be able to delete it on shutdown. If $2 is defined then
+ # the lock file should be created for the current command
+ if [ "X$LOCKPROP" != "X" ]
+ then
+ if [ "X$2" != "X" ]
+ then
+ # Resolve the primary group
+ RUN_AS_GROUP=`groups $RUN_AS_USER | awk '{print $3}' | tail -1`
+ if [ "X$RUN_AS_GROUP" = "X" ]
+ then
+ RUN_AS_GROUP=$RUN_AS_USER
+ fi
+ touch $LOCKFILE
+ chown $RUN_AS_USER:$RUN_AS_GROUP $LOCKFILE
+ fi
+ fi
+
+ # Still want to change users, recurse. This means that the user will only be
+ # prompted for a password once.
+ su -m $RUN_AS_USER -s /bin/sh -c "$REALPATH $1"
+ RETVAL=$?
+
+ # Now that we are the original user again, we may need to clean up the lock file.
+ if [ "X$LOCKPROP" != "X" ]
+ then
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ # Wrapper is not running so make sure the lock file is deleted.
+ if [ -f $LOCKFILE ]
+ then
+ rm $LOCKFILE
+ fi
+ fi
+ fi
+
+ exit $RETVAL
+ fi
+}
+
+getpid() {
+ if [ -f $PIDFILE ]
+ then
+ if [ -r $PIDFILE ]
+ then
+ pid=`cat $PIDFILE`
+ if [ "X$pid" != "X" ]
+ then
+ # It is possible that 'a' process with the pid exists but that it is not the
+ # correct process. This can happen in a number of cases, but the most
+ # common is during system startup after an unclean shutdown.
+ # The ps statement below looks for the specific wrapper command running as
+ # the pid. If it is not found then the pid file is considered to be stale.
+ if [ "$DIST_OS" = "solaris" ]
+ then
+ pidtest=`$PSEXE -p $pid -o comm | grep $WRAPPER_CMD | tail -1`
+ else
+ pidtest=`$PSEXE -p $pid -o command | grep $WRAPPER_CMD | tail -1`
+ fi
+ if [ "X$pidtest" = "X" ]
+ then
+ # This is a stale pid file.
+ rm -f $PIDFILE
+ echo "Removed stale pid file: $PIDFILE"
+ pid=""
+ fi
+ fi
+ else
+ echo "Cannot read $PIDFILE."
+ exit 1
+ fi
+ fi
+}
+
+testpid() {
+ pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
+ if [ "X$pid" = "X" ]
+ then
+ # Process is gone so remove the pid file.
+ rm -f $PIDFILE
+ pid=""
+ fi
+}
+
+console() {
+ echo "Running $APP_LONG_NAME..."
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ COMMAND_LINE="$CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.syslog.ident=$APP_NAME wrapper.pidfile=$PIDFILE $ANCHORPROP $LOCKPROP"
+ exec $COMMAND_LINE
+ else
+ echo "$APP_LONG_NAME is already running."
+ exit 1
+ fi
+}
+
+start() {
+ echo "Starting $APP_LONG_NAME..."
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ if [ ! -d $DATADIR ]; then
+ mkdir $DATADIR
+ fi
+ if [ ! -d $DATADIR/log ]; then
+ mkdir $DATADIR/log
+ fi
+ COMMAND_LINE="$CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.syslog.ident=$APP_NAME wrapper.pidfile=$PIDFILE wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $LOCKPROP"
+ exec $COMMAND_LINE
+ else
+ echo "$APP_LONG_NAME is already running."
+ exit 1
+ fi
+}
+
+stopit() {
+ echo "Stopping $APP_LONG_NAME..."
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ echo "$APP_LONG_NAME was not running."
+ else
+ if [ "X$IGNORE_SIGNALS" = "X" ]
+ then
+ # Running so try to stop it.
+ kill $pid
+ if [ $? -ne 0 ]
+ then
+ # An explanation for the failure should have been given
+ echo "Unable to stop $APP_LONG_NAME."
+ exit 1
+ fi
+ else
+ rm -f $ANCHORFILE
+ if [ -f $ANCHORFILE ]
+ then
+ # An explanation for the failure should have been given
+ echo "Unable to stop $APP_LONG_NAME."
+ exit 1
+ fi
+ fi
+
+ # We can not predict how long it will take for the wrapper to
+ # actually stop as it depends on settings in wrapper.conf.
+ # Loop until it does.
+ savepid=$pid
+ CNT=0
+ TOTCNT=0
+ while [ "X$pid" != "X" ]
+ do
+ # Show a waiting message every 5 seconds.
+ if [ "$CNT" -lt "5" ]
+ then
+ CNT=`expr $CNT + 1`
+ else
+ echo "Waiting for $APP_LONG_NAME to exit..."
+ CNT=0
+ fi
+ TOTCNT=`expr $TOTCNT + 1`
+
+ sleep 1
+
+ testpid
+ done
+
+ pid=$savepid
+ testpid
+ if [ "X$pid" != "X" ]
+ then
+ echo "Failed to stop $APP_LONG_NAME."
+ exit 1
+ else
+ echo "Stopped $APP_LONG_NAME."
+ fi
+ fi
+}
+
+status() {
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ echo "$APP_LONG_NAME is not running."
+ exit 1
+ else
+ echo "$APP_LONG_NAME is running ($pid)."
+ exit 0
+ fi
+}
+
+dump() {
+ echo "Dumping $APP_LONG_NAME..."
+ getpid
+ if [ "X$pid" = "X" ]
+ then
+ echo "$APP_LONG_NAME was not running."
+
+ else
+ kill -3 $pid
+
+ if [ $? -ne 0 ]
+ then
+ echo "Failed to dump $APP_LONG_NAME."
+ exit 1
+ else
+ echo "Dumped $APP_LONG_NAME."
+ fi
+ fi
+}
+
+case "$1" in
+
+ 'console')
+ checkUser $1 touchlock
+ console
+ ;;
+
+ 'start')
+ checkUser $1 touchlock
+ start
+ ;;
+
+ 'stop')
+ checkUser $1
+ stopit
+ ;;
+
+ 'restart')
+ checkUser $1 touchlock
+ stopit
+ start
+ ;;
+
+ 'status')
+ checkUser $1
+ status
+ ;;
+
+ 'dump')
+ checkUser $1
+ dump
+ ;;
+
+ *)
+ echo "Usage: $0 { console | start | stop | restart | status | dump }"
+ exit 1
+ ;;
+esac
+
+exit 0
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
new file mode 100644
index 0000000..a3f98a5
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/unix/karaf-wrapper.conf
@@ -0,0 +1,135 @@
+# ------------------------------------------------------------------------
+# 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.
+# ------------------------------------------------------------------------
+
+#********************************************************************
+# Wrapper Properties
+#********************************************************************
+set.default.JAVA_HOME=${java.home}
+set.default.KARAF_HOME=${karaf.home}
+set.default.KARAF_BASE=${karaf.base}
+set.default.KARAF_DATA=${karaf.data}
+set.default.KARAF_ETC=${karaf.etc}
+
+# Java Application
+wrapper.working.dir=%KARAF_BASE%
+wrapper.java.command=%JAVA_HOME%/bin/java
+wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
+wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
+wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
+wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
+wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
+wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
+wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
+wrapper.java.library.path.1=%KARAF_HOME%/lib/
+
+# Application Parameters. Add parameters as needed starting from 1
+#wrapper.app.parameter.1=
+
+# JVM Parameters
+# note that n is the parameter number starting from 1.
+wrapper.java.additional.1=-Dkaraf.home=%KARAF_HOME%
+wrapper.java.additional.2=-Dkaraf.base=%KARAF_BASE%
+wrapper.java.additional.3=-Dkaraf.data=%KARAF_DATA%
+wrapper.java.additional.4=-Dkaraf.etc=%KARAF_ETC%
+wrapper.java.additional.5=-Dcom.sun.management.jmxremote
+wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
+wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
+wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
+wrapper.java.additional.9=-Djava.endorsed.dirs=%JAVA_HOME%/jre/lib/endorsed:%JAVA_HOME%/lib/endorsed:%KARAF_HOME%/lib/endorsed
+wrapper.java.additional.10=-Djava.ext.dirs=%JAVA_HOME%/jre/lib/ext:%JAVA_HOME%/lib/ext:%KARAF_HOME%/lib/ext
+
+# Uncomment to enable jmx
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
+
+# Uncomment to enable YourKit profiling
+#wrapper.java.additional.n=-Xrunyjpagent
+
+# Uncomment to enable remote debugging
+#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
+#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
+
+# Initial Java Heap Size (in MB)
+#wrapper.java.initmemory=3
+
+# Maximum Java Heap Size (in MB)
+wrapper.java.maxmemory=512
+
+
+#********************************************************************
+# Wrapper Logging Properties
+#********************************************************************
+# Format of output for the console. (See docs for formats)
+wrapper.console.format=PM
+
+# Log Level for console output. (See docs for log levels)
+wrapper.console.loglevel=INFO
+
+# Log file to use for wrapper output logging.
+wrapper.logfile=%KARAF_DATA%/log/wrapper.log
+
+# Format of output for the log file. (See docs for formats)
+wrapper.logfile.format=LPTM
+
+# Log Level for log file output. (See docs for log levels)
+wrapper.logfile.loglevel=INFO
+
+# Maximum size that the log file will be allowed to grow to before
+# the log is rolled. Size is specified in bytes. The default value
+# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
+# 'm' (mb) suffix. For example: 10m = 10 megabytes.
+wrapper.logfile.maxsize=10m
+
+# Maximum number of rolled log files which will be allowed before old
+# files are deleted. The default value of 0 implies no limit.
+wrapper.logfile.maxfiles=5
+
+# Log Level for sys/event log output. (See docs for log levels)
+wrapper.syslog.loglevel=NONE
+
+#********************************************************************
+# Wrapper Windows Properties
+#********************************************************************
+# Title to use when running as a console
+wrapper.console.title=${name}
+
+#********************************************************************
+# Wrapper Windows NT/2000/XP Service Properties
+#********************************************************************
+# WARNING - Do not modify any of these properties when an application
+# using this configuration file has been installed as a service.
+# Please uninstall the service before modifying this section. The
+# service can then be reinstalled.
+
+# Name of the service
+wrapper.ntservice.name=${name}
+
+# Display name of the service
+wrapper.ntservice.displayname=${displayName}
+
+# Description of the service
+wrapper.ntservice.description=${description}
+
+# Service dependencies. Add dependencies as needed starting from 1
+wrapper.ntservice.dependency.1=
+
+# Mode in which the service is installed. AUTO_START or DEMAND_START
+wrapper.ntservice.starttype=${startType}
+
+# Allow the service to interact with the desktop.
+wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
new file mode 100644
index 0000000..0dd0474
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-service.bat
@@ -0,0 +1,51 @@
+@echo off
+
+REM ------------------------------------------------------------------------
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM ------------------------------------------------------------------------
+
+setlocal
+
+set APP_NAME=${name}
+set APP_LONG_NAME=${displayName}
+set APP_BASE=${karaf.base}
+set APP_ETC=${karaf.etc}
+
+if ""%1"" == ""run"" goto doRun
+if ""%1"" == ""install"" goto doInstall
+if ""%1"" == ""remove"" goto doRemove
+
+echo Usage: karaf-service ( commands ... )
+echo commands:
+echo run Start %APP_NAME% in the current console
+echo install Install %APP_NAME% as a Windows service
+echo remove Remove the %APP_NAME% Windows service
+goto end
+
+:doRun
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -c "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:doInstall
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -i "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:doRemove
+"%APP_BASE%\bin\%APP_NAME%-wrapper.exe" -r "%APP_ETC%\%APP_NAME%-wrapper.conf"
+goto end
+
+:end
+if not "%PAUSE%" == "" pause
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
new file mode 100644
index 0000000..def40f7
--- /dev/null
+++ b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.conf
@@ -0,0 +1,135 @@
+# ------------------------------------------------------------------------
+# 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.
+# ------------------------------------------------------------------------
+
+#********************************************************************
+# Wrapper Properties
+#********************************************************************
+set.default.JAVA_HOME=${java.home}
+set.default.KARAF_HOME=${karaf.home}
+set.default.KARAF_BASE=${karaf.base}
+set.default.KARAF_DATA=${karaf.data}
+set.default.KARAF_ETC=${karaf.etc}
+
+# Java Application
+wrapper.working.dir=%KARAF_BASE%
+wrapper.java.command=%JAVA_HOME%/bin/java
+wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
+wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
+wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
+wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
+wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
+wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
+wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
+wrapper.java.library.path.1=%KARAF_HOME%/lib/
+
+# Application Parameters. Add parameters as needed starting from 1
+#wrapper.app.parameter.1=
+
+# JVM Parameters
+# note that n is the parameter number starting from 1.
+wrapper.java.additional.1=-Dkaraf.home="%KARAF_HOME%"
+wrapper.java.additional.2=-Dkaraf.base="%KARAF_BASE%"
+wrapper.java.additional.3=-Dkaraf.data="%KARAF_DATA%"
+wrapper.java.additional.4=-Dkaraf.etc="%KARAF_ETC%"
+wrapper.java.additional.5=-Dcom.sun.management.jmxremote
+wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
+wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
+wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
+wrapper.java.additional.9=-Djava.endorsed.dirs="%JAVA_HOME%/jre/lib/endorsed;%JAVA_HOME%/lib/endorsed;%KARAF_HOME%/lib/endorsed"
+wrapper.java.additional.10=-Djava.ext.dirs="%JAVA_HOME%/jre/lib/ext;%JAVA_HOME%/lib/ext;%KARAF_HOME%/lib/ext"
+
+# Uncomment to enable jmx
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
+#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
+
+# Uncomment to enable YourKit profiling
+#wrapper.java.additional.n=-Xrunyjpagent
+
+# Uncomment to enable remote debugging
+#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
+#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
+
+# Initial Java Heap Size (in MB)
+#wrapper.java.initmemory=3
+
+# Maximum Java Heap Size (in MB)
+wrapper.java.maxmemory=512
+
+
+#********************************************************************
+# Wrapper Logging Properties
+#********************************************************************
+# Format of output for the console. (See docs for formats)
+wrapper.console.format=PM
+
+# Log Level for console output. (See docs for log levels)
+wrapper.console.loglevel=INFO
+
+# Log file to use for wrapper output logging.
+wrapper.logfile=%KARAF_DATA%/log/wrapper.log
+
+# Format of output for the log file. (See docs for formats)
+wrapper.logfile.format=LPTM
+
+# Log Level for log file output. (See docs for log levels)
+wrapper.logfile.loglevel=INFO
+
+# Maximum size that the log file will be allowed to grow to before
+# the log is rolled. Size is specified in bytes. The default value
+# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
+# 'm' (mb) suffix. For example: 10m = 10 megabytes.
+wrapper.logfile.maxsize=10m
+
+# Maximum number of rolled log files which will be allowed before old
+# files are deleted. The default value of 0 implies no limit.
+wrapper.logfile.maxfiles=5
+
+# Log Level for sys/event log output. (See docs for log levels)
+wrapper.syslog.loglevel=NONE
+
+#********************************************************************
+# Wrapper Windows Properties
+#********************************************************************
+# Title to use when running as a console
+wrapper.console.title=${name}
+
+#********************************************************************
+# Wrapper Windows NT/2000/XP Service Properties
+#********************************************************************
+# WARNING - Do not modify any of these properties when an application
+# using this configuration file has been installed as a service.
+# Please uninstall the service before modifying this section. The
+# service can then be reinstalled.
+
+# Name of the service
+wrapper.ntservice.name=${name}
+
+# Display name of the service
+wrapper.ntservice.displayname=${displayName}
+
+# Description of the service
+wrapper.ntservice.description=${description}
+
+# Service dependencies. Add dependencies as needed starting from 1
+wrapper.ntservice.dependency.1=
+
+# Mode in which the service is installed. AUTO_START or DEMAND_START
+wrapper.ntservice.starttype=${startType}
+
+# Allow the service to interact with the desktop.
+wrapper.ntservice.interactive=false
http://git-wip-us.apache.org/repos/asf/karaf/blob/4182735c/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe
new file mode 100644
index 0000000..b4cfc55
Binary files /dev/null and b/wrapper/src/main/resources/org/apache/karaf/wrapper/internal/windows/karaf-wrapper.exe differ
[09/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
deleted file mode 100644
index bed8104..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/BundleManagerTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.internal.service;
-
-import org.apache.karaf.features.TestBase;
-
-public class BundleManagerTest extends TestBase {
-
- /*
- @Test
- public void testfindBundlestoRefreshWithHostToRefresh() throws Exception {
- Bundle hostBundle = createDummyBundle(12345l, "Host", headers());
- Bundle fragmentBundle = createDummyBundle(54321l, "fragment", headers(Constants.FRAGMENT_HOST, "Host"));
-
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- BundleManager bundleManager = new BundleManager(bundleContext);
-
- // Host was already installed, fragment is new
- Set<Bundle> existing = new HashSet<Bundle>(Arrays.asList(hostBundle, fragmentBundle));
- Set<Bundle> installed = new HashSet<Bundle>(Arrays.asList(fragmentBundle));
-
- replay(bundleContext);
- Set<Bundle> bundles = bundleManager.findBundlesWithFragmentsToRefresh(existing, installed);
- EasyMock.verify(bundleContext);
-
- Assert.assertEquals(1, bundles.size());
- Assert.assertEquals(hostBundle, bundles.iterator().next());
- }
-
- @Test
- public void testfindBundlestoRefreshWithOptionalPackages() throws Exception {
- Bundle exporterBundle = createDummyBundle(12345l, "exporter", headers(Constants.EXPORT_PACKAGE, "org.my.package"));
- Bundle importerBundle = createDummyBundle(54321l, "importer", headers(Constants.IMPORT_PACKAGE, "org.my.package;resolution:=optional"));
-
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- BundleManager bundleManager = new BundleManager(bundleContext);
-
- // Importer was already installed, exporter is new
- Set<Bundle> existing = new HashSet<Bundle>(Arrays.asList(importerBundle, exporterBundle));
- Set<Bundle> installed = new HashSet<Bundle>(Arrays.asList(exporterBundle));
-
- replay(bundleContext);
- Set<Bundle> bundles = bundleManager.findBundlesWithOptionalPackagesToRefresh(existing, installed);
- EasyMock.verify(bundleContext);
-
- Assert.assertEquals(1, bundles.size());
- Assert.assertEquals(importerBundle, bundles.iterator().next());
- }
- */
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
deleted file mode 100644
index b8b5fc0..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.internal.service;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Map;
-
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.TestBase;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test cases for {@link org.apache.karaf.features.internal.service.FeaturesServiceImpl}
- */
-public class FeaturesServiceImplTest extends TestBase {
-
- File dataFile;
-
- @Before
- public void setUp() throws IOException {
- dataFile = File.createTempFile("features", null, null);
- }
-
- @Test
- public void testGetFeature() throws Exception {
- Feature transactionFeature = feature("transaction", "1.0.0");
- final Map<String, Map<String, Feature>> features = features(transactionFeature);
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
- protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
- return features;
- }
- };
- assertNotNull(impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
- assertSame(transactionFeature, impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
- }
-
- @Test
- public void testGetFeatureStripVersion() throws Exception {
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
- protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
- return features(feature("transaction", "1.0.0"));
- }
- };
- Feature feature = impl.getFeature("transaction", " 1.0.0 ");
- assertNotNull(feature);
- assertSame("transaction", feature.getName());
- }
-
- @Test
- public void testGetFeatureNotAvailable() throws Exception {
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
- protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
- return features(feature("transaction", "1.0.0"));
- }
- };
- assertNull(impl.getFeature("activemq", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
- }
-
- @Test
- public void testGetFeatureHighestAvailable() throws Exception {
- final Map<String, Map<String, Feature>> features = features(
- feature("transaction", "1.0.0"),
- feature("transaction", "2.0.0")
- );
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
- protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
- return features;
- }
- };
- assertNotNull(impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION));
- assertSame("2.0.0", impl.getFeature("transaction", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION).getVersion());
- }
-
- /**
- * This test ensures that every feature get installed only once, even if it appears multiple times in the list
- * of transitive feature dependencies (KARAF-1600)
- */
- /*
- @Test
- @SuppressWarnings("unchecked")
- public void testNoDuplicateFeaturesInstallation() throws Exception {
- final List<Feature> installed = new LinkedList<Feature>();
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- expect(bundleManager.installBundleIfNeeded(EasyMock.anyObject(String.class), EasyMock.anyInt(), EasyMock.anyObject(String.class)))
- .andReturn(new BundleInstallerResult(createDummyBundle(1l, "", headers()), true)).anyTimes();
- bundleManager.refreshBundles(EasyMock.anyObject(Set.class), EasyMock.anyObject(Set.class), EasyMock.anyObject(EnumSet.class));
- EasyMock.expectLastCall();
- final FeaturesServiceImpl impl = new FeaturesServiceImpl(bundleManager, null) {
- // override methods which refers to bundle context to avoid mocking everything
- @Override
- protected boolean loadState() {
- return true;
- }
-
- @Override
- protected void saveState() {
-
- }
-
- @Override
- protected void doInstallFeature(InstallationState state, Feature feature, boolean verbose) throws Exception {
- installed.add(feature);
-
- super.doInstallFeature(state, feature, verbose);
- }
-
- };
- replay(bundleManager);
- impl.addRepository(getClass().getResource("repo2.xml").toURI());
- impl.installFeature("all");
-
- // copying the features to a set to filter out the duplicates
- Set<Feature> noduplicates = new HashSet<Feature>();
- noduplicates.addAll(installed);
-
- assertEquals("Every feature should only have been installed once", installed.size(), noduplicates.size());
- }
-
- @Test
- public void testGetOptionalImportsOnly() {
- BundleManager bundleManager = new BundleManager(null, 0l);
-
- List<Clause> result = bundleManager.getOptionalImports("org.apache.karaf,org.apache.karaf.optional;resolution:=optional");
- assertEquals("One optional import expected", 1, result.size());
- assertEquals("org.apache.karaf.optional", result.get(0).getName());
-
- result = bundleManager.getOptionalImports(null);
- assertNotNull(result);
- assertEquals("No optional imports expected", 0, result.size());
- }
- */
-
- static class Storage extends StateStorage {
- @Override
- protected InputStream getInputStream() throws IOException {
- return null;
- }
- @Override
- protected OutputStream getOutputStream() throws IOException {
- return null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java
deleted file mode 100644
index f3ca2e6..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesValidationTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.internal.service;
-
-import org.junit.Test;
-
-import static org.junit.Assert.fail;
-
-public class FeaturesValidationTest {
-
- @Test
- public void testNoNs() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f01.xml").toURI());
- }
-
- @Test
- public void testNs10() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f02.xml").toURI());
- }
-
- @Test
- public void testNs10NoName() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f03.xml").toURI());
- }
-
- @Test
- public void testNs11() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f04.xml").toURI());
- }
-
- @Test
- public void testNs12() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f06.xml").toURI());
- }
-
- @Test
- public void testNs11NoName() throws Exception {
- try {
- FeatureValidationUtil.validate(getClass().getResource("f05.xml").toURI());
- fail("Validation should have failed");
- } catch (Exception e) {
- // ok
- }
- }
-
- @Test
- public void testNs13() throws Exception {
- FeatureValidationUtil.validate(getClass().getResource("f07.xml").toURI());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
deleted file mode 100644
index c4976cf..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.internal.model.Bundle;
-import org.apache.karaf.features.internal.resolver.ResourceBuilder;
-import org.apache.karaf.features.internal.resolver.UriNamespace;
-import org.junit.Before;
-import org.junit.Test;
-import org.ops4j.pax.tinybundles.core.TinyBundles;
-import org.osgi.framework.BundleException;
-import org.osgi.resource.Resource;
-
-import static org.apache.karaf.features.internal.resolver.UriNamespace.getUri;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class OverridesTest {
-
- private String bsn = "bsn";
- private Resource b100;
- private Resource b101;
- private Resource b102;
- private Resource b110;
- private Resource c100;
- private Resource c101;
- private Resource c110;
-
- @Before
- public void setUp() throws BundleException {
- b100 = resource("karaf-100.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.0.0")
- .build();
-
- b101 = resource("karaf-101.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.0.1")
- .build();
-
- b102 = resource("karaf-102.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.0.2")
- .build();
-
- b110 = resource("karaf-110.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.1.0")
- .build();
-
- c100 = resource("karafc-100.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.0.0")
- .set("Bundle-Vendor", "Apache")
- .build();
-
- c101 = resource("karafc-101.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.0.1")
- .set("Bundle-Vendor", "NotApache")
- .build();
-
- c110 = resource("karafc-110.jar")
- .set("Bundle-SymbolicName", bsn)
- .set("Bundle-Version", "1.1.0")
- .set("Bundle-Vendor", "NotApache")
- .build();
- }
-
- @Test
- public void testDifferentVendors() throws IOException {
- Map<String, Resource> map = asResourceMap(c100, c101, c110);
- assertEquals(c100, map.get(getUri(c100)));
- Overrides.override(map, Arrays.asList(getUri(c101), getUri(c110)));
- assertEquals(c101, map.get(getUri(c100)));
- }
-
- @Test
- public void testMatching101() throws IOException {
- Map<String, Resource> map = asResourceMap(b100, b101, b110);
- assertEquals(b100, map.get(getUri(b100)));
- Overrides.override(map, Arrays.asList(getUri(b101), getUri(b110)));
- assertEquals(b101, map.get(getUri(b100)));
- }
-
- @Test
- public void testMatching102() throws IOException {
- Map<String, Resource> map = asResourceMap(b100, b101, b102, b110);
- assertEquals(b100, map.get(getUri(b100)));
- Overrides.override(map, Arrays.asList(getUri(b101), getUri(b102), getUri(b110)));
- assertEquals(b102, map.get(getUri(b100)));
- }
-
- @Test
- public void testMatchingRange() throws IOException {
- Map<String, Resource> map = asResourceMap(b100, b101, b110);
- assertEquals(b100, map.get(getUri(b100)));
- Overrides.override(map, Arrays.asList(getUri(b101), getUri(b110) + ";range=\"[1.0, 2.0)\""));
- assertEquals(b110, map.get(getUri(b100)));
- }
-
- @Test
- public void testNotMatching() throws IOException {
- Map<String, Resource> map = asResourceMap(b100, b110);
- assertEquals(b100, map.get(getUri(b100)));
- Overrides.override(map, Arrays.asList(getUri(b110)));
- assertEquals(b100, map.get(getUri(b100)));
- }
-
- @Test
- public void testLoadOverrides() {
- Set<String> overrides = Overrides.loadOverrides(getClass().getResource("overrides.properties").toExternalForm());
- assertEquals(2, overrides.size());
-
- Clause karafAdminCommand = null;
- Clause karafAdminCore = null;
- for (Clause clause : Parser.parseClauses(overrides.toArray(new String[overrides.size()]))) {
- if (clause.getName().equals("mvn:org.apache.karaf.admin/org.apache.karaf.admin.command/2.3.0.redhat-61033X")) {
- karafAdminCommand = clause;
- }
- if (clause.getName().equals("mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/2.3.0.redhat-61033X")) {
- karafAdminCore = clause;
- }
- }
- assertNotNull("Missing admin.command bundle override", karafAdminCommand);
- assertNotNull("Missing admin.core bundle override", karafAdminCore);
- assertNotNull("Missing range on admin.core override", karafAdminCore.getAttribute(Overrides.OVERRIDE_RANGE));
- }
-
- /**
- * Copies the content of {@link java.io.InputStream} to {@link java.io.OutputStream}.
- *
- * @param input
- * @param output
- * @throws java.io.IOException
- */
- private void copy(final InputStream input, final OutputStream output) throws IOException {
- byte[] buffer = new byte[1024 * 16];
- int n;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- output.flush();
- }
- input.close();
- output.close();
- }
-
- static Builder resource(String uri) {
- return new Builder(uri);
- }
-
- static Map<String, Resource> asResourceMap(Resource... resources) {
- Map<String, Resource> map = new HashMap<String, Resource>();
- for (Resource resource : resources) {
- map.put(getUri(resource), resource);
- }
- return map;
- }
-
- static class Builder {
- String uri;
- Map<String,String> headers = new HashMap<String,String>();
- Builder(String uri) {
- this.uri = uri;
- this.headers.put("Bundle-ManifestVersion", "2");
- }
- Builder set(String key, String value) {
- this.headers.put(key, value);
- return this;
- }
- Resource build() throws BundleException {
- return ResourceBuilder.build(uri, headers);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f01.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
deleted file mode 100644
index 814c722..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f01.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="karaf-2.0.0">
- <feature name="spring" version="3.0.3.RELEASE">
- <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-asm/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-expression/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-beans/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-aop/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-context/3.0.3.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-context-support/3.0.3.RELEASE</bundle>
- </feature>
- <feature name="spring-dm" version="1.2.0">
- <feature version="3.0.3.RELEASE">spring</feature>
- <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/2.2.2_1</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-io/1.2.0</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-core/1.2.0</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-extender/1.2.0</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-annotation/1.2.0</bundle>
- <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.spring/2.0.0</bundle>
- </feature>
- <feature name="wrapper" version="2.0.0">
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.wrapper/2.0.0</bundle>
- </feature>
- <feature name="obr" version="2.0.0">
- <bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/1.6.4</bundle>
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.obr/2.0.0</bundle>
- <bundle>mvn:org.apache.karaf.features/org.apache.karaf.features.obr/2.0.0</bundle>
- </feature>
- <feature name="http" version="2.0.0">
- <config name="org.ops4j.pax.web">
- org.osgi.service.http.port=8181
- </config>
- <bundle>mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2</bundle>
- <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jetty-bundle/6.1.22_1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-api/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-spi/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-runtime/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-jetty/0.7.2</bundle>
- </feature>
- <feature name="war" version="2.0.0">
- <feature version="2.0.0">http</feature>
- <bundle>mvn:org.ops4j.pax.web/pax-web-jsp/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-extender-war/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-extender-whiteboard/0.7.2</bundle>
- <bundle>mvn:org.ops4j.pax.url/pax-url-war/1.1.3</bundle>
- <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.war/2.0.0</bundle>
- </feature>
- <feature name="webconsole" version="2.0.0">
- <feature version="2.0.0">http</feature>
- <config name="org.apache.karaf.webconsole">
- realm=karaf
- </config>
- <bundle>mvn:org.apache.felix/org.apache.felix.metatype/1.0.2</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/2.0.0</bundle>
- <bundle>mvn:org.apache.felix/org.apache.felix.webconsole/3.1.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.0.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.0.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.0.0</bundle>
- </feature>
- <feature name="ssh" version="2.0.0">
- <config name="org.apache.karaf.shell.ssh">
- sshPort=8101
- sshHost=0.0.0.0
- sshRealm=karaf
- </config>
- <bundle>mvn:org.apache.mina/mina-core/2.0.0-RC1</bundle>
- <bundle>mvn:org.apache.sshd/sshd-core/0.4.0</bundle>
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.ssh/2.0.0</bundle>
- </feature>
- <feature name="management" version="2.0.0">
- <bundle>mvn:org.apache.karaf/org.apache.karaf.management/2.0.0</bundle>
- <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.1-r964701</bundle>
- <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.1-r964701</bundle>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f02.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
deleted file mode 100644
index 1578faa..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f02.xml
+++ /dev/null
@@ -1,164 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="karaf-2.2.0" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- </feature>
- <feature name="spring-web" version="2.5.6.SEC02" resolver="(obr)">
- <feature version="2.5.6.SEC02">spring</feature>
- <feature version="2.2.0">http</feature>
- <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-webmvc/2.5.6.SEC02</bundle>
- </feature>
- <feature name="spring" version="3.0.5.RELEASE" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-asm/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-expression/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-beans/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-aop/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-context/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-context-support/3.0.5.RELEASE</bundle>
- </feature>
- <feature name="spring-web" version="3.0.5.RELEASE" resolver="(obr)">
- <feature version="3.0.5.RELEASE">spring</feature>
- <feature version="2.2.0">http</feature>
- <bundle>mvn:org.springframework/spring-web/3.0.5.RELEASE</bundle>
- <bundle>mvn:org.springframework/spring-webmvc/3.0.5.RELEASE</bundle>
- </feature>
- <feature name="spring-dm" version="1.2.1" resolver="(obr)">
- <feature version="[2.5.6,4)">spring</feature>
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/2.2.2_1</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-io/1.2.1</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-core/1.2.1</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-extender/1.2.1</bundle>
- <bundle>mvn:org.springframework.osgi/spring-osgi-annotation/1.2.1</bundle>
- <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.spring/2.2.0</bundle>
- </feature>
- <feature name="spring-dm-web" version="1.2.1" resolver="(obr)">
- <feature version="1.2.1">spring-dm</feature>
- <feature version="[2.5.6,4)">spring-web</feature>
- <feature version="2.2.0">http</feature>
- <bundle>mvn:org.springframework.osgi/spring-osgi-web/1.2.1</bundle>
- </feature>
- <feature name="wrapper" version="2.2.0">
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.wrapper/2.2.0</bundle>
- </feature>
- <feature name="obr" version="2.2.0">
- <bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/1.6.4</bundle>
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.obr/2.2.0</bundle>
- <bundle>mvn:org.apache.karaf.features/org.apache.karaf.features.obr/2.2.0</bundle>
- </feature>
- <feature name="config" version="2.2.0">
- <bundle start-level='30'>mvn:org.apache.karaf.shell/org.apache.karaf.shell.config/2.2.0</bundle>
- </feature>
- <feature name="jetty" version="7.2.2.v20101205" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2</bundle>
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.asm/3.3_1</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-util/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-io/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-http/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-continuation/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-server/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-security/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-servlet/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-xml/7.2.2.v20101205</bundle>
- </feature>
- <feature name="jetty-jaas" version="7.2.2.v20101205" resolver="(obr)">
- <feature version="[7.0,8.0)">jetty</feature>
- <bundle dependency='true'>mvn:javax.mail/mail/1.4.3</bundle>
- <bundle dependency='true'>mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/1.1.1</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-webapp/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-jndi/7.2.2.v20101205</bundle>
- <bundle>mvn:org.eclipse.jetty/jetty-plus/7.2.2.v20101205</bundle>
- </feature>
- <feature name="http" version="2.2.0" resolver="(obr)">
- <configfile finalname="/etc/jetty.xml">mvn:org.apache.karaf/apache-karaf/2.2.0/xml/jettyconfig</configfile>
- <config name="org.ops4j.pax.web">
- org.osgi.service.http.port=8181
- javax.servlet.context.tempdir=${karaf.data}/pax-web-jsp
- org.ops4j.pax.web.config.file=${karaf.etc}/jetty.xml
- </config>
- <feature version="[7.0,8.0)">jetty</feature>
- <bundle>mvn:org.ops4j.pax.web/pax-web-api/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-spi/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-runtime/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-jetty/1.0.1</bundle>
- </feature>
- <feature name="war" version="2.2.0" resolver="(obr)">
- <config name="org.ops4j.pax.url.war">
- org.ops4j.pax.url.war.importPaxLoggingPackages=true
- </config>
- <feature>http</feature>
- <bundle start-level='30'>mvn:org.apache.karaf.shell/org.apache.karaf.shell.web/2.2.0</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-jsp/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-extender-war/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-extender-whiteboard/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.web/pax-web-deployer/1.0.1</bundle>
- <bundle>mvn:org.ops4j.pax.url/pax-url-war/1.2.5</bundle>
- </feature>
- <feature name="kar" version="2.2.0">
- <bundle>mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.kar/2.2.0</bundle>
- </feature>
- <feature name="webconsole-base" version="2.2.0">
- <config name="org.apache.karaf.webconsole">
- realm=karaf
- </config>
- <feature>http</feature>
- <bundle>mvn:org.apache.felix/org.apache.felix.metatype/1.0.4</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/2.2.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.console/2.2.0</bundle>
- </feature>
- <feature name="webconsole" version="2.2.0">
- <feature version="2.2.0">webconsole-base</feature>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.2.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.2.0</bundle>
- <bundle>mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.2.0</bundle>
- <bundle>mvn:org.apache.felix/org.apache.felix.webconsole.plugins.event/1.0.2</bundle>
- </feature>
- <feature name="ssh" version="2.2.0">
- <config name="org.apache.karaf.shell">
- sshPort=8101
- sshHost=0.0.0.0
- sshRealm=karaf
- hostKey=${karaf.etc}/host.key
- </config>
- <bundle dependency='true'>mvn:org.apache.mina/mina-core/2.0.1</bundle>
- <bundle dependency='true'>mvn:org.apache.sshd/sshd-core/0.5.0</bundle>
- <bundle>mvn:org.apache.karaf.shell/org.apache.karaf.shell.ssh/2.2.0</bundle>
- </feature>
- <feature name="management" version="2.2.0">
- <bundle>mvn:org.apache.karaf/org.apache.karaf.management/2.2.0</bundle>
- <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.3</bundle>
- <bundle>mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.3</bundle>
- </feature>
- <feature name="eventadmin" version="2.2.0">
- <bundle start-level='30'>mvn:org.apache.felix/org.apache.felix.eventadmin/1.2.8</bundle>
- </feature>
- <feature name="jasypt-encryption" version="2.2.0" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-codec/1.3_3</bundle>
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-lang/2.4_4</bundle>
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.7_1</bundle>
- <bundle>mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.jasypt/2.2.0</bundle>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f03.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
deleted file mode 100644
index c058095..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f03.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f04.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
deleted file mode 100644
index 85f28ad..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f04.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- </feature>
-</features>
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f05.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
deleted file mode 100644
index 15d84e2..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f05.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_6</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- </feature>
-</features>
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f06.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
deleted file mode 100644
index 496cbdb..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f06.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_4</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- <conditional>
- <condition>http</condition>
- <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
- </conditional>
- </feature>
-</features>
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
deleted file mode 100644
index 5b7dd90..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="karaf" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
- <feature name="spring" version="2.5.6.SEC02" resolver="(obr)">
- <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aopalliance/1.0_4</bundle>
- <bundle>mvn:org.springframework/spring-core/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-beans/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-aop/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context/2.5.6.SEC02</bundle>
- <bundle>mvn:org.springframework/spring-context-support/2.5.6.SEC02</bundle>
- <conditional>
- <condition>http</condition>
- <bundle>mvn:org.springframework/spring-web/2.5.6.SEC02</bundle>
- </conditional>
- <capability>
- service-reference;effective:=active;objectClass=org.apache.aries.proxy.ProxyManager
- </capability>
- </feature>
-</features>
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties b/features/core/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
deleted file mode 100644
index d34fa7e..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/overrides.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-# Sample etc/overrides.properties file for testing purposes
-mvn:org.apache.karaf.admin/org.apache.karaf.admin.command/2.3.0.redhat-61033X
-mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/2.3.0.redhat-61033X;range=[2.3.0,2.5)
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
deleted file mode 100644
index 5fd51d0..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/repo2.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-
- 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.
--->
-<features name="repo2">
- <feature name="common">
- <bundle>b1</bundle>
- </feature>
- <feature name="f1">
- <feature>common</feature>
- <bundle>b2</bundle>
- </feature>
- <feature name="f2">
- <feature>common</feature>
- <feature>f1</feature>
- <bundle>b3</bundle>
- </feature>
- <feature name="f3">
- <feature>f1</feature>
- <feature>f2</feature>
- <bundle>b4</bundle>
- </feature>
- <feature name="all">
- <feature>f1</feature>
- <feature>f2</feature>
- <feature>f3</feature>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/repo1.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/repo1.xml b/features/core/src/test/resources/org/apache/karaf/features/repo1.xml
deleted file mode 100644
index 641ef12..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/repo1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.1.0">
- <repository>urn:r1</repository>
- <feature name="f1" region="foo">
- <config name="c1">
- k=v
- </config>
- <bundle>b1</bundle>
- <bundle>b2</bundle>
- </feature>
- <feature name="f2">
- <feature>f1</feature>
- <bundle>b3</bundle>
- </feature>
- <feature name="f3">
- <configfile finalname="cf1" override="true">cfloc</configfile>
- <bundle>b4</bundle>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/repo2.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/repo2.xml b/features/core/src/test/resources/org/apache/karaf/features/repo2.xml
deleted file mode 100644
index f5e96ae..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/repo2.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
- <repository>
- urn:r1
- </repository>
- <feature name="f1" region="foo">
- <config name="c1">
- k=v
- </config>
- <bundle>b1</bundle>
- <bundle>b2</bundle>
- </feature>
- <feature name="f2">
- <feature>f1</feature>
- <bundle>b3</bundle>
- </feature>
- <feature name="f3">
- <configfile finalname="cf1" override="true">cfloc</configfile>
- <bundle>b4</bundle>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/resources/org/apache/karaf/features/repo3.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/repo3.xml b/features/core/src/test/resources/org/apache/karaf/features/repo3.xml
deleted file mode 100644
index ffe08ed..0000000
--- a/features/core/src/test/resources/org/apache/karaf/features/repo3.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
- <feature name="f1">
- <capability>
- cap
- </capability>
- <requirement>
- req
- </requirement>
- </feature>
-</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/pom.xml
----------------------------------------------------------------------
diff --git a/features/pom.xml b/features/pom.xml
index 8cfede1..5013057 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -29,13 +29,120 @@
</parent>
<groupId>org.apache.karaf.features</groupId>
- <artifactId>features</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Features</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Features :: Core</name>
+ <description>This bundle is the core implementation of the Karaf features support.</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>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.resolver</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.ops4j.pax.tinybundles</groupId>
+ <artifactId>tinybundles</artifactId>
+ <scope>test</scope>
+ </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>
+ <Export-Package>
+ org.apache.karaf.features;
+ org.apache.karaf.features.command;
+ org.apache.karaf.features.command.completers;
+ org.apache.karaf.features.management;
+ org.apache.karaf.features.management.codec;
+ -noimport:=true
+ </Export-Package>
+ <Provide-Capability>
+ service-reference;effective:=active;objectClass=org.apache.karaf.features.FeaturesService
+ </Provide-Capability>
+ <Private-Package>
+ org.apache.karaf.features.internal.*,
+ org.apache.felix.resolver,
+ org.apache.felix.utils.version,
+ org.apache.felix.utils.manifest,
+ org.apache.karaf.util.collections,
+ org.apache.karaf.util.json,
+ org.apache.karaf.util.tracker,
+ org.osgi.service.resolver,
+ org.osgi.service.repository
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.features.internal.osgi.Activator
+ </Bundle-Activator>
+ <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/999f4970/features/src/main/java/org/apache/karaf/features/BootFinished.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/BootFinished.java b/features/src/main/java/org/apache/karaf/features/BootFinished.java
new file mode 100644
index 0000000..aa72248
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/BootFinished.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Marker interface for a service that announces when the karaf boot is finished
+ */
+public interface BootFinished {
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/BundleInfo.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/BundleInfo.java b/features/src/main/java/org/apache/karaf/features/BundleInfo.java
new file mode 100644
index 0000000..97a541f
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/BundleInfo.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * A bundle info holds info about a Bundle.
+ */
+public interface BundleInfo {
+
+ String getLocation();
+
+ int getStartLevel();
+
+ boolean isStart();
+
+ boolean isDependency();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Capability.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Capability.java b/features/src/main/java/org/apache/karaf/features/Capability.java
new file mode 100644
index 0000000..d329708
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Capability.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.features;
+
+public interface Capability {
+
+ String getValue();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Conditional.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Conditional.java b/features/src/main/java/org/apache/karaf/features/Conditional.java
new file mode 100644
index 0000000..c0e4d59
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Conditional.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+
+public interface Conditional {
+
+ List<? extends Dependency> getCondition();
+
+ List<Dependency> getDependencies();
+
+ List<BundleInfo> getBundles();
+
+ Map<String, Map<String, String>> getConfigurations();
+
+ List<ConfigFileInfo> getConfigurationFiles();
+
+ Feature asFeature(String name, String version);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/ConfigFileInfo.java b/features/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
new file mode 100644
index 0000000..960fb31
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/ConfigFileInfo.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+public interface ConfigFileInfo {
+
+ String getLocation();
+
+ String getFinalname();
+
+ boolean isOverride();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Dependency.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Dependency.java b/features/src/main/java/org/apache/karaf/features/Dependency.java
new file mode 100644
index 0000000..cafdd92
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Dependency.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public interface Dependency {
+
+ String getName();
+
+ String getVersion();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/EventConstants.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/EventConstants.java b/features/src/main/java/org/apache/karaf/features/EventConstants.java
new file mode 100644
index 0000000..f83f185
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/EventConstants.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Constants for EventAdmin events
+ */
+public final class EventConstants {
+
+ public static final String TYPE = "type";
+ public static final String EVENT = "event";
+ public static final String TIMESTAMP = "timestamp";
+
+ public static final String FEATURE_NAME = "name";
+ public static final String FEATURE_VERSION = "version";
+
+ public static final String REPOSITORY_NAME = "name";
+ public static final String REPOSITORY_URI = "uri";
+
+ public static final String TOPIC_EVENTS = "org/apache/karaf/features";
+ public static final String TOPIC_FEATURES_INSTALLED = TOPIC_EVENTS + "/features/INSTALLED";
+ public static final String TOPIC_FEATURES_UNINSTALLED = TOPIC_EVENTS + "/features/UNINSTALLED";
+ public static final String TOPIC_REPOSITORY_ADDED = TOPIC_EVENTS + "/repositories/ADDED";
+ public static final String TOPIC_REPOSITORY_REMOVED = TOPIC_EVENTS + "/repositories/REMOVED";
+
+ private EventConstants() {
+ // non-instantiable class
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/Feature.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/Feature.java b/features/src/main/java/org/apache/karaf/features/Feature.java
new file mode 100644
index 0000000..2f9f001
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/Feature.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A feature is a list of bundles associated identified by its name.
+ */
+public interface Feature {
+
+ public static String DEFAULT_INSTALL_MODE = "auto";
+
+ String getId();
+
+ String getName();
+
+ String getDescription();
+
+ String getDetails();
+
+ String getVersion();
+
+ boolean hasVersion();
+
+ String getResolver();
+
+ String getInstall();
+
+ List<Dependency> getDependencies();
+
+ List<BundleInfo> getBundles();
+
+ Map<String, Map<String, String>> getConfigurations();
+
+ List<ConfigFileInfo> getConfigurationFiles();
+
+ List<? extends Conditional> getConditional();
+
+ int getStartLevel();
+
+ String getRegion();
+
+ List<? extends Capability> getCapabilities();
+
+ List<? extends Requirement> getRequirements();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/FeatureEvent.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/FeatureEvent.java b/features/src/main/java/org/apache/karaf/features/FeatureEvent.java
new file mode 100644
index 0000000..516c988
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/FeatureEvent.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import java.util.EventObject;
+
+public class FeatureEvent extends EventObject {
+
+ public static enum EventType {
+ FeatureInstalled,
+ FeatureUninstalled
+ }
+
+ private final EventType type;
+ private final Feature feature;
+ private final boolean replay;
+
+ public FeatureEvent(Feature feature, EventType type, boolean replay) {
+ super(feature);
+ this.type = type;
+ this.feature = feature;
+ this.replay = replay;
+ }
+
+ public EventType getType() {
+ return type;
+ }
+
+ public Feature getFeature() {
+ return feature;
+ }
+
+ public boolean isReplay() {
+ return replay;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/FeaturesListener.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/FeaturesListener.java b/features/src/main/java/org/apache/karaf/features/FeaturesListener.java
new file mode 100644
index 0000000..69f68c6
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/FeaturesListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+public interface FeaturesListener {
+
+ void featureEvent(FeatureEvent event);
+
+ void repositoryEvent(RepositoryEvent event);
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java b/features/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
new file mode 100644
index 0000000..282ff71
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Provides features XML/XSD constants.
+ */
+public interface FeaturesNamespaces {
+
+ String URI_0_0_0 = "";
+ String URI_1_0_0 = "http://karaf.apache.org/xmlns/features/v1.0.0";
+ String URI_1_1_0 = "http://karaf.apache.org/xmlns/features/v1.1.0";
+ String URI_1_2_0 = "http://karaf.apache.org/xmlns/features/v1.2.0";
+ String URI_1_3_0 = "http://karaf.apache.org/xmlns/features/v1.3.0";
+
+ String URI_CURRENT = URI_1_3_0;
+
+ QName FEATURES_0_0_0 = new QName("features");
+ QName FEATURES_1_0_0 = new QName(URI_1_0_0, "features");
+ QName FEATURES_1_1_0 = new QName(URI_1_1_0, "features");
+ QName FEATURES_1_2_0 = new QName(URI_1_2_0, "features");
+ QName FEATURES_1_3_0 = new QName(URI_1_3_0, "features");
+
+ QName FEATURES_CURRENT = FEATURES_1_3_0;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/FeaturesService.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/FeaturesService.java b/features/src/main/java/org/apache/karaf/features/FeaturesService.java
new file mode 100644
index 0000000..ef3dbcf
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/FeaturesService.java
@@ -0,0 +1,104 @@
+/*
+ * 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;
+
+import java.net.URI;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * The service managing features repositories.
+ */
+public interface FeaturesService {
+
+ enum Option {
+ NoFailOnFeatureNotFound,
+ NoAutoRefreshManagedBundles,
+ NoAutoRefreshUnmanagedBundles,
+ NoAutoRefreshBundles,
+ NoAutoStartBundles,
+ Simulate,
+ Verbose
+ }
+
+ /**
+ * Validate repository contents.
+ *
+ * @param uri Repository uri.
+ * @throws Exception When validation fails.
+ */
+ void validateRepository(URI uri) throws Exception;
+
+ void addRepository(URI uri) throws Exception;
+
+ void addRepository(URI uri, boolean install) throws Exception;
+
+ void removeRepository(URI uri) throws Exception;
+
+ void removeRepository(URI uri, boolean uninstall) throws Exception;
+
+ void restoreRepository(URI uri) throws Exception;
+
+ Repository[] listRequiredRepositories() throws Exception;
+
+ Repository[] listRepositories() throws Exception;
+
+ Repository getRepository(String repoName) throws Exception;
+
+ void installFeature(String name) throws Exception;
+
+ void installFeature(String name, EnumSet<Option> options) throws Exception;
+
+ void installFeature(String name, String version) throws Exception;
+
+ void installFeature(String name, String version, EnumSet<Option> options) throws Exception;
+
+ void installFeature(Feature f, EnumSet<Option> options) throws Exception;
+
+ void installFeatures(Set<String> features, EnumSet<Option> options) throws Exception;
+
+ void uninstallFeature(String name, EnumSet<Option> options) throws Exception;
+
+ void uninstallFeature(String name) throws Exception;
+
+ void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception;
+
+ void uninstallFeature(String name, String version) throws Exception;
+
+ void uninstallFeatures(Set<String> features, EnumSet<Option> options) throws Exception;
+
+ Feature[] listFeatures() throws Exception;
+
+ Feature[] listRequiredFeatures() throws Exception;
+
+ Feature[] listInstalledFeatures() throws Exception;
+
+ boolean isRequired(Feature f);
+
+ boolean isInstalled(Feature f);
+
+ Feature getFeature(String name, String version) throws Exception;
+
+ Feature getFeature(String name) throws Exception;
+
+ void refreshRepository(URI uri) throws Exception;
+
+ public URI getRepositoryUriFor(String name, String version);
+
+ public String[] getRepositoryNames();
+
+}
[39/59] [abbrv] git commit: [KARAF-2852] Merge package/core and
package/command
Posted by gn...@apache.org.
[KARAF-2852] Merge package/core and package/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/91232f80
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/91232f80
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/91232f80
Branch: refs/heads/master
Commit: 91232f80fede4df8e71b6bd15c3055ce0ab4df7c
Parents: 7f1463c
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 23:18:14 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:23 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
package/NOTICE | 71 +++++++++
.../apache/karaf/packages/command/Exports.java | 132 -----------------
.../apache/karaf/packages/command/Imports.java | 65 ---------
package/core/NOTICE | 71 ---------
package/core/pom.xml | 119 ---------------
.../karaf/packages/core/PackageRequirement.java | 64 ---------
.../karaf/packages/core/PackageService.java | 51 -------
.../karaf/packages/core/PackageVersion.java | 52 -------
.../karaf/packages/core/PackagesMBean.java | 32 -----
.../core/internal/PackageServiceImpl.java | 134 -----------------
.../core/internal/PackagesMBeanImpl.java | 143 -------------------
.../packages/core/internal/osgi/Activator.java | 34 -----
.../src/main/resources/OSGI-INF/bundle.info | 15 --
.../karaf/packages/core/InstallMBeantest.java | 44 ------
.../packages/core/PackageRequirementTest.java | 32 -----
package/pom.xml | 107 ++++++++++++--
.../apache/karaf/packages/command/Exports.java | 132 +++++++++++++++++
.../apache/karaf/packages/command/Imports.java | 65 +++++++++
.../karaf/packages/core/PackageRequirement.java | 64 +++++++++
.../karaf/packages/core/PackageService.java | 51 +++++++
.../karaf/packages/core/PackageVersion.java | 52 +++++++
.../karaf/packages/core/PackagesMBean.java | 32 +++++
.../core/internal/PackageServiceImpl.java | 134 +++++++++++++++++
.../core/internal/PackagesMBeanImpl.java | 143 +++++++++++++++++++
.../packages/core/internal/osgi/Activator.java | 34 +++++
package/src/main/resources/OSGI-INF/bundle.info | 15 ++
.../karaf/packages/core/InstallMBeantest.java | 44 ++++++
.../packages/core/PackageRequirementTest.java | 32 +++++
29 files changed, 967 insertions(+), 998 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/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 6fa3319..ae6ab68 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -157,7 +157,6 @@
<feature name="package" version="${project.version}" resolver="(obr)" description="Package commands and mbeans">
<bundle start-level="30">mvn:org.apache.karaf.package/org.apache.karaf.package.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.package/org.apache.karaf.package.command/${project.version}</bundle>
</feature>
<feature name="service" description="Provide Service support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/NOTICE
----------------------------------------------------------------------
diff --git a/package/NOTICE b/package/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/package/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/91232f80/package/command/src/main/java/org/apache/karaf/packages/command/Exports.java
----------------------------------------------------------------------
diff --git a/package/command/src/main/java/org/apache/karaf/packages/command/Exports.java b/package/command/src/main/java/org/apache/karaf/packages/command/Exports.java
deleted file mode 100644
index c09a5f6..0000000
--- a/package/command/src/main/java/org/apache/karaf/packages/command/Exports.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.packages.command;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.karaf.packages.core.PackageService;
-import org.apache.karaf.packages.core.PackageVersion;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-
-@Command(scope = "package", name = "exports", description = "Lists exported packages and the bundles that export them")
-@Service
-public class Exports implements Action {
-
- @Option(name = "-d", description = "Only show packages that are exported by more than one bundle", required = false, multiValued = false)
- private boolean onlyDuplicates;
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private PackageService packageService;
-
- @Reference
- private BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- if (onlyDuplicates) {
- checkDuplicateExports();
- } else {
- showExports();
- }
- return null;
- }
-
- private void showExports() {
- SortedMap<String, PackageVersion> exports = packageService.getExports();
- ShellTable table = new ShellTable();
- table.column(new Col("Package Name"));
- table.column(new Col("Version"));
- table.column(new Col("ID"));
- table.column(new Col("Bundle Name"));
-
- for (String key : exports.keySet()) {
- PackageVersion pVer = exports.get(key);
- for (Bundle bundle : pVer.getBundles()) {
- table.addRow().addContent(pVer.getPackageName(),pVer.getVersion().toString(), bundle.getBundleId(), bundle.getSymbolicName());
- }
- }
- table.print(System.out, !noFormat);
- }
-
- private void checkDuplicateExports() {
- Bundle[] bundles = bundleContext.getBundles();
- SortedMap<String, PackageVersion> packageVersionMap = getDuplicatePackages(bundles);
- ShellTable table = new ShellTable();
- table.column(new Col("Package Name"));
- table.column(new Col("Version"));
- table.column(new Col("Exporting bundles (ID)"));
-
- for (String key : packageVersionMap.keySet()) {
- PackageVersion pVer = packageVersionMap.get(key);
- if (pVer.getBundles().size() > 1) {
- String pBundles = getBundlesSt(pVer.getBundles());
- table.addRow().addContent(pVer.getPackageName(), pVer.getVersion().toString(), pBundles);
- }
- }
- table.print(System.out, !noFormat);
- }
-
- private String getBundlesSt(Set<Bundle> bundles) {
- StringBuilder st = new StringBuilder();
- for (Bundle bundle : bundles) {
- st.append(bundle.getBundleId() + " ");
- }
- return st.toString();
- }
-
- private SortedMap<String, PackageVersion> getDuplicatePackages(
- Bundle[] bundles) {
- SortedMap<String, PackageVersion> packageVersionMap = new TreeMap<String, PackageVersion>();
- for (Bundle bundle : bundles) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- if (rev!=null) {
- List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- for (BundleCapability cap : caps) {
- Map<String, Object> attr = cap.getAttributes();
- String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
- Version version = (Version)attr.get("version");
- String key = packageName + ":" + version.toString();
- PackageVersion pVer = packageVersionMap.get(key);
- if (pVer == null) {
- pVer = new PackageVersion(packageName, version);
- packageVersionMap.put(key, pVer);
- }
- pVer.addBundle(bundle);
- }
- }
- }
- return packageVersionMap;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/command/src/main/java/org/apache/karaf/packages/command/Imports.java
----------------------------------------------------------------------
diff --git a/package/command/src/main/java/org/apache/karaf/packages/command/Imports.java b/package/command/src/main/java/org/apache/karaf/packages/command/Imports.java
deleted file mode 100644
index 3d086e9..0000000
--- a/package/command/src/main/java/org/apache/karaf/packages/command/Imports.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.packages.command;
-
-import java.util.SortedMap;
-
-import org.apache.karaf.packages.core.PackageRequirement;
-import org.apache.karaf.packages.core.PackageService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "package", name = "imports", description = "Lists imported packages and the bundles that import them")
-@Service
-public class Imports implements Action {
-
- @Option(name = "-p", description = "Only show package instead of full filter", required = false, multiValued = false)
- boolean onlyPackage;
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private PackageService packageService;
-
- @Override
- public Object execute() throws Exception {
- SortedMap<String, PackageRequirement> imports = packageService.getImports();
- ShellTable table = new ShellTable();
- table.column(new Col(onlyPackage ? "Package name" : "Filter"));
- table.column(new Col("Optional"));
- table.column(new Col("ID"));
- table.column(new Col("Bundle Name"));
- table.column(new Col("Resolveable"));
-
- for (String filter : imports.keySet()) {
- PackageRequirement req = imports.get(filter);
- Bundle bundle = req.getBundle();
- String firstCol = onlyPackage ? req.getPackageName() : req.getFilter();
- table.addRow().addContent(firstCol, req.isOptional() ? "optional" : "", bundle.getBundleId(), bundle.getSymbolicName(), req.isResolveable());
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/NOTICE
----------------------------------------------------------------------
diff --git a/package/core/NOTICE b/package/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/package/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/91232f80/package/core/pom.xml
----------------------------------------------------------------------
diff --git a/package/core/pom.xml b/package/core/pom.xml
deleted file mode 100644
index bc5238f..0000000
--- a/package/core/pom.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?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.package</groupId>
- <artifactId>package</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.package.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Package :: Core</name>
- <description>Package Services and API</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.apache.aries.blueprint</groupId>
- <artifactId>org.apache.aries.blueprint.api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <Export-Package>
- org.apache.karaf.packages.core;-noimport:=true
- </Export-Package>
- <Private-Package>
- org.apache.karaf.packages.core.internal,
- org.apache.karaf.packages.core.internal.osgi,
- org.apache.karaf.util.tracker,
- org.apache.felix.utils.version,
- org.apache.felix.utils.manifest
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.packages.core.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java b/package/core/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
deleted file mode 100644
index ed8550b..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.packages.core;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.osgi.framework.Bundle;
-
-public class PackageRequirement {
- private String filter;
- private boolean optional;
- private Bundle bundle;
- private boolean resolveable;
- private static Pattern packagePattern = Pattern.compile(".*" + Pattern.quote("(osgi.wiring.package=") + "(.*?)\\).*");
-
- public PackageRequirement(String filter, boolean optional, Bundle bundle, boolean resolveable) {
- super();
- this.filter = filter;
- this.optional = optional;
- this.bundle = bundle;
- this.resolveable = resolveable;
- }
-
- public Bundle getBundle() {
- return bundle;
- }
-
- public String getFilter() {
- return filter;
- }
- public boolean isOptional() {
- return optional;
- }
-
- public boolean isResolveable() {
- return resolveable;
- }
-
- public String getPackageName() {
- return getPackageName(filter);
- }
-
- public static String getPackageName(String filter) {
- Matcher matcher = packagePattern.matcher(filter);
- matcher.matches();
- return matcher.group(1);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/PackageService.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/PackageService.java b/package/core/src/main/java/org/apache/karaf/packages/core/PackageService.java
deleted file mode 100644
index d6ccc65..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/PackageService.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.packages.core;
-
-import java.util.List;
-import java.util.SortedMap;
-
-public interface PackageService {
-
- /**
- * Gets the simplified package exports of a bundle. This does not show the
- * package versions.
- *
- * @param bundleId
- * @return
- */
- List<String> getExports(long bundleId);
-
- List<String> getImports(long bundleId);
-
- /**
- * Gets a map of all exported packages with their version and the bundles that exprot them
- * The key is in the form packagename:version.
- *
- * @return
- */
- SortedMap<String, PackageVersion> getExports();
-
- /**
- * Gets a map of all package imports.
- * The key is the import filter.
- *
- * @return
- */
- SortedMap<String, PackageRequirement> getImports();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/PackageVersion.java b/package/core/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
deleted file mode 100644
index aed0c48..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.packages.core;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-
-public class PackageVersion {
-
- private String packageName;
- private Version version;
- private Set<Bundle> bundles = new HashSet<Bundle>();
-
- public PackageVersion(String packageName, Version version) {
- this.packageName = packageName;
- this.version = version;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public Version getVersion() {
- return version;
- }
-
- public void addBundle(Bundle bundle) {
- this.bundles.add(bundle);
- }
-
- public Set<Bundle> getBundles() {
- return this.bundles;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java b/package/core/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
deleted file mode 100644
index 9f07546..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.packages.core;
-
-import java.util.List;
-
-import javax.management.openmbean.TabularData;
-
-/**
- * Packages MBean.
- */
-public interface PackagesMBean {
-
- TabularData getExports();
- TabularData getImports();
- List<String> getExports(long bundleId);
- List<String> getImports(long bundleId);
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java b/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
deleted file mode 100644
index a7e7dd1..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.packages.core.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.karaf.packages.core.PackageRequirement;
-import org.apache.karaf.packages.core.PackageService;
-import org.apache.karaf.packages.core.PackageVersion;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-public class PackageServiceImpl implements PackageService {
-
- private final BundleContext bundleContext;
-
- public PackageServiceImpl(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public SortedMap<String, PackageVersion> getExports() {
- Bundle[] bundles = bundleContext.getBundles();
- SortedMap<String, PackageVersion> packageVersionMap = new TreeMap<String, PackageVersion>();
- for (Bundle bundle : bundles) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- if (rev != null) {
- List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- for (BundleCapability cap : caps) {
- Map<String, Object> attr = cap.getAttributes();
- String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
- Version version = (Version)attr.get("version");
- String key = packageName + ":" + version.toString();
- PackageVersion pVer = packageVersionMap.get(key);
- if (pVer == null) {
- pVer = new PackageVersion(packageName, version);
- packageVersionMap.put(key, pVer);
- }
- pVer.addBundle(bundle);
- }
- }
- }
- return packageVersionMap;
- }
-
- @Override
- public SortedMap<String, PackageRequirement> getImports() {
- Bundle[] bundles = bundleContext.getBundles();
- SortedMap<String, PackageRequirement> filterMap = new TreeMap<String, PackageRequirement>();
- for (Bundle bundle : bundles) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- if (rev != null) {
- List<BundleRequirement> reqs = rev.getDeclaredRequirements(BundleRevision.PACKAGE_NAMESPACE);
- for (BundleRequirement req : reqs) {
- Map<String, String> attr = req.getDirectives();
- String filter = attr.get("filter");
- String resolution = attr.get("resolution");
- boolean optional = "optional".equals(resolution);
- boolean resolveable = checkResolveAble(req);
- PackageRequirement preq = new PackageRequirement(filter, optional, bundle, resolveable);
- filterMap.put(filter, preq);
- }
- }
- }
- return filterMap;
- }
-
- private boolean checkResolveAble(BundleRequirement req) {
- Bundle[] bundles = bundleContext.getBundles();
- for (Bundle bundle : bundles) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- if (rev != null) {
- List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- for (BundleCapability cap : caps) {
- if (req.matches(cap)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- @Override
- public List<String> getExports(long bundleId) {
- Bundle bundle = bundleContext.getBundle(bundleId);
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- List<String> exports = new ArrayList<String>();
- for (BundleCapability cap : caps) {
- Map<String, Object> attr = cap.getAttributes();
- String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
- exports.add(packageName);
- }
- return exports ;
- }
-
- @Override
- public List<String> getImports(long bundleId) {
- Bundle bundle = bundleContext.getBundle(bundleId);
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- List<BundleRequirement> reqs = rev.getDeclaredRequirements(BundleRevision.PACKAGE_NAMESPACE);
- List<String> imports = new ArrayList<String>();
- for (BundleRequirement req : reqs) {
- Map<String, String> attr = req.getDirectives();
- String filter = attr.get("filter");
- String name = PackageRequirement.getPackageName(filter);
- imports.add(name);
- }
- return imports;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java b/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
deleted file mode 100644
index bce7b8f..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.packages.core.internal;
-
-import java.util.List;
-import java.util.SortedMap;
-
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.karaf.packages.core.PackageRequirement;
-import org.apache.karaf.packages.core.PackageService;
-import org.apache.karaf.packages.core.PackageVersion;
-import org.apache.karaf.packages.core.PackagesMBean;
-import org.osgi.framework.Bundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of the Packages MBean.
- */
-public class PackagesMBeanImpl extends StandardMBean implements PackagesMBean {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(PackagesMBeanImpl.class);
-
- private final PackageService packageService;
-
- public PackagesMBeanImpl(PackageService packageService) throws NotCompliantMBeanException {
- super(PackagesMBean.class);
- this.packageService = packageService;
- }
-
- public TabularData getExports() {
- try {
- String[] names = new String[] {"Name", "Version", "ID", "Bundle Name"};
- CompositeType bundleType = new CompositeType("PackageExport", "Exported packages", names,
- new String[] {"Package name", "Version of the Package",
- "ID of the Bundle", "Bundle symbolic name"},
- new OpenType[] {SimpleType.STRING, SimpleType.STRING,
- SimpleType.LONG, SimpleType.STRING});
- TabularType tableType = new TabularType("PackageExports", "Exported packages", bundleType,
- new String[] {"Name", "Version", "ID"});
- TabularData table = new TabularDataSupport(tableType);
-
- SortedMap<String, PackageVersion> exports = packageService.getExports();
-
- for (String key : exports.keySet()) {
- PackageVersion export = exports.get(key);
- for (Bundle bundle : export.getBundles()) {
- Object[] data = new Object[] {
- export.getPackageName(),
- export.getVersion().toString(),
- bundle.getBundleId(),
- bundle.getSymbolicName()};
- CompositeData comp = new CompositeDataSupport(bundleType, names, data);
- LOGGER.debug("Adding CompositeDataSupport {} for key: {}", comp, key);
- table.put(comp);
- }
- }
- return table;
- } catch (RuntimeException e) {
- // To avoid the exception gets swallowed by jmx
- LOGGER.error(e.getMessage(), e);
- throw e;
- } catch (OpenDataException e) {
- LOGGER.error(e.getMessage(), e);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- @Override
- public TabularData getImports() {
- try {
- String[] names = new String[] {"PackageName", "Filter", "Optional", "ID", "Bundle Name", "Resolvable"};
- CompositeType bundleType = new CompositeType("PackageImports", "Imported packages",
- names,
- names,
- new OpenType[] {SimpleType.STRING, SimpleType.STRING, SimpleType.BOOLEAN,
- SimpleType.LONG, SimpleType.STRING, SimpleType.BOOLEAN});
- TabularType tableType = new TabularType("PackageImports", "Imported packages", bundleType,
- new String[] {"Filter", "ID"});
- TabularData table = new TabularDataSupport(tableType);
-
- SortedMap<String, PackageRequirement> imports = packageService.getImports();
-
- for (String key : imports.keySet()) {
- PackageRequirement req = imports.get(key);
- Object[] data = new Object[] {
- req.getPackageName(),
- req.getFilter(),
- req.isOptional(),
- req.getBundle().getBundleId(),
- req.getBundle().getSymbolicName(),
- req.isResolveable()};
- CompositeData comp = new CompositeDataSupport(bundleType, names, data);
- table.put(comp);
- }
- return table;
- } catch (RuntimeException e) {
- // To avoid the exception gets swallowed by jmx
- LOGGER.error(e.getMessage(), e);
- throw e;
- } catch (OpenDataException e) {
- LOGGER.error(e.getMessage(), e);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- @Override
- public List<String> getExports(long bundleId) {
- return packageService.getExports(bundleId);
-
- }
-
- @Override
- public List<String> getImports(long bundleId) {
- return packageService.getImports(bundleId);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/package/core/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java b/package/core/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
deleted file mode 100644
index ea8ce1d..0000000
--- a/package/core/src/main/java/org/apache/karaf/packages/core/internal/osgi/Activator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.packages.core.internal.osgi;
-
-import org.apache.karaf.packages.core.PackageService;
-import org.apache.karaf.packages.core.internal.PackageServiceImpl;
-import org.apache.karaf.packages.core.internal.PackagesMBeanImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doStart() throws Exception {
- PackageService packageService = new PackageServiceImpl(bundleContext);
- register(PackageService.class, packageService);
-
- PackagesMBeanImpl mbean = new PackagesMBeanImpl(packageService);
- registerMBean(mbean, "type=package");
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/package/core/src/main/resources/OSGI-INF/bundle.info b/package/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index b5747b7..0000000
--- a/package/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,15 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
- [mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-Services for handling packages
-
-h1. See also
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
----------------------------------------------------------------------
diff --git a/package/core/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java b/package/core/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
deleted file mode 100644
index a9ab11b..0000000
--- a/package/core/src/test/java/org/apache/karaf/packages/core/InstallMBeantest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.packages.core;
-
-import java.lang.management.ManagementFactory;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.karaf.packages.core.internal.PackagesMBeanImpl;
-import org.junit.Test;
-
-/**
- * Checks that the PackagesMBean is valid and can be installed in the MBeanServer
- *
- */
-public class InstallMBeantest {
-
- @Test
- public void test() throws Exception {
- MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- PackagesMBeanImpl pack = new PackagesMBeanImpl(null);
- ObjectName oName = new ObjectName("org.apache.karaf:type=package,name=root");
- server.registerMBean(pack, oName);
- server.unregisterMBean(oName);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/core/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
----------------------------------------------------------------------
diff --git a/package/core/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java b/package/core/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
deleted file mode 100644
index 2ea1cf8..0000000
--- a/package/core/src/test/java/org/apache/karaf/packages/core/PackageRequirementTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.packages.core;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-public class PackageRequirementTest {
-
- @Test
- public void testGetPackageName() {
- PackageRequirement req = new PackageRequirement("(&(osgi.wiring.package=org.osgi.service.useradmin)(version>=1.1.0))", false, null, false);
- String packageName = req.getPackageName();
- Assert.assertEquals("org.osgi.service.useradmin", packageName);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/pom.xml
----------------------------------------------------------------------
diff --git a/package/pom.xml b/package/pom.xml
index ae401d8..8c3e1a1 100644
--- a/package/pom.xml
+++ b/package/pom.xml
@@ -10,7 +10,7 @@
(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
+ 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,
@@ -29,13 +29,102 @@
</parent>
<groupId>org.apache.karaf.package</groupId>
- <artifactId>package</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Bundle</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.package.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Package :: Core</name>
+ <description>Package Services and API</description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </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>
+ <Export-Package>
+ org.apache.karaf.packages.core;-noimport:=true
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.packages.command,
+ org.apache.karaf.packages.core.internal,
+ org.apache.karaf.packages.core.internal.osgi,
+ org.apache.karaf.util.tracker,
+ org.apache.felix.utils.version,
+ org.apache.felix.utils.manifest
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.packages.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>
+ org.apache.karaf.packages.command
+ </Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/command/Exports.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/command/Exports.java b/package/src/main/java/org/apache/karaf/packages/command/Exports.java
new file mode 100644
index 0000000..c09a5f6
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/command/Exports.java
@@ -0,0 +1,132 @@
+/*
+ * 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.packages.command;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.karaf.packages.core.PackageService;
+import org.apache.karaf.packages.core.PackageVersion;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.Col;
+import org.apache.karaf.shell.support.table.ShellTable;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+@Command(scope = "package", name = "exports", description = "Lists exported packages and the bundles that export them")
+@Service
+public class Exports implements Action {
+
+ @Option(name = "-d", description = "Only show packages that are exported by more than one bundle", required = false, multiValued = false)
+ private boolean onlyDuplicates;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ private PackageService packageService;
+
+ @Reference
+ private BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ if (onlyDuplicates) {
+ checkDuplicateExports();
+ } else {
+ showExports();
+ }
+ return null;
+ }
+
+ private void showExports() {
+ SortedMap<String, PackageVersion> exports = packageService.getExports();
+ ShellTable table = new ShellTable();
+ table.column(new Col("Package Name"));
+ table.column(new Col("Version"));
+ table.column(new Col("ID"));
+ table.column(new Col("Bundle Name"));
+
+ for (String key : exports.keySet()) {
+ PackageVersion pVer = exports.get(key);
+ for (Bundle bundle : pVer.getBundles()) {
+ table.addRow().addContent(pVer.getPackageName(),pVer.getVersion().toString(), bundle.getBundleId(), bundle.getSymbolicName());
+ }
+ }
+ table.print(System.out, !noFormat);
+ }
+
+ private void checkDuplicateExports() {
+ Bundle[] bundles = bundleContext.getBundles();
+ SortedMap<String, PackageVersion> packageVersionMap = getDuplicatePackages(bundles);
+ ShellTable table = new ShellTable();
+ table.column(new Col("Package Name"));
+ table.column(new Col("Version"));
+ table.column(new Col("Exporting bundles (ID)"));
+
+ for (String key : packageVersionMap.keySet()) {
+ PackageVersion pVer = packageVersionMap.get(key);
+ if (pVer.getBundles().size() > 1) {
+ String pBundles = getBundlesSt(pVer.getBundles());
+ table.addRow().addContent(pVer.getPackageName(), pVer.getVersion().toString(), pBundles);
+ }
+ }
+ table.print(System.out, !noFormat);
+ }
+
+ private String getBundlesSt(Set<Bundle> bundles) {
+ StringBuilder st = new StringBuilder();
+ for (Bundle bundle : bundles) {
+ st.append(bundle.getBundleId() + " ");
+ }
+ return st.toString();
+ }
+
+ private SortedMap<String, PackageVersion> getDuplicatePackages(
+ Bundle[] bundles) {
+ SortedMap<String, PackageVersion> packageVersionMap = new TreeMap<String, PackageVersion>();
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev!=null) {
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleCapability cap : caps) {
+ Map<String, Object> attr = cap.getAttributes();
+ String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
+ Version version = (Version)attr.get("version");
+ String key = packageName + ":" + version.toString();
+ PackageVersion pVer = packageVersionMap.get(key);
+ if (pVer == null) {
+ pVer = new PackageVersion(packageName, version);
+ packageVersionMap.put(key, pVer);
+ }
+ pVer.addBundle(bundle);
+ }
+ }
+ }
+ return packageVersionMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/command/Imports.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/command/Imports.java b/package/src/main/java/org/apache/karaf/packages/command/Imports.java
new file mode 100644
index 0000000..3d086e9
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/command/Imports.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.packages.command;
+
+import java.util.SortedMap;
+
+import org.apache.karaf.packages.core.PackageRequirement;
+import org.apache.karaf.packages.core.PackageService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.Col;
+import org.apache.karaf.shell.support.table.ShellTable;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "package", name = "imports", description = "Lists imported packages and the bundles that import them")
+@Service
+public class Imports implements Action {
+
+ @Option(name = "-p", description = "Only show package instead of full filter", required = false, multiValued = false)
+ boolean onlyPackage;
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ private PackageService packageService;
+
+ @Override
+ public Object execute() throws Exception {
+ SortedMap<String, PackageRequirement> imports = packageService.getImports();
+ ShellTable table = new ShellTable();
+ table.column(new Col(onlyPackage ? "Package name" : "Filter"));
+ table.column(new Col("Optional"));
+ table.column(new Col("ID"));
+ table.column(new Col("Bundle Name"));
+ table.column(new Col("Resolveable"));
+
+ for (String filter : imports.keySet()) {
+ PackageRequirement req = imports.get(filter);
+ Bundle bundle = req.getBundle();
+ String firstCol = onlyPackage ? req.getPackageName() : req.getFilter();
+ table.addRow().addContent(firstCol, req.isOptional() ? "optional" : "", bundle.getBundleId(), bundle.getSymbolicName(), req.isResolveable());
+ }
+ table.print(System.out, !noFormat);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java b/package/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
new file mode 100644
index 0000000..ed8550b
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/PackageRequirement.java
@@ -0,0 +1,64 @@
+/*
+ * 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.packages.core;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Bundle;
+
+public class PackageRequirement {
+ private String filter;
+ private boolean optional;
+ private Bundle bundle;
+ private boolean resolveable;
+ private static Pattern packagePattern = Pattern.compile(".*" + Pattern.quote("(osgi.wiring.package=") + "(.*?)\\).*");
+
+ public PackageRequirement(String filter, boolean optional, Bundle bundle, boolean resolveable) {
+ super();
+ this.filter = filter;
+ this.optional = optional;
+ this.bundle = bundle;
+ this.resolveable = resolveable;
+ }
+
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+ public boolean isOptional() {
+ return optional;
+ }
+
+ public boolean isResolveable() {
+ return resolveable;
+ }
+
+ public String getPackageName() {
+ return getPackageName(filter);
+ }
+
+ public static String getPackageName(String filter) {
+ Matcher matcher = packagePattern.matcher(filter);
+ matcher.matches();
+ return matcher.group(1);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/PackageService.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/PackageService.java b/package/src/main/java/org/apache/karaf/packages/core/PackageService.java
new file mode 100644
index 0000000..d6ccc65
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/PackageService.java
@@ -0,0 +1,51 @@
+/*
+ * 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.packages.core;
+
+import java.util.List;
+import java.util.SortedMap;
+
+public interface PackageService {
+
+ /**
+ * Gets the simplified package exports of a bundle. This does not show the
+ * package versions.
+ *
+ * @param bundleId
+ * @return
+ */
+ List<String> getExports(long bundleId);
+
+ List<String> getImports(long bundleId);
+
+ /**
+ * Gets a map of all exported packages with their version and the bundles that exprot them
+ * The key is in the form packagename:version.
+ *
+ * @return
+ */
+ SortedMap<String, PackageVersion> getExports();
+
+ /**
+ * Gets a map of all package imports.
+ * The key is the import filter.
+ *
+ * @return
+ */
+ SortedMap<String, PackageRequirement> getImports();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/PackageVersion.java b/package/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
new file mode 100644
index 0000000..aed0c48
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/PackageVersion.java
@@ -0,0 +1,52 @@
+/*
+ * 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.packages.core;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+public class PackageVersion {
+
+ private String packageName;
+ private Version version;
+ private Set<Bundle> bundles = new HashSet<Bundle>();
+
+ public PackageVersion(String packageName, Version version) {
+ this.packageName = packageName;
+ this.version = version;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public Version getVersion() {
+ return version;
+ }
+
+ public void addBundle(Bundle bundle) {
+ this.bundles.add(bundle);
+ }
+
+ public Set<Bundle> getBundles() {
+ return this.bundles;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java b/package/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
new file mode 100644
index 0000000..9f07546
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/PackagesMBean.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packages.core;
+
+import java.util.List;
+
+import javax.management.openmbean.TabularData;
+
+/**
+ * Packages MBean.
+ */
+public interface PackagesMBean {
+
+ TabularData getExports();
+ TabularData getImports();
+ List<String> getExports(long bundleId);
+ List<String> getImports(long bundleId);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java b/package/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
new file mode 100644
index 0000000..a7e7dd1
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/internal/PackageServiceImpl.java
@@ -0,0 +1,134 @@
+/*
+ * 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.packages.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.karaf.packages.core.PackageRequirement;
+import org.apache.karaf.packages.core.PackageService;
+import org.apache.karaf.packages.core.PackageVersion;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+public class PackageServiceImpl implements PackageService {
+
+ private final BundleContext bundleContext;
+
+ public PackageServiceImpl(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public SortedMap<String, PackageVersion> getExports() {
+ Bundle[] bundles = bundleContext.getBundles();
+ SortedMap<String, PackageVersion> packageVersionMap = new TreeMap<String, PackageVersion>();
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev != null) {
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleCapability cap : caps) {
+ Map<String, Object> attr = cap.getAttributes();
+ String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
+ Version version = (Version)attr.get("version");
+ String key = packageName + ":" + version.toString();
+ PackageVersion pVer = packageVersionMap.get(key);
+ if (pVer == null) {
+ pVer = new PackageVersion(packageName, version);
+ packageVersionMap.put(key, pVer);
+ }
+ pVer.addBundle(bundle);
+ }
+ }
+ }
+ return packageVersionMap;
+ }
+
+ @Override
+ public SortedMap<String, PackageRequirement> getImports() {
+ Bundle[] bundles = bundleContext.getBundles();
+ SortedMap<String, PackageRequirement> filterMap = new TreeMap<String, PackageRequirement>();
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev != null) {
+ List<BundleRequirement> reqs = rev.getDeclaredRequirements(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleRequirement req : reqs) {
+ Map<String, String> attr = req.getDirectives();
+ String filter = attr.get("filter");
+ String resolution = attr.get("resolution");
+ boolean optional = "optional".equals(resolution);
+ boolean resolveable = checkResolveAble(req);
+ PackageRequirement preq = new PackageRequirement(filter, optional, bundle, resolveable);
+ filterMap.put(filter, preq);
+ }
+ }
+ }
+ return filterMap;
+ }
+
+ private boolean checkResolveAble(BundleRequirement req) {
+ Bundle[] bundles = bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ if (rev != null) {
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleCapability cap : caps) {
+ if (req.matches(cap)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public List<String> getExports(long bundleId) {
+ Bundle bundle = bundleContext.getBundle(bundleId);
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ List<String> exports = new ArrayList<String>();
+ for (BundleCapability cap : caps) {
+ Map<String, Object> attr = cap.getAttributes();
+ String packageName = (String)attr.get(BundleRevision.PACKAGE_NAMESPACE);
+ exports.add(packageName);
+ }
+ return exports ;
+ }
+
+ @Override
+ public List<String> getImports(long bundleId) {
+ Bundle bundle = bundleContext.getBundle(bundleId);
+ BundleRevision rev = bundle.adapt(BundleRevision.class);
+ List<BundleRequirement> reqs = rev.getDeclaredRequirements(BundleRevision.PACKAGE_NAMESPACE);
+ List<String> imports = new ArrayList<String>();
+ for (BundleRequirement req : reqs) {
+ Map<String, String> attr = req.getDirectives();
+ String filter = attr.get("filter");
+ String name = PackageRequirement.getPackageName(filter);
+ imports.add(name);
+ }
+ return imports;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/91232f80/package/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
----------------------------------------------------------------------
diff --git a/package/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java b/package/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
new file mode 100644
index 0000000..bce7b8f
--- /dev/null
+++ b/package/src/main/java/org/apache/karaf/packages/core/internal/PackagesMBeanImpl.java
@@ -0,0 +1,143 @@
+/*
+ * 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.packages.core.internal;
+
+import java.util.List;
+import java.util.SortedMap;
+
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.karaf.packages.core.PackageRequirement;
+import org.apache.karaf.packages.core.PackageService;
+import org.apache.karaf.packages.core.PackageVersion;
+import org.apache.karaf.packages.core.PackagesMBean;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the Packages MBean.
+ */
+public class PackagesMBeanImpl extends StandardMBean implements PackagesMBean {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(PackagesMBeanImpl.class);
+
+ private final PackageService packageService;
+
+ public PackagesMBeanImpl(PackageService packageService) throws NotCompliantMBeanException {
+ super(PackagesMBean.class);
+ this.packageService = packageService;
+ }
+
+ public TabularData getExports() {
+ try {
+ String[] names = new String[] {"Name", "Version", "ID", "Bundle Name"};
+ CompositeType bundleType = new CompositeType("PackageExport", "Exported packages", names,
+ new String[] {"Package name", "Version of the Package",
+ "ID of the Bundle", "Bundle symbolic name"},
+ new OpenType[] {SimpleType.STRING, SimpleType.STRING,
+ SimpleType.LONG, SimpleType.STRING});
+ TabularType tableType = new TabularType("PackageExports", "Exported packages", bundleType,
+ new String[] {"Name", "Version", "ID"});
+ TabularData table = new TabularDataSupport(tableType);
+
+ SortedMap<String, PackageVersion> exports = packageService.getExports();
+
+ for (String key : exports.keySet()) {
+ PackageVersion export = exports.get(key);
+ for (Bundle bundle : export.getBundles()) {
+ Object[] data = new Object[] {
+ export.getPackageName(),
+ export.getVersion().toString(),
+ bundle.getBundleId(),
+ bundle.getSymbolicName()};
+ CompositeData comp = new CompositeDataSupport(bundleType, names, data);
+ LOGGER.debug("Adding CompositeDataSupport {} for key: {}", comp, key);
+ table.put(comp);
+ }
+ }
+ return table;
+ } catch (RuntimeException e) {
+ // To avoid the exception gets swallowed by jmx
+ LOGGER.error(e.getMessage(), e);
+ throw e;
+ } catch (OpenDataException e) {
+ LOGGER.error(e.getMessage(), e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public TabularData getImports() {
+ try {
+ String[] names = new String[] {"PackageName", "Filter", "Optional", "ID", "Bundle Name", "Resolvable"};
+ CompositeType bundleType = new CompositeType("PackageImports", "Imported packages",
+ names,
+ names,
+ new OpenType[] {SimpleType.STRING, SimpleType.STRING, SimpleType.BOOLEAN,
+ SimpleType.LONG, SimpleType.STRING, SimpleType.BOOLEAN});
+ TabularType tableType = new TabularType("PackageImports", "Imported packages", bundleType,
+ new String[] {"Filter", "ID"});
+ TabularData table = new TabularDataSupport(tableType);
+
+ SortedMap<String, PackageRequirement> imports = packageService.getImports();
+
+ for (String key : imports.keySet()) {
+ PackageRequirement req = imports.get(key);
+ Object[] data = new Object[] {
+ req.getPackageName(),
+ req.getFilter(),
+ req.isOptional(),
+ req.getBundle().getBundleId(),
+ req.getBundle().getSymbolicName(),
+ req.isResolveable()};
+ CompositeData comp = new CompositeDataSupport(bundleType, names, data);
+ table.put(comp);
+ }
+ return table;
+ } catch (RuntimeException e) {
+ // To avoid the exception gets swallowed by jmx
+ LOGGER.error(e.getMessage(), e);
+ throw e;
+ } catch (OpenDataException e) {
+ LOGGER.error(e.getMessage(), e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public List<String> getExports(long bundleId) {
+ return packageService.getExports(bundleId);
+
+ }
+
+ @Override
+ public List<String> getImports(long bundleId) {
+ return packageService.getImports(bundleId);
+ }
+
+}
[07/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java b/features/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
new file mode 100644
index 0000000..b1a5865
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/management/FeaturesServiceMBeanImpl.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed 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.internal.management;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+
+import org.apache.karaf.features.*;
+import org.apache.karaf.features.management.FeaturesServiceMBean;
+import org.apache.karaf.features.management.codec.JmxFeature;
+import org.apache.karaf.features.management.codec.JmxFeatureEvent;
+import org.apache.karaf.features.management.codec.JmxRepository;
+import org.apache.karaf.features.management.codec.JmxRepositoryEvent;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Implementation of {@link FeaturesServiceMBean}.
+ */
+public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements
+ MBeanRegistration, FeaturesServiceMBean {
+
+ private ServiceRegistration<FeaturesListener> registration;
+
+ private BundleContext bundleContext;
+
+ private ObjectName objectName;
+
+ private volatile long sequenceNumber = 0;
+
+ private org.apache.karaf.features.FeaturesService featuresService;
+
+ public FeaturesServiceMBeanImpl() throws NotCompliantMBeanException {
+ super(FeaturesServiceMBean.class);
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+ objectName = name;
+ return name;
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ registration = bundleContext.registerService(FeaturesListener.class,
+ getFeaturesListener(), new Hashtable<String, String>());
+ }
+
+ public void preDeregister() throws Exception {
+ registration.unregister();
+ }
+
+ public void postDeregister() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TabularData getFeatures() throws Exception {
+ try {
+ List<Feature> allFeatures = Arrays.asList(featuresService.listFeatures());
+ List<Feature> insFeatures = Arrays.asList(featuresService.listInstalledFeatures());
+ ArrayList<JmxFeature> features = new ArrayList<JmxFeature>();
+ for (Feature feature : allFeatures) {
+ try {
+ features.add(new JmxFeature(feature, insFeatures.contains(feature)));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ TabularData table = JmxFeature.tableFrom(features);
+ return table;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TabularData getRepositories() throws Exception {
+ try {
+ List<Repository> allRepositories = Arrays.asList(featuresService.listRepositories());
+ ArrayList<JmxRepository> repositories = new ArrayList<JmxRepository>();
+ for (Repository repository : allRepositories) {
+ try {
+ repositories.add(new JmxRepository(repository));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ TabularData table = JmxRepository.tableFrom(repositories);
+ return table;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return null;
+ }
+ }
+
+ public void addRepository(String uri) throws Exception {
+ featuresService.addRepository(new URI(uri));
+ }
+
+ public void addRepository(String uri, boolean install) throws Exception {
+ featuresService.addRepository(new URI(uri), install);
+ }
+
+ public void removeRepository(String uri) throws Exception {
+ featuresService.removeRepository(new URI(uri));
+ }
+
+ public void removeRepository(String uri, boolean uninstall) throws Exception {
+ featuresService.removeRepository(new URI(uri), uninstall);
+ }
+
+ public void installFeature(String name) throws Exception {
+ featuresService.installFeature(name);
+ }
+
+ public void installFeature(String name, boolean noRefresh) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ featuresService.installFeature(name, options);
+ }
+
+ public void installFeature(String name, boolean noRefresh, boolean noStart) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (noStart) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoStartBundles);
+ }
+ featuresService.installFeature(name, options);
+ }
+
+ public void installFeature(String name, String version) throws Exception {
+ featuresService.installFeature(name, version);
+ }
+
+ public void installFeature(String name, String version, boolean noRefresh) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ featuresService.installFeature(name, version, options);
+ }
+
+ public void installFeature(String name, String version, boolean noRefresh, boolean noStart) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ if (noStart) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoStartBundles);
+ }
+ featuresService.installFeature(name, version, options);
+ }
+
+ public TabularData infoFeature(String name) throws Exception {
+ try {
+ Feature feature = featuresService.getFeature(name);
+ return infoFeature(feature);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return null;
+ }
+ }
+
+ public TabularData infoFeature(String name, String version) throws Exception {
+ try {
+ Feature feature = featuresService.getFeature(name, version);
+ return infoFeature(feature);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return null;
+ }
+ }
+
+ private TabularData infoFeature(Feature feature) throws Exception {
+ JmxFeature jmxFeature = null;
+ if (featuresService.isInstalled(feature)) {
+ jmxFeature = new JmxFeature(feature, true);
+ } else {
+ jmxFeature = new JmxFeature(feature, false);
+ }
+ ArrayList<JmxFeature> features = new ArrayList<JmxFeature>();
+ features.add(jmxFeature);
+ TabularData table = JmxFeature.tableFrom(features);
+ return table;
+ }
+
+ public void uninstallFeature(String name) throws Exception {
+ featuresService.uninstallFeature(name);
+ }
+
+ public void uninstallFeature(String name, boolean noRefresh) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ featuresService.uninstallFeature(name, options);
+ }
+
+ public void uninstallFeature(String name, String version) throws Exception {
+ featuresService.uninstallFeature(name, version);
+ }
+
+ public void uninstallFeature(String name, String version, boolean noRefresh) throws Exception {
+ EnumSet<org.apache.karaf.features.FeaturesService.Option> options = EnumSet.noneOf(org.apache.karaf.features.FeaturesService.Option.class);
+ if (noRefresh) {
+ options.add(org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles);
+ }
+ featuresService.uninstallFeature(name, version, options);
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setFeaturesService(org.apache.karaf.features.FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+ public FeaturesListener getFeaturesListener() {
+ return new FeaturesListener() {
+ public void featureEvent(FeatureEvent event) {
+ if (!event.isReplay()) {
+ Notification notification = new Notification(FEATURE_EVENT_TYPE, objectName, sequenceNumber++);
+ notification.setUserData(new JmxFeatureEvent(event).asCompositeData());
+ sendNotification(notification);
+ }
+ }
+
+ public void repositoryEvent(RepositoryEvent event) {
+ if (!event.isReplay()) {
+ Notification notification = new Notification(REPOSITORY_EVENT_TYPE, objectName, sequenceNumber++);
+ notification.setUserData(new JmxRepositoryEvent(event).asCompositeData());
+ sendNotification(notification);
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ return o.equals(this);
+ }
+
+ };
+ }
+
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ return getBroadcastInfo();
+ }
+
+ private static MBeanNotificationInfo[] getBroadcastInfo() {
+ String type = Notification.class.getCanonicalName();
+ MBeanNotificationInfo info1 = new MBeanNotificationInfo(new String[]{FEATURE_EVENT_EVENT_TYPE},
+ type, "Some features notification");
+ MBeanNotificationInfo info2 = new MBeanNotificationInfo(new String[]{REPOSITORY_EVENT_EVENT_TYPE},
+ type, "Some repository notification");
+ return new MBeanNotificationInfo[]{info1, info2};
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java b/features/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
new file mode 100644
index 0000000..13a4b6c
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/management/StandardEmitterMBean.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed 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.internal.management;
+
+import javax.management.*;
+
+public class StandardEmitterMBean extends StandardMBean implements NotificationEmitter {
+
+ private final NotificationBroadcasterSupport emitter;
+
+ @SuppressWarnings("rawtypes")
+ public StandardEmitterMBean(Class mbeanInterface) throws NotCompliantMBeanException {
+ super(mbeanInterface);
+ this.emitter = new NotificationBroadcasterSupport() {
+ @Override
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ return StandardEmitterMBean.this.getNotificationInfo();
+ }
+ };
+ }
+
+ public void sendNotification(Notification notification) {
+ emitter.sendNotification(notification);
+ }
+
+
+ public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
+ emitter.removeNotificationListener(listener, filter, handback);
+ }
+
+ public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {
+ emitter.addNotificationListener(listener, filter, handback);
+ }
+
+ public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
+ emitter.removeNotificationListener(listener);
+ }
+
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ return new MBeanNotificationInfo[0];
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ MBeanInfo mbeanInfo = super.getMBeanInfo();
+ if (mbeanInfo != null) {
+ MBeanNotificationInfo[] notificationInfo = getNotificationInfo();
+ mbeanInfo = new MBeanInfo(mbeanInfo.getClassName(), mbeanInfo.getDescription(), mbeanInfo.getAttributes(),
+ mbeanInfo.getConstructors(), mbeanInfo.getOperations(), notificationInfo);
+ }
+ return mbeanInfo;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Bundle.java b/features/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
new file mode 100644
index 0000000..7eebbe5
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Bundle.java
@@ -0,0 +1,198 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+import org.apache.karaf.features.BundleInfo;
+
+
+/**
+ *
+ * Deployable element to install.
+ *
+ *
+ * <p>Java class for bundle complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="bundle">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>anyURI">
+ * <attribute name="start-level" type="{http://www.w3.org/2001/XMLSchema}int" />
+ * <attribute name="start" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * <attribute name="dependency" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "bundle", propOrder = {
+ "value"
+})
+public class Bundle implements BundleInfo {
+
+ @XmlValue
+ @XmlSchemaType(name = "anyURI")
+ protected String value;
+ @XmlAttribute(name = "start-level")
+ protected Integer startLevel;
+ @XmlAttribute
+ protected Boolean start;// = true;
+ @XmlAttribute
+ protected Boolean dependency;
+
+
+ public Bundle() {
+ }
+
+ public Bundle(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLocation() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLocation(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the startLevel property.
+ *
+ * @return
+ * possible object is
+ * {@link Integer }
+ *
+ */
+ public int getStartLevel() {
+ return startLevel == null? 0: startLevel;
+ }
+
+ /**
+ * Sets the value of the startLevel property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Integer }
+ *
+ */
+ public void setStartLevel(Integer value) {
+ this.startLevel = value;
+ }
+
+ /**
+ * Gets the value of the start property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public boolean isStart() {
+ return start == null? true: start;
+ }
+
+ /**
+ * Sets the value of the start property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setStart(Boolean value) {
+ this.start = value;
+ }
+
+ /**
+ * Gets the value of the dependency property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public boolean isDependency() {
+ return dependency == null? false: dependency;
+ }
+
+ /**
+ * Sets the value of the dependency property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setDependency(Boolean value) {
+ this.dependency = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Bundle bundle = (Bundle) o;
+
+ if (dependency != bundle.dependency) return false;
+ if (start != bundle.start) return false;
+ if (startLevel != bundle.startLevel) return false;
+ if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = value != null ? value.hashCode() : 0;
+ result = 31 * result + getStartLevel();
+ result = 31 * result + (isStart() ? 1 : 0);
+ result = 31 * result + (isDependency() ? 1 : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Capability.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Capability.java b/features/src/main/java/org/apache/karaf/features/internal/model/Capability.java
new file mode 100644
index 0000000..ef60454
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Capability.java
@@ -0,0 +1,89 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+import org.apache.karaf.features.BundleInfo;
+
+
+/**
+ *
+ * Additional capability for a feature.
+ *
+ *
+ * <p>Java class for bundle complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="capability">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "capability", propOrder = {
+ "value"
+})
+public class Capability implements org.apache.karaf.features.Capability {
+
+ @XmlValue
+ protected String value;
+
+
+ public Capability() {
+ }
+
+ public Capability(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Capability bundle = (Capability) o;
+
+ if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = value != null ? value.hashCode() : 0;
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Conditional.java b/features/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
new file mode 100644
index 0000000..5bc0b95
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Conditional.java
@@ -0,0 +1,71 @@
+/*
+ * 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.internal.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.karaf.features.Feature;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "conditional", propOrder = {
+ "condition",
+ "config",
+ "configfile",
+ "feature",
+ "bundle"
+})
+public class Conditional extends Content implements org.apache.karaf.features.Conditional {
+
+ @XmlElement(name = "condition")
+ protected List<Dependency> condition;
+
+ public List<Dependency> getCondition() {
+ if (condition == null) {
+ this.condition = new ArrayList<Dependency>();
+ }
+ return condition;
+ }
+
+ @Override
+ public Feature asFeature(String name, String version) {
+ String conditionName = name + "-condition-" + getConditionId().replaceAll("[^A-Za-z0-9 ]", "_");
+ org.apache.karaf.features.internal.model.Feature f = new org.apache.karaf.features.internal.model.Feature(conditionName, version);
+ f.getBundle().addAll(getBundle());
+ f.getConfig().addAll(getConfig());
+ f.getConfigfile().addAll(getConfigfile());
+ f.getFeature().addAll(getFeature());
+ return f;
+ }
+
+ private String getConditionId() {
+ StringBuffer sb = new StringBuffer();
+ Iterator<Dependency> di = getCondition().iterator();
+ while (di.hasNext()) {
+ Dependency dependency = di.next();
+ sb.append(dependency.getName() + "_" + dependency.getVersion());
+ if (di.hasNext()) {
+ sb.append("_");
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Config.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Config.java b/features/src/main/java/org/apache/karaf/features/internal/model/Config.java
new file mode 100644
index 0000000..a2c6674
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Config.java
@@ -0,0 +1,110 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+
+/**
+ *
+ * Configuration entries which should be created during feature installation. This
+ * configuration may be used with OSGi Configuration Admin.
+ *
+ *
+ * <p>Java class for config complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="config">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "config", propOrder = {
+ "value"
+})
+public class Config {
+
+ @XmlValue
+ protected String value;
+ @XmlAttribute(required = true)
+ protected String name;
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java b/features/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
new file mode 100644
index 0000000..e5d9d94
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/ConfigFile.java
@@ -0,0 +1,136 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+import org.apache.karaf.features.ConfigFileInfo;
+
+
+/**
+ *
+ * Additional configuration files which should be created during feature installation.
+ *
+ *
+ * <p>Java class for configFile complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="configFile">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ * <attribute name="finalname" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="override" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "configFile", propOrder = {
+ "value"
+})
+public class ConfigFile implements ConfigFileInfo {
+
+ @XmlValue
+ protected String value;
+ @XmlAttribute(required = true)
+ protected String finalname;
+ @XmlAttribute
+ protected Boolean override;
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLocation() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLocation(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the finalname property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getFinalname() {
+ return finalname;
+ }
+
+ /**
+ * Sets the value of the finalname property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setFinalname(String value) {
+ this.finalname = value;
+ }
+
+ /**
+ * Gets the value of the override property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public boolean isOverride() {
+ return override == null? false: override;
+ }
+
+ /**
+ * Sets the value of the override property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setOverride(Boolean value) {
+ this.override = value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Content.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Content.java b/features/src/main/java/org/apache/karaf/features/internal/model/Content.java
new file mode 100644
index 0000000..756e4c1
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Content.java
@@ -0,0 +1,199 @@
+/*
+ * 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.internal.model;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.bind.annotation.XmlTransient;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.ConfigFileInfo;
+
+@XmlTransient
+public class Content {
+
+ protected List<Config> config;
+ protected List<ConfigFile> configfile;
+ protected List<Dependency> feature;
+ protected List<Bundle> bundle;
+
+ /**
+ * Gets the value of the config property.
+ * <p/>
+ * <p/>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the config property.
+ * <p/>
+ * <p/>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getConfig().add(newItem);
+ * </pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * Objects of the following type(s) are allowed in the list
+ * {@link Config }
+ */
+ public List<Config> getConfig() {
+ if (config == null) {
+ config = new ArrayList<Config>();
+ }
+ return this.config;
+ }
+
+ /**
+ * Gets the value of the configfile property.
+ * <p/>
+ * <p/>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the configfile property.
+ * <p/>
+ * <p/>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getConfigfile().add(newItem);
+ * </pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * Objects of the following type(s) are allowed in the list
+ * {@link ConfigFile }
+ */
+ public List<ConfigFile> getConfigfile() {
+ if (configfile == null) {
+ configfile = new ArrayList<ConfigFile>();
+ }
+ return this.configfile;
+ }
+
+ /**
+ * Gets the value of the feature property.
+ * <p/>
+ * <p/>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the feature property.
+ * <p/>
+ * <p/>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getFeature().add(newItem);
+ * </pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * Objects of the following type(s) are allowed in the list
+ * {@link Dependency }
+ */
+ public List<Dependency> getFeature() {
+ if (feature == null) {
+ feature = new ArrayList<Dependency>();
+ }
+ return this.feature;
+ }
+
+ /**
+ * Gets the value of the bundle property.
+ * <p/>
+ * <p/>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the bundle property.
+ * <p/>
+ * <p/>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getBundle().add(newItem);
+ * </pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * Objects of the following type(s) are allowed in the list
+ * {@link Bundle }
+ */
+ public List<Bundle> getBundle() {
+ if (bundle == null) {
+ bundle = new ArrayList<Bundle>();
+ }
+ return this.bundle;
+ }
+
+ public List<org.apache.karaf.features.Dependency> getDependencies() {
+ return Collections.<org.apache.karaf.features.Dependency>unmodifiableList(getFeature());
+ }
+
+ public List<BundleInfo> getBundles() {
+ return Collections.<BundleInfo>unmodifiableList(getBundle());
+ }
+
+ public Map<String, Map<String, String>> getConfigurations() {
+ Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
+ for (Config config : getConfig()) {
+ String name = config.getName();
+ StringReader propStream = new StringReader(config.getValue());
+ Properties props = new Properties();
+ try {
+ props.load(propStream);
+ } catch (IOException e) {
+ //ignore??
+ }
+ interpolation(props);
+ Map<String, String> propMap = new HashMap<String, String>();
+ for (Map.Entry<Object, Object> entry : props.entrySet()) {
+ propMap.put((String) entry.getKey(), (String) entry.getValue());
+ }
+ result.put(name, propMap);
+ }
+ return result;
+ }
+
+ public List<ConfigFileInfo> getConfigurationFiles() {
+ return Collections.<ConfigFileInfo>unmodifiableList(getConfigfile());
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected void interpolation(Properties properties) {
+ for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
+ String key = (String) e.nextElement();
+ String val = properties.getProperty(key);
+ Matcher matcher = Pattern.compile("\\$\\{([^}]+)\\}").matcher(val);
+ while (matcher.find()) {
+ String rep = System.getProperty(matcher.group(1));
+ if (rep != null) {
+ val = val.replace(matcher.group(0), rep);
+ matcher.reset(val);
+ }
+ }
+ properties.put(key, val);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Dependency.java b/features/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
new file mode 100644
index 0000000..9c92a93
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
@@ -0,0 +1,121 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+
+/**
+ *
+ * Dependency of feature.
+ *
+ *
+ * <p>Java class for dependency complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="dependency">
+ * <simpleContent>
+ * <extension base="<http://karaf.apache.org/xmlns/features/v1.0.0>featureName">
+ * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" default="0.0.0" />
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "dependency", propOrder = {
+ "value"
+})
+public class Dependency implements org.apache.karaf.features.Dependency {
+
+ @XmlValue
+ protected String value;
+ @XmlAttribute
+ protected String version;
+
+ /**
+ *
+ * Feature name should be non empty string.
+ *
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the version property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getVersion() {
+ if (version == null) {
+ return "0.0.0";
+ } else {
+ return version;
+ }
+ }
+
+ /**
+ * Sets the value of the version property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setVersion(String value) {
+ this.version = value;
+ }
+
+ public String toString() {
+ String ret = getName() + Feature.SPLIT_FOR_NAME_AND_VERSION + getVersion();
+ return ret;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Feature.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Feature.java b/features/src/main/java/org/apache/karaf/features/internal/model/Feature.java
new file mode 100644
index 0000000..46580da
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Feature.java
@@ -0,0 +1,374 @@
+/*
+ * 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.internal.model;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ *
+ * Definition of the Feature.
+ *
+ *
+ * <p>Java class for feature complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="feature">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="details" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="config" type="{http://karaf.apache.org/xmlns/features/v1.0.0}config" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="configfile" type="{http://karaf.apache.org/xmlns/features/v1.0.0}configFile" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="feature" type="{http://karaf.apache.org/xmlns/features/v1.0.0}dependency" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="bundle" type="{http://karaf.apache.org/xmlns/features/v1.0.0}bundle" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="conditional" type="{http://karaf.apache.org/xmlns/features/v1.0.0}conditional" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="capability" type="{http://karaf.apache.org/xmlns/features/v1.0.0}capability" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="requirement" type="{http://karaf.apache.org/xmlns/features/v1.0.0}requirement" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="name" use="required" type="{http://karaf.apache.org/xmlns/features/v1.0.0}featureName" />
+ * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" default="0.0.0" />
+ * <attribute name="description" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="resolver" type="{http://karaf.apache.org/xmlns/features/v1.0.0}resolver" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "feature", propOrder = {
+ "details",
+ "config",
+ "configfile",
+ "feature",
+ "bundle",
+ "conditional",
+ "capability",
+ "requirement"
+})
+public class Feature extends Content implements org.apache.karaf.features.Feature {
+ public static String SPLIT_FOR_NAME_AND_VERSION = "/";
+ public static String DEFAULT_VERSION = "0.0.0";
+
+
+ protected String details;
+ @XmlAttribute(required = true)
+ protected String name;
+ @XmlAttribute
+ protected String version;
+ @XmlAttribute
+ protected String description;
+ @XmlAttribute
+ protected String resolver;
+ @XmlAttribute
+ protected String install;
+ @XmlAttribute(name = "start-level")
+ protected Integer startLevel;
+ @XmlAttribute
+ protected String region;
+ protected List<Conditional> conditional;
+ protected List<Capability> capability;
+ protected List<Requirement> requirement;
+
+ public Feature() {
+ }
+
+ public Feature(String name) {
+ this.name = name;
+ }
+
+ public Feature(String name, String version) {
+ this.name = name;
+ this.version = version;
+ }
+
+
+ public static org.apache.karaf.features.Feature valueOf(String str) {
+ if (str.contains(SPLIT_FOR_NAME_AND_VERSION)) {
+ String strName = str.substring(0, str.indexOf(SPLIT_FOR_NAME_AND_VERSION));
+ String strVersion = str.substring(str.indexOf(SPLIT_FOR_NAME_AND_VERSION)
+ + SPLIT_FOR_NAME_AND_VERSION.length(), str.length());
+ return new Feature(strName, strVersion);
+ } else {
+ return new Feature(str);
+ }
+
+
+ }
+
+
+ public String getId() {
+ return getName() + SPLIT_FOR_NAME_AND_VERSION + getVersion();
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ /**
+ * Gets the value of the version property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getVersion() {
+ if (version == null) {
+ return DEFAULT_VERSION;
+ } else {
+ return version;
+ }
+ }
+
+ /**
+ * Sets the value of the version property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setVersion(String value) {
+ this.version = value;
+ }
+
+ /**
+ * Since version has a default value ("0.0.0"), returns
+ * whether or not the version has been set.
+ */
+ public boolean hasVersion() {
+ return this.version != null;
+ }
+
+ /**
+ * Gets the value of the description property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets the value of the description property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setDescription(String value) {
+ this.description = value;
+ }
+
+ public String getDetails() {
+ return details;
+ }
+
+ public void setDetails(String details) {
+ this.details = details;
+ }
+
+ /**
+ * Gets the value of the resolver property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getResolver() {
+ return resolver;
+ }
+
+ public String getInstall() {
+ return install;
+ }
+
+ public void setInstall(String install) {
+ this.install = install;
+ }
+
+ /**
+ * Sets the value of the resolver property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setResolver(String value) {
+ this.resolver = value;
+ }
+
+ /**
+ * Gets the value of the startLevel property.
+ *
+ * @return
+ * possible object is
+ * {@link Integer }
+ *
+ */
+ public int getStartLevel() {
+ return startLevel == null? 0: startLevel;
+ }
+
+ /**
+ * Sets the value of the startLevel property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Integer }
+ *
+ */
+ public void setStartLevel(Integer value) {
+ this.startLevel = value;
+ }
+
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ /**
+ * Gets the value of the conditional property.
+ * <p/>
+ * <p/>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the feature property.
+ * <p/>
+ * <p/>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getConditionals().add(newItem);
+ * </pre>
+ * <p/>
+ * <p/>
+ * <p/>
+ * Objects of the following type(s) are allowed in the list
+ * {@link Conditional }
+ */
+ public List<Conditional> getConditional() {
+ if (conditional == null) {
+ conditional = new ArrayList<Conditional>();
+ }
+ return this.conditional;
+ }
+
+ public List<Capability> getCapabilities() {
+ if (capability == null) {
+ capability = new ArrayList<Capability>();
+ }
+ return this.capability;
+ }
+
+ public List<Requirement> getRequirements() {
+ if (requirement == null) {
+ requirement = new ArrayList<Requirement>();
+ }
+ return this.requirement;
+ }
+
+ public String toString() {
+ return getId();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Feature feature = (Feature) o;
+
+ if (name != null ? !name.equals(feature.name) : feature.name != null) return false;
+ if (version != null ? !version.equals(feature.version) : feature.version != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (version != null ? version.hashCode() : 0);
+ return result;
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected void interpolation(Properties properties) {
+ for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String val = properties.getProperty(key);
+ Matcher matcher = Pattern.compile("\\$\\{([^}]+)\\}").matcher(val);
+ while (matcher.find()) {
+ String rep = System.getProperty(matcher.group(1));
+ if (rep != null) {
+ val = val.replace(matcher.group(0), rep);
+ matcher.reset(val);
+ }
+ }
+ properties.put(key, val);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Features.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Features.java b/features/src/main/java/org/apache/karaf/features/internal/model/Features.java
new file mode 100644
index 0000000..e116f31
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Features.java
@@ -0,0 +1,155 @@
+/*
+ * 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.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ *
+ * Root element of Feature definition. It contains optional attribute which allow
+ * name of repository. This name will be used in shell to display source repository
+ * of given feature.
+ *
+ *
+ * <p>Java class for featuresRoot complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="features">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="repository" type="{http://www.w3.org/2001/XMLSchema}anyURI" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="feature" type="{http://karaf.apache.org/xmlns/features/v1.0.0}feature" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlRootElement(name = "features")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "features", propOrder = {
+ "repository",
+ "feature"
+})
+public class Features {
+
+ @XmlSchemaType(name = "anyURI")
+ protected List<String> repository;
+ protected List<Feature> feature;
+ @XmlAttribute
+ protected String name;
+
+ /**
+ * Gets the value of the repository property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the repository property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getRepository().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link String }
+ *
+ *
+ */
+ public List<String> getRepository() {
+ if (repository == null) {
+ repository = new ArrayList<String>();
+ }
+ return this.repository;
+ }
+
+ /**
+ * Gets the value of the feature property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the feature property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getFeature().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link Feature }
+ *
+ *
+ */
+ public List<Feature> getFeature() {
+ if (feature == null) {
+ feature = new ArrayList<Feature>();
+ }
+ return this.feature;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java b/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
new file mode 100644
index 0000000..39c057a
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/JaxbUtil.java
@@ -0,0 +1,149 @@
+/*
+ * 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.internal.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.ValidationEvent;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.karaf.features.FeaturesNamespaces;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+public class JaxbUtil {
+
+ public static final XMLInputFactory XMLINPUT_FACTORY = XMLInputFactory.newInstance();
+ private static final JAXBContext FEATURES_CONTEXT;
+ static {
+ try {
+ FEATURES_CONTEXT = JAXBContext.newInstance(Features.class);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void marshal(Features features, OutputStream out) throws JAXBException {
+ Marshaller marshaller = FEATURES_CONTEXT.createMarshaller();
+
+ marshaller.setProperty("jaxb.formatted.output", true);
+
+ marshaller.marshal(features, out);
+ }
+
+ public static void marshal(Features features, Writer out) throws JAXBException {
+ Marshaller marshaller = FEATURES_CONTEXT.createMarshaller();
+
+ marshaller.setProperty("jaxb.formatted.output", true);
+
+ marshaller.marshal(features, out);
+ }
+
+
+ /**
+ * Read in a Features from the input stream.
+ *
+ * @param in input stream to read
+ * @param validate whether to validate the input.
+ * @return a Features read from the input stream
+ * @throws ParserConfigurationException is the SAX parser can not be configured
+ * @throws SAXException if there is an xml problem
+ * @throws JAXBException if the xml cannot be marshalled into a T.
+ */
+ public static Features unmarshal(InputStream in, boolean validate) {
+ InputSource inputSource = new InputSource(in);
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setValidating(validate);
+ SAXParser parser;
+ try {
+ parser = factory.newSAXParser();
+
+
+ Unmarshaller unmarshaller = FEATURES_CONTEXT.createUnmarshaller();
+ unmarshaller.setEventHandler(new ValidationEventHandler() {
+ public boolean handleEvent(ValidationEvent validationEvent) {
+ System.out.println(validationEvent);
+ return false;
+ }
+ });
+
+ XMLFilter xmlFilter = new NoSourceAndNamespaceFilter(parser.getXMLReader());
+ xmlFilter.setContentHandler(unmarshaller.getUnmarshallerHandler());
+
+ SAXSource source = new SAXSource(xmlFilter, inputSource);
+
+ return (Features)unmarshaller.unmarshal(source);
+
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Provides an empty inputsource for the entity resolver.
+ * Converts all elements to the features namespace to make old feature files
+ * compatible to the new format
+ */
+ public static class NoSourceAndNamespaceFilter extends XMLFilterImpl {
+ private static final InputSource EMPTY_INPUT_SOURCE = new InputSource(new ByteArrayInputStream(new byte[0]));
+
+ public NoSourceAndNamespaceFilter(XMLReader xmlReader) {
+ super(xmlReader);
+ }
+
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+ return EMPTY_INPUT_SOURCE;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+ super.startElement(FeaturesNamespaces.URI_CURRENT, localName, qName, atts);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ super.endElement(FeaturesNamespaces.URI_CURRENT, localName, qName);
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java b/features/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
new file mode 100644
index 0000000..96fbb0f
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/ObjectFactory.java
@@ -0,0 +1,111 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the org.apache.karaf.features.wrapper package.
+ * <p>An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+ private final static QName _Features_QNAME = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features");
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.karaf.features.wrapper
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link ConfigFile }
+ *
+ */
+ public ConfigFile createConfigFile() {
+ return new ConfigFile();
+ }
+
+ /**
+ * Create an instance of {@link Dependency }
+ *
+ */
+ public Dependency createDependency() {
+ return new Dependency();
+ }
+
+ /**
+ * Create an instance of {@link Bundle }
+ *
+ */
+ public Bundle createBundle() {
+ return new Bundle();
+ }
+
+ /**
+ * Create an instance of {@link Features }
+ *
+ */
+ public Features createFeaturesRoot() {
+ return new Features();
+ }
+
+ /**
+ * Create an instance of {@link Config }
+ *
+ */
+ public Config createConfig() {
+ return new Config();
+ }
+
+ /**
+ * Create an instance of {@link Feature }
+ *
+ */
+ public Feature createFeature() {
+ return new Feature();
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link Features }{@code >}}
+ *
+ */
+ @XmlElementDecl(namespace = "http://karaf.apache.org/xmlns/features/v1.0.0", name = "features")
+ public JAXBElement<Features> createFeatures(Features value) {
+ return new JAXBElement<Features>(_Features_QNAME, Features.class, null, value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/Requirement.java b/features/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
new file mode 100644
index 0000000..f7b5775
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/Requirement.java
@@ -0,0 +1,87 @@
+/*
+ * 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.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+
+/**
+ *
+ * Additional requirement for a feature.
+ *
+ *
+ * <p>Java class for bundle complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="capability">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "requirement", propOrder = {
+ "value"
+})
+public class Requirement implements org.apache.karaf.features.Requirement {
+
+ @XmlValue
+ protected String value;
+
+
+ public Requirement() {
+ }
+
+ public Requirement(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Requirement bundle = (Requirement) o;
+
+ if (value != null ? !value.equals(bundle.value) : bundle.value != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = value != null ? value.hashCode() : 0;
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/model/package-info.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/model/package-info.java b/features/src/main/java/org/apache/karaf/features/internal/model/package-info.java
new file mode 100644
index 0000000..c86a58c
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/model/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+@javax.xml.bind.annotation.XmlSchema(namespace = org.apache.karaf.features.FeaturesNamespaces.URI_CURRENT, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.karaf.features.internal.model;
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
new file mode 100644
index 0000000..be0da05
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
@@ -0,0 +1,208 @@
+/*
+ * 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.internal.osgi;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import org.apache.karaf.features.FeaturesListener;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.internal.service.EventAdminListener;
+import org.apache.karaf.features.internal.service.FeatureConfigInstaller;
+import org.apache.karaf.features.internal.service.FeatureFinder;
+import org.apache.karaf.features.internal.service.BootFeaturesInstaller;
+import org.apache.karaf.features.internal.service.FeaturesServiceImpl;
+import org.apache.karaf.features.internal.service.StateStorage;
+import org.apache.karaf.features.internal.management.FeaturesServiceMBeanImpl;
+import org.apache.karaf.features.RegionsPersistence;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.util.tracker.SingleServiceTracker;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.url.URLStreamHandlerService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class Activator extends BaseActivator {
+
+ public static final String FEATURES_REPOS_PID = "org.apache.karaf.features.repos";
+ public static final String FEATURES_SERVICE_CONFIG_FILE = "org.apache.karaf.features.cfg";
+
+ private ServiceTracker<FeaturesListener, FeaturesListener> featuresListenerTracker;
+ private FeaturesServiceImpl featuresService;
+ private SingleServiceTracker<RegionsPersistence> regionsTracker;
+
+ public Activator() {
+ // Special case here, as we don't want the activator to wait for current job to finish,
+ // else it would forbid the features service to refresh itself
+ setSchedulerStopTimeout(0);
+ }
+
+ @Override
+ protected void doOpen() throws Exception {
+ trackService(URLStreamHandlerService.class, "(url.handler.protocol=mvn)");
+ trackService(ConfigurationAdmin.class);
+
+ Properties configuration = new Properties();
+ File configFile = new File(System.getProperty("karaf.etc"), FEATURES_SERVICE_CONFIG_FILE);
+ if (configFile.isFile() && configFile.canRead()) {
+ try {
+ configuration.load(new FileReader(configFile));
+ } catch (IOException e) {
+ logger.warn("Error reading configuration file " + configFile.toString(), e);
+ }
+ }
+ updated((Dictionary) configuration);
+ }
+
+ protected void doStart() throws Exception {
+ ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
+ URLStreamHandlerService mvnUrlHandler = getTrackedService(URLStreamHandlerService.class);
+
+ if (configurationAdmin == null || mvnUrlHandler == null) {
+ return;
+ }
+
+ FeatureFinder featureFinder = new FeatureFinder();
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_PID, FEATURES_REPOS_PID);
+ register(ManagedService.class, featureFinder, props);
+
+ // TODO: region support
+// final BundleManager bundleManager = new BundleManager(bundleContext);
+// regionsTracker = new SingleServiceTracker<RegionsPersistence>(bundleContext, RegionsPersistence.class,
+// new SingleServiceTracker.SingleServiceListener() {
+// @Override
+// public void serviceFound() {
+// bundleManager.setRegionsPersistence(regionsTracker.getService());
+// }
+// @Override
+// public void serviceLost() {
+// serviceFound();
+// }
+// @Override
+// public void serviceReplaced() {
+// serviceFound();
+// }
+// });
+// regionsTracker.open();
+
+
+ FeatureConfigInstaller configInstaller = new FeatureConfigInstaller(configurationAdmin);
+ // TODO: honor respectStartLvlDuringFeatureStartup and respectStartLvlDuringFeatureUninstall
+// boolean respectStartLvlDuringFeatureStartup = getBoolean("respectStartLvlDuringFeatureStartup", true);
+// boolean respectStartLvlDuringFeatureUninstall = getBoolean("respectStartLvlDuringFeatureUninstall", true);
+ String overrides = getString("overrides", new File(System.getProperty("karaf.etc"), "overrides.properties").toURI().toString());
+ String featureResolutionRange = getString("featureResolutionRange", FeaturesServiceImpl.DEFAULT_FEATURE_RESOLUTION_RANGE);
+ String bundleUpdateRange = getString("bundleUpdateRange", FeaturesServiceImpl.DEFAULT_BUNDLE_UPDATE_RANGE);
+ String updateSnapshots = getString("updateSnapshots", FeaturesServiceImpl.DEFAULT_UPDATE_SNAPSHOTS);
+ StateStorage stateStorage = new StateStorage() {
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ File file = bundleContext.getDataFile("FeaturesServiceState.properties");
+ if (file.exists()) {
+ return new FileInputStream(file);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ protected OutputStream getOutputStream() throws IOException {
+ File file = bundleContext.getDataFile("FeaturesServiceState.properties");
+ return new FileOutputStream(file);
+ }
+ };
+ EventAdminListener eventAdminListener;
+ try {
+ eventAdminListener = new EventAdminListener(bundleContext);
+ } catch (Throwable t) {
+ eventAdminListener = null;
+ }
+ featuresService = new FeaturesServiceImpl(
+ bundleContext.getBundle(),
+ bundleContext.getBundle(0).getBundleContext(),
+ stateStorage,
+ featureFinder,
+ eventAdminListener,
+ configInstaller,
+ overrides,
+ featureResolutionRange,
+ bundleUpdateRange,
+ updateSnapshots);
+ register(FeaturesService.class, featuresService);
+
+ featuresListenerTracker = new ServiceTracker<FeaturesListener, FeaturesListener>(
+ bundleContext, FeaturesListener.class, new ServiceTrackerCustomizer<FeaturesListener, FeaturesListener>() {
+ @Override
+ public FeaturesListener addingService(ServiceReference<FeaturesListener> reference) {
+ FeaturesListener service = bundleContext.getService(reference);
+ featuresService.registerListener(service);
+ return service;
+ }
+ @Override
+ public void modifiedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
+ }
+ @Override
+ public void removedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
+ featuresService.unregisterListener(service);
+ bundleContext.ungetService(reference);
+ }
+ }
+ );
+ featuresListenerTracker.open();
+
+ String featuresRepositories = getString("featuresRepositories", "");
+ String featuresBoot = getString("featuresBoot", "");
+ boolean featuresBootAsynchronous = getBoolean("featuresBootAsynchronous", false);
+ BootFeaturesInstaller bootFeaturesInstaller = new BootFeaturesInstaller(
+ bundleContext, featuresService,
+ featuresRepositories, featuresBoot, featuresBootAsynchronous);
+ bootFeaturesInstaller.start();
+
+ FeaturesServiceMBeanImpl featuresServiceMBean = new FeaturesServiceMBeanImpl();
+ featuresServiceMBean.setBundleContext(bundleContext);
+ featuresServiceMBean.setFeaturesService(featuresService);
+ registerMBean(featuresServiceMBean, "type=feature");
+ }
+
+ protected void doStop() {
+ if (regionsTracker != null) {
+ regionsTracker.close();
+ regionsTracker = null;
+ }
+ if (featuresListenerTracker != null) {
+ featuresListenerTracker.close();
+ featuresListenerTracker = null;
+ }
+ super.doStop();
+ if (featuresService != null) {
+ featuresService = null;
+ }
+ }
+
+}
[56/59] [abbrv] git commit: [KARAF-2852] Merge region/core and
region/command
Posted by gn...@apache.org.
[KARAF-2852] Merge region/core and region/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/1bcdb173
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/1bcdb173
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/1bcdb173
Branch: refs/heads/master
Commit: 1bcdb173169e899deebd91654eb1a14b24a6f584
Parents: 2b7e96d
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 10:16:41 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:03:02 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 2 +-
region/NOTICE | 71 ++
region/command/NOTICE | 71 --
region/command/pom.xml | 100 ---
.../karaf/region/commands/AddBundleCommand.java | 52 --
.../karaf/region/commands/AddFilterCommand.java | 169 -----
.../karaf/region/commands/AddRegionCommand.java | 38 --
.../karaf/region/commands/InfoCommand.java | 117 ----
.../region/commands/RegionCommandSupport.java | 79 ---
.../karaf/region/commands/util/FileUtil.java | 177 -----
.../src/main/resources/OSGI-INF/bundle.info | 18 -
region/core/NOTICE | 71 --
region/core/pom.xml | 122 ----
.../region/persist/internal/Activator.java | 91 ---
.../persist/internal/RegionsBundleTracker.java | 77 ---
.../internal/RegionsPersistenceImpl.java | 203 ------
.../internal/model/FilterAttributeType.java | 94 ---
.../internal/model/FilterBundleType.java | 156 -----
.../internal/model/FilterNamespaceType.java | 102 ---
.../internal/model/FilterPackageType.java | 129 ----
.../persist/internal/model/FilterType.java | 195 ------
.../persist/internal/model/ObjectFactory.java | 116 ----
.../internal/model/RegionBundleType.java | 94 ---
.../persist/internal/model/RegionType.java | 106 ---
.../persist/internal/model/RegionsType.java | 112 ----
.../persist/internal/model/package-info.java | 9 -
.../internal/util/ManifestHeaderProcessor.java | 661 -------------------
.../internal/util/ManifestHeaderUtils.java | 85 ---
.../persist/internal/util/VersionRange.java | 456 -------------
.../org/apache/karaf/region/persist/region.xsd | 109 ---
region/pom.xml | 190 +++---
.../karaf/region/commands/AddBundleCommand.java | 52 ++
.../karaf/region/commands/AddFilterCommand.java | 169 +++++
.../karaf/region/commands/AddRegionCommand.java | 38 ++
.../karaf/region/commands/InfoCommand.java | 117 ++++
.../region/commands/RegionCommandSupport.java | 79 +++
.../karaf/region/commands/util/FileUtil.java | 177 +++++
.../region/persist/internal/Activator.java | 91 +++
.../persist/internal/RegionsBundleTracker.java | 77 +++
.../internal/RegionsPersistenceImpl.java | 203 ++++++
.../internal/model/FilterAttributeType.java | 94 +++
.../internal/model/FilterBundleType.java | 156 +++++
.../internal/model/FilterNamespaceType.java | 102 +++
.../internal/model/FilterPackageType.java | 129 ++++
.../persist/internal/model/FilterType.java | 195 ++++++
.../persist/internal/model/ObjectFactory.java | 116 ++++
.../internal/model/RegionBundleType.java | 94 +++
.../persist/internal/model/RegionType.java | 106 +++
.../persist/internal/model/RegionsType.java | 112 ++++
.../persist/internal/model/package-info.java | 9 +
.../internal/util/ManifestHeaderProcessor.java | 661 +++++++++++++++++++
.../internal/util/ManifestHeaderUtils.java | 85 +++
.../persist/internal/util/VersionRange.java | 456 +++++++++++++
.../org/apache/karaf/region/persist/region.xsd | 109 +++
54 files changed, 3603 insertions(+), 3896 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/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 fb3dd93..4d06455 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -146,9 +146,9 @@
</feature>
<feature name="region" description="Provide Region Support" version="${project.version}">
+ <bundle dependency="true" start-level="20">mvn:org.apache.aries/org.apache.aries.util/${aries.util.version}</bundle>
<bundle start-level="30">mvn:org.eclipse.equinox/region/${equinox.region.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.region/org.apache.karaf.region.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.region/org.apache.karaf.region.command/${project.version}</bundle>
</feature>
<feature name="package" version="${project.version}" resolver="(obr)" description="Package commands and mbeans">
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/NOTICE
----------------------------------------------------------------------
diff --git a/region/NOTICE b/region/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/region/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/1bcdb173/region/command/NOTICE
----------------------------------------------------------------------
diff --git a/region/command/NOTICE b/region/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/region/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/1bcdb173/region/command/pom.xml
----------------------------------------------------------------------
diff --git a/region/command/pom.xml b/region/command/pom.xml
deleted file mode 100644
index e5382a3..0000000
--- a/region/command/pom.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?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.region</groupId>
- <artifactId>region</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>org.apache.karaf.region.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Region :: Shell Commands</name>
- <description>This bundle provides Karaf shell commands to manipulate the Region service.</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.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.aries</groupId>
- <artifactId>org.apache.aries.util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.eclipse.equinox</groupId>
- <artifactId>region</artifactId>
- <version>1.0.0.v20110506</version>
- </dependency>
-
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java b/region/command/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
deleted file mode 100644
index 30af1e0..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.region.commands;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "region", name = "bundle-add", description = "Adds a list of known bundles by id to a specified region.")
-@Service
-public class AddBundleCommand extends RegionCommandSupport {
-
- @Argument(index = 0, name = "region", description = "Region to add the bundles to", required = true, multiValued = false)
- String region;
-
- @Argument(index = 1, name = "bundles", description = "Bundles by id to add to the region", required = true, multiValued = true)
- List<Long> ids;
-
- protected void doExecute(RegionDigraph regionDigraph) throws Exception {
- Region r = getRegion(regionDigraph, region);
- for (Long id : ids) {
- for (Region existing: regionDigraph.getRegions()) {
- if (existing.contains(id)) {
- Bundle b = bundleContext.getBundle(id);
- System.out.println("Removing bundle " + id + " from region " + existing.getName());
- existing.removeBundle(b);
- break;
- }
- }
- r.addBundle(id);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java b/region/command/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
deleted file mode 100644
index ec3766d..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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.region.commands;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.aries.util.VersionRange;
-import org.apache.aries.util.manifest.ManifestHeaderProcessor;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilter;
-import org.eclipse.equinox.region.RegionFilterBuilder;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-
-@Command(scope = "region", name = "filter-add", description = "Adds a filter between two regions.")
-@Service
-public class AddFilterCommand extends RegionCommandSupport {
-
- @Argument(index = 0, name = "from", description = "The from region.", required = true, multiValued = false)
- String fromRegion;
-
- @Argument(index = 1, name = "to", description = "The to region.", required = true, multiValued = false)
- String toRegion;
-
- @Argument(index = 2, name = "items", description = "The bundles by id and packages with version to allow.", required = false, multiValued = true)
- List<String> items;
-
- protected void doExecute(RegionDigraph regionDigraph) throws Exception {
- Region rFrom = getRegion(regionDigraph, fromRegion);
- Region rTo = getRegion(regionDigraph, toRegion);
- RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
- BundleContext framework = bundleContext.getBundle(0).getBundleContext();
- if (items != null) {
- for (String item : items) {
- try {
- long id = Long.parseLong(item);
- Bundle b = framework.getBundle(id);
- builder.allow("osgi.wiring.bundle", "(osgi.wiring.bundle=" + b.getSymbolicName() + ")");
- } catch (NumberFormatException e) {
- for (Map.Entry<String, Map<String, String>> parsed: ManifestHeaderProcessor.parseImportString(item).entrySet()) {
- String packageName = parsed.getKey();
- Map<String, String> attributes = new HashMap<String, String>(parsed.getValue());
- attributes.put("osgi.wiring.package", packageName);
- String filter = generateFilter(attributes);
- System.out.println("adding filter " + filter);
- builder.allow("osgi.wiring.package", filter);
- }
- }
-
- }
- }
- RegionFilter f = builder.build();
- regionDigraph.connect(rFrom, f, rTo);
- }
-
- //from aries util, with obr specific weirdness removed
- public static String generateFilter(Map<String, String> attribs) {
- StringBuilder filter = new StringBuilder("(&");
- boolean realAttrib = false;
- StringBuffer realAttribs = new StringBuffer();
-
- if (attribs == null) {
- attribs = new HashMap<String, String>();
- }
-
- for (Map.Entry<String, String> attrib : attribs.entrySet()) {
- String attribName = attrib.getKey();
-
- if (attribName.endsWith(":")) {
- // skip all directives. It is used to affect the attribs on the
- // filter xml.
- } else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
- || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
- // version and bundle-version attrib requires special
- // conversion.
- realAttrib = true;
-
- VersionRange vr = ManifestHeaderProcessor
- .parseVersionRange(attrib.getValue());
-
- filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
-
- if (vr.getMaximumVersion() != null) {
- filter.append(")(" + attribName + "<=");
- filter.append(vr.getMaximumVersion());
- }
-
- if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
- filter.append(")(!(" + attribName + "=");
- filter.append(vr.getMinimumVersion());
- filter.append(")");
- }
-
- if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
- filter.append(")(!(" + attribName + "=");
- filter.append(vr.getMaximumVersion());
- filter.append(")");
- }
- filter.append(")");
-
- } else if (Constants.OBJECTCLASS.equals(attribName)) {
- realAttrib = true;
- // objectClass has a "," separated list of interfaces
- String[] values = attrib.getValue().split(",");
- for (String s : values)
- filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
-
- } else {
- // attribName was not version..
- realAttrib = true;
-
- filter.append("(" + attribName + "=" + attrib.getValue() + ")");
- // store all attributes in order to build up the mandatory
- // filter and separate them with ", "
- // skip bundle-symbolic-name in the mandatory directive query
- if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
- .equals(attribName)) {
- realAttribs.append(attribName);
- realAttribs.append(", ");
- }
- }
- }
-
- // Prune (& off the front and ) off end
- String filterString = filter.toString();
- int openBraces = 0;
- for (int i = 0; openBraces < 3; i++) {
- i = filterString.indexOf('(', i);
- if (i == -1) {
- break;
- } else {
- openBraces++;
- }
- }
- if (openBraces < 3 && filterString.length() > 2) {
- filter.delete(0, 2);
- } else {
- filter.append(")");
- }
-
- String result = "";
- if (realAttrib != false) {
- result = filter.toString();
- }
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java b/region/command/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
deleted file mode 100644
index 22c817b..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.region.commands;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.RegionDigraph;
-
-@Command(scope = "region", name = "region-add", description = "Adds a list of regions to the region digraph service.")
-@Service
-public class AddRegionCommand extends RegionCommandSupport {
-
- @Argument(index = 0, name = "name", description = "Regions to add to the region digraph service separated by whitespaces.", required = true, multiValued = true)
- List<String> regions;
-
- protected void doExecute(RegionDigraph regionDigraph) throws Exception {
- for (String region : regions) {
- regionDigraph.createRegion(region);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/InfoCommand.java b/region/command/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
deleted file mode 100644
index 7c71e36..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.region.commands;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.karaf.shell.api.action.Argument;
-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.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilter;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "region", name = "info", description = "Prints information about region digraph.")
-@Service
-public class InfoCommand extends RegionCommandSupport {
-
- @Option(name = "-v", aliases = "--verbose", required = false, description = "Show all info.")
- boolean verbose;
-
- @Option(name = "-b", aliases = "--bundles", required = false, description = "Show bundles in each region.")
- boolean bundles;
-
- @Option(name = "-f", aliases = "--filters", required = false, description = "Show filters.")
- boolean filters;
-
- @Option(name = "-n", aliases = "--namespaces", required = false, description = "Show namespaces in each filter.")
- boolean namespaces;
-
- @Argument(index = 0, name = "regions", description = "Regions to provide detailed info for.", required = false, multiValued = true)
- List<String> regions;
-
- protected void doExecute(RegionDigraph regionDigraph) throws Exception {
- System.out.println("Regions");
- if (regions == null) {
- for (Region region : regionDigraph.getRegions()) {
- showRegion(region);
- }
- } else {
- bundles = true;
- filters = true;
- namespaces = true;
- for (String regionName : regions) {
- Region region = regionDigraph.getRegion(regionName);
- if (region == null) {
- System.out.println("No region " + regionName);
- } else {
- showRegion(region);
- }
- }
- }
- }
-
- private void showRegion(Region region) {
- System.out.println(region.getName());
- if (verbose || bundles) {
- for (Long id : region.getBundleIds()) {
- Bundle b = bundleContext.getBundle(id);
- System.out.println(" " + id + " " + getStateString(b) + b);
- }
- }
- if (verbose || filters || namespaces) {
- for (RegionDigraph.FilteredRegion f : region.getEdges()) {
- System.out.println(" filter to " + f.getRegion().getName());
- if (verbose || namespaces) {
- RegionFilter rf = f.getFilter();
- for (Map.Entry<String, Collection<String>> policy : rf.getSharingPolicy().entrySet()) {
- String namespace = policy.getKey();
- System.out.println(" namespace: " + namespace);
- for (String e : policy.getValue()) {
- System.out.println(" " + e);
- }
- }
- }
- }
- }
- }
-
- public String getStateString(Bundle bundle) {
- if (bundle == null) {
- return "Bundle null";
- }
- int state = bundle.getState();
- if (state == Bundle.ACTIVE) {
- return "Active ";
- } else if (state == Bundle.INSTALLED) {
- return "Installed ";
- } else if (state == Bundle.RESOLVED) {
- return "Resolved ";
- } else if (state == Bundle.STARTING) {
- return "Starting ";
- } else if (state == Bundle.STOPPING) {
- return "Stopping ";
- } else {
- return "Unknown ";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java b/region/command/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
deleted file mode 100644
index bcdfb6c..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.region.commands;
-
-import java.io.PrintStream;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-
-public abstract class RegionCommandSupport implements Action {
-
- protected static final char VERSION_DELIM = ',';
-
- @Reference
- BundleContext bundleContext;
-
- @Override
- public Object execute() throws Exception {
- // Get repository instance service.
- ServiceReference ref = bundleContext.getServiceReference(RegionDigraph.class.getName());
- if (ref == null) {
- System.out.println("RegionDigraph service is unavailable.");
- return null;
- }
- try {
- RegionDigraph admin = (RegionDigraph) bundleContext.getService(ref);
- if (admin == null) {
- System.out.println("RegionDigraph service is unavailable.");
- return null;
- }
-
- doExecute(admin);
- }
- finally {
- bundleContext.ungetService(ref);
- }
- return null;
- }
-
- abstract void doExecute(RegionDigraph admin) throws Exception;
-
- protected void printUnderline(PrintStream out, int length)
- {
- for (int i = 0; i < length; i++)
- {
- out.print('-');
- }
- out.println("");
- }
-
-
- protected Region getRegion(RegionDigraph regionDigraph, String region) throws BundleException {
- Region r = regionDigraph.getRegion(region);
- if (r == null) {
- System.out.println("No region: " + region + ", creating it");
- r = regionDigraph.createRegion(region);
- }
- return r;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/region/command/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java b/region/command/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
deleted file mode 100644
index 07c39e9..0000000
--- a/region/command/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.region.commands.util;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-
-public class FileUtil
-{
- public static void downloadSource(
- PrintStream out, PrintStream err,
- URL srcURL, String dirStr, boolean extract)
- {
- // Get the file name from the URL.
- String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
- ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
- : srcURL.getFile();
-
- try
- {
- out.println("Connecting...");
-
- File dir = new File(dirStr);
- if (!dir.exists())
- {
- err.println("Destination directory does not exist.");
- }
- File file = new File(dir, fileName);
-
- OutputStream os = new FileOutputStream(file);
- URLConnection conn = srcURL.openConnection();
- int total = conn.getContentLength();
- InputStream is = conn.getInputStream();
-
- if (total > 0)
- {
- out.println("Downloading " + fileName
- + " ( " + total + " bytes ).");
- }
- else
- {
- out.println("Downloading " + fileName + ".");
- }
- byte[] buffer = new byte[4096];
- int count = 0;
- for (int len = is.read(buffer); len > 0; len = is.read(buffer))
- {
- count += len;
- os.write(buffer, 0, len);
- }
-
- os.close();
- is.close();
-
- if (extract)
- {
- is = new FileInputStream(file);
- JarInputStream jis = new JarInputStream(is);
- out.println("Extracting...");
- unjar(jis, dir);
- jis.close();
- file.delete();
- }
- }
- catch (Exception ex)
- {
- err.println(ex);
- }
- }
-
- public static void unjar(JarInputStream jis, File dir)
- throws IOException
- {
- // Reusable buffer.
- byte[] buffer = new byte[4096];
-
- // Loop through JAR entries.
- for (JarEntry je = jis.getNextJarEntry();
- je != null;
- je = jis.getNextJarEntry())
- {
- if (je.getName().startsWith("/"))
- {
- throw new IOException("JAR resource cannot contain absolute paths.");
- }
-
- File target = new File(dir, je.getName());
-
- // Check to see if the JAR entry is a directory.
- if (je.isDirectory())
- {
- if (!target.exists())
- {
- if (!target.mkdirs())
- {
- throw new IOException("Unable to create target directory: "
- + target);
- }
- }
- // Just continue since directories do not have content to copy.
- continue;
- }
-
- int lastIndex = je.getName().lastIndexOf('/');
- String name = (lastIndex >= 0) ?
- je.getName().substring(lastIndex + 1) : je.getName();
- String destination = (lastIndex >= 0) ?
- je.getName().substring(0, lastIndex) : "";
-
- // JAR files use '/', so convert it to platform separator.
- destination = destination.replace('/', File.separatorChar);
- copy(jis, dir, name, destination, buffer);
- }
- }
-
- public static void copy(
- InputStream is, File dir, String destName, String destDir, byte[] buffer)
- throws IOException
- {
- if (destDir == null)
- {
- destDir = "";
- }
-
- // Make sure the target directory exists and
- // that is actually a directory.
- File targetDir = new File(dir, destDir);
- if (!targetDir.exists())
- {
- if (!targetDir.mkdirs())
- {
- throw new IOException("Unable to create target directory: "
- + targetDir);
- }
- }
- else if (!targetDir.isDirectory())
- {
- throw new IOException("Target is not a directory: "
- + targetDir);
- }
-
- BufferedOutputStream bos = new BufferedOutputStream(
- new FileOutputStream(new File(targetDir, destName)));
- int count = 0;
- while ((count = is.read(buffer)) > 0)
- {
- bos.write(buffer, 0, count);
- }
- bos.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/region/command/src/main/resources/OSGI-INF/bundle.info b/region/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 0005414..0000000
--- a/region/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,18 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to manipulate the Karaf embedded Region service.
-
-The following commands are available:
-* region:addbundle - Adds specified bundles (by id) to a region.
-* region:addfilter - Adds a filter between two regions containing bundles (by id) and packages (with attributes including version).
-* region:addregion - adds regions.
-* region:info - Prints information about region digraph.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/NOTICE
----------------------------------------------------------------------
diff --git a/region/core/NOTICE b/region/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/region/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/1bcdb173/region/core/pom.xml
----------------------------------------------------------------------
diff --git a/region/core/pom.xml b/region/core/pom.xml
deleted file mode 100644
index f1a792a..0000000
--- a/region/core/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?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.region</groupId>
- <artifactId>region</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>org.apache.karaf.region.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Region :: Persistence</name>
- <description>This bundle provides an xml regions model and install/dump actions.</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.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.features</groupId>
- <artifactId>org.apache.karaf.features.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse.equinox</groupId>
- <artifactId>region</artifactId>
- <version>1.0.0.v20110506</version>
- </dependency>
-
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <Bundle-Activator>
- org.apache.karaf.region.persist.internal.Activator
- </Bundle-Activator>
- <Private-Package>
- org.apache.karaf.region.persist.internal.*,
- org.apache.karaf.util.tracker
- </Private-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/Activator.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
deleted file mode 100644
index aa7215f..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.region.persist.internal;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.util.tracker.SingleServiceTracker;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Activator implements BundleActivator {
-
- private static final Logger log = LoggerFactory.getLogger(Activator.class);
-
- private SingleServiceTracker<RegionDigraph> tracker;
- private final AtomicReference<RegionsPersistenceImpl> persistence = new AtomicReference<RegionsPersistenceImpl>();
- private final AtomicReference<RegionsBundleTracker> bundleTracker = new AtomicReference<RegionsBundleTracker>();
- private ServiceRegistration<RegionsPersistence> reg;
-
- @Override
- public void start(final BundleContext bundleContext) throws Exception {
- tracker = new SingleServiceTracker<RegionDigraph>(bundleContext, RegionDigraph.class, new SingleServiceTracker.SingleServiceListener() {
- public void serviceFound() {
- log.debug("Found RegionDigraph service, initializing");
- RegionDigraph regionDigraph = tracker.getService();
- Bundle framework = bundleContext.getBundle(0);
- RegionsPersistenceImpl persistence = null;
- try {
- persistence = new RegionsPersistenceImpl(regionDigraph, framework);
- reg = bundleContext.registerService(RegionsPersistence.class, persistence, null);
-
- RegionsBundleTracker bundleTracker = new RegionsBundleTracker();
- bundleTracker.start(bundleContext, persistence);
- Activator.this.bundleTracker.set(bundleTracker);
- } catch (Exception e) {
- log.info("Could not create RegionsPersistenceImpl", e);
- }
- Activator.this.persistence.set(persistence);
- }
-
- public void serviceLost() {
- if (reg != null) {
- reg.unregister();
- reg = null;
- }
- Activator.this.persistence.set(null);
- Activator.this.bundleTracker.set(null);
- }
-
- public void serviceReplaced() {
- //??
- }
- });
- tracker.open();
- }
-
- @Override
- public void stop(BundleContext bundleContext) throws Exception {
- tracker.close();
- persistence.set(null);
- RegionsBundleTracker tracker = bundleTracker.getAndSet(null);
- if (tracker != null) {
- tracker.stop();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
deleted file mode 100644
index 7035303..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.region.persist.internal;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.util.tracker.BundleTracker;
-import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RegionsBundleTracker {
- private static final Logger log = LoggerFactory.getLogger(RegionsBundleTracker.class);
-
- private BundleTracker bundleTracker;
- private RegionsPersistence regionsPersistence;
-
- void start(BundleContext bundleContext, RegionsPersistence regionsPersistence) {
- this.regionsPersistence = regionsPersistence;
- int stateMask = Bundle.INSTALLED;
- bundleTracker = new BundleTracker<Bundle>(bundleContext, stateMask, new BundleTrackerCustomizer<Bundle>() {
- @Override
- public Bundle addingBundle(Bundle bundle, BundleEvent bundleEvent) {
- return RegionsBundleTracker.this.addingBundle(bundle);
- }
-
- @Override
- public void modifiedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
- }
-
- @Override
- public void removedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
- }
- });
- bundleTracker.open();
- }
-
- private Bundle addingBundle(Bundle bundle) {
- String region = bundle.getHeaders().get("Region");
- if (region != null) {
- try {
- regionsPersistence.install(bundle, region);
- log.debug("Installed bundle " + bundle + " in region " + region);
- return bundle;
- } catch (BundleException e) {
- log.info("Could not install bundle " + bundle + " in region " + region, e);
- }
- }
- return null;
- }
-
- void stop() {
- bundleTracker.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
deleted file mode 100644
index dcf5d26..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.region.persist.internal;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.region.persist.internal.model.FilterAttributeType;
-import org.apache.karaf.region.persist.internal.model.FilterBundleType;
-import org.apache.karaf.region.persist.internal.model.FilterNamespaceType;
-import org.apache.karaf.region.persist.internal.model.FilterPackageType;
-import org.apache.karaf.region.persist.internal.model.FilterType;
-import org.apache.karaf.region.persist.internal.model.RegionBundleType;
-import org.apache.karaf.region.persist.internal.model.RegionType;
-import org.apache.karaf.region.persist.internal.model.RegionsType;
-import org.apache.karaf.region.persist.internal.util.ManifestHeaderProcessor;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilterBuilder;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RegionsPersistenceImpl implements RegionsPersistence {
-
- private static final Logger log = LoggerFactory.getLogger(RegionsPersistenceImpl.class);
-
- private JAXBContext jaxbContext;
- private RegionDigraph regionDigraph;
- private Region kernel;
- private Bundle framework;
-
- public RegionsPersistenceImpl(RegionDigraph regionDigraph, Bundle framework) throws JAXBException, BundleException, IOException, InvalidSyntaxException {
- log.info("Loading region digraph persistence");
- this.framework = framework;
- this.regionDigraph = regionDigraph;
- kernel = regionDigraph.getRegion(0);
- jaxbContext = JAXBContext.newInstance(RegionsType.class);
- load();
- }
-
- @Override
- public void install(Bundle b, String regionName) throws BundleException {
- Region region = regionDigraph.getRegion(regionName);
- if (region == null) {
- region = regionDigraph.createRegion(regionName);
- }
- kernel.removeBundle(b);
- region.addBundle(b);
- }
-
- void save(RegionsType regionsType, Writer out) throws JAXBException {
- Marshaller marshaller = jaxbContext.createMarshaller();
- marshaller.marshal(regionsType, out);
- }
-
- void load() throws IOException, BundleException, JAXBException, InvalidSyntaxException {
- if (this.regionDigraph.getRegions().size() <= 1) {
- File etc = new File(System.getProperty("karaf.etc"));
- File regionsConfig = new File(etc, "regions-config.xml");
- if (regionsConfig.exists()) {
- log.info("initializing region digraph from etc/regions-config.xml");
- Reader in = new FileReader(regionsConfig);
- try {
- load(this.regionDigraph, in);
- } finally {
- in.close();
- }
- } else {
- log.info("no regions config file");
- }
- }
-
- }
-
- void load(RegionDigraph regionDigraph, Reader in) throws JAXBException, BundleException, InvalidSyntaxException {
- RegionsType regionsType = load(in);
- load(regionsType, regionDigraph);
- }
-
- RegionsType load(Reader in) throws JAXBException {
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- return (RegionsType) unmarshaller.unmarshal(in);
- }
-
- void load(RegionsType regionsType, RegionDigraph regionDigraph) throws BundleException, InvalidSyntaxException {
- BundleContext frameworkContext = framework.getBundleContext();
- for (RegionType regionType: regionsType.getRegion()) {
- String name = regionType.getName();
- log.debug("Creating region: " + name);
- Region region = regionDigraph.createRegion(name);
- for (RegionBundleType bundleType: regionType.getBundle()) {
- if (bundleType.getId() != null) {
- region.addBundle(bundleType.getId());
- } else {
- Bundle b = frameworkContext.getBundle(bundleType.getLocation());
- region.addBundle(b);
- }
- }
- }
- for (FilterType filterType: regionsType.getFilter()) {
- Region from = regionDigraph.getRegion(filterType.getFrom());
- Region to = regionDigraph.getRegion(filterType.getTo());
- log.debug("Creating filter between " + from.getName() + " to " + to.getName());
- RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
- for (FilterBundleType bundleType: filterType.getBundle()) {
- String symbolicName = bundleType.getSymbolicName();
- String version = bundleType.getVersion();
- if (bundleType.getId() != null) {
- Bundle b = frameworkContext.getBundle(bundleType.getId());
- symbolicName = b.getSymbolicName();
- version = b.getVersion().toString();
- }
- String namespace = BundleRevision.BUNDLE_NAMESPACE;
- List<FilterAttributeType> attributeTypes = bundleType.getAttribute();
- buildFilter(symbolicName, version, namespace, attributeTypes, builder);
- }
- for (FilterPackageType packageType: filterType.getPackage()) {
- String packageName = packageType.getName();
- String version = packageType.getVersion();
- String namespace = BundleRevision.PACKAGE_NAMESPACE;
- List<FilterAttributeType> attributeTypes = packageType.getAttribute();
- buildFilter(packageName, version, namespace, attributeTypes, builder);
- }
- if (to == kernel) {
- //add framework exports
- BundleRevision rev = framework.adapt(BundleRevision.class);
- List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- for (BundleCapability cap : caps) {
- String filter = ManifestHeaderProcessor.generateFilter(filter(cap.getAttributes()));
- builder.allow(BundleRevision.PACKAGE_NAMESPACE, filter);
- }
- }
- //TODO explicit services?
- for (FilterNamespaceType namespaceType: filterType.getNamespace()) {
- String namespace = namespaceType.getName();
- HashMap<String, Object> attributes = new HashMap<String, Object>();
- for (FilterAttributeType attributeType: namespaceType.getAttribute()) {
- attributes.put(attributeType.getName(), attributeType.getValue());
- }
- String filter = ManifestHeaderProcessor.generateFilter(attributes);
- builder.allow(namespace, filter);
- }
- regionDigraph.connect(from, builder.build(), to);
- }
- }
-
- private Map<String, Object> filter(Map<String, Object> attributes) {
- Map<String, Object> result = new HashMap<String, Object>(attributes);
- result.remove("bundle-version");
- result.remove("bundle-symbolic-name");
- return result;
- }
-
- private void buildFilter(String packageName, String version, String namespace, List<FilterAttributeType> attributeTypes, RegionFilterBuilder builder) throws InvalidSyntaxException {
- HashMap<String, Object> attributes = new HashMap<String, Object>();
- if (namespace != null) {
- attributes.put(namespace, packageName);
- }
- if (version != null) {
- attributes.put("version", version);
- }
- for (FilterAttributeType attributeType: attributeTypes) {
- attributes.put(attributeType.getName(), attributeType.getValue());
- }
- String filter = ManifestHeaderProcessor.generateFilter(attributes);
- builder.allow(namespace, filter);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
deleted file mode 100644
index 857c2b3..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for filterAttributeType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="filterAttributeType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * </sequence>
- * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "filterAttributeType")
-public class FilterAttributeType {
-
- @XmlAttribute(required = true)
- protected String name;
- @XmlAttribute(required = true)
- protected String value;
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
- /**
- * Gets the value of the value property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Sets the value of the value property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setValue(String value) {
- this.value = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
deleted file mode 100644
index a9a9fbb..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for filterBundleType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="filterBundleType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}long" />
- * <attribute name="symbolic-name" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "filterBundleType", propOrder = {
- "attribute"
-})
-public class FilterBundleType {
-
- protected List<FilterAttributeType> attribute;
- @XmlAttribute
- protected Long id;
- @XmlAttribute(name = "symbolic-name")
- protected String symbolicName;
- @XmlAttribute
- protected String version;
-
- /**
- * Gets the value of the attribute property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the attribute property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getAttribute().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterAttributeType }
- *
- *
- */
- public List<FilterAttributeType> getAttribute() {
- if (attribute == null) {
- attribute = new ArrayList<FilterAttributeType>();
- }
- return this.attribute;
- }
-
- /**
- * Gets the value of the id property.
- *
- * @return
- * possible object is
- * {@link Long }
- *
- */
- public Long getId() {
- return id;
- }
-
- /**
- * Sets the value of the id property.
- *
- * @param value
- * allowed object is
- * {@link Long }
- *
- */
- public void setId(Long value) {
- this.id = value;
- }
-
- /**
- * Gets the value of the symbolicName property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getSymbolicName() {
- return symbolicName;
- }
-
- /**
- * Sets the value of the symbolicName property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setSymbolicName(String value) {
- this.symbolicName = value;
- }
-
- /**
- * Gets the value of the version property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getVersion() {
- return version;
- }
-
- /**
- * Sets the value of the version property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setVersion(String value) {
- this.version = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
deleted file mode 100644
index 52b937a..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for filterNamespaceType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="filterNamespaceType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "filterNamespaceType", propOrder = {
- "attribute"
-})
-public class FilterNamespaceType {
-
- protected List<FilterAttributeType> attribute;
- @XmlAttribute(required = true)
- protected String name;
-
- /**
- * Gets the value of the attribute property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the attribute property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getAttribute().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterAttributeType }
- *
- *
- */
- public List<FilterAttributeType> getAttribute() {
- if (attribute == null) {
- attribute = new ArrayList<FilterAttributeType>();
- }
- return this.attribute;
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
deleted file mode 100644
index b4216ee..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
+++ /dev/null
@@ -1,129 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for filterPackageType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="filterPackageType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "filterPackageType", propOrder = {
- "attribute"
-})
-public class FilterPackageType {
-
- protected List<FilterAttributeType> attribute;
- @XmlAttribute
- protected String name;
- @XmlAttribute
- protected String version;
-
- /**
- * Gets the value of the attribute property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the attribute property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getAttribute().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterAttributeType }
- *
- *
- */
- public List<FilterAttributeType> getAttribute() {
- if (attribute == null) {
- attribute = new ArrayList<FilterAttributeType>();
- }
- return this.attribute;
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
- /**
- * Gets the value of the version property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getVersion() {
- return version;
- }
-
- /**
- * Sets the value of the version property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setVersion(String value) {
- this.version = value;
- }
-
-}
[50/59] [abbrv] git commit: [KARAF-2833] Make obr independent of
blueprint
Posted by gn...@apache.org.
[KARAF-2833] Make obr independent of blueprint
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/04afd902
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/04afd902
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/04afd902
Branch: refs/heads/master
Commit: 04afd9029a156a66d9ad5a241bf69d41cff72939
Parents: 4182735
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 09:54:47 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:54 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
obr/pom.xml | 11 ++++++
.../karaf/obr/core/internal/osgi/Activator.java | 36 ++++++++++++++++++++
.../resources/OSGI-INF/blueprint/blueprint.xml | 34 ------------------
4 files changed, 47 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/04afd902/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 6813d27..b6f8dea 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -109,7 +109,6 @@
</feature>
<feature name="obr" description="Provide OSGi Bundle Repository (OBR) support" version="${project.version}">
- <feature>aries-blueprint</feature>
<bundle start-level="30">mvn:org.apache.felix/org.osgi.service.obr/${felix.obr.version}</bundle>
<bundle start-level="30">mvn:org.apache.felix/org.apache.felix.bundlerepository/${felix.bundlerepository.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.obr/org.apache.karaf.obr.core/${project.version}</bundle>
http://git-wip-us.apache.org/repos/asf/karaf/blob/04afd902/obr/pom.xml
----------------------------------------------------------------------
diff --git a/obr/pom.xml b/obr/pom.xml
index e0498c7..1e9b381 100644
--- a/obr/pom.xml
+++ b/obr/pom.xml
@@ -50,6 +50,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.core</artifactId>
<optional>true</optional>
@@ -83,8 +88,14 @@
</Export-Package>
<Private-Package>
org.apache.karaf.obr.command,
+ org.apache.karaf.obr.command.util,
org.apache.karaf.obr.core.internal,
+ org.apache.karaf.obr.core.internal.osgi,
+ org.apache.karaf.util.tracker
</Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.obr.core.internal.osgi.Activator
+ </Bundle-Activator>
<Karaf-Commands>*</Karaf-Commands>
</instructions>
</configuration>
http://git-wip-us.apache.org/repos/asf/karaf/blob/04afd902/obr/src/main/java/org/apache/karaf/obr/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/obr/src/main/java/org/apache/karaf/obr/core/internal/osgi/Activator.java b/obr/src/main/java/org/apache/karaf/obr/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..183508e
--- /dev/null
+++ b/obr/src/main/java/org/apache/karaf/obr/core/internal/osgi/Activator.java
@@ -0,0 +1,36 @@
+/*
+ * 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.obr.core.internal.osgi;
+
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.karaf.obr.core.internal.ObrMBeanImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doOpen() throws Exception {
+ trackService(RepositoryAdmin.class);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ RepositoryAdmin admin = getTrackedService(RepositoryAdmin.class);
+ ObrMBeanImpl mbean = new ObrMBeanImpl(bundleContext, admin);
+ registerMBean(mbean, "type=obr");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/04afd902/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
deleted file mode 100644
index 4fbe9fb..0000000
--- a/obr/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed 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.
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
- xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
-
- <ext:property-placeholder />
-
- <reference id="repositoryAdmin" interface="org.apache.felix.bundlerepository.RepositoryAdmin"/>
-
- <bean id="obrMBean" class="org.apache.karaf.obr.core.internal.ObrMBeanImpl">
- <argument ref="blueprintBundleContext"/>
- <argument ref="repositoryAdmin"/>
- </bean>
-
- <service ref="obrMBean" auto-export="interfaces">
- <service-properties>
- <entry key="jmx.objectname" value="org.apache.karaf:type=obr,name=${karaf.name}"/>
- </service-properties>
- </service>
-
-</blueprint>
\ No newline at end of file
[59/59] [abbrv] git commit: [KARAF-2833] Make jndi independent of
blueprint
Posted by gn...@apache.org.
[KARAF-2833] Make jndi independent of blueprint
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/48ef3aa0
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/48ef3aa0
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/48ef3aa0
Branch: refs/heads/master
Commit: 48ef3aa0146bf891fbefa70172ed5377fb6d4fd9
Parents: 85c65dd
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 10:36:46 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:03:22 2014 +0200
----------------------------------------------------------------------
.../enterprise/src/main/feature/feature.xml | 3 +-
jndi/pom.xml | 13 ++++-
.../karaf/jndi/internal/osgi/Activator.java | 53 ++++++++++++++++++++
.../resources/OSGI-INF/blueprint/jndi-core.xml | 53 --------------------
4 files changed, 66 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/48ef3aa0/assemblies/features/enterprise/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/src/main/feature/feature.xml b/assemblies/features/enterprise/src/main/feature/feature.xml
index 823d3ba..0a57038 100644
--- a/assemblies/features/enterprise/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise/src/main/feature/feature.xml
@@ -174,14 +174,13 @@
<feature name="jndi" description="OSGi Service Registry JNDI access" version="${project.version}" resolver="(obr)">
<details>JNDI support provided by Apache Aries JNDI ${aries.jndi.version}, including additional service, commands, and MBean.</details>
<feature>aries-proxy</feature>
- <feature>aries-blueprint</feature>
<bundle start-level="30">mvn:org.apache.xbean/xbean-naming/${xbean.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.jndi/org.apache.karaf.jndi.core/${project.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.api/${aries.jndi.api.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.core/${aries.jndi.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.rmi/${aries.jndi.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.url/${aries.jndi.version}</bundle>
<bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.legacy.support/${aries.jndi.version}</bundle>
+ <bundle start-level="30">mvn:org.apache.karaf.jndi/org.apache.karaf.jndi.core/${project.version}</bundle>
</feature>
<feature name="jdbc" description="JDBC service and commands" version="${project.version}" resolver="(obr)">
http://git-wip-us.apache.org/repos/asf/karaf/blob/48ef3aa0/jndi/pom.xml
----------------------------------------------------------------------
diff --git a/jndi/pom.xml b/jndi/pom.xml
index f2db373..1b01030 100644
--- a/jndi/pom.xml
+++ b/jndi/pom.xml
@@ -52,6 +52,11 @@
<artifactId>org.apache.aries.proxy.api</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.core</artifactId>
<optional>true</optional>
@@ -85,9 +90,15 @@
</Export-Package>
<Private-Package>
org.apache.karaf.jndi.command,
- org.apache.karaf.jndi.internal
+ org.apache.karaf.jndi.command.completers,
+ org.apache.karaf.jndi.internal,
+ org.apache.karaf.jndi.internal.osgi,
+ org.apache.karaf.util.tracker
</Private-Package>
<Karaf-Commands>*</Karaf-Commands>
+ <Bundle-Activator>
+ org.apache.karaf.jndi.internal.osgi.Activator
+ </Bundle-Activator>
</instructions>
</configuration>
</plugin>
http://git-wip-us.apache.org/repos/asf/karaf/blob/48ef3aa0/jndi/src/main/java/org/apache/karaf/jndi/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/jndi/src/main/java/org/apache/karaf/jndi/internal/osgi/Activator.java b/jndi/src/main/java/org/apache/karaf/jndi/internal/osgi/Activator.java
new file mode 100644
index 0000000..5470e7e
--- /dev/null
+++ b/jndi/src/main/java/org/apache/karaf/jndi/internal/osgi/Activator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.jndi.internal.osgi;
+
+import java.util.Hashtable;
+
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.aries.proxy.ProxyManager;
+import org.apache.karaf.jndi.JndiService;
+import org.apache.karaf.jndi.KarafInitialContextFactory;
+import org.apache.karaf.jndi.internal.JndiMBeanImpl;
+import org.apache.karaf.jndi.internal.JndiServiceImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+
+public class Activator extends BaseActivator {
+ @Override
+ protected void doOpen() throws Exception {
+ trackService(ProxyManager.class);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ ProxyManager proxyManager = getTrackedService(ProxyManager.class);
+
+ register(InitialContextFactory.class, new KarafInitialContextFactory());
+
+ JndiServiceImpl service = new JndiServiceImpl();
+ service.setBundleContext(bundleContext);
+ service.setProxyManager(proxyManager);
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ // bind the JNDI service itself in the JNDI context
+ props.put("osgi.jndi.service.name", "jndi");
+ register(JndiService.class, service, props);
+ JndiMBeanImpl mbean = new JndiMBeanImpl();
+ mbean.setJndiService(service);
+ registerMBean(mbean, "type=jndi");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/48ef3aa0/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
----------------------------------------------------------------------
diff --git a/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml b/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
deleted file mode 100644
index e6be3b1..0000000
--- a/jndi/src/main/resources/OSGI-INF/blueprint/jndi-core.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
- -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
- default-activation="lazy">
-
- <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]"/>
-
- <bean id="karafInitialContextFactory" class="org.apache.karaf.jndi.KarafInitialContextFactory"/>
-
- <reference id="proxyManager" interface="org.apache.aries.proxy.ProxyManager"/>
-
- <service ref="karafInitialContextFactory" interface="javax.naming.spi.InitialContextFactory"/>
-
- <bean id="jndiService" class="org.apache.karaf.jndi.internal.JndiServiceImpl">
- <property name="bundleContext" ref="blueprintBundleContext"/>
- <property name="proxyManager" ref="proxyManager"/>
- </bean>
-
- <service ref="jndiService" interface="org.apache.karaf.jndi.JndiService">
- <service-properties>
- <!-- bind the JNDI service itself in the JNDI context -->
- <entry key="osgi.jndi.service.name" value="jndi"/>
- </service-properties>
- </service>
-
- <!-- Management -->
- <bean id="jndiMBeanImpl" class="org.apache.karaf.jndi.internal.JndiMBeanImpl">
- <property name="jndiService" ref="jndiService"/>
- </bean>
-
- <service ref="jndiMBeanImpl" auto-export="interfaces">
- <service-properties>
- <entry key="jmx.objectname" value="org.apache.karaf:type=jndi,name=$[karaf.name]"/>
- </service-properties>
- </service>
-
-</blueprint>
\ No newline at end of file
[10/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
deleted file mode 100644
index 9536ba1..0000000
--- a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.0.0.xsd
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
-
--->
-<xs:schema elementFormDefault="qualified"
- targetNamespace="http://karaf.apache.org/xmlns/features/v1.0.0"
- xmlns:tns="http://karaf.apache.org/xmlns/features/v1.0.0"
- xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
- <xs:annotation>
- <xs:documentation><![CDATA[
-Karaf features mechanism. For documentation please visit the
-<a href="http://karaf.apache.org/">Karaf website</a>.
- ]]></xs:documentation>
- </xs:annotation>
-
- <xs:complexType name="features">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Root element of the Feature definition. It contains an optional attribute for
-designating the name of the repository of this feature. The Karaf shell will
-show the repository name when displaying information about the feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="repository" type="xs:anyURI">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional repositories where dependencies are stored.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="feature" type="tns:feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature definition.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:choice>
- <xs:attribute name="name" type="xs:string" />
- </xs:complexType>
-
- <xs:complexType name="feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="details" minOccurs="0" type="xs:string">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The help text shown for this feature when using the feature:info console command.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- </xs:choice>
- <xs:attribute name="name" type="tns:featureName" use="required" />
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- <xs:attribute name="description" type="xs:string" />
- <xs:attribute name="resolver" type="tns:resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Optional alternative resolver to use for determining the list of bundles to install for a given feature.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="install" type="tns:install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If true, marks that the feature should start automatically when placed in the deploy folder.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for the bundles in this feature different
-from the default start level defined in Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="region" type="xs:string"/>
- </xs:complexType>
-
- <xs:complexType name="bundle">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Deployable element to install.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this bundle different
-from the default start level defined in Karaf's config.properties.
-
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start" type="xs:boolean" default="true">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If false, leaves the bundle in resolved state rather than the default active state.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="dependency" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Mark this bundle as a dependency for the resolver.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="dependency">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Dependency of feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="tns:featureName">
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="config">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Configuration entries which should be created during feature installation. This
-configuration may be used with OSGi Configuration Admin. The element content is
-read in as a properties file.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- <xs:attribute name="name" type="xs:string" use="required" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="configFile">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional configuration files which should be created during feature installation.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="finalname" type="xs:string" use="required">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The final destination path and name for the configuration file (relative to the KARAF_BASE).
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="override" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If the configFile already exists at the finalname location, whether or not to replace it.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:simpleType name="featureName">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature name should be non empty string.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Resolver to use. Karaf will look for OSGi service which has following properties:
-objectClass: org.apache.karaf.features.Resolver
-name: the value
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
-dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
-command line or as part of the org.apache.karaf.features.cfg.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:element name="features" type="tns:features" />
-
-</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
deleted file mode 100644
index 7138573..0000000
--- a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
+++ /dev/null
@@ -1,237 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
-
--->
-<xs:schema elementFormDefault="qualified"
- targetNamespace="http://karaf.apache.org/xmlns/features/v1.1.0"
- xmlns:tns="http://karaf.apache.org/xmlns/features/v1.1.0"
- xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
- <xs:annotation>
- <xs:documentation><![CDATA[
-Karaf features mechanism. For documentation please visit the
-<a href="http://karaf.apache.org/">Karaf website</a>.
- ]]></xs:documentation>
- </xs:annotation>
-
- <xs:complexType name="features">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Root element of Feature definition. It contains an required attribute for
-designating from which repository this feature should be loaded. The Karaf
-shell will show the repository name when displaying information about the feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="repository" type="xs:anyURI">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional repositories where dependencies are stored.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="feature" type="tns:feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature definition.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:choice>
- <xs:attribute name="name" type="xs:string" use="required"/>
- </xs:complexType>
-
- <xs:complexType name="feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="details" minOccurs="0" type="xs:string">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The help text shown for this feature when using feature:info console command.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- </xs:choice>
- <xs:attribute name="name" type="tns:featureName" use="required" />
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- <xs:attribute name="description" type="xs:string" />
- <xs:attribute name="resolver" type="tns:resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Optional alternative resolver to use for determining the list of bundles to install for a given feature.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="install" type="tns:install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Marks if the feaute will be automatically started when thrown to the deploy folder.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this feature different
-from the default start level defined in Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:complexType>
-
- <xs:complexType name="bundle">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Deployable element to install.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this bundle different
-from the default start level defined in the Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start" type="xs:boolean" default="true">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If false, leaves bundle in resolved state rather than the default active state.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="dependency" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Mark this bundle as a dependency for the resolver.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="dependency">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Dependency of feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="tns:featureName">
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="config">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Configuration entries which should be created during feature installation. This
-configuration may be used with OSGi Configuration Admin. The element content is
-read in as a properties file.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- <xs:attribute name="name" type="xs:string" use="required" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="configFile">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional configuration files which should be created during feature installation.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="finalname" type="xs:string" use="required">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The final destination path and name for the configuration file.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="override" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If the configFile already exists at the finalname location, whether or not to replace it.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:simpleType name="featureName">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature name should be non empty string.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Resolver to use. Karaf will look for OSGi service which have following properties:
-objectClass: org.apache.karaf.features.Resolver
-name: the value
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
-dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
-command line or as part of the org.apache.karaf.features.cfg.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:element name="features" type="tns:features" />
-
-</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
deleted file mode 100644
index dbc4bfa..0000000
--- a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.2.0.xsd
+++ /dev/null
@@ -1,254 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
-
--->
-<xs:schema elementFormDefault="qualified"
- targetNamespace="http://karaf.apache.org/xmlns/features/v1.2.0"
- xmlns:tns="http://karaf.apache.org/xmlns/features/v1.2.0"
- xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
- <xs:annotation>
- <xs:documentation><![CDATA[
-Karaf features mechanism. For documentation please visit the
-<a href="http://karaf.apache.org/">Karaf website</a>.
- ]]></xs:documentation>
- </xs:annotation>
-
- <xs:complexType name="features">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Root element of Feature definition. It contains an required attribute for
-designating from which repository this feature should be loaded. The Karaf
-shell will show the repository name when displaying information about the feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="repository" type="xs:anyURI">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional repositories where dependencies are stored.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="feature" type="tns:feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature definition.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:choice>
- <xs:attribute name="name" type="xs:string" use="required"/>
- </xs:complexType>
-
- <xs:complexType name="feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="details" minOccurs="0" type="xs:string">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The help text shown for this feature when using feature:info console command.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- <xs:element name="conditional" type="tns:conditional" />
- </xs:choice>
- <xs:attribute name="name" type="tns:featureName" use="required" />
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- <xs:attribute name="description" type="xs:string" />
- <xs:attribute name="resolver" type="tns:resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Optional alternative resolver to use for determining the list of bundles to install for a given feature.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="install" type="tns:install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Marks if the feaute will be automatically started when thrown to the deploy folder.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this feature different
-from the default start level defined in Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:complexType>
-
- <xs:complexType name="conditional">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Conditional.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- <xs:element name="condition" type="tns:dependency" minOccurs="0" maxOccurs="1" />
- </xs:choice>
- </xs:complexType>
-
-
- <xs:complexType name="bundle">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Deployable element to install.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this bundle different
-from the default start level defined in the Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start" type="xs:boolean" default="true">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If false, leaves bundle in resolved state rather than the default active state.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="dependency" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Mark this bundle as a dependency for the resolver.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="dependency">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Dependency of feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="tns:featureName">
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="config">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Configuration entries which should be created during feature installation. This
-configuration may be used with OSGi Configuration Admin. The element content is
-read in as a properties file.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- <xs:attribute name="name" type="xs:string" use="required" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="configFile">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional configuration files which should be created during feature installation.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="finalname" type="xs:string" use="required">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The final destination path and name for the configuration file.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="override" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If the configFile already exists at the finalname location, whether or not to replace it.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:simpleType name="featureName">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature name should be non empty string.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Resolver to use. Karaf will look for OSGi service which have following properties:
-objectClass: org.apache.karaf.features.Resolver
-name: the value
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
-dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
-command line or as part of the org.apache.karaf.features.cfg.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:element name="features" type="tns:features" />
-
-</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
deleted file mode 100644
index 60ec8d2..0000000
--- a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
+++ /dev/null
@@ -1,280 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
-
--->
-<xs:schema elementFormDefault="qualified"
- targetNamespace="http://karaf.apache.org/xmlns/features/v1.3.0"
- xmlns:tns="http://karaf.apache.org/xmlns/features/v1.3.0"
- xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
- <xs:annotation>
- <xs:documentation><![CDATA[
-Karaf features mechanism. For documentation please visit the
-<a href="http://karaf.apache.org/">Karaf website</a>.
- ]]></xs:documentation>
- </xs:annotation>
-
- <xs:complexType name="features">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Root element of Feature definition. It contains an required attribute for
-designating from which repository this feature should be loaded. The Karaf
-shell will show the repository name when displaying information about the feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="repository" type="xs:anyURI">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional repositories where dependencies are stored.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="feature" type="tns:feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature definition.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:choice>
- <xs:attribute name="name" type="xs:string" use="required"/>
- </xs:complexType>
-
- <xs:complexType name="feature">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="details" minOccurs="0" type="xs:string">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The help text shown for this feature when using feature:info console command.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- <xs:element name="conditional" type="tns:conditional" />
- <xs:element name="requirement" type="tns:requirement" />
- <xs:element name="capability" type="tns:capability" />
- </xs:choice>
- <xs:attribute name="name" type="tns:featureName" use="required" />
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- <xs:attribute name="description" type="xs:string" />
- <xs:attribute name="resolver" type="tns:resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Optional alternative resolver to use for determining the list of bundles to install for a given feature.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="install" type="tns:install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Marks if the feaute will be automatically started when thrown to the deploy folder.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this feature different
-from the default start level defined in Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:complexType>
-
- <xs:complexType name="conditional">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Definition of the Conditional.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="config" type="tns:config" />
- <xs:element name="configfile" type="tns:configFile" />
- <xs:element name="feature" type="tns:dependency" />
- <xs:element name="bundle" type="tns:bundle" />
- <xs:element name="condition" type="tns:dependency" minOccurs="0" maxOccurs="1" />
- </xs:choice>
- </xs:complexType>
-
-
- <xs:complexType name="bundle">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Deployable element to install.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="start-level" type="xs:int">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Set this attribute to have an OSGi start level for this bundle different
-from the default start level defined in the Karaf's config.properties.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="start" type="xs:boolean" default="true">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If false, leaves bundle in resolved state rather than the default active state.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="dependency" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Mark this bundle as a dependency for the resolver.
- ]]>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="dependency">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Dependency of feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="tns:featureName">
- <xs:attribute name="version" type="xs:string" default="0.0.0" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="config">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Configuration entries which should be created during feature installation. This
-configuration may be used with OSGi Configuration Admin. The element content is
-read in as a properties file.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- <xs:attribute name="name" type="xs:string" use="required" />
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="configFile">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional configuration files which should be created during feature installation.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI">
- <xs:attribute name="finalname" type="xs:string" use="required">
- <xs:annotation>
- <xs:documentation><![CDATA[
-The final destination path and name for the configuration file.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="override" type="xs:boolean">
- <xs:annotation>
- <xs:documentation><![CDATA[
-If the configFile already exists at the finalname location, whether or not to replace it.
- ]]></xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="requirement">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional requirements of this feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:complexType name="capability">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Additional capability of this feature.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
-
- <xs:simpleType name="featureName">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Feature name should be non empty string.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="resolver">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Resolver to use. Karaf will look for OSGi service which have following properties:
-objectClass: org.apache.karaf.features.Resolver
-name: the value
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="install">
- <xs:annotation>
- <xs:documentation><![CDATA[
-Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
-dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
-command line or as part of the org.apache.karaf.features.cfg.
- ]]></xs:documentation>
- </xs:annotation>
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- <xs:element name="features" type="tns:features" />
-
-</xs:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/ConditionalTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/ConditionalTest.java b/features/core/src/test/java/org/apache/karaf/features/ConditionalTest.java
deleted file mode 100644
index d5e7e46..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/ConditionalTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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;
-
-import junit.framework.TestCase;
-import org.apache.karaf.features.internal.service.RepositoryImpl;
-
-
-public class ConditionalTest extends TestCase {
-
- public void testLoad() throws Exception {
- RepositoryImpl r = new RepositoryImpl(getClass().getResource("internal/service/f06.xml").toURI());
- // Check repo
- Feature[] features = r.getFeatures();
- assertNotNull(features);
- assertEquals(1, features.length);
- Feature feature = features[0];
-
- assertNotNull(feature.getConditional());
- assertEquals(1,feature.getConditional().size());
-
- Conditional conditional = feature.getConditional().get(0);
- assertNotNull(conditional.getCondition());
- assertEquals(1,conditional.getCondition().size());
- Dependency dependency = conditional.getCondition().get(0);
- assertNotNull(dependency);
- assertEquals(dependency.getName(),"http");
- assertNotNull(conditional.getBundles());
- assertEquals(1, feature.getConditional().get(0).getBundles().size());
-
- String wrapperName = "my6/1.5.3-beta-3".replaceAll("[^A-Za-z0-9 ]", "_");
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/FeatureTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/FeatureTest.java b/features/core/src/test/java/org/apache/karaf/features/FeatureTest.java
deleted file mode 100644
index b7d4c27..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/FeatureTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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;
-
-import junit.framework.TestCase;
-
-public class FeatureTest extends TestCase {
-
- public void testValueOf() {
- Feature feature = org.apache.karaf.features.internal.model.Feature.valueOf("name" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + "version");
- assertEquals(feature.getName(), "name");
- assertEquals(feature.getVersion(), "version");
- feature = org.apache.karaf.features.internal.model.Feature.valueOf("name");
- assertEquals(feature.getName(), "name");
- assertEquals(feature.getVersion(), org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
deleted file mode 100644
index 9f7e67b..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * 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;
-
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.apache.karaf.features.internal.service.FeaturesServiceImpl;
-import org.apache.karaf.features.internal.service.StateStorage;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-public class FeaturesServiceTest extends TestBase {
- private static final String FEATURE_WITH_INVALID_BUNDLE = "<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1'><bundle>%s</bundle><bundle>zfs:unknown</bundle></feature>"
- + " <feature name='f2'><bundle>%s</bundle></feature>"
- + "</features>";
-
- File dataFile;
-
- @Before
- public void setUp() throws IOException {
- dataFile = File.createTempFile("features", null, null);
- }
-
- private URI createTempRepo(String repoContent, Object ... variables) throws IOException {
- File tmp = File.createTempFile("karaf", ".feature");
- PrintWriter pw = new PrintWriter(new FileWriter(tmp));
- pw.printf(repoContent, variables);
- pw.close();
- return tmp.toURI();
- }
-
- /*
- TODO: migrate those tests
-
- @Test
- public void testInstallFeature() throws Exception {
- URI uri = createTempRepo(
- "<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1'><bundle start='true'>bundle-f1</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- Bundle installedBundle = createDummyBundle(12345L, "bundle-f1", headers());
- FeaturesServiceImpl svc = testAddRepository("bundle-f1", uri, bundleManager, installedBundle);
-
- reset(bundleManager);
-
- expect(bundleManager.installBundleIfNeeded(eq("bundle-f1"), eq(0), eq((String)null))).andReturn(new BundleInstallerResult(installedBundle, true));
- expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile);
- ignoreRefreshes(bundleManager);
- replay(bundleManager);
- svc.installFeature("f1", org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
- verify(bundleManager);
-
- Feature[] installed = svc.listInstalledFeatures();
- assertEquals(1, installed.length);
- assertEquals("f1", installed[0].getName());
- }
-
- private FeaturesServiceImpl testAddRepository(String name, URI uri, BundleManager bundleManager,
- Bundle installedBundle) throws IOException, BundleException, Exception {
- expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile);
- expect(bundleManager.installBundleIfNeeded(eq(name), eq(0), eq((String)null))).andReturn(new BundleInstallerResult(installedBundle, true)).anyTimes();
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
- Repository[] repositories = svc.listRepositories();
- verify(bundleManager);
-
- assertNotNull(repositories);
- assertEquals(1, repositories.length);
- assertNotNull(repositories[0]);
- Feature[] features = repositories[0].getFeatures();
- assertNotNull(features);
- assertEquals(1, features.length);
- assertNotNull(features[0]);
- assertEquals("f1", features[0].getName());
- assertNotNull(features[0].getDependencies());
- assertEquals(0, features[0].getDependencies().size());
- assertNotNull(features[0].getBundles());
- assertEquals(1, features[0].getBundles().size());
- assertEquals(name, features[0].getBundles().get(0).getLocation());
- assertTrue(features[0].getBundles().get(0).isStart());
- return svc;
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testUninstallFeatureWithTwoVersions() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><bundle>bundle-0.1</bundle></feature>"
- + " <feature name='f1' version='0.2'><bundle>bundle-0.1</bundle></feature>"
- + "</features>");
-
- Bundle bundlef101 = createDummyBundle(12345L, "bundle-0.1", headers());
-
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- expect(bundleManager.getDataFile(EasyMock.anyObject(String.class))).andReturn(dataFile).anyTimes();
- expect(bundleManager.installBundleIfNeeded("bundle-0.1", 0, null)).andReturn(new BundleInstallerResult(bundlef101, true));
- expect(bundleManager.installBundleIfNeeded("bundle-0.1", 0, null)).andReturn(new BundleInstallerResult(bundlef101, false));
- expect(bundleManager.getBundleContext()).andReturn(bundleContext);
- ignoreRefreshes(bundleManager);
- bundleManager.uninstall(Collections.EMPTY_LIST, true);
- EasyMock.expectLastCall().times(2);
-
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
-
- try {
- svc.uninstallFeature("f1");
- fail("Uninstall should have failed as feature is not installed");
- } catch (Exception e) {
- // ok
- }
-
- svc.installFeature("f1", "0.1", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
- svc.installFeature("f1", "0.2", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
-
- try {
- svc.uninstallFeature("f1");
- fail("Uninstall should have failed as feature is installed in multiple versions");
- } catch (Exception e) {
- // ok
- }
-
- svc.uninstallFeature("f1", "0.1");
- svc.uninstallFeature("f1");
- verify(bundleManager);
- }
-
- @Test
- public void testAddAndRemoveRepository() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><bundle>bundle-f1-0.1</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- EasyMock.verify(bundleManager);
-
- svc.addRepository(uri);
- svc.removeRepository(uri);
- verify(bundleManager);
- }
-
- // Tests install of a Repository that includes a feature
- // with a feature dependency
- // The dependant feature is in the same repository
- // Tests uninstall of features
- @SuppressWarnings("unchecked")
- @Test
- public void testInstallFeatureWithDependantFeatures() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><feature version='0.1'>f2</feature><bundle>bundle-f1-0.1</bundle></feature>"
- + " <feature name='f2' version='0.1'><bundle>bundle-f2-0.1</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- Bundle bundlef101 = createDummyBundle(12345L, "bundle-f1-0.1", headers());
- Bundle bundlef201 = createDummyBundle(54321L, "bundle-f2-0.1", headers());
- expect(bundleManager.getDataFile(EasyMock.<String> anyObject())).andReturn(dataFile).anyTimes();
- expect(bundleManager.installBundleIfNeeded("bundle-f1-0.1", 0, null))
- .andReturn(new BundleInstallerResult(bundlef101, true));
- expect(bundleManager.installBundleIfNeeded("bundle-f2-0.1", 0, null))
- .andReturn(new BundleInstallerResult(bundlef201, true));
- expect(bundleManager.getBundleContext()).andReturn(bundleContext).anyTimes();
- expect(bundleContext.getBundle(12345)).andReturn(bundlef101).anyTimes();
- ignoreRefreshes(bundleManager);
- bundleManager.uninstall(Collections.EMPTY_LIST, true);
-
- EasyMock.expectLastCall().anyTimes();
- replay(bundleManager);
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
- svc.installFeature("f1", "0.1");
- svc.uninstallFeature("f1", "0.1");
- verify(bundleManager);
-
- }
-
- @SuppressWarnings("unchecked")
- private BundleManager prepareBundleManagerForInstallUninstall(String bundleUri, String bundlename) throws Exception {
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- Bundle installedBundle = createDummyBundle(12345L, bundlename, headers());
- expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
- expect(bundleManager.installBundleIfNeeded(bundleUri, 0, null)).andReturn(new BundleInstallerResult(installedBundle, true));
- expect(bundleManager.getBundleContext()).andReturn(bundleContext);
- ignoreRefreshes(bundleManager);
- bundleManager.uninstall(Collections.EMPTY_LIST, true);
- EasyMock.expectLastCall().times(2);
- return bundleManager;
- }
-
- @Test
- public void testInstallFeatureWithDependantFeaturesAndVersionWithoutPreinstall() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><feature version='0.1'>f2</feature></feature>"
- + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
- + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = prepareBundleManagerForInstallUninstall("bundle-0.1", "bundle-0.1");
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
- svc.installFeature("f1", "0.1");
- svc.uninstallFeature("f1", "0.1");
- svc.uninstallFeature("f2", "0.1");
- verify(bundleManager);
- }
-
- @Test
- public void testInstallFeatureWithDependantFeaturesAndNoVersionWithoutPreinstall() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><feature>f2</feature></feature>"
- + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
- + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = prepareBundleManagerForInstallUninstall("bundle-0.2", "bundle-0.2");
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
- svc.installFeature("f1", "0.1");
- svc.uninstallFeature("f1", "0.1");
- svc.uninstallFeature("f2", "0.2");
- verify(bundleManager);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testInstallFeatureWithDependantFeaturesAndRangeWithoutPreinstall() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
- + " <feature name='f2' version='0.1'><bundle>bundle-0.1</bundle></feature>"
- + " <feature name='f2' version='0.2'><bundle>bundle-0.2</bundle></feature>"
- + "</features>");
-
- BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- Bundle bundleVer02 = createDummyBundle(54321L, "bundleVer02", headers());
- expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
- expect(bundleManager.installBundleIfNeeded("bundle-0.2", 0, null)).andReturn(new BundleInstallerResult(bundleVer02, true));
- expect(bundleManager.getBundleContext()).andReturn(bundleContext);
- ignoreRefreshes(bundleManager);
- bundleManager.uninstall(Collections.EMPTY_LIST, true);
-
- EasyMock.expectLastCall().times(2);
-
- replay(bundleManager);
- FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
- svc.addRepository(uri);
- svc.installFeature("f1", "0.1");
- svc.uninstallFeature("f1", "0.1");
- svc.uninstallFeature("f2", "0.2");
- verify(bundleManager);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testInstallFeatureWithDependantFeaturesAndRangeWithPreinstall() throws Exception {
- String bundleVer01Uri = "bundle-0.1";
- String bundleVer02Uri = "bundle-0.2";
-
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + "<feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
- + " <feature name='f2' version='0.1'><bundle>%s</bundle></feature>"
- + " <feature name='f2' version='0.2'><bundle>%s</bundle></feature>"
- + "</features>", bundleVer01Uri, bundleVer02Uri);
-
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
- replay(bundleContext);
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null);
- svc.addRepository(uri);
- svc.installFeature("f2", "0.1");
- svc.installFeature("f1", "0.1");
- svc.uninstallFeature("f1", "0.1");
- svc.uninstallFeature("f2", "0.1");
-
- verify(bundleContext);
- }
- */
-
- @Test
- public void testGetFeaturesShouldHandleDifferentVersionPatterns() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1' version='0.1'><feature version='[0.1,0.3)'>f2</feature></feature>"
- + " <feature name='f2' version='0.1'><bundle>bundle1</bundle></feature>"
- + " <feature name='f2' version='0.2'><bundle>bundle2</bundle></feature>"
- + "</features>");
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
- svc.addRepository(uri);
-
- assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "[0.1,0.3)"));
- assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "0.0.0"));
- assertEquals(feature("f2", "0.2"), svc.getFeature("f2", "0.2"));
- assertNull(svc.getFeature("f2", "0.3"));
- }
-
- @Test
- public void testInstallBatchFeatureWithFailure() throws Exception {
- String bundle1Uri = "file:bundle1";
- String bundle2Uri = "file:bundle2";
-
- URI uri = createTempRepo(FEATURE_WITH_INVALID_BUNDLE, bundle1Uri, bundle2Uri);
-
- BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
- expect(bundleContext.getBundles()).andReturn(new Bundle[0]);
- replay(bundleContext);
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, bundleContext, new Storage(), null, null, null, null, null, null, null);
- svc.addRepository(uri);
- try {
- List<String> features = new ArrayList<String>();
- for (Feature feature : svc.listFeatures()) {
- features.add(feature.getId());
- }
- Collections.reverse(features);
- svc.installFeatures(new CopyOnWriteArraySet<String>(features),
- EnumSet.noneOf(FeaturesService.Option.class));
- fail("Call should have thrown an exception");
- } catch (MalformedURLException e) {
- }
- verify(bundleContext);
- }
-
- /**
- * This test checks schema validation of submited uri.
- */
- @Test
- public void testSchemaValidation() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <featur><bundle>somebundle</bundle></featur></features>");
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
- try {
- svc.addRepository(uri);
- fail("exception expected");
- } catch (Exception e) {
- assertTrue(e.getMessage().contains("Unable to validate"));
- }
- }
-
- /**
- * This test checks feature service behavior with old, non namespaced descriptor.
- */
- @Test
- public void testLoadOldFeatureFile() throws Exception {
- URI uri = createTempRepo("<features name='test' xmlns='http://karaf.apache.org/xmlns/features/v1.0.0'>"
- + " <feature name='f1'><bundle>file:bundle1</bundle><bundle>file:bundle2</bundle></feature>"
- + "</features>");
-
- FeaturesServiceImpl svc = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, null, null, null);
- svc.addRepository(uri);
- Feature feature = svc.getFeature("f1");
- Assert.assertNotNull("No feature named fi found", feature);
- List<BundleInfo> bundles = feature.getBundles();
- Assert.assertEquals(2, bundles.size());
- }
-
- static class Storage extends StateStorage {
- @Override
- protected InputStream getInputStream() throws IOException {
- return null;
- }
- @Override
- protected OutputStream getOutputStream() throws IOException {
- return null;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java b/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
deleted file mode 100644
index 164dc79..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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;
-
-import java.net.URI;
-
-import junit.framework.TestCase;
-import org.apache.karaf.features.internal.resolver.FeatureResource;
-import org.apache.karaf.features.internal.service.RepositoryImpl;
-import org.osgi.resource.Resource;
-
-
-public class RepositoryTest extends TestCase {
-
- public void testLoad() throws Exception {
- RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo1.xml").toURI());
- // Check repo
- URI[] repos = r.getRepositories();
- assertNotNull(repos);
- assertEquals(1, repos.length);
- assertEquals(URI.create("urn:r1"), repos[0]);
- // Check features
- Feature[] features = r.getFeatures();
- assertNotNull(features);
- assertEquals(3, features.length);
- assertNotNull(features[0]);
- assertEquals("f1", features[0].getName());
- assertNotNull(features[0].getConfigurations());
- assertEquals(1, features[0].getConfigurations().size());
- assertNotNull(features[0].getConfigurations().get("c1"));
- assertEquals(1, features[0].getConfigurations().get("c1").size());
- assertEquals("v", features[0].getConfigurations().get("c1").get("k"));
- assertNotNull(features[0].getDependencies());
- assertEquals(0, features[0].getDependencies().size());
- assertNotNull(features[0].getBundles());
- assertEquals(2, features[0].getBundles().size());
- assertEquals("b1", features[0].getBundles().get(0).getLocation());
- assertEquals("b2", features[0].getBundles().get(1).getLocation());
- assertNotNull(features[1]);
- assertEquals("f2", features[1].getName());
- assertNotNull(features[1].getConfigurations());
- assertEquals(0, features[1].getConfigurations().size());
- assertNotNull(features[1].getDependencies());
- assertEquals(1, features[1].getDependencies().size());
- assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
- assertNotNull(features[1].getBundles());
- assertEquals(1, features[1].getBundles().size());
- assertEquals("b3", features[1].getBundles().get(0).getLocation());
- assertEquals("f3", features[2].getName());
- assertNotNull(features[2].getConfigurationFiles());
- assertEquals(1, features[2].getConfigurationFiles().size());
- assertEquals("cf1", features[2].getConfigurationFiles().get(0).getFinalname());
- assertEquals(true, features[2].getConfigurationFiles().get(0).isOverride());
- assertEquals("cfloc", features[2].getConfigurationFiles().get(0).getLocation());
- }
-
- public void testLoadFormattedRepo() throws Exception {
- RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo2.xml").toURI());
- // Check repo
- URI[] repos = r.getRepositories();
- assertNotNull(repos);
- assertEquals(1, repos.length);
- assertEquals(URI.create("urn:r1"), repos[0]);
- // Check features
- Feature[] features = r.getFeatures();
- assertNotNull(features);
- assertEquals(3, features.length);
- assertNotNull(features[0]);
- assertEquals("f1", features[0].getName());
- assertNotNull(features[0].getConfigurations());
- assertEquals(1, features[0].getConfigurations().size());
- assertNotNull(features[0].getConfigurations().get("c1"));
- assertEquals(1, features[0].getConfigurations().get("c1").size());
- assertEquals("v", features[0].getConfigurations().get("c1").get("k"));
- assertNotNull(features[0].getDependencies());
- assertEquals(0, features[0].getDependencies().size());
- assertNotNull(features[0].getBundles());
- assertEquals(2, features[0].getBundles().size());
- assertEquals("b1", features[0].getBundles().get(0).getLocation());
- assertEquals("b2", features[0].getBundles().get(1).getLocation());
- assertNotNull(features[1]);
- assertEquals("f2", features[1].getName());
- assertNotNull(features[1].getConfigurations());
- assertEquals(0, features[1].getConfigurations().size());
- assertNotNull(features[1].getDependencies());
- assertEquals(1, features[1].getDependencies().size());
- assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
- assertNotNull(features[1].getBundles());
- assertEquals(1, features[1].getBundles().size());
- assertEquals("b3", features[1].getBundles().get(0).getLocation());
- assertEquals("f3", features[2].getName());
- assertNotNull(features[2].getConfigurationFiles());
- assertEquals(1, features[2].getConfigurationFiles().size());
- assertEquals("cf1", features[2].getConfigurationFiles().get(0).getFinalname());
- assertEquals(true, features[2].getConfigurationFiles().get(0).isOverride());
- assertEquals("cfloc", features[2].getConfigurationFiles().get(0).getLocation());
- }
-
- public void testLoadRepoWithCapabilitiesAndRequirement() throws Exception {
- RepositoryImpl r = new RepositoryImpl(getClass().getResource("repo3.xml").toURI());
- // Check features
- Feature[] features = r.getFeatures();
- assertNotNull(features);
- assertEquals(1, features.length);
- assertNotNull(features[0]);
- assertEquals("f1", features[0].getName());
- assertEquals(1, features[0].getCapabilities().size());
- assertEquals("cap", features[0].getCapabilities().get(0).getValue().trim());
- assertEquals(1, features[0].getRequirements().size());
- assertEquals("req", features[0].getRequirements().get(0).getValue().trim());
-
- Resource res = FeatureResource.build(features[0], null, null);
- assertEquals(1, res.getCapabilities("cap").size());
- assertEquals(1, res.getRequirements("req").size());
- }
-
- public void testShowWrongUriInException() throws Exception {
- String uri = "src/test/resources/org/apache/karaf/shell/features/repo1.xml";
- RepositoryImpl r = new RepositoryImpl(new URI(uri));
- try {
- r.load();
- } catch (Exception e) {
- assertTrue(e.getMessage().contains(uri));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/TestBase.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/TestBase.java b/features/core/src/test/java/org/apache/karaf/features/TestBase.java
deleted file mode 100644
index ac8f3d9..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/TestBase.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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;
-
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-
-import org.easymock.EasyMock;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.startlevel.BundleStartLevel;
-
-import static java.util.Arrays.asList;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-public class TestBase {
- public Bundle createDummyBundle(long id, final String symbolicName, Dictionary<String,String> headers) {
- Bundle bundle = EasyMock.createNiceMock(Bundle.class);
-
- // Be aware that this means all bundles are treated as different
- expect(bundle.compareTo(EasyMock.<Bundle>anyObject())).andReturn(1).anyTimes();
-
- expect(bundle.getBundleId()).andReturn(id).anyTimes();
- expect(bundle.getSymbolicName()).andReturn(symbolicName).anyTimes();
- expect(bundle.getHeaders()).andReturn(headers).anyTimes();
- BundleStartLevel sl = EasyMock.createMock(BundleStartLevel.class);
- expect(sl.isPersistentlyStarted()).andReturn(true).anyTimes();
- expect(bundle.adapt(BundleStartLevel.class)).andReturn(sl).anyTimes();
- replay(bundle, sl);
- return bundle;
- }
-
- public Dictionary<String, String> headers(String ... keyAndHeader) {
- Hashtable<String, String> headersTable = new Hashtable<String, String>();
- int c=0;
- while (c < keyAndHeader.length) {
- String key = keyAndHeader[c++];
- String value = keyAndHeader[c++];
- headersTable.put(key, value);
- }
- return headersTable;
- }
-
- public Map<String, Map<String, Feature>> features(Feature ... features) {
- final Map<String, Map<String, Feature>> featuresMap = new HashMap<String, Map<String,Feature>>();
- for (Feature feature : features) {
- Map<String, Feature> featureVersion = getOrCreate(featuresMap, feature);
- featureVersion.put(feature.getVersion(), feature);
- }
- return featuresMap;
- }
-
- private Map<String, Feature> getOrCreate(final Map<String, Map<String, Feature>> featuresMap, Feature feature) {
- Map<String, Feature> featureVersion = featuresMap.get(feature.getName());
- if (featureVersion == null) {
- featureVersion = new HashMap<String, Feature>();
- featuresMap.put(feature.getName(), featureVersion);
- }
- return featureVersion;
- }
-
- public Feature feature(String name) {
- return feature(name, null);
- }
-
- public Feature feature(String name, String version) {
- return new org.apache.karaf.features.internal.model.Feature(name, version);
- }
-
- public Set<Bundle> setOf(Bundle ... elements) {
- return new HashSet<Bundle>(Arrays.asList(elements));
- }
-
- public Set<Long> setOf(Long ... elements) {
- return new HashSet<Long>(Arrays.asList(elements));
- }
-
- public Set<String> setOf(String ... elements) {
- return new HashSet<String>(asList(elements));
- }
-
- public Set<Feature> setOf(Feature ... elements) {
- return new HashSet<Feature>(Arrays.asList(elements));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
deleted file mode 100644
index 31f4f29..0000000
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/BootFeaturesInstallerTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.internal.service;
-
-import static java.util.Arrays.asList;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.fail;
-
-import java.net.URI;
-import java.util.EnumSet;
-
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService.Option;
-import org.apache.karaf.features.TestBase;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class BootFeaturesInstallerTest extends TestBase {
-
- @Test
- @SuppressWarnings("unchecked")
- public void testParser() {
- BootFeaturesInstaller installer = new BootFeaturesInstaller(null, null, "", "", false);
- Assert.assertEquals(asList(setOf("test1", "test2"),setOf("test3")), installer.parseBootFeatures("(test1, test2), test3"));
- Assert.assertEquals(asList(setOf("test1", "test2", "test3")), installer.parseBootFeatures("test1, test2, test3"));
- }
-
- @Test
- public void testDefaultBootFeatures() throws Exception {
- FeaturesServiceImpl impl = EasyMock.createMock(FeaturesServiceImpl.class);
-
- impl.installFeatures(setOf("config", "standard", "region"), EnumSet.of(Option.NoFailOnFeatureNotFound));
- EasyMock.expectLastCall();
-
- impl.bootDone();
- EasyMock.expectLastCall();
-
- replay(impl);
- BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl, "", "config,standard,region", false);
- bootFeatures.installBootFeatures();
- EasyMock.verify(impl);
- }
-
- @Test
- public void testStagedBoot() throws Exception {
- FeaturesServiceImpl impl = EasyMock.createStrictMock(FeaturesServiceImpl.class);
-
- impl.installFeatures(setOf("transaction"), EnumSet.of(Option.NoFailOnFeatureNotFound));
- EasyMock.expectLastCall();
- impl.installFeatures(setOf("ssh"), EnumSet.of(Option.NoFailOnFeatureNotFound));
- EasyMock.expectLastCall();
-
- impl.bootDone();
- EasyMock.expectLastCall();
-
- replay(impl);
- BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl , "", "(transaction), ssh", false);
- bootFeatures.installBootFeatures();
- EasyMock.verify(impl);
- }
-
- @Test
- public void testStartDoesNotFailWithOneInvalidUri() throws Exception {
- FeaturesServiceImpl impl = EasyMock.createStrictMock(FeaturesServiceImpl.class);
- impl.addRepository(URI.create("mvn:inexistent/features/1.0/xml/features"));
- EasyMock.expectLastCall().andThrow(new IllegalArgumentException());
-
- impl.bootDone();
- EasyMock.expectLastCall();
-
- replay(impl);
- BootFeaturesInstaller bootFeatures = new BootFeaturesInstaller(null, impl, "mvn:inexistent/features/1.0/xml/features", "", false);
- bootFeatures.installBootFeatures();
- EasyMock.verify(impl);
- }
-
-}
[27/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java b/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
deleted file mode 100644
index c9541d3..0000000
--- a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.instance.core.management.internal;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.internal.InstanceToTableMapper;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-
-public class InstanceToTableMapperTest extends TestCase {
- public void testJMXInstance() throws Exception {
- Instance instance = EasyMock.createMock(Instance.class);
- EasyMock.expect(instance.getPid()).andReturn(1712);
- EasyMock.expect(instance.getName()).andReturn("MyInstance");
- EasyMock.expect(instance.isRoot()).andReturn(false);
- EasyMock.expect(instance.getSshPort()).andReturn(0);
- EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
- EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
- EasyMock.expect(instance.getState()).andThrow(new Exception("gotcha"));
- EasyMock.expect(instance.getLocation()).andReturn("somewhere");
- EasyMock.expect(instance.getJavaOpts()).andReturn("someopts");
- EasyMock.replay(instance);
-
- TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
- Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
- Assert.assertEquals("MyInstance", keys.iterator().next());
-
- CompositeData cd = td.get(keys.toArray());
- Assert.assertEquals(1712, cd.get("Pid"));
- Assert.assertEquals("MyInstance", cd.get("Name"));
- Assert.assertEquals(false, cd.get("Is Root"));
- Assert.assertEquals(0, cd.get("SSH Port"));
- Assert.assertEquals(0, cd.get("RMI Registry Port"));
- Assert.assertEquals(0, cd.get("RMI Server Port"));
- Assert.assertEquals("Error", cd.get("State"));
- Assert.assertEquals("somewhere", cd.get("Location"));
- Assert.assertEquals("someopts", cd.get("JavaOpts"));
- }
-
- public void testJMXInstance2() throws Exception {
- Instance instance = EasyMock.createMock(Instance.class);
- EasyMock.expect(instance.getPid()).andReturn(1712);
- EasyMock.expect(instance.getName()).andReturn("MyInstance");
- EasyMock.expect(instance.isRoot()).andReturn(true);
- EasyMock.expect(instance.getSshPort()).andReturn(0);
- EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
- EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
- EasyMock.expect(instance.getState()).andReturn("Started");
- EasyMock.expect(instance.getLocation()).andReturn(null);
- EasyMock.expect(instance.getJavaOpts()).andReturn(null);
- EasyMock.replay(instance);
-
- TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
- Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
- Assert.assertEquals("MyInstance", keys.iterator().next());
-
- CompositeData cd = td.get(keys.toArray());
- Assert.assertEquals(1712, cd.get("Pid"));
- Assert.assertEquals("MyInstance", cd.get("Name"));
- Assert.assertEquals(true, cd.get("Is Root"));
- Assert.assertEquals(0, cd.get("SSH Port"));
- Assert.assertEquals(0, cd.get("RMI Registry Port"));
- Assert.assertEquals(0, cd.get("RMI Server Port"));
- Assert.assertEquals("Started", cd.get("State"));
- Assert.assertNull(cd.get("Location"));
- Assert.assertNull(cd.get("JavaOpts"));
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java b/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
deleted file mode 100644
index e7f7c83..0000000
--- a/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.jpm;
-
-public class MainTest {
-
- public static void main(String[] args) throws Exception {
- Thread.sleep(Long.parseLong(args[0]));
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java b/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
deleted file mode 100644
index 9cdc5ad..0000000
--- a/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.jpm;
-
-import java.io.File;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.jpm.impl.ProcessBuilderFactoryImpl;
-import org.apache.karaf.jpm.impl.ScriptUtils;
-
-public class ProcessTest extends TestCase {
-
- public void testCreate() throws Exception {
- String javaPath = new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath();
- System.err.println(javaPath);
- StringBuilder command = new StringBuilder();
- command.append("\"").append(javaPath).append("\"");
- command.append(" -Dprop=\"key\"");
- command.append(" -classpath ");
- String clRes = getClass().getName().replace('.', '/') + ".class";
- String str = getClass().getClassLoader().getResource(clRes).toString();
- str = str.substring("file:".length(), str.indexOf(clRes));
- command.append(str);
- command.append(" ");
- command.append(MainTest.class.getName());
- command.append(" ");
- command.append(60000);
- System.err.println("Executing: " + command.toString());
-
- ProcessBuilder builder = new ProcessBuilderFactoryImpl().newBuilder();
- org.apache.karaf.jpm.Process p = builder.command(command.toString()).start();
- assertNotNull(p);
- System.err.println("Process: " + p.getPid());
- assertNotNull(p.getPid());
- Thread.sleep(1000);
- System.err.println("Running: " + p.isRunning());
- assertTrue(p.isRunning());
- System.err.println("Destroying");
- p.destroy();
- Thread.sleep(1000);
- System.err.println("Running: " + p.isRunning());
- assertFalse(p.isRunning());
- }
-
- /*
- * When the process creation fails, no error is reported by the script
- *
- public void testFailure() throws Exception {
- ProcessBuilder builder = ProcessBuilderFactory.newInstance().newBuilder();
- Process p = builder.command("ec").start();
- fail("An exception should have been thrown");
- }
- */
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/resources/etc/startup.properties
----------------------------------------------------------------------
diff --git a/instance/core/src/test/resources/etc/startup.properties b/instance/core/src/test/resources/etc/startup.properties
deleted file mode 100644
index df7c9bc..0000000
--- a/instance/core/src/test/resources/etc/startup.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-# Fake startup.properties for unit tests as the startup properties in generated by the karaf-maven-plugin
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/pom.xml
----------------------------------------------------------------------
diff --git a/instance/pom.xml b/instance/pom.xml
index c6c1930..baeb2f9 100644
--- a/instance/pom.xml
+++ b/instance/pom.xml
@@ -10,7 +10,7 @@
(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
+ 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,
@@ -29,13 +29,172 @@
</parent>
<groupId>org.apache.karaf.instance</groupId>
- <artifactId>instance</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Instance</name>
+ <artifactId>org.apache.karaf.instance.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Instance :: Core</name>
+ <description>Core implementation of the instance feature to manipulate Karaf child instances.</description>
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <properties>
+ <appendedResourcesDirectory>${project.basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </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>
+ <resource>
+ <directory>${project.build.directory}/generated-resources</directory>
+ <includes>
+ <include>**/*.*</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources/org/apache/karaf/instance/</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/resources</directory>
+ <excludes>
+ <exclude>**/org.apache.karaf.management.cfg</exclude>
+ <exclude>**/org.apache.karaf.shell.cfg</exclude>
+ <exclude>**/system.properties</exclude>
+ </excludes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/filtered-resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.properties</include>
+ <include>**/*.cfg</include>
+ <include>**/*.xml</include>
+ <include>**/*.info</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/snapshot</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.cfg</include>
+ </includes>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.karaf.instance.core
+ </Export-Package>
+ <!-- We have to avoid importing instance.core.internal and jansi
+ as Execute.java accesses the InstanceServiceImpl and jansi
+ (but only outside OSGi) -->
+ <Import-Package>
+ !org.apache.karaf.shell.impl.action.command,
+ !org.apache.karaf.instance.core.internal,
+ *
+ </Import-Package>
+ <Provide-Capability>
+ service-reference;effective:=active;objectClass=org.apache.karaf.instance.core.InstanceService
+ </Provide-Capability>
+ <Private-Package>
+ org.apache.karaf.jpm,
+ org.apache.karaf.jpm.impl,
+ org.apache.karaf.instance.main,
+ org.apache.karaf.instance.command,
+ org.apache.karaf.instance.command.completers,
+ org.apache.karaf.instance.core.internal,
+ org.apache.karaf.instance.core.internal.osgi,
+ org.apache.felix.utils.properties;-split-package:=merge-first,
+ org.apache.karaf.util.locks,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.instance.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.instance.command.*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <!-- this is not a unit test but an application used for testing -->
+ <exclude>**/MainTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
new file mode 100644
index 0000000..c526c07
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "opts-change", description = "Changes the Java options of an existing container instance.")
+@Service
+public class ChangeOptsCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "javaOpts", description = "The new Java options to set", required = true, multiValued = false)
+ private String javaOpts;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeJavaOpts(javaOpts);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
new file mode 100644
index 0000000..de5bfaf
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "rmi-registry-port-change", description = "Changes the RMI registry port (used by management layer) of an existing container instance.")
+@Service
+public class ChangeRmiRegistryPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new RMI registry port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeRmiRegistryPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
new file mode 100644
index 0000000..0ac2cf7
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "rmi-server-port-change", description = "Changes the RMI server port (used by management layer) of an existing instance.")
+@Service
+public class ChangeRmiServerPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new RMI server port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeRmiServerPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
new file mode 100644
index 0000000..17ad26c
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "ssh-port-change", description = "Changes the secure shell port of an existing container instance.")
+@Service
+public class ChangeSshPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new secure shell port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeSshPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
new file mode 100644
index 0000000..e4f28c5
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.InstanceSettings;
+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;
+
+/**
+ * Clone an existing instance.
+ */
+@Command(scope = "instance", name = "clone", description = "Clones an existing container instance.")
+@Service
+public class CloneCommand extends InstanceCommandSupport {
+
+ @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
+ int sshPort = 0;
+
+ @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
+ int rmiRegistryPort = 0;
+
+ @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
+ int rmiServerPort = 0;
+
+ @Option(name = "-l", aliases = {"--location"}, description = "Location of the cloned container instance in the file system", required = false, multiValued = false)
+ String location;
+
+ @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the cloned instance", required = false, multiValued = false)
+ String javaOpts;
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description = "The name of the source container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ String name;
+
+ @Argument(index = 1, name = "cloneName", description = "The name of the cloned container instance", required = true, multiValued = false)
+ String cloneName;
+
+
+ protected Object doExecute() throws Exception {
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, null, null);
+ getInstanceService().cloneInstance(name, cloneName, settings, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
new file mode 100644
index 0000000..c81a3eb
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.instance.command;
+
+import java.util.List;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
+
+@Command(scope = "instance", name = "connect", description = "Connects to an existing container instance.")
+@Service
+public class ConnectCommand extends InstanceCommandSupport {
+
+ @Option(name="-u", aliases={"--username"}, description="Remote user name", required = false, multiValued = false)
+ private String username;
+
+ @Option(name = "-p", aliases = {"--password"}, description = "Remote password", required = false, multiValued = false)
+ private String password;
+
+ @Argument(index = 0, name="name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "command", description = "Optional command to execute", required = false, multiValued = true)
+ private List<String> command;
+
+ @Reference
+ Session session;
+
+ protected Object doExecute() throws Exception {
+ String cmdStr = "";
+ if (command != null) {
+ StringBuilder sb = new StringBuilder();
+ for (String cmd : command) {
+ if (sb.length() > 0) {
+ sb.append(' ');
+ }
+ sb.append(cmd);
+ }
+ cmdStr = "'" + sb.toString().replaceAll("'", "\\'") + "'";
+ }
+
+ int port = getExistingInstance(instance).getSshPort();
+ if (username != null) {
+ if (password == null) {
+ session.execute("ssh:ssh -q -l " + username + " -p " + port + " localhost " + cmdStr);
+ } else {
+ session.execute("ssh:ssh -q -l " + username + " -P " + password + " -p " + port + " localhost " + cmdStr);
+ }
+ } else {
+ session.execute("ssh:ssh -q -p " + port + " localhost " + cmdStr);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
new file mode 100644
index 0000000..0dcc3ac
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
@@ -0,0 +1,74 @@
+/*
+ * 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.instance.command;
+
+import java.util.List;
+
+import org.apache.karaf.features.command.completers.AllFeatureCompleter;
+import org.apache.karaf.features.command.completers.InstalledRepoUriCompleter;
+import org.apache.karaf.instance.core.InstanceSettings;
+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;
+
+/**
+ * Creates a new instance.
+ */
+@Command(scope = "instance", name = "create", description = "Creates a new container instance.")
+@Service
+public class CreateCommand extends InstanceCommandSupport
+{
+ @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
+ int sshPort = 0;
+
+ @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
+ int rmiRegistryPort = 0;
+
+ @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
+ int rmiServerPort = 0;
+
+ @Option(name = "-l", aliases = {"--location"}, description = "Location of the new container instance in the file system", required = false, multiValued = false)
+ String location;
+
+ @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the instance", required = false, multiValued = false)
+ String javaOpts;
+
+ @Option(name = "-f", aliases = {"--feature"},
+ description = "Initial features. This option can be specified multiple times to enable multiple initial features", required = false, multiValued = true)
+ @Completion(AllFeatureCompleter.class)
+ List<String> features;
+
+ @Option(name = "-furl", aliases = {"--featureURL"},
+ description = "Additional feature descriptor URLs. This option can be specified multiple times to add multiple URLs", required = false, multiValued = true)
+ @Completion(InstalledRepoUriCompleter.class)
+ List<String> featureURLs;
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description="The name of the new container instance", required = true, multiValued = false)
+ String instance = null;
+
+ protected Object doExecute() throws Exception {
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
+ getInstanceService().createInstance(instance, settings, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
new file mode 100644
index 0000000..fb2964f
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+/**
+ * Destroy an existing instance.
+ */
+@Command(scope = "instance", name = "destroy", description = "Destroys an existing container instance.")
+@Service
+public class DestroyCommand extends InstanceCommandSupport
+{
+ @Argument(index = 0, name = "name", description= "The name of the container instance to destroy", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).destroy();
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java b/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
new file mode 100644
index 0000000..3b0b535
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
@@ -0,0 +1,51 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+
+public abstract class InstanceCommandSupport implements Action {
+
+ @Reference
+ private InstanceService instanceService;
+
+ public InstanceService getInstanceService() {
+ return instanceService;
+ }
+
+ public void setInstanceService(InstanceService instanceService) {
+ this.instanceService = instanceService;
+ }
+
+ protected Instance getExistingInstance(String name) {
+ Instance i = instanceService.getInstance(name);
+ if (i == null) {
+ throw new IllegalArgumentException("Instances '" + name + "' does not exist");
+ }
+ return i;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ return doExecute();
+ }
+
+ protected abstract Object doExecute() throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
new file mode 100644
index 0000000..fe571a8
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
@@ -0,0 +1,81 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.core.Instance;
+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 = "instance", name = "list", description = "Lists all existing container instances.")
+@Service
+public class ListCommand extends InstanceCommandSupport {
+
+ @Option(name = "-l", aliases = { "--location" }, description = "Displays the location of the container instances", required = false, multiValued = false)
+ boolean location;
+
+ @Option(name = "-o", aliases = { "--java-opts" }, description = "Displays the Java options used to launch the JVM", required = false, multiValued = false)
+ boolean javaOpts;
+
+ @Option(name = "--no-color", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected Object doExecute() throws Exception {
+ getInstanceService().refreshInstance();
+ Instance[] instances = getInstanceService().getInstances();
+ ShellTable table = new ShellTable();
+ table.column("SSH Port").alignRight();
+ table.column("RMI Registry").alignRight();
+ table.column("RMI Server").alignRight();
+ table.column("State");
+ table.column("PID");
+ table.column(getRightColumnHeader());
+ for (Instance instance : instances) {
+ table.addRow().addContent(
+ instance.getSshPort(),
+ instance.getRmiRegistryPort(),
+ instance.getRmiServerPort(),
+ instance.getState(),
+ instance.getPid(),
+ getRightColumnValue(instance));
+ }
+ table.print(System.out, !noFormat);
+ return null;
+ }
+
+ private String getRightColumnHeader() {
+ if (javaOpts) {
+ return "JavaOpts";
+ } else if (location) {
+ return "Location";
+ } else {
+ return "Name";
+ }
+ }
+
+ private String getRightColumnValue(Instance instance) {
+ if (javaOpts) {
+ return instance.getJavaOpts();
+ } else if (location) {
+ return instance.getLocation();
+ } else {
+ return instance.getName();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
new file mode 100644
index 0000000..ef68400
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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 = "instance", name = "rename", description = "Rename an existing container instance.")
+@Service
+public class RenameCommand extends InstanceCommandSupport {
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance to rename", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ String instance = null;
+
+ @Argument(index = 1, name = "new-name", description = "The new name of the container instance", required = true, multiValued = false)
+ String newName = null;
+
+ protected Object doExecute() throws Exception {
+ getInstanceService().renameInstance(instance, newName, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
new file mode 100644
index 0000000..8c52d5e
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.Instance;
+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 = "instance", name = "start", description = "Start an existing container instance.")
+@Service
+public class StartCommand extends InstanceCommandSupport {
+
+ @Option(name = "-d", aliases = { "--debug"}, description = "Start the instance in debug mode", required = false, multiValued = false)
+ private boolean debug;
+
+ @Option(name = "-o", aliases = { "--java-opts"}, description = "Java options when launching the instance", required = false, multiValued = false)
+ private String javaOpts;
+
+ @Option(name = "-w", aliases = { "--wait"}, description = "Wait for the instance to be fully started", required = false, multiValued = false)
+ private boolean wait;
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ static final String DEBUG_OPTS = " -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005";
+ static final String DEFAULT_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote";
+
+ protected Object doExecute() throws Exception {
+ Instance child = getExistingInstance(instance);
+ String opts = javaOpts;
+ if (opts == null) {
+ opts = child.getJavaOpts();
+ }
+ if (opts == null) {
+ opts = DEFAULT_OPTS;
+ }
+ if (debug) {
+ opts += DEBUG_OPTS;
+ }
+ if (wait) {
+ String state = child.getState();
+ if (Instance.STOPPED.equals(state)) {
+ child.start(opts);
+ }
+ if (!Instance.STARTED.equals(state)) {
+ do {
+ Thread.sleep(500);
+ state = child.getState();
+ } while (Instance.STARTING.equals(state));
+ }
+ } else {
+ child.start(opts);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
new file mode 100644
index 0000000..82100e1
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.Instance;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "status", description = "Check the current status of an instance.")
+@Service
+public class StatusCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String name;
+
+ protected Object doExecute() throws Exception {
+ Instance instance = getExistingInstance(name);
+ System.out.println(instance.getState());
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java
new file mode 100644
index 0000000..6c8de10
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "instance", name = "stop", description = "Stop an existing container instance.")
+@Service
+public class StopCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).stop();
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java b/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
new file mode 100644
index 0000000..4468374
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
@@ -0,0 +1,52 @@
+/*
+ * 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.instance.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+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;
+
+/**
+ * Displays a list of configured server instances for the instance commands.
+ *
+ */
+@Service
+public class InstanceCompleter implements Completer {
+
+ @Reference
+ private InstanceService instanceService;
+
+ public void setInstanceService(InstanceService instanceService) {
+ this.instanceService = instanceService;
+ }
+
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ for (Instance instance : instanceService.getInstances()) {
+ delegate.getStrings().add(instance.getName());
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/Instance.java b/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
new file mode 100644
index 0000000..5e78bb2
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
@@ -0,0 +1,66 @@
+/*
+ * 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.instance.core;
+
+public interface Instance {
+
+ String STOPPED = "Stopped";
+ String STARTING = "Starting";
+ String STARTED = "Started";
+ String ERROR = "Error";
+
+ String getName();
+
+ @Deprecated
+ void setName(String name);
+
+ boolean isRoot();
+
+ String getLocation();
+
+ @Deprecated
+ void setLocation(String location);
+
+ int getPid();
+
+ int getSshPort();
+
+ void changeSshPort(int port) throws Exception;
+
+ int getRmiRegistryPort();
+
+ void changeRmiRegistryPort(int port) throws Exception;
+
+ int getRmiServerPort();
+
+ void changeRmiServerPort(int port) throws Exception;
+
+ String getJavaOpts();
+
+ void changeJavaOpts(String javaOpts) throws Exception;
+
+ void start(String javaOpts) throws Exception;
+
+ void stop() throws Exception;
+
+ void destroy() throws Exception;
+
+ String getState() throws Exception;
+
+ @Deprecated
+ boolean isAttached();
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java b/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java
new file mode 100644
index 0000000..cc6c10c
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.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.instance.core;
+
+public interface InstanceService {
+
+ Instance createInstance(String name, InstanceSettings settings, boolean printOutput) throws Exception;
+
+ void renameInstance(String name, String newName, boolean printOutput) throws Exception;
+
+ @Deprecated
+ void refreshInstance() throws Exception;
+
+ Instance cloneInstance(String name, String cloneName, InstanceSettings settings, boolean printOutput) throws Exception;
+
+ Instance[] getInstances();
+
+ Instance getInstance(String name);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java b/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
new file mode 100644
index 0000000..0f9cf97
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
@@ -0,0 +1,97 @@
+/*
+ * 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.instance.core;
+
+import java.util.List;
+
+public class InstanceSettings {
+
+ private final int sshPort;
+ private final int rmiRegistryPort;
+ private final int rmiServerPort;
+ private final String location;
+ private final String javaOpts;
+ private final List<String> featureURLs;
+ private final List<String> features;
+
+ public InstanceSettings(int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, List<String> featureURLs, List<String> features) {
+ this.sshPort = sshPort;
+ this.rmiRegistryPort = rmiRegistryPort;
+ this.rmiServerPort = rmiServerPort;
+ this.location = location;
+ this.javaOpts = javaOpts;
+ this.featureURLs = featureURLs;
+ this.features = features;
+ }
+
+ public int getSshPort() {
+ return sshPort;
+ }
+
+ public int getRmiRegistryPort() {
+ return rmiRegistryPort;
+ }
+
+ public int getRmiServerPort() {
+ return rmiServerPort;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getJavaOpts() {
+ return javaOpts;
+ }
+
+ public List<String> getFeatureURLs() {
+ return featureURLs;
+ }
+
+ public List<String> getFeatures() {
+ return features;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof InstanceSettings)) {
+ return false;
+ }
+ InstanceSettings is = (InstanceSettings) o;
+ return is.sshPort == sshPort &&
+ is.rmiRegistryPort == rmiRegistryPort &&
+ is.rmiServerPort == rmiServerPort &&
+ (location == null ? is.location == null : location.equals(is.location)) &&
+ (javaOpts == null ? is.javaOpts == null : javaOpts.equals(is.javaOpts)) &&
+ (featureURLs == null ? is.featureURLs == null : featureURLs.equals(is.featureURLs)) &&
+ (features == null ? is.features == null : features.equals(is.features));
+ }
+
+ @Override
+ public int hashCode() {
+ int result = sshPort + rmiRegistryPort + rmiServerPort;
+ result = 31 * result + (location != null ? location.hashCode() : 0);
+ result = 31 * result + (javaOpts != null ? javaOpts.hashCode() : 0);
+ result = 31 * result + (featureURLs != null ? featureURLs.hashCode() : 0);
+ result = 31 * result + (features != null ? features.hashCode() : 0);
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java b/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
new file mode 100644
index 0000000..f75e099
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
@@ -0,0 +1,55 @@
+/*
+ * 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.instance.core;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+
+public interface InstancesMBean {
+
+ String INSTANCE_PID = "Pid";
+ String INSTANCE_NAME = "Name";
+ String INSTANCE_IS_ROOT = "Is Root";
+ String INSTANCE_SSH_PORT = "SSH Port";
+ String INSTANCE_RMI_REGISTRY_PORT = "RMI Registry Port";
+ String INSTANCE_RMI_SERVER_PORT = "RMI Server Port";
+ String INSTANCE_STATE = "State";
+ String INSTANCE_LOCATION = "Location";
+ String INSTANCE_JAVAOPTS = "JavaOpts";
+
+ String[] INSTANCE = {INSTANCE_PID, INSTANCE_NAME, INSTANCE_IS_ROOT, INSTANCE_SSH_PORT, INSTANCE_RMI_REGISTRY_PORT,
+ INSTANCE_RMI_SERVER_PORT, INSTANCE_STATE, INSTANCE_LOCATION, INSTANCE_JAVAOPTS };
+
+ // Operations
+ int createInstance(String name, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, String features, String featureURLs) throws MBeanException;
+ void changeSshPort(String name, int port) throws MBeanException;
+ void changeRmiRegistryPort(String name, int port) throws MBeanException;
+ void changeRmiServerPort(String name, int port) throws MBeanException;
+ void changeJavaOpts(String name, String javaopts) throws MBeanException;
+ void destroyInstance(String name) throws MBeanException;
+ void startInstance(String name) throws MBeanException;
+ void startInstance(String name, String opts) throws MBeanException;
+ void startInstance(String name, String opts, boolean wait, boolean debug) throws MBeanException;
+ void stopInstance(String name) throws MBeanException;
+ void renameInstance(String originalName, String newName) throws MBeanException;
+ void renameInstance(String originalName, String newName, boolean verbose) throws MBeanException;
+ void cloneInstance(String name, String cloneName, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts) throws MBeanException;
+
+ // Attributes
+ TabularData getInstances() throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
new file mode 100644
index 0000000..edc4ec5
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
@@ -0,0 +1,110 @@
+/*
+ * 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.instance.core.internal;
+
+import org.apache.karaf.instance.core.Instance;
+
+public class InstanceImpl implements Instance {
+
+ private final InstanceServiceImpl service;
+ private String name;
+
+ public InstanceImpl(InstanceServiceImpl service, String name) {
+ this.service = service;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ void doSetName(String name) {
+ this.name = name;
+ }
+
+ public boolean isRoot() {
+ return service.isInstanceRoot(name);
+ }
+
+ public String getLocation() {
+ return service.getInstanceLocation(name);
+ }
+
+ public void setLocation(String location) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getPid() {
+ return service.getInstancePid(name);
+ }
+
+ public int getSshPort() {
+ return service.getInstanceSshPort(name);
+ }
+
+ public void changeSshPort(int port) throws Exception {
+ service.changeInstanceSshPort(name, port);
+ }
+
+ public int getRmiRegistryPort() {
+ return service.getInstanceRmiRegistryPort(name);
+ }
+
+ public void changeRmiRegistryPort(int port) throws Exception {
+ service.changeInstanceRmiRegistryPort(name, port);
+ }
+
+ public int getRmiServerPort() {
+ return service.getInstanceRmiServerPort(name);
+ }
+
+ public void changeRmiServerPort(int port) throws Exception {
+ service.changeInstanceRmiServerPort(name, port);
+ }
+
+ public String getJavaOpts() {
+ return service.getInstanceJavaOpts(name);
+ }
+
+ public void changeJavaOpts(String javaOpts) throws Exception {
+ service.changeInstanceJavaOpts(name, javaOpts);
+ }
+
+ public void start(String javaOpts) throws Exception {
+ service.startInstance(name, javaOpts);
+ }
+
+ public void stop() throws Exception {
+ service.stopInstance(name);
+ }
+
+ public void destroy() throws Exception {
+ service.destroyInstance(name);
+ }
+
+ public String getState() throws Exception {
+ return service.getInstanceState(name);
+ }
+
+ public boolean isAttached() {
+ return getPid() != 0;
+ }
+}
\ No newline at end of file
[41/59] [abbrv] [KARAF-2852] Merge system/core and system/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/SystemService.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/SystemService.java b/system/src/main/java/org/apache/karaf/system/SystemService.java
new file mode 100644
index 0000000..2f53946
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/SystemService.java
@@ -0,0 +1,130 @@
+ /*
+ * 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.system;
+
+/**
+ * Describe a system service
+ */
+public interface SystemService {
+
+ /**
+ * Types defining what to remove on a restart of Karaf
+ */
+ public enum Swipe {
+ /** Delete nothing; simple restart */
+ NONE,
+ /** Delete only the cache; everything else remains */
+ CACHE,
+ /** Forces a clean restart by removing the working directory; this option is compatible to the former clean method. */
+ ALL
+ }
+
+ /**
+ * Halt the Karaf container.
+ */
+ void halt() throws Exception;
+
+ /**
+ * Halt the Karaf container.
+ *
+ * @param time shutdown delay. The time argument can have different formats.
+ * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm
+ * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes
+ * to wait. The word now is an alias for +0.
+ */
+ void halt(String time) throws Exception;
+
+ /**
+ * Reboot the Karaf container.
+ *
+ * @throws Exception
+ */
+ void reboot() throws Exception;
+
+ /**
+ * Reboot the Karaf container.
+ *
+ * @param time reboot delay. The time argument can have different formats.
+ * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm
+ * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes
+ * to wait. The word now is an alias for +0.
+ * @param clean Force a clean restart by deleting the working directory.
+ */
+ void reboot(String time, Swipe clean) throws Exception;
+
+ /**
+ * Set the system start level.
+ *
+ * @param startLevel the new system start level.
+ */
+ void setStartLevel(int startLevel) throws Exception;
+
+ /**
+ * Get the system start level.
+ *
+ * @return the current system start level.
+ */
+ int getStartLevel() throws Exception;
+
+ /**
+ * Get the version of the current Karaf instance
+ *
+ * @return instance version
+ */
+ String getVersion();
+
+ /**
+ * Get the name of the current Karaf instance
+ *
+ * @return instance name
+ */
+ String getName();
+
+ /**
+ * Set the name of the Karaf instance
+ *
+ * @param name new instance name
+ */
+ void setName(String name);
+
+ /**
+ * Get the current OSGi framework in use.
+ *
+ * @return the name of the OSGi framework in use.
+ * @throws Exception
+ */
+ FrameworkType getFramework();
+
+ /**
+ * change OSGi framework
+ *
+ * @param framework to use.
+ */
+ void setFramework(FrameworkType framework);
+
+ /**
+ * Enable or diable debgging
+ * @param debug enable if true
+ */
+ void setFrameworkDebug(boolean debug);
+
+ /**
+ * Set a system property and persist to etc/system.properties
+ * @param key
+ */
+ String setSystemProperty(String key, String value, boolean persist);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java b/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java
new file mode 100644
index 0000000..9e16a7d
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.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.system.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.system.FrameworkType;
+import org.apache.karaf.system.SystemService;
+
+/**
+ * Command for enabling/disabling debug logging on the OSGi framework
+ */
+@Command(scope = "system", name = "framework", description = "OSGi Framework options.")
+@Service
+public class FrameworkOptions implements Action {
+
+ @Option(name = "-debug", aliases={"--enable-debug"}, description="Enable debug for the OSGi framework", required = false, multiValued = false)
+ boolean debug;
+
+ @Option(name = "-nodebug", aliases={"--disable-debug"}, description="Disable debug for the OSGi framework", required = false, multiValued = false)
+ boolean nodebug;
+
+ @Argument(name = "framework", required = false, description = "Name of the OSGi framework to use")
+ String framework;
+
+ @Reference
+ SystemService systemService;
+
+ @Override
+ public Object execute() throws Exception {
+
+ if (!debug^nodebug && framework == null) {
+ System.out.printf("Current OSGi framework is %s%n", systemService.getFramework().name());
+ return null;
+ }
+ if (framework != null) {
+ FrameworkType frameworkType = FrameworkType.valueOf(framework);
+ systemService.setFramework(frameworkType);
+ System.out.println("Changed OSGi framework to " + frameworkType.toString().toLowerCase() + ". Karaf needs to be restarted to make the change effective");
+ }
+ if (debug) {
+ FrameworkType frameworkType = systemService.getFramework();
+ System.out.printf("Enabling debug for OSGi framework (%s)%n", frameworkType.name());
+ systemService.setFrameworkDebug(true);
+ }
+ if (nodebug) {
+ FrameworkType frameworkType = systemService.getFramework();
+ System.out.printf("Disabling debug for OSGi framework (%s)%n", frameworkType.name());
+ systemService.setFrameworkDebug(false);
+ }
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Name.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/Name.java b/system/src/main/java/org/apache/karaf/system/commands/Name.java
new file mode 100644
index 0000000..a716d82
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/Name.java
@@ -0,0 +1,51 @@
+/*
+ * 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.system.commands;
+
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.system.SystemService;
+
+/**
+ * Command to shut down Karaf container.
+ */
+@Command(scope = "system", name = "name", description = "Show or change Karaf instance name.")
+@Service
+public class Name implements Action {
+
+ @Argument(name = "name", index = 0, description = "New name for the instance", required = false, multiValued = false)
+ String name;
+
+ @Reference
+ SystemService systemService;
+
+ @Override
+ public Object execute() throws Exception {
+ if (name == null) {
+ System.out.println(systemService.getName());
+ } else {
+ systemService.setName(name);
+ System.out.println("Instance name changed to " + name + ". Restart needed for this to take effect.");
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java b/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java
new file mode 100644
index 0000000..b8b4b41
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java
@@ -0,0 +1,104 @@
+/*
+ * 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.system.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+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.Session;
+import org.apache.karaf.system.SystemService;
+
+/**
+ * Command to shut down Karaf container.
+ */
+@Command(scope = "system", name = "shutdown", description = "Shutdown Karaf.")
+@Service
+public class Shutdown implements Action {
+
+ @Option(name = "-f", aliases = "--force", description = "Force the shutdown without confirmation message.", required = false, multiValued = false)
+ boolean force = false;
+
+ @Option(name = "-r", aliases = "--reboot", description = "Reboot the Karaf container.", required = false, multiValued = false)
+ boolean reboot = false;
+
+ @Option(name = "-h", aliases = "--halt", description = "Halt the Karaf container.", required = false, multiValued = false)
+ boolean halt = false;
+
+ @Option(name = "-c", aliases = {"--clean", "--clean-all", "-ca"}, description = "Force a clean restart by deleting the data directory")
+ private boolean cleanAll;
+
+ @Option(name = "-cc", aliases = {"--clean-cache", "-cc"}, description = "Force a clean restart by deleting the cache directory")
+ private boolean cleanCache;
+
+
+ @Argument(name = "time", index = 0, description = "Shutdown after a specified delay. The time argument can have different" +
+ " formats. First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm" +
+ " is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes" +
+ " to wait. The word now is an alias for +0.", required = false, multiValued = false)
+ String time;
+
+ @Reference
+ SystemService systemService;
+
+ @Reference
+ Session session;
+
+ @Override
+ public Object execute() throws Exception {
+
+ if (force) {
+ if (reboot) {
+ systemService.reboot(time, determineSwipeType());
+ } else {
+ systemService.halt(time);
+ }
+ return null;
+ }
+
+ for (; ; ) {
+ String karafName = System.getProperty("karaf.name");
+ String msg;
+ if (reboot) {
+ msg = String.format("Confirm: reboot instance %s (yes/no): ", karafName);
+ } else {
+ msg = String.format("Confirm: halt instance %s (yes/no): ", karafName);
+ }
+ String str = session.readLine(msg, null);
+ if (str.equalsIgnoreCase("yes")) {
+ if (reboot) {
+ systemService.reboot(time, determineSwipeType());
+ } else {
+ systemService.halt(time);
+ }
+ }
+ return null;
+ }
+ }
+
+ private SystemService.Swipe determineSwipeType() {
+ if (cleanAll) {
+ return SystemService.Swipe.ALL;
+ } else if (cleanCache) {
+ return SystemService.Swipe.CACHE;
+ }
+ return SystemService.Swipe.NONE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java b/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java
new file mode 100644
index 0000000..e91c15a
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java
@@ -0,0 +1,49 @@
+/*
+ * 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.system.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.system.SystemService;
+
+/**
+ * Get/set the system start level.
+ */
+@Command(scope = "system", name = "start-level", description = "Gets or sets the system start level.")
+@Service
+public class StartLevel implements Action {
+
+ @Argument(index = 0, name = "level", description = "The new system start level to set", required = false, multiValued = false)
+ Integer level;
+
+ @Reference
+ SystemService systemService;
+
+ @Override
+ public Object execute() throws Exception {
+ if (level == null) {
+ System.out.println("Level " + systemService.getStartLevel());
+ } else {
+ systemService.setStartLevel(level);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java b/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
new file mode 100644
index 0000000..37c2a1e
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java
@@ -0,0 +1,157 @@
+/*
+ * 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.system.commands;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.system.SystemService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Command that allow access to system properties easily.
+ */
+@Command(scope = "system", name = "property", description = "Get or set a system property.")
+@Service
+public class SystemProperty implements Action {
+
+ @Option(name = "-p", aliases = {"--persistent"}, description = "Persist the new value to the etc/system.properties file")
+ boolean persistent;
+
+ @Option(name = "-f", aliases = {"--file-dump"}, description = "Dump all system properties in a file (in data folder)")
+ boolean dumpToFile;
+
+ @Option(name = "-u", aliases = {"--unset"}, description = "Show unset know properties with value unset")
+ boolean unset;
+
+ @Argument(index = 0, name = "key", required = false, description = "The system property name")
+ String key;
+
+ @Argument(index = 1, name = "value", required = false, description = "New value for the system property")
+ String value;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Reference
+ SystemService systemService;
+
+ @Override
+ public Object execute() throws Exception {
+ if (key == null && value == null) {
+ Properties props = (Properties) System.getProperties().clone();
+
+ String def = null;
+ if (unset) {
+ def = "unset";
+ }
+
+ setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def);
+ setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def);
+ setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def);
+ setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def);
+ setProperty(props, Constants.FRAMEWORK_LANGUAGE, def);
+ setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def);
+ setProperty(props, Constants.FRAMEWORK_OS_NAME, def);
+ setProperty(props, Constants.FRAMEWORK_OS_VERSION, def);
+ setProperty(props, Constants.FRAMEWORK_PROCESSOR, def);
+ setProperty(props, Constants.FRAMEWORK_SECURITY, def);
+ setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def);
+ setProperty(props, Constants.FRAMEWORK_STORAGE, def);
+ setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def);
+ setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def);
+ setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def);
+ setProperty(props, Constants.FRAMEWORK_VENDOR, def);
+ setProperty(props, Constants.FRAMEWORK_VERSION, def);
+ setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def);
+
+ setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def);
+
+ if (dumpToFile) {
+ PrintStream ps = new PrintStream(
+ new File(
+ bundleContext.getProperty("karaf.data"),
+ "dump-properties-" + System.currentTimeMillis() + ".properties"
+ )
+ );
+ ps.println("#Dump of the System and OSGi properties with the command system:property");
+ ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date()));
+ printOrderedProperties(props, ps);
+ ps.flush();
+ ps.close();
+ } else {
+ printOrderedProperties(props, System.out);
+ }
+
+ return null;
+ }
+
+ if (value != null) {
+ systemService.setSystemProperty(key, value, persistent);
+ } else {
+ System.out.println(System.getProperty(key));
+ }
+
+ return null;
+ }
+
+ private void printOrderedProperties(Properties props, PrintStream out) {
+ Set<Object> keys = props.keySet();
+ Vector<String> order = new Vector<String>(keys.size());
+ for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
+ Object str = (Object) i.next();
+ order.add((String) str);
+ }
+ Collections.sort(order);
+ for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ out.println(key + "=" + props.getProperty(key));
+ }
+ }
+
+ private void setProperty(Properties props, String key, String def) {
+ String val = bundleContext.getProperty(key);
+ if (val == null && def != null) {
+ props.setProperty(key, def);
+ } else if (val != null) {
+ props.setProperty(key, val);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Version.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/commands/Version.java b/system/src/main/java/org/apache/karaf/system/commands/Version.java
new file mode 100644
index 0000000..9837aaa
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/commands/Version.java
@@ -0,0 +1,38 @@
+/*
+ * 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.system.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.system.SystemService;
+
+@Command(scope = "system", name = "version", description = "Display the instance version")
+@Service
+public class Version implements Action {
+
+ @Reference
+ SystemService systemService;
+
+ @Override
+ public Object execute() throws Exception {
+ System.out.println(systemService.getVersion());
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java b/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
new file mode 100644
index 0000000..8fa5a38
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java
@@ -0,0 +1,238 @@
+/*
+* 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.system.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.felix.utils.properties.Properties;
+import org.apache.karaf.system.FrameworkType;
+import org.apache.karaf.system.SystemService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the system service.
+ */
+public class SystemServiceImpl implements SystemService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SystemServiceImpl.class);
+
+ private BundleContext bundleContext;
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public BundleContext getBundleContext() {
+ return this.bundleContext;
+ }
+
+ public void halt() throws Exception {
+ halt(null);
+ }
+
+ public void halt(String time) throws Exception {
+ shutdown(timeToSleep(time));
+ }
+
+ public void reboot() throws Exception {
+ reboot(null, Swipe.NONE);
+ }
+
+ public void reboot(String time, Swipe cleanup) throws Exception {
+ reboot(timeToSleep(time), cleanup);
+ }
+
+ private void shutdown(final long sleep) {
+ new Thread() {
+ public void run() {
+ try {
+ sleepWithMsg(sleep, "Shutdown in " + sleep / 1000 / 60 + " minute(s)");
+ getBundleContext().getBundle(0).stop();
+ } catch (Exception e) {
+ LOGGER.error("Halt error", e);
+ }
+ }
+ }.start();
+ }
+
+ private void reboot(final long sleep, final Swipe clean) {
+ new Thread() {
+ public void run() {
+ try {
+ sleepWithMsg(sleep, "Reboot in " + sleep / 1000 / 60 + " minute(s)");
+ System.setProperty("karaf.restart", "true");
+ if (clean.equals(Swipe.ALL)) {
+ System.setProperty("karaf.clean.all", "true");
+ } else if (clean.equals(Swipe.CACHE)) {
+ System.setProperty("karaf.clean.cache", "true");
+ }
+ bundleContext.getBundle(0).stop();
+ } catch (Exception e) {
+ LOGGER.error("Reboot error", e);
+ }
+ }
+ }.start();
+ }
+
+ private void sleepWithMsg(final long sleep, String msg)
+ throws InterruptedException {
+ if (sleep > 0) {
+ LOGGER.info(msg);
+ System.err.println(msg);
+ }
+ Thread.sleep(sleep);
+ }
+
+ public void setStartLevel(int startLevel) throws Exception {
+ getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).setStartLevel(startLevel);
+ }
+
+ public int getStartLevel() throws Exception {
+ return getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+ }
+
+ /**
+ * Convert a time string to sleep period (in millisecond).
+ *
+ * @param time the time string.
+ * @return the corresponding sleep period in millisecond.
+ */
+ private long timeToSleep(String time) throws Exception {
+ long sleep = 0;
+ if (time != null) {
+ if (!time.equals("now")) {
+ if (time.startsWith("+")) {
+ // delay in number of minutes provided
+ time = time.substring(1);
+ try {
+ sleep = Long.parseLong(time) * 60 * 1000;
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Time " + time + " is not valid");
+ }
+ } else {
+ // try to parse the date in hh:mm
+ String[] strings = time.split(":");
+ if (strings.length != 2) {
+ throw new IllegalArgumentException("Time " + time + " is not valid");
+ }
+ GregorianCalendar currentDate = new GregorianCalendar();
+ GregorianCalendar shutdownDate = new GregorianCalendar(currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE), Integer.parseInt(strings[0]), Integer.parseInt(strings[1]));
+ if (shutdownDate.before(currentDate)) {
+ shutdownDate.set(Calendar.DATE, shutdownDate.get(Calendar.DATE) + 1);
+ }
+ sleep = shutdownDate.getTimeInMillis() - currentDate.getTimeInMillis();
+ }
+ }
+ }
+ return sleep;
+ }
+
+ @Override
+ public String getVersion() {
+ return System.getProperty("karaf.version");
+ }
+
+ @Override
+ public String getName() {
+ return bundleContext.getProperty("karaf.name");
+ }
+
+ @Override
+ public void setName(String name) {
+ try {
+ String karafEtc = bundleContext.getProperty("karaf.etc");
+ File etcDir = new File(karafEtc);
+ File syspropsFile = new File(etcDir, "system.properties");
+ FileInputStream fis = new FileInputStream(syspropsFile);
+ Properties props = new Properties();
+ props.load(fis);
+ fis.close();
+ props.setProperty("karaf.name", name);
+ FileOutputStream fos = new FileOutputStream(syspropsFile);
+ props.store(fos, "");
+ fos.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public FrameworkType getFramework() {
+ if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) {
+ return FrameworkType.felix;
+ } else {
+ return FrameworkType.equinox;
+ }
+ }
+
+ private Properties loadProps() throws IOException {
+ return new Properties(new File(System.getProperty("karaf.etc"), "config.properties"));
+ }
+
+ public void setFramework(FrameworkType framework) {
+ if (framework == null) {
+ return;
+ }
+ try {
+ Properties properties = loadProps();
+ properties.put("karaf.framework", framework.name());
+ properties.save();
+ } catch (IOException e) {
+ throw new RuntimeException("Error setting framework: " + e.getMessage(), e);
+ }
+ }
+
+ public void setFrameworkDebug(boolean debug) {
+ try {
+ Properties properties = loadProps();
+ if (debug) {
+ properties.put("felix.log.level", "4");
+ properties.put("osgi.debug", "etc/equinox-debug.properties");
+ } else {
+ properties.remove("felix.log.level");
+ properties.remove("osgi.debug");
+ }
+ // TODO populate the equinox-debug.properties file with the one provided in shell/dev module
+ properties.save();
+ } catch (IOException e) {
+ throw new RuntimeException("Error settting framework debugging: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public String setSystemProperty(String key, String value, boolean persist) {
+ if (persist) {
+ try {
+ String etc = System.getProperty("karaf.etc");
+ Properties props = new Properties(new File(etc, "system.properties"));
+ props.put(key, value);
+ props.save();
+ } catch (IOException e) {
+ throw new RuntimeException("Error persisting system property", e);
+ }
+ }
+ return System.setProperty(key, value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java b/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
new file mode 100644
index 0000000..b7f8eab
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.system.internal.osgi;
+
+import org.apache.karaf.system.SystemService;
+import org.apache.karaf.system.internal.SystemServiceImpl;
+import org.apache.karaf.system.management.internal.SystemMBeanImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doStart() throws Exception {
+ SystemServiceImpl systemService = new SystemServiceImpl();
+ systemService.setBundleContext(bundleContext);
+ register(SystemService.class, systemService);
+
+ SystemMBeanImpl mbean = new SystemMBeanImpl();
+ mbean.setBundleContext(bundleContext);
+ mbean.setSystemService(systemService);
+ registerMBean(mbean, "type=system");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java b/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java
new file mode 100644
index 0000000..5d9bdbc
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java
@@ -0,0 +1,157 @@
+/*
+ * 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.system.management;
+
+import javax.management.MBeanException;
+import java.util.Map;
+
+/**
+ * Describe the system MBean.
+ */
+public interface SystemMBean {
+
+ /**
+ * Stop the Karaf instance
+ *
+ * @throws Exception
+ */
+ void halt() throws MBeanException;
+
+ /**
+ * Stop the Karaf instance at a given time.
+ *
+ * @param time the time when to stop the Karaf instance.
+ * @throws Exception
+ */
+ void halt(String time) throws MBeanException;
+
+ /**
+ * Reboot the Karaf instance.
+ *
+ * @throws Exception
+ */
+ void reboot() throws MBeanException;
+
+ /**
+ * Reboot the Karaf instance at a given time.
+ *
+ * @param time the time when to reboot the Karaf instance.
+ * @throws Exception
+ */
+ void reboot(String time) throws MBeanException;
+
+ /**
+ * Reboot the Karaf instance at a given time and clean the cache.
+ *
+ * @param time the time when to reboot the Karaf instance.
+ * @throws Exception
+ */
+ void rebootCleanCache(String time) throws MBeanException;
+
+ /**
+ * Reboot the Karaf instance at a given time and clean all working files.
+ *
+ * @param time the time when to reboot the Karaf instance.
+ * @throws Exception
+ */
+ void rebootCleanAll(String time) throws MBeanException;
+
+ /**
+ * Set the system bundle start level.
+ *
+ * @param startLevel the new system bundle start level.
+ * @throws Exception
+ */
+ void setStartLevel(int startLevel) throws MBeanException;
+
+ /**
+ * Get the current system bundle start level.
+ *
+ * @return the current system bundle start level.
+ * @throws Exception
+ */
+ int getStartLevel() throws MBeanException;
+
+ /**
+ * Get the current OSGi framework in use.
+ *
+ * @return the name of the OSGi framework in use.
+ * @throws Exception
+ */
+ String getFramework();
+
+ /**
+ * change OSGi framework
+ *
+ * @param framework to use.
+ */
+ void setFramework(String framework);
+
+ /**
+ * Enable or diable debgging
+ * @param debug enable if true
+ */
+ void setFrameworkDebug(boolean debug);
+
+ /**
+ * Get the current Karaf instance name.
+ *
+ * @return the current Karaf instance name.
+ */
+ String getName();
+
+ /**
+ * Change Karaf instance name.
+ *
+ * @param name the new Karaf instance name.
+ */
+ void setName(String name);
+
+ /**
+ * Get the version of the current Karaf instance.
+ *
+ * @return the current Karaf instance version.
+ */
+ String getVersion();
+
+ /**
+ * Get all system properties.
+ *
+ * @param unset if true, display the OSGi properties even if they are not defined (with "undef" value).
+ * @param dumpToFile if true, dump the properties into a file in the data folder.
+ * @return the list of system properties.
+ */
+ Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException;
+
+ /**
+ * Get the value of a given system property.
+ *
+ * @param key the system property key.
+ * @return the system property value.
+ */
+ String getProperty(String key);
+
+ /**
+ * Set the value of a system property.
+ *
+ * @param key the system property key.
+ * @param value the new system property value.
+ * @param persistent if true, persist the new value to the etc/system.properties file.
+ */
+ void setProperty(String key, String value, boolean persistent);
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
----------------------------------------------------------------------
diff --git a/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java b/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
new file mode 100644
index 0000000..c0f34cd
--- /dev/null
+++ b/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java
@@ -0,0 +1,259 @@
+/*
+ * 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.system.management.internal;
+
+import org.apache.karaf.system.FrameworkType;
+import org.apache.karaf.system.SystemService;
+import org.apache.karaf.system.management.SystemMBean;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import java.io.File;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * System MBean implementation.
+ */
+public class SystemMBeanImpl extends StandardMBean implements SystemMBean {
+
+ private SystemService systemService;
+ private BundleContext bundleContext;
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public SystemMBeanImpl() throws NotCompliantMBeanException {
+ super(SystemMBean.class);
+ }
+
+ public void setSystemService(SystemService systemService) {
+ this.systemService = systemService;
+ }
+
+ public SystemService getSystemService() {
+ return this.systemService;
+ }
+
+ public void halt() throws MBeanException {
+ try {
+ systemService.halt();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void halt(String time) throws MBeanException {
+ try {
+ systemService.halt(time);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void reboot() throws MBeanException {
+ try {
+ systemService.reboot();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void reboot(String time) throws MBeanException {
+ try {
+ systemService.reboot(time, SystemService.Swipe.NONE);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void rebootCleanCache(String time) throws MBeanException {
+ try {
+ systemService.reboot(time, SystemService.Swipe.CACHE);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void rebootCleanAll(String time) throws MBeanException {
+ try {
+ systemService.reboot(time, SystemService.Swipe.ALL);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void setStartLevel(int startLevel) throws MBeanException {
+ try {
+ systemService.setStartLevel(startLevel);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public int getStartLevel() throws MBeanException {
+ try {
+ return systemService.getStartLevel();
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @Override
+ public String getFramework() {
+ return this.systemService.getFramework().toString();
+ }
+
+ @Override
+ public void setFramework(String framework) {
+ this.systemService.setFramework(FrameworkType.valueOf(framework.toLowerCase()));
+ }
+
+ @Override
+ public void setFrameworkDebug(boolean debug) {
+ this.systemService.setFrameworkDebug(debug);
+ }
+
+ @Override
+ public String getName() {
+ return this.systemService.getName();
+ }
+
+ @Override
+ public void setName(String name) {
+ if (name == null || name.trim().isEmpty()) {
+ throw new IllegalArgumentException("Instance name can't be null or empty");
+ }
+ this.systemService.setName(name);
+ }
+
+ @Override
+ public String getVersion() {
+ return this.systemService.getVersion();
+ }
+
+ @Override
+ public Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException {
+ try {
+ Map<String, String> result = new HashMap<String, String>();
+
+ Properties props = (Properties) java.lang.System.getProperties().clone();
+
+ String def = null;
+ if (unset) {
+ def = "unset";
+ }
+
+ setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def);
+ setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def);
+ setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def);
+ setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def);
+ setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def);
+ setProperty(props, Constants.FRAMEWORK_LANGUAGE, def);
+ setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def);
+ setProperty(props, Constants.FRAMEWORK_OS_NAME, def);
+ setProperty(props, Constants.FRAMEWORK_OS_VERSION, def);
+ setProperty(props, Constants.FRAMEWORK_PROCESSOR, def);
+ setProperty(props, Constants.FRAMEWORK_SECURITY, def);
+ setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def);
+ setProperty(props, Constants.FRAMEWORK_STORAGE, def);
+ setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def);
+ setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def);
+ setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def);
+ setProperty(props, Constants.FRAMEWORK_VENDOR, def);
+ setProperty(props, Constants.FRAMEWORK_VERSION, def);
+ setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def);
+
+ setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def);
+ setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def);
+
+ if (dumpToFile) {
+ PrintStream ps = new PrintStream(new File(bundleContext.getProperty("karaf.data"), "dump-properties-" + java.lang.System.currentTimeMillis() + ".properties"));
+ ps.println("#Dump of the System and OSGi properties");
+ ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date()));
+ printOrderedProperties(props, ps);
+ ps.flush();
+ ps.close();
+ } else {
+ printOrderedProperties(props, result);
+ }
+
+ return result;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ private void printOrderedProperties(Properties props, PrintStream out) {
+ Set<Object> keys = props.keySet();
+ Vector<String> order = new Vector<String>(keys.size());
+ for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
+ Object str = (Object) i.next();
+ order.add((String) str);
+ }
+ Collections.sort(order);
+ for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ out.println(key + "=" + props.getProperty(key));
+ }
+ }
+
+ private void printOrderedProperties(Properties props, Map<String, String> result) {
+ Set<Object> keys = props.keySet();
+ Vector<String> order = new Vector<String>(keys.size());
+ for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) {
+ Object str = (Object) i.next();
+ order.add((String) str);
+ }
+ Collections.sort(order);
+ for (Iterator<String> i = order.iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ result.put(key, props.getProperty(key));
+ }
+ }
+
+ private void setProperty(Properties props, String key, String def) {
+ String val = bundleContext.getProperty(key);
+ if (val == null && def != null) {
+ props.setProperty(key, def);
+ } else if (val != null) {
+ props.setProperty(key, val);
+ }
+ }
+
+ @Override
+ public String getProperty(String key) {
+ return java.lang.System.getProperty(key);
+ }
+
+ @Override
+ public void setProperty(String key, String value, boolean persistent) {
+ systemService.setSystemProperty(key, value, persistent);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/system/src/main/resources/OSGI-INF/bundle.info b/system/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..acca1c8
--- /dev/null
+++ b/system/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,16 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle provides support of the system service, which control the Karaf container.
+
+h1. See also
+
+Shutdown - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
----------------------------------------------------------------------
diff --git a/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java b/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
new file mode 100644
index 0000000..2de4e1e
--- /dev/null
+++ b/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java
@@ -0,0 +1,53 @@
+/*
+* 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.system.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.felix.utils.properties.Properties;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Implementation of the system service.
+ */
+
+public class SystemServiceImplTest {
+
+ private static final String NEW_NAME = "newName";
+
+ @Test
+ public void testSetName() throws URISyntaxException, IOException {
+ SystemServiceImpl system = new SystemServiceImpl();
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ URL propUrl = this.getClass().getClassLoader().getResource("etc/system.properties");
+ File propfile = new File(propUrl.toURI());
+ EasyMock.expect(bundleContext.getProperty("karaf.etc")).andReturn(propfile.getParentFile().getParent() + "/etc");
+ EasyMock.replay(bundleContext);
+ system.setBundleContext(bundleContext);
+ system.setName(NEW_NAME);
+ EasyMock.verify(bundleContext);
+ Properties props = new Properties(propfile);
+ String nameAfter = props.getProperty("karaf.name");
+ Assert.assertEquals(NEW_NAME, nameAfter);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/test/resources/etc/system.properties
----------------------------------------------------------------------
diff --git a/system/src/test/resources/etc/system.properties b/system/src/test/resources/etc/system.properties
new file mode 100644
index 0000000..6749fbb
--- /dev/null
+++ b/system/src/test/resources/etc/system.properties
@@ -0,0 +1,22 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#Comment
+karaf.name=oldName
+#Comment2
[23/59] [abbrv] [KARAF-2852] Merge config/core and config/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
----------------------------------------------------------------------
diff --git a/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java b/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
deleted file mode 100644
index a8b8090..0000000
--- a/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.core.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-
-import org.apache.karaf.config.core.ConfigMBean;
-import org.apache.karaf.config.core.ConfigRepository;
-import org.osgi.service.cm.Configuration;
-
-/**
- * Implementation of the ConfigMBean.
- */
-public class ConfigMBeanImpl extends StandardMBean implements ConfigMBean {
-
- private ConfigRepository configRepo;
-
- public ConfigMBeanImpl() throws NotCompliantMBeanException {
- super(ConfigMBean.class);
- }
-
- private Configuration getConfiguration(String pid) throws IOException {
- Configuration configuration = configRepo.getConfigAdmin().getConfiguration(pid);
- if (configuration == null) {
- throw new IllegalArgumentException("Configuration PID " + pid + " doesn't exist");
- }
- return configuration;
- }
-
- @SuppressWarnings("rawtypes")
- private Dictionary getConfigProperties(String pid) throws IOException {
- Configuration configuration = getConfiguration(pid);
-
- Dictionary dictionary = configuration.getProperties();
- if (dictionary == null) {
- dictionary = new java.util.Properties();
- }
- return dictionary;
- }
-
- /**
- * Get all config pids
- */
- public List<String> getConfigs() throws MBeanException {
- try {
- Configuration[] configurations = this.configRepo.getConfigAdmin().listConfigurations(null);
- List<String> pids = new ArrayList<String>();
- for (int i = 0; i < configurations.length; i++) {
- pids.add(configurations[i].getPid());
- }
- return pids;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @SuppressWarnings("rawtypes")
- public void create(String pid) throws MBeanException {
- try {
- configRepo.update(pid, new Hashtable());
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void delete(String pid) throws MBeanException {
- try {
- this.configRepo.delete(pid);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @SuppressWarnings("rawtypes")
- public Map<String, String> listProperties(String pid) throws MBeanException {
- try {
- Dictionary dictionary = getConfigProperties(pid);
-
- Map<String, String> propertiesMap = new HashMap<String, String>();
- for (Enumeration e = dictionary.keys(); e.hasMoreElements(); ) {
- Object key = e.nextElement();
- Object value = dictionary.get(key);
- propertiesMap.put(key.toString(), value.toString());
- }
- return propertiesMap;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @SuppressWarnings("rawtypes")
- public void deleteProperty(String pid, String key) throws MBeanException {
- try {
- Dictionary dictionary = getConfigProperties(pid);
- dictionary.remove(key);
- configRepo.update(pid, dictionary);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- public void appendProperty(String pid, String key, String value) throws MBeanException {
- try {
- Dictionary dictionary = getConfigProperties(pid);
- Object currentValue = dictionary.get(key);
- if (currentValue == null) {
- dictionary.put(key, value);
- } else if (currentValue instanceof String) {
- dictionary.put(key, currentValue + value);
- } else {
- throw new IllegalStateException("Current value is not a String");
- }
- configRepo.update(pid, dictionary);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- public void setProperty(String pid, String key, String value) throws MBeanException {
- try {
- Dictionary dictionary = getConfigProperties(pid);
- dictionary.put(key, value);
- configRepo.update(pid, dictionary);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void update(String pid, Map<String, String> properties) throws MBeanException {
- try {
- if (properties == null) {
- properties = new HashMap<String, String>();
- }
- Dictionary<String, String> dictionary = toDictionary(properties);
- configRepo.update(pid, dictionary);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- private Dictionary<String, String> toDictionary(
- Map<String, String> properties) {
- Dictionary<String, String> dictionary = new Hashtable<String, String>();
- for (String key : properties.keySet()) {
- dictionary.put(key, properties.get(key));
- }
- return dictionary;
- }
-
-
- public void setConfigRepo(ConfigRepository configRepo) {
- this.configRepo = configRepo;
- }
-
- @Override
- public String createFactoryConfiguration(String factoryPid,
- Map<String, String> properties) throws MBeanException {
- Dictionary<String, String> dict = toDictionary(properties);
- return configRepo.createFactoryConfiguration(factoryPid, dict);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java b/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
deleted file mode 100644
index 11bb720..0000000
--- a/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.core.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.karaf.config.core.ConfigRepository;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-public class ConfigRepositoryImpl implements ConfigRepository {
- private ConfigurationAdmin configAdmin;
-
- private File storage;
-
- public ConfigRepositoryImpl(ConfigurationAdmin configAdmin) {
- this.configAdmin = configAdmin;
- }
-
- /* (non-Javadoc)
- * @see org.apache.karaf.shell.config.impl.ConfigRepository#update(java.lang.String, java.util.Dictionary, boolean)
- */
- @Override
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void update(String pid, Dictionary props) throws IOException {
- Configuration cfg = this.configAdmin.getConfiguration(pid, null);
- if (cfg.getBundleLocation() != null) {
- cfg.setBundleLocation(null);
- }
- cfg.update(props);
- }
-
- /* (non-Javadoc)
- * @see org.apache.karaf.shell.config.impl.ConfigRepository#delete(java.lang.String)
- */
- @Override
- public void delete(String pid) throws Exception {
- Configuration configuration = this.configAdmin.getConfiguration(pid);
- configuration.delete();
- deleteStorage(pid);
- }
-
- protected void deleteStorage(String pid) throws Exception {
- if (storage != null) {
- File cfgFile = new File(storage, pid + ".cfg");
- cfgFile.delete();
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.karaf.shell.config.impl.ConfigRepository#getConfigProperties(java.lang.String)
- */
- @Override
- @SuppressWarnings("rawtypes")
- public Dictionary getConfigProperties(String pid) throws IOException, InvalidSyntaxException {
- if(pid != null && configAdmin != null) {
- Configuration configuration = this.configAdmin.getConfiguration(pid);
- if(configuration != null) {
- Dictionary props = configuration.getProperties();
- return (props != null) ? props : new Hashtable<String, String>();
- }
- }
- return null;
- }
-
- public ConfigurationAdmin getConfigAdmin() {
- return this.configAdmin;
- }
-
- @Override
- public String createFactoryConfiguration(String factoryPid, Dictionary<String, ?> properties) {
- try {
- Configuration config = configAdmin.createFactoryConfiguration(factoryPid);
- config.update(properties);
- return config.getPid();
- } catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/config/core/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java b/config/core/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
deleted file mode 100644
index bdfab09..0000000
--- a/config/core/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.config.core.impl.osgi;
-
-import org.apache.karaf.config.core.ConfigRepository;
-import org.apache.karaf.config.core.impl.ConfigMBeanImpl;
-import org.apache.karaf.config.core.impl.ConfigRepositoryImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doOpen() throws Exception {
- trackService(ConfigurationAdmin.class);
- }
-
- protected void doStart() throws Exception {
- ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
- if (configurationAdmin == null) {
- return;
- }
-
- ConfigRepository configRepository = new ConfigRepositoryImpl(configurationAdmin);
- register(ConfigRepository.class, configRepository);
-
- ConfigMBeanImpl configMBean = new ConfigMBeanImpl();
- configMBean.setConfigRepo(configRepository);
- registerMBean(configMBean, "type=config");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/config/core/src/main/resources/OSGI-INF/bundle.info b/config/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 3cd35da..0000000
--- a/config/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,27 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to manipulate the ConfigAdmin OSGi service.
-
-The following commands are available:
-* config:cancel - Cancels the changes to the configuration being edited.
-* config:edit - Creates or edits a configuration.
-* config:list - Lists existing configurations.
-* config:propappend - Appends the given value to an existing property or creates
- the property with the specified name and value.
-* config:propdel - Deletes a property from the edited configuration.
-* config:proplist - Lists properties from the currently edited configuration.
-* config:propset - Sets a property in the currently edited configuration.
-* config:update - Saves and propagates changes from the configuration being edited.
-
-h1. See also
-
-Commands - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/resources/OSGI-INF/metatype/metatype.properties
----------------------------------------------------------------------
diff --git a/config/core/src/main/resources/OSGI-INF/metatype/metatype.properties b/config/core/src/main/resources/OSGI-INF/metatype/metatype.properties
deleted file mode 100644
index 3bce187..0000000
--- a/config/core/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# 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.
-#
-
-#
-# This file contains localization strings for configuration labels and
-# descriptions as used in the metatype.xml descriptor
-
-config.name = Apache Karaf Shell Config
-config.description = Configuration of Apache Karaf Shell Config
-
-storage.name = Storage directory
-storage.description = the directory used as a storage for configurations
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/core/src/main/resources/OSGI-INF/metatype/metatype.xml
----------------------------------------------------------------------
diff --git a/config/core/src/main/resources/OSGI-INF/metatype/metatype.xml b/config/core/src/main/resources/OSGI-INF/metatype/metatype.xml
deleted file mode 100644
index 83d3242..0000000
--- a/config/core/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0" localization="OSGI-INF/metatype/metatype">
- <OCD id="org.apache.karaf.config" name="%config.name" description="%config.description">
- <AD id="storage" type="String" default="${karaf.etc}/"
- name="%storage.name" description="%storage.description"/>
- </OCD>
- <Designate pid="org.apache.karaf.config">
- <Object ocdref="org.apache.karaf.config"/>
- </Designate>
-</metatype:MetaData>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/pom.xml
----------------------------------------------------------------------
diff --git a/config/pom.xml b/config/pom.xml
index 10cc1af..af0de85 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -10,7 +10,7 @@
(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
+ 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,
@@ -29,13 +29,92 @@
</parent>
<groupId>org.apache.karaf.config</groupId>
- <artifactId>config</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: ConfigAdmin</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.config.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: ConfigAdmin :: Core</name>
+ <description>This bundle provides Karaf services</description>
+
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </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>
+ <Export-Package>
+ org.apache.karaf.config.command*,
+ org.apache.karaf.config.core
+ </Export-Package>
+ <Import-Package>
+ *
+ </Import-Package>
+ <Private-Package>
+ org.apache.karaf.config.core.impl,
+ org.apache.karaf.config.core.impl.osgi,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.config.core.impl.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.config.command.*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/CancelCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/CancelCommand.java b/config/src/main/java/org/apache/karaf/config/command/CancelCommand.java
new file mode 100644
index 0000000..dff43fa
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/CancelCommand.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "config", name = "cancel", description = "Cancels the changes to the configuration being edited.")
+@Service
+public class CancelCommand extends ConfigCommandSupport {
+
+ protected Object doExecute() throws Exception {
+ session.put(PROPERTY_CONFIG_PID, null);
+ session.put(PROPERTY_CONFIG_PROPS, null);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java b/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
new file mode 100644
index 0000000..fe0ca93
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.config.core.ConfigRepository;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.console.Session;
+
+/**
+ * Abstract class from which all commands related to the ConfigurationAdmin
+ * service should derive.
+ * This command retrieves a reference to the ConfigurationAdmin service before
+ * calling another method to actually process the command.
+ */
+public abstract class ConfigCommandSupport implements Action {
+
+ public static final String PROPERTY_CONFIG_PID = "ConfigCommand.PID";
+ public static final String PROPERTY_CONFIG_PROPS = "ConfigCommand.Props";
+ public static final String PROPERTY_FACTORY = "ConfigCommand.Factory";
+
+ @Reference
+ protected ConfigRepository configRepository;
+
+ @Reference
+ protected Session session;
+
+ @Override
+ public Object execute() throws Exception {
+ return doExecute();
+ }
+
+ protected abstract Object doExecute() throws Exception;
+
+ @SuppressWarnings("rawtypes")
+ protected Dictionary getEditedProps() throws Exception {
+ return (Dictionary) this.session.get(PROPERTY_CONFIG_PROPS);
+ }
+
+ public void setConfigRepository(ConfigRepository configRepository) {
+ this.configRepository = configRepository;
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java b/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
new file mode 100644
index 0000000..619c224
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.karaf.config.command.completers.ConfigurationCompleter;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+
+/**
+ * Abstract class which commands that are related to property processing should extend.
+ */
+public abstract class ConfigPropertyCommandSupport extends ConfigCommandSupport {
+
+ @Option(name = "-p", aliases = "--pid", description = "The configuration pid", required = false, multiValued = false)
+ @Completion(ConfigurationCompleter.class)
+ protected String pid;
+
+ @SuppressWarnings("rawtypes")
+ protected Object doExecute() throws Exception {
+ Dictionary props = getEditedProps();
+ if (props == null && pid == null) {
+ System.err.println("No configuration is being edited--run the edit command first");
+ } else {
+ if (props == null) {
+ props = new Properties();
+ }
+ propertyAction(props);
+ if(requiresUpdate(pid)) {
+ this.configRepository.update(pid, props);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Perform an action on the properties.
+ * @param props
+ */
+ @SuppressWarnings("rawtypes")
+ protected abstract void propertyAction(Dictionary props);
+
+ /**
+ * Checks if the configuration requires to be updated.
+ * The default behavior is to update if a valid pid has been passed to the method.
+ * @param pid
+ * @return
+ */
+ protected boolean requiresUpdate(String pid) {
+ if (pid != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Retrieves confguration from the pid, if used or delegates to session from getting the configuration.
+ * @return
+ * @throws Exception
+ */
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected Dictionary getEditedProps() throws Exception {
+ Dictionary props = this.configRepository.getConfigProperties(pid);
+ return (props != null) ? props : super.getEditedProps();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/DeleteCommand.java b/config/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
new file mode 100644
index 0000000..6953ef0
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/DeleteCommand.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import org.apache.karaf.config.command.completers.ConfigurationCompleter;
+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 = "config", name = "delete", description = "Delete a configuration.")
+@Service
+public class DeleteCommand extends ConfigCommandSupport {
+
+ @Argument(index = 0, name = "pid", description = "PID of the configuration", required = true, multiValued = false)
+ @Completion(ConfigurationCompleter.class)
+ String pid;
+
+ @Option(name = "--force", aliases = {}, description = "Force the edition of this config, even if another one was under edition", required = false, multiValued = false)
+ boolean force;
+
+ protected Object doExecute() throws Exception {
+ String oldPid = (String) this.session.get(PROPERTY_CONFIG_PID);
+ if (oldPid != null && oldPid.equals(pid) && !force) {
+ System.err.println("This config is being edited. Cancel / update first, or use the --force option");
+ return null;
+ }
+
+ this.configRepository.delete(pid);
+ if (oldPid != null && oldPid.equals(pid) && !force) {
+ this.session.put(PROPERTY_CONFIG_PID, null);
+ this.session.put(PROPERTY_CONFIG_PROPS, null);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/EditCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/EditCommand.java b/config/src/main/java/org/apache/karaf/config/command/EditCommand.java
new file mode 100644
index 0000000..8c48b83
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/EditCommand.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.config.command.completers.ConfigurationCompleter;
+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.osgi.service.cm.Configuration;
+
+@Command(scope = "config", name = "edit", description = "Creates or edits a configuration.", detailedDescription="classpath:edit.txt")
+@Service
+public class EditCommand extends ConfigCommandSupport {
+
+ @Argument(index = 0, name = "pid", description = "PID of the configuration or of the factory if --factory is given. Pid can also be specified as ldap query", required = true, multiValued = false)
+ @Completion(ConfigurationCompleter.class)
+ String pid;
+
+ @Option(name = "--force", aliases = {}, description = "Force the edition of this config, even if another one was under edition", required = false, multiValued = false)
+ boolean force;
+
+ @Option(name = "--factory", aliases = {}, description = "Define this config as a factory config. Will be crearted on calling update", required = false, multiValued = false)
+ boolean factory;
+
+ @SuppressWarnings("rawtypes")
+ protected Object doExecute() throws Exception {
+ String oldPid = (String) this.session.get(PROPERTY_CONFIG_PID);
+ if (oldPid != null && !oldPid.equals(pid) && !force) {
+ System.err.println("Another config is being edited. Cancel / update first, or use the --force option");
+ return null;
+ }
+
+ if (pid.startsWith("(")) {
+ Configuration[] configs = this.configRepository.getConfigAdmin().listConfigurations(pid);
+ if (configs.length == 0) {
+ throw new RuntimeException("Filter matches no config");
+ }
+ if (configs.length > 1) {
+ throw new RuntimeException("Filter matches more than one config");
+ }
+ pid = configs[0].getPid();
+ System.out.println("Editing config " + pid);
+ }
+
+ Dictionary props = this.configRepository.getConfigProperties(pid);
+ this.session.put(PROPERTY_CONFIG_PID, pid);
+ this.session.put(PROPERTY_FACTORY, factory);
+ this.session.put(PROPERTY_CONFIG_PROPS, props);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/ListCommand.java b/config/src/main/java/org/apache/karaf/config/command/ListCommand.java
new file mode 100644
index 0000000..bce8410
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/ListCommand.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.service.cm.Configuration;
+
+@Command(scope = "config", name = "list", description = "Lists existing configurations.")
+@Service
+public class ListCommand extends ConfigCommandSupport {
+
+ @Argument(index = 0, name = "query", description = "Query in LDAP syntax. Example: \"(service.pid=org.apache.karaf.log)\"", required = false, multiValued = false)
+ String query;
+
+ @SuppressWarnings("rawtypes")
+ protected Object doExecute() throws Exception {
+ Configuration[] configs = configRepository.getConfigAdmin().listConfigurations(query);
+ if (configs != null) {
+ Map<String, Configuration> sortedConfigs = new TreeMap<String, Configuration>();
+ for (Configuration config : configs) {
+ sortedConfigs.put(config.getPid(), config);
+ }
+ for (String pid : sortedConfigs.keySet()) {
+ Configuration config = sortedConfigs.get(pid);
+ System.out.println("----------------------------------------------------------------");
+ System.out.println("Pid: " + config.getPid());
+ if (config.getFactoryPid() != null) {
+ System.out.println("FactoryPid: " + config.getFactoryPid());
+ }
+ System.out.println("BundleLocation: " + config.getBundleLocation());
+ if (config.getProperties() != null) {
+ System.out.println("Properties:");
+ Dictionary props = config.getProperties();
+ Map<String, Object> sortedProps = new TreeMap<String, Object>();
+ for (Enumeration e = props.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ sortedProps.put(key.toString(), props.get(key));
+ }
+ for (String key : sortedProps.keySet()) {
+ System.out.println(" " + key + " = " + sortedProps.get(key));
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java b/config/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
new file mode 100644
index 0000000..f021146
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/PropAppendCommand.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.config.command.completers.ConfigurationPropertyCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "config", name = "property-append", description = "Appends the given value to an existing property or creates the property with the specified name and value.")
+@Service
+public class PropAppendCommand extends ConfigPropertyCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the property", required = true, multiValued = false)
+ @Completion(ConfigurationPropertyCompleter.class)
+ String prop;
+
+ @Argument(index = 1, name = "value", description = "The value to append to the property", required = true, multiValued = false)
+ String value;
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Override
+ public void propertyAction(Dictionary props) {
+ final Object currentValue = props.get(prop);
+ if (currentValue == null) {
+ props.put(prop, value);
+ } else if (currentValue instanceof String) {
+ props.put(prop, currentValue + value);
+ } else {
+ System.err.println("Append Failed: current value is not a String.");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/PropDelCommand.java b/config/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
new file mode 100644
index 0000000..e416cf6
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/PropDelCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+
+@Command(scope = "config", name = "property-delete", description = "Deletes a property from the configuration being edited.")
+@Service
+public class PropDelCommand extends ConfigPropertyCommandSupport {
+
+ @Argument(index = 0, name = "property", description = "The name of the property to delete", required = true, multiValued = false)
+ String prop;
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void propertyAction(Dictionary props) {
+ props.remove(prop);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/PropListCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/PropListCommand.java b/config/src/main/java/org/apache/karaf/config/command/PropListCommand.java
new file mode 100644
index 0000000..a0d3a61
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/PropListCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "config", name = "property-list", description = "Lists properties from the currently edited configuration.")
+@Service
+public class PropListCommand extends ConfigPropertyCommandSupport {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void propertyAction(Dictionary props) {
+ for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
+ Object key = e.nextElement();
+ System.out.println(" " + key + " = " + props.get(key));
+ }
+ }
+
+ /**
+ * List commands never requires an update, so it always returns false.
+ * @param pid
+ * @return
+ */
+ @Override
+ protected boolean requiresUpdate(String pid) {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java b/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
new file mode 100644
index 0000000..8337f6a
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.config.command.completers.ConfigurationPropertyCompleter;
+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.lifecycle.Service;
+
+@Command(scope = "config", name = "property-set", description = "Sets a property in the currently edited configuration.")
+@Service
+public class PropSetCommand extends ConfigPropertyCommandSupport {
+
+ @Argument(index = 0, name = "property", description = "The name of the property to set", required = true, multiValued = false)
+ @Completion(ConfigurationPropertyCompleter.class)
+ String prop;
+
+ @Argument(index = 1, name = "value", description = "The value of the property", required = true, multiValued = false)
+ String value;
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Override
+ public void propertyAction(Dictionary props) {
+ props.put(prop, value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/UpdateCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/UpdateCommand.java b/config/src/main/java/org/apache/karaf/config/command/UpdateCommand.java
new file mode 100644
index 0000000..cc368b8
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/UpdateCommand.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.config.command;
+
+import java.util.Dictionary;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "config", name = "update", description = "Saves and propagates changes from the configuration being edited.")
+@Service
+public class UpdateCommand extends ConfigCommandSupport {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected Object doExecute() throws Exception {
+ Dictionary props = getEditedProps();
+ if (props == null) {
+ System.err.println("No configuration is being edited--run the edit command first");
+ return null;
+ }
+
+ String pid = (String) this.session.get(PROPERTY_CONFIG_PID);
+ boolean isFactory = this.session.get(PROPERTY_FACTORY) != null && (Boolean) this.session.get(PROPERTY_FACTORY);
+ if (isFactory) {
+ this.configRepository.createFactoryConfiguration(pid, props);
+ } else {
+ this.configRepository.update(pid, props);
+ }
+ this.session.put(PROPERTY_CONFIG_PID, null);
+ this.session.put(PROPERTY_FACTORY, null);
+ this.session.put(PROPERTY_CONFIG_PROPS, null);
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java b/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
new file mode 100644
index 0000000..fe60c56
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationCompleter.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.karaf.config.command.completers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.lifecycle.Destroy;
+import org.apache.karaf.shell.api.action.lifecycle.Init;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+
+/**
+ * {@link Completer} for Configuration Admin configurations.
+ *
+ * Displays a list of existing config instance configurations for completion.
+ *
+ */
+@Service
+public class ConfigurationCompleter implements Completer, ConfigurationListener {
+
+ private final StringsCompleter delegate = new StringsCompleter();
+
+ @Reference
+ private ConfigurationAdmin admin;
+
+ @Reference
+ private BundleContext bundleContext;
+
+ private ServiceRegistration<ConfigurationListener> registration;
+
+ public void setAdmin(ConfigurationAdmin admin) {
+ this.admin = admin;
+ }
+
+ @Init
+ public void init() {
+ registration = bundleContext.registerService(ConfigurationListener.class, this, null);
+
+ Configuration[] configs;
+ try {
+ configs = admin.listConfigurations(null);
+ if (configs == null) {
+ return;
+ }
+ } catch (Exception e) {
+ return;
+ }
+
+ Collection<String> pids = new ArrayList<String>();
+ for (Configuration config : configs) {
+ pids.add(config.getPid());
+ }
+
+ delegate.getStrings().addAll(pids);
+ }
+
+ @Destroy
+ public void destroy() {
+ registration.unregister();
+ }
+
+ public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ public void configurationEvent(ConfigurationEvent configurationEvent) {
+ String pid = configurationEvent.getPid();
+ if (configurationEvent.getType() == ConfigurationEvent.CM_DELETED) {
+ delegate.getStrings().remove(pid);
+ } else if (configurationEvent.getType() == ConfigurationEvent.CM_UPDATED) {
+ delegate.getStrings().add(pid);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java b/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
new file mode 100644
index 0000000..2b43fec
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/command/completers/ConfigurationPropertyCompleter.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.karaf.config.command.completers;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.karaf.config.command.ConfigCommandSupport;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * {@link Completer} for Configuration Admin properties.
+ *
+ * Displays a list of existing properties based on the current configuration being edited.
+ *
+ */
+@Service
+public class ConfigurationPropertyCompleter implements Completer {
+
+ private final StringsCompleter delegate = new StringsCompleter();
+
+ private static final String OPTION = "-p";
+ private static final String ALIAS = "--pid";
+
+ @Reference
+ private ConfigurationAdmin configAdmin;
+
+ @SuppressWarnings("rawtypes")
+ public int complete(final Session session, final CommandLine commandLine, final List<String> candidates) {
+ if (session != null) {
+ String pid = getPid(session, commandLine);
+ Set<String> propertyNames = getPropertyNames(pid);
+ delegate.getStrings().clear();
+ if (propertyNames != null && !propertyNames.isEmpty()) {
+ delegate.getStrings().addAll(propertyNames);
+ }
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+ /**
+ * Retrieves the pid stored in the {@link Session} or passed as an argument.
+ * Argument takes precedence from pid stored in the {@link Session}.
+ */
+ private String getPid(Session session, CommandLine commandLine) {
+ String pid = (String) session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID);
+ if (commandLine.getArguments().length > 0) {
+ List<String> arguments = Arrays.asList(commandLine.getArguments());
+ if (arguments.contains(OPTION)) {
+ int index = arguments.indexOf(OPTION);
+ if (arguments.size() > index) {
+ return arguments.get(index + 1);
+ }
+ }
+
+ if (arguments.contains(ALIAS)) {
+ int index = arguments.indexOf(ALIAS);
+ if (arguments.size() > index) {
+ return arguments.get(index + 1);
+ }
+ }
+ }
+ return pid;
+ }
+
+ /**
+ * Returns the property names for the given pid.
+ * @param pid
+ * @return
+ */
+ @SuppressWarnings("rawtypes")
+ private Set<String> getPropertyNames(String pid) {
+ Set<String> propertyNames = new HashSet<String>();
+ if (pid != null) {
+ Configuration configuration = null;
+ try {
+ Configuration[] configs = configAdmin.listConfigurations("(service.pid="+pid+")");
+ if (configs != null && configs.length > 0) {
+ configuration = configs[0];
+ if (configuration != null) {
+ Dictionary properties = configuration.getProperties();
+ if (properties != null) {
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ propertyNames.add(String.valueOf(keys.nextElement()));
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ //Ignore
+ } catch (InvalidSyntaxException e) {
+ //Ignore
+ }
+ }
+ return propertyNames;
+ }
+
+ public ConfigurationAdmin getConfigAdmin() {
+ return configAdmin;
+ }
+
+ public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+ this.configAdmin = configAdmin;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java b/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
new file mode 100644
index 0000000..9cb9f7f
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/ConfigMBean.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.core;
+
+import javax.management.MBeanException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MBean to manipulate the Config layer.
+ */
+public interface ConfigMBean {
+
+ /**
+ * Get the list of all configuration PIDs.
+ *
+ * @return the list of all configuration PIDs.
+ * @throws Exception
+ */
+ List<String> getConfigs() throws MBeanException;
+
+ /**
+ * Create a new configuration for the given PID.
+ *
+ * @param pid the configuration PID.
+ * @throws Exception
+ */
+ void create(String pid) throws MBeanException;
+
+ /**
+ * Delete a configuration identified by the given PID.
+ *
+ * @param pid the configuration PID to delete.
+ * @throws Exception
+ */
+ void delete(String pid) throws MBeanException;
+
+ /**
+ * Get the list of properties for a configuration PID.
+ *
+ * @param pid the configuration PID.
+ * @return the list of properties.
+ * @throws Exception
+ */
+ Map<String, String> listProperties(String pid) throws MBeanException;
+
+ /**
+ * Remove the configuration property identified by the given key.
+ *
+ * @param pid the configuration PID.
+ * @param key the property key.
+ * @throws Exception
+ */
+ void deleteProperty(String pid, String key) throws MBeanException;
+
+ /**
+ * Append (or add) a value for the given configuration key.
+ *
+ * @param pid the configuration PID.
+ * @param key the property key.
+ * @param value the value to append to the current property value.
+ * @throws Exception
+ */
+ void appendProperty(String pid, String key, String value) throws MBeanException;
+
+ /**
+ * Set a configuration property.
+ *
+ * @param pid the configuration PID.
+ * @param key the property key.
+ * @param value the property value.
+ * @throws Exception
+ */
+ void setProperty(String pid, String key, String value) throws MBeanException;
+
+ /**
+ * Update a complete configuration.
+ *
+ * @param pid the configuration PID.
+ * @param properties the new properties to set in the configuration.
+ * @throws MBeanException
+ */
+ void update(String pid, Map<String, String> properties) throws MBeanException;
+
+ /**
+ * Create a factory based configuration.
+ *
+ * @param factoryPid
+ * @param properties the new properties to set in the configuration.
+ * @return created pid
+ * @throws MBeanException
+ */
+ String createFactoryConfiguration(String factoryPid, Map<String, String> properties) throws MBeanException;
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java b/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
new file mode 100644
index 0000000..8121679
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.core;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public interface ConfigRepository {
+
+ /**
+ * Saves config to storage or ConfigurationAdmin.
+ * @param pid
+ * @param props
+ * @throws IOException
+ */
+ @SuppressWarnings("rawtypes")
+ void update(String pid, Dictionary props) throws IOException;
+
+ void delete(String pid) throws Exception;
+
+ @SuppressWarnings("rawtypes")
+ Dictionary getConfigProperties(String pid) throws IOException, InvalidSyntaxException;
+
+ ConfigurationAdmin getConfigAdmin();
+
+ /**
+ * Create a factory based configuration.
+ *
+ * @param factoryPid
+ * @param properties the new properties to set in the configuration.
+ * @return created pid
+ */
+ String createFactoryConfiguration(String factoryPid, Dictionary<String, ?> properties);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
new file mode 100644
index 0000000..a8b8090
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigMBeanImpl.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.core.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+
+import org.apache.karaf.config.core.ConfigMBean;
+import org.apache.karaf.config.core.ConfigRepository;
+import org.osgi.service.cm.Configuration;
+
+/**
+ * Implementation of the ConfigMBean.
+ */
+public class ConfigMBeanImpl extends StandardMBean implements ConfigMBean {
+
+ private ConfigRepository configRepo;
+
+ public ConfigMBeanImpl() throws NotCompliantMBeanException {
+ super(ConfigMBean.class);
+ }
+
+ private Configuration getConfiguration(String pid) throws IOException {
+ Configuration configuration = configRepo.getConfigAdmin().getConfiguration(pid);
+ if (configuration == null) {
+ throw new IllegalArgumentException("Configuration PID " + pid + " doesn't exist");
+ }
+ return configuration;
+ }
+
+ @SuppressWarnings("rawtypes")
+ private Dictionary getConfigProperties(String pid) throws IOException {
+ Configuration configuration = getConfiguration(pid);
+
+ Dictionary dictionary = configuration.getProperties();
+ if (dictionary == null) {
+ dictionary = new java.util.Properties();
+ }
+ return dictionary;
+ }
+
+ /**
+ * Get all config pids
+ */
+ public List<String> getConfigs() throws MBeanException {
+ try {
+ Configuration[] configurations = this.configRepo.getConfigAdmin().listConfigurations(null);
+ List<String> pids = new ArrayList<String>();
+ for (int i = 0; i < configurations.length; i++) {
+ pids.add(configurations[i].getPid());
+ }
+ return pids;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void create(String pid) throws MBeanException {
+ try {
+ configRepo.update(pid, new Hashtable());
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void delete(String pid) throws MBeanException {
+ try {
+ this.configRepo.delete(pid);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Map<String, String> listProperties(String pid) throws MBeanException {
+ try {
+ Dictionary dictionary = getConfigProperties(pid);
+
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ for (Enumeration e = dictionary.keys(); e.hasMoreElements(); ) {
+ Object key = e.nextElement();
+ Object value = dictionary.get(key);
+ propertiesMap.put(key.toString(), value.toString());
+ }
+ return propertiesMap;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void deleteProperty(String pid, String key) throws MBeanException {
+ try {
+ Dictionary dictionary = getConfigProperties(pid);
+ dictionary.remove(key);
+ configRepo.update(pid, dictionary);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public void appendProperty(String pid, String key, String value) throws MBeanException {
+ try {
+ Dictionary dictionary = getConfigProperties(pid);
+ Object currentValue = dictionary.get(key);
+ if (currentValue == null) {
+ dictionary.put(key, value);
+ } else if (currentValue instanceof String) {
+ dictionary.put(key, currentValue + value);
+ } else {
+ throw new IllegalStateException("Current value is not a String");
+ }
+ configRepo.update(pid, dictionary);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public void setProperty(String pid, String key, String value) throws MBeanException {
+ try {
+ Dictionary dictionary = getConfigProperties(pid);
+ dictionary.put(key, value);
+ configRepo.update(pid, dictionary);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ public void update(String pid, Map<String, String> properties) throws MBeanException {
+ try {
+ if (properties == null) {
+ properties = new HashMap<String, String>();
+ }
+ Dictionary<String, String> dictionary = toDictionary(properties);
+ configRepo.update(pid, dictionary);
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+ private Dictionary<String, String> toDictionary(
+ Map<String, String> properties) {
+ Dictionary<String, String> dictionary = new Hashtable<String, String>();
+ for (String key : properties.keySet()) {
+ dictionary.put(key, properties.get(key));
+ }
+ return dictionary;
+ }
+
+
+ public void setConfigRepo(ConfigRepository configRepo) {
+ this.configRepo = configRepo;
+ }
+
+ @Override
+ public String createFactoryConfiguration(String factoryPid,
+ Map<String, String> properties) throws MBeanException {
+ Dictionary<String, String> dict = toDictionary(properties);
+ return configRepo.createFactoryConfiguration(factoryPid, dict);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
new file mode 100644
index 0000000..11bb720
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.core.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.karaf.config.core.ConfigRepository;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class ConfigRepositoryImpl implements ConfigRepository {
+ private ConfigurationAdmin configAdmin;
+
+ private File storage;
+
+ public ConfigRepositoryImpl(ConfigurationAdmin configAdmin) {
+ this.configAdmin = configAdmin;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.karaf.shell.config.impl.ConfigRepository#update(java.lang.String, java.util.Dictionary, boolean)
+ */
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void update(String pid, Dictionary props) throws IOException {
+ Configuration cfg = this.configAdmin.getConfiguration(pid, null);
+ if (cfg.getBundleLocation() != null) {
+ cfg.setBundleLocation(null);
+ }
+ cfg.update(props);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.karaf.shell.config.impl.ConfigRepository#delete(java.lang.String)
+ */
+ @Override
+ public void delete(String pid) throws Exception {
+ Configuration configuration = this.configAdmin.getConfiguration(pid);
+ configuration.delete();
+ deleteStorage(pid);
+ }
+
+ protected void deleteStorage(String pid) throws Exception {
+ if (storage != null) {
+ File cfgFile = new File(storage, pid + ".cfg");
+ cfgFile.delete();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.karaf.shell.config.impl.ConfigRepository#getConfigProperties(java.lang.String)
+ */
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Dictionary getConfigProperties(String pid) throws IOException, InvalidSyntaxException {
+ if(pid != null && configAdmin != null) {
+ Configuration configuration = this.configAdmin.getConfiguration(pid);
+ if(configuration != null) {
+ Dictionary props = configuration.getProperties();
+ return (props != null) ? props : new Hashtable<String, String>();
+ }
+ }
+ return null;
+ }
+
+ public ConfigurationAdmin getConfigAdmin() {
+ return this.configAdmin;
+ }
+
+ @Override
+ public String createFactoryConfiguration(String factoryPid, Dictionary<String, ?> properties) {
+ try {
+ Configuration config = configAdmin.createFactoryConfiguration(factoryPid);
+ config.update(properties);
+ return config.getPid();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java b/config/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
new file mode 100644
index 0000000..bdfab09
--- /dev/null
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/osgi/Activator.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.core.impl.osgi;
+
+import org.apache.karaf.config.core.ConfigRepository;
+import org.apache.karaf.config.core.impl.ConfigMBeanImpl;
+import org.apache.karaf.config.core.impl.ConfigRepositoryImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doOpen() throws Exception {
+ trackService(ConfigurationAdmin.class);
+ }
+
+ protected void doStart() throws Exception {
+ ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
+ if (configurationAdmin == null) {
+ return;
+ }
+
+ ConfigRepository configRepository = new ConfigRepositoryImpl(configurationAdmin);
+ register(ConfigRepository.class, configRepository);
+
+ ConfigMBeanImpl configMBean = new ConfigMBeanImpl();
+ configMBean.setConfigRepo(configRepository);
+ registerMBean(configMBean, "type=config");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/config/src/main/resources/OSGI-INF/bundle.info b/config/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..3cd35da
--- /dev/null
+++ b/config/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,27 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle provides Karaf shell commands to manipulate the ConfigAdmin OSGi service.
+
+The following commands are available:
+* config:cancel - Cancels the changes to the configuration being edited.
+* config:edit - Creates or edits a configuration.
+* config:list - Lists existing configurations.
+* config:propappend - Appends the given value to an existing property or creates
+ the property with the specified name and value.
+* config:propdel - Deletes a property from the edited configuration.
+* config:proplist - Lists properties from the currently edited configuration.
+* config:propset - Sets a property in the currently edited configuration.
+* config:update - Saves and propagates changes from the configuration being edited.
+
+h1. See also
+
+Commands - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/resources/OSGI-INF/metatype/metatype.properties
----------------------------------------------------------------------
diff --git a/config/src/main/resources/OSGI-INF/metatype/metatype.properties b/config/src/main/resources/OSGI-INF/metatype/metatype.properties
new file mode 100644
index 0000000..3bce187
--- /dev/null
+++ b/config/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor
+
+config.name = Apache Karaf Shell Config
+config.description = Configuration of Apache Karaf Shell Config
+
+storage.name = Storage directory
+storage.description = the directory used as a storage for configurations
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/resources/OSGI-INF/metatype/metatype.xml
----------------------------------------------------------------------
diff --git a/config/src/main/resources/OSGI-INF/metatype/metatype.xml b/config/src/main/resources/OSGI-INF/metatype/metatype.xml
new file mode 100644
index 0000000..83d3242
--- /dev/null
+++ b/config/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0" localization="OSGI-INF/metatype/metatype">
+ <OCD id="org.apache.karaf.config" name="%config.name" description="%config.description">
+ <AD id="storage" type="String" default="${karaf.etc}/"
+ name="%storage.name" description="%storage.description"/>
+ </OCD>
+ <Designate pid="org.apache.karaf.config">
+ <Object ocdref="org.apache.karaf.config"/>
+ </Designate>
+</metatype:MetaData>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/main/resources/org/apache/karaf/config/command/edit.txt
----------------------------------------------------------------------
diff --git a/config/src/main/resources/org/apache/karaf/config/command/edit.txt b/config/src/main/resources/org/apache/karaf/config/command/edit.txt
new file mode 100644
index 0000000..88fa6d5
--- /dev/null
+++ b/config/src/main/resources/org/apache/karaf/config/command/edit.txt
@@ -0,0 +1,13 @@
+The edit command can be used to create or edit a configuration in three ways.
+
+Edit or create a config by pid:
+ > config:edit org.apache.karaf.sample.pid
+The command above will also create a file etc/org.apache.karaf.sample.pid which corresponds to a configuration object with pid org.apache.karaf.sample.pid.
+
+Create a factory config by factory pid:
+ > config:edit --factory myfactorypid
+In this case the config is created with a pid like myfactorypid.<generated id>. This config is not written to a file.
+
+Edit a config specified by an ldap query
+ > config:edit '(myattribute=myvalue)'
+This executes an ldap query like in config:list. If the result is exactly one config then it is edited.
[18/59] [abbrv] [KARAF-2852] Merge bundle/command into bundle/core
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
new file mode 100644
index 0000000..a83ce39
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
@@ -0,0 +1,245 @@
+/*
+ * 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.bundle.command;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.bundle.command.bundletree.Node;
+import org.apache.karaf.bundle.command.bundletree.Tree;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.lang.String.format;
+
+/**
+ * Command for showing the full tree of bundles that have been used to resolve
+ * a given bundle.
+ */
+@Command(scope = "bundle", name = "tree-show", description = "Shows the tree of bundles based on the wiring information.")
+@Service
+public class ShowBundleTree extends BundleCommand {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ShowBundleTree.class);
+ private Tree<Bundle> tree;
+
+ public ShowBundleTree() {
+ super(false);
+ }
+
+ @Override
+ protected void doExecute(Bundle bundle) throws Exception {
+ long start = System.currentTimeMillis();
+ // let's do the real work here
+ printHeader(bundle);
+ tree = new Tree<Bundle>(bundle);
+ createTree(bundle);
+ printTree(tree);
+ printDuplicatePackages(tree);
+ LOGGER.debug(format("Dependency tree calculated in %d ms",
+ System.currentTimeMillis() - start));
+ }
+
+ /**
+ * Return a String representation of a bundle state
+ */
+ private String getState(Bundle bundle) {
+ switch (bundle.getState()) {
+ case Bundle.UNINSTALLED : return "UNINSTALLED";
+ case Bundle.INSTALLED : return "INSTALLED";
+ case Bundle.RESOLVED: return "RESOLVED";
+ case Bundle.STARTING : return "STARTING";
+ case Bundle.STOPPING : return "STOPPING";
+ case Bundle.ACTIVE : return "ACTIVE";
+ default : return "UNKNOWN";
+ }
+ }
+
+ /*
+ * Print the header
+ */
+ private void printHeader(Bundle bundle) {
+ System.out.printf("Bundle %s [%s] is currently %s%n",
+ bundle.getSymbolicName(),
+ bundle.getBundleId(),
+ getState(bundle));
+ }
+
+ /*
+ * Print the dependency tree
+ */
+ private void printTree(Tree<Bundle> tree) {
+ System.out.printf("%n");
+ tree.write(System.out, new Tree.Converter<Bundle>() {
+
+ public String toString(Node<Bundle> node) {
+ return String.format("%s [%s]",
+ node.getValue().getSymbolicName(),
+ node.getValue().getBundleId());
+ }
+ });
+ }
+
+ /*
+ * Check for bundles in the tree exporting the same package
+ * as a possible cause for 'Unresolved constraint...' on a uses-conflict
+ */
+ private void printDuplicatePackages(Tree<Bundle> tree) {
+ Set<Bundle> bundles = tree.flatten();
+ Map<String, Set<Bundle>> exports = new HashMap<String, Set<Bundle>>();
+
+ for (Bundle bundle : bundles) {
+ for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions()) {
+ BundleWiring wiring = revision.getWiring();
+ if (wiring != null) {
+ List<BundleWire> wires = wiring.getProvidedWires(BundleRevision.PACKAGE_NAMESPACE);
+ if (wires != null) {
+ for (BundleWire wire : wires) {
+ String name = wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString();
+ if (exports.get(name) == null) {
+ exports.put(name, new HashSet<Bundle>());
+ }
+ exports.get(name).add(bundle);
+ }
+ }
+ }
+ }
+ }
+
+ for (String pkg : exports.keySet()) {
+ if (exports.get(pkg).size() > 1) {
+ System.out.printf("%n");
+ System.out.printf("WARNING: multiple bundles are exporting package %s%n", pkg);
+ for (Bundle bundle : exports.get(pkg)) {
+ System.out.printf("- %s%n", bundle);
+ }
+ }
+ }
+ }
+
+ /*
+ * Creates the bundle tree
+ */
+ protected void createTree(Bundle bundle) {
+ if (bundle.getState() >= Bundle.RESOLVED) {
+ createNode(tree);
+ } else {
+ createNodesForImports(tree, bundle);
+ System.out.print("\nWarning: the below tree is a rough approximation of a possible resolution");
+ }
+ }
+
+ /*
+ * Creates nodes for the imports of the bundle (instead of reporting wiring information
+ */
+ private void createNodesForImports(Node<Bundle> node, Bundle bundle) {
+ Clause[] imports = Parser.parseHeader(bundle.getHeaders().get("Import-Package"));
+ Clause[] exports = Parser.parseHeader(bundle.getHeaders().get("Export-Package"));
+ for (Clause i : imports) {
+ boolean exported = false;
+ for (Clause e : exports) {
+ if (e.getName().equals(i.getName())) {
+ exported = true;
+ break;
+ }
+ }
+ if (!exported) {
+ createNodeForImport(node, bundle, i);
+ }
+ }
+ }
+
+ /*
+ * Create a child node for a given import (by finding a matching export in the currently installed bundles)
+ */
+ private void createNodeForImport(Node<Bundle> node, Bundle bundle, Clause i) {
+ VersionRange range = VersionRange.parseVersionRange(i.getAttribute(Constants.VERSION_ATTRIBUTE));
+ boolean foundMatch = false;
+ for (Bundle b : bundleContext.getBundles()) {
+ BundleWiring wiring = b.adapt(BundleWiring.class);
+ if (wiring != null) {
+ List<BundleCapability> caps = wiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ if (caps != null) {
+ for (BundleCapability cap : caps) {
+ String n = getAttribute(cap, BundleRevision.PACKAGE_NAMESPACE);
+ String v = getAttribute(cap, Constants.VERSION_ATTRIBUTE);
+ if (i.getName().equals(n) && range.contains(VersionTable.getVersion(v))) {
+ boolean existing = tree.flatten().contains(b);
+ System.out.printf("- import %s: resolved using %s%n", i, b);
+ foundMatch = true;
+ if (!node.hasChild(b)) {
+ Node<Bundle> child = node.addChild(b);
+ if (!existing) {
+ createNode(child);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!foundMatch) {
+ System.out.printf("- import %s: WARNING - unable to find matching export%n", i);
+ }
+ }
+
+ private String getAttribute(BundleCapability capability, String name) {
+ Object o = capability.getAttributes().get(name);
+ return o != null ? o.toString() : null;
+ }
+
+ /*
+ * Creates a node in the bundle tree
+ */
+ private void createNode(Node<Bundle> node) {
+ Bundle bundle = node.getValue();
+ Collection<Bundle> exporters = new HashSet<Bundle>();
+ exporters.addAll(bundleService.getWiredBundles(bundle).values());
+
+ for (Bundle exporter : exporters) {
+ if (node.hasAncestor(exporter)) {
+ LOGGER.debug(format("Skipping %s (already exists in the current branch)", exporter));
+ } else {
+ boolean existing = tree.flatten().contains(exporter);
+ LOGGER.debug(format("Adding %s as a dependency for %s", exporter, bundle));
+ Node<Bundle> child = node.addChild(exporter);
+ if (existing) {
+ LOGGER.debug(format("Skipping children of %s (already exists in another branch)", exporter));
+ } else {
+ createNode(child);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Start.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Start.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Start.java
new file mode 100644
index 0000000..48e90fa
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Start.java
@@ -0,0 +1,32 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "start", description = "Starts bundles.")
+@Service
+public class Start extends BundlesCommandWithConfirmation {
+
+ @Override
+ protected void executeOnBundle(Bundle bundle) throws Exception {
+ bundle.start();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/StartLevel.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
new file mode 100644
index 0000000..30bec0f
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
@@ -0,0 +1,64 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.startlevel.BundleStartLevel;
+
+@Command(scope = "bundle", name = "start-level", description = "Gets or sets the start level of a bundle.")
+@Service
+public class StartLevel extends BundleCommandWithConfirmation {
+
+ @Argument(index = 1, name = "startLevel", description = "The bundle's new start level", required = false, multiValued = false)
+ Integer level;
+
+ @Reference
+ Session session;
+
+ protected void doExecute(Bundle bundle) throws Exception {
+ // Get package instance service.
+ BundleStartLevel bsl = bundle.adapt(BundleStartLevel.class);
+ if (bsl == null) {
+ System.out.println("StartLevel service is unavailable.");
+ return;
+ }
+ if (level == null) {
+ System.out.println("Level " + bsl.getStartLevel());
+ }
+ else if ((level < 50) && (bsl.getStartLevel() > 50) && !force){
+ for (;;) {
+ String msg = "You are about to designate bundle as a system bundle. Do you wish to continue (yes/no): ";
+ String str = session.readLine(msg, null);
+ if ("yes".equalsIgnoreCase(str)) {
+ bsl.setStartLevel(level);
+ break;
+ } else if ("no".equalsIgnoreCase(str)) {
+ break;
+ }
+ }
+
+ } else {
+ bsl.setStartLevel(level);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Stop.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Stop.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Stop.java
new file mode 100644
index 0000000..0b0fed2
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Stop.java
@@ -0,0 +1,44 @@
+/*
+ * 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.bundle.command;
+
+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.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "stop", description = "Stop bundles.")
+@Service
+public class Stop extends BundlesCommandWithConfirmation {
+
+ @Option(name = "-t", aliases={"--transient"}, description="Keep the bundle as auto-start", required = false, multiValued = false)
+ boolean transientStop;
+
+ public Stop() {
+ this.errorMessage = "Unable to stop bundle";
+ }
+
+ @Override
+ protected void executeOnBundle(Bundle bundle) throws Exception {
+ if (transientStop) {
+ bundle.stop(Bundle.STOP_TRANSIENT);
+ } else {
+ bundle.stop();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Uninstall.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
new file mode 100644
index 0000000..67b5b14
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
@@ -0,0 +1,36 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "uninstall", description = "Uninstall bundles.")
+@Service
+public class Uninstall extends BundlesCommandWithConfirmation {
+
+ public Uninstall() {
+ this.errorMessage = "Unable to uninstall bundle";
+ }
+
+ @Override
+ protected void executeOnBundle(Bundle bundle) throws Exception {
+ bundle.uninstall();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
new file mode 100644
index 0000000..71ae74d
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.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.bundle.command;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "bundle", name = "update", description = "Update bundle.")
+@Service
+public class Update extends BundleCommandWithConfirmation {
+
+ @Argument(index = 1, name = "location", description = "The bundles update location", required = false, multiValued = false)
+ String location;
+
+ protected void doExecute(Bundle bundle) throws Exception {
+ InputStream is = null;
+ if (location != null) {
+ try {
+ is = new URL(location).openStream();
+ bundle.update(is);
+ } finally {
+ is.close();
+ }
+ } else {
+ bundle.update();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/Watch.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Watch.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Watch.java
new file mode 100644
index 0000000..9203f59
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Watch.java
@@ -0,0 +1,128 @@
+/*
+ * 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.bundle.command;
+
+import java.util.List;
+
+import org.apache.karaf.bundle.core.BundleWatcher;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+@Command(scope = "bundle", name = "watch", description = "Watches and updates bundles", detailedDescription = "Watches the local maven repo for changes in snapshot jars and redploys changed jars")
+@Service
+public class Watch implements Action {
+
+ @Argument(index = 0, name = "urls", description = "The bundle IDs or URLs", required = false, multiValued = true)
+ List<String> urls;
+
+ @Option(name = "-i", aliases = {}, description = "Watch interval", required = false, multiValued = false)
+ private long interval;
+
+ @Option(name = "--start", description = "Starts watching the selected bundles", required = false, multiValued = false)
+ protected boolean start;
+
+ @Option(name = "--stop", description = "Stops watching all bundles", required = false, multiValued = false)
+ protected boolean stop;
+
+ @Option(name = "--remove", description = "Removes bundles from the watch list", required = false, multiValued = false)
+ protected boolean remove;
+
+ @Option(name = "--list", description = "Displays the watch list", required = false, multiValued = false)
+ protected boolean list;
+
+ @Reference
+ private BundleWatcher bundleWatcher;
+
+ public void setBundleWatcher(BundleWatcher bundleWatcher) {
+ this.bundleWatcher = bundleWatcher;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ if (start && stop) {
+ System.err.println("Please use only one of --start and --stop options!");
+ return null;
+ }
+
+ if (interval > 0) {
+ System.out.println("Setting watch interval to " + interval + " ms");
+ bundleWatcher.setInterval(interval);
+ }
+ if (stop) {
+ System.out.println("Stopping watch");
+ bundleWatcher.stop();
+ }
+ if (urls != null) {
+ if (remove) {
+ for (String url : urls) {
+ bundleWatcher.remove(url);
+ }
+ } else {
+ for (String url : urls) {
+ bundleWatcher.add(url);
+ }
+ }
+ }
+ if (start) {
+ System.out.println("Starting watch");
+ bundleWatcher.start();
+ }
+
+ if (list) { //List the watched bundles.
+ String format = "%-40s %6s %-80s";
+ System.out.println(String.format(format, "URL", "ID", "Bundle Name"));
+ for (String url : bundleWatcher.getWatchURLs()) {
+
+ List<Bundle> bundleList = bundleWatcher.getBundlesByURL(url);
+ if (bundleList != null && bundleList.size() > 0) {
+ for (Bundle bundle : bundleList) {
+ System.out.println(String.format(format, url, bundle.getBundleId(), bundle.getHeaders().get(Constants.BUNDLE_NAME)));
+ }
+ } else {
+ System.out.println(String.format(format, url, "", ""));
+ }
+ }
+ } else {
+ List<String> urls = bundleWatcher.getWatchURLs();
+ if (urls != null && urls.size()>0) {
+ System.out.println("Watched URLs/IDs: ");
+ for (String url : bundleWatcher.getWatchURLs()) {
+ System.out.println(url);
+ }
+ } else {
+ System.out.println("No watched URLs/IDs");
+ }
+ }
+
+ return null;
+ }
+
+}
+
+
+
+
+
+
+
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
new file mode 100644
index 0000000..fe4dc2a
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
@@ -0,0 +1,159 @@
+/*
+ * 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.bundle.command.bundletree;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Represents a node in a {@link Tree}
+ */
+public class Node<T> {
+
+ private final T value;
+ private Node<T> parent;
+ private List<Node<T>> children = new LinkedList<Node<T>>();
+
+ /**
+ * Creates a new node. Only meant for wrapper use,
+ * new nodes should be added using the {@link #addChild(Object)} method
+ *
+ * @param value the node value
+ */
+ protected Node(T value) {
+ super();
+ this.value = value;
+ }
+
+ /**
+ * Creates a new node. Only meant for wrapper use,
+ * new nodes should be added using the {@link #addChild(Object)} method
+ *
+ * @param value the node value
+ */
+ protected Node(T value, Node<T> parent) {
+ this(value);
+ this.parent = parent;
+ }
+
+ /**
+ * Access the node's value
+ */
+ public T getValue() {
+ return value;
+ }
+
+ /**
+ * Access the node's child nodes
+ */
+ public List<Node<T>> getChildren() {
+ return children;
+ }
+
+ /**
+ * Adds a child to this node
+ *
+ * @param value the child's value
+ * @return the child node
+ */
+ public Node<T> addChild(T value) {
+ Node<T> node = new Node<T>(value, this);
+ children.add(node);
+ return node;
+ }
+
+ /**
+ * Give a set of values in the tree.
+ *
+ * @return
+ */
+ public Set<T> flatten() {
+ Set<T> result = new HashSet<T>();
+ result.add(getValue());
+ for (Node<T> child : getChildren()) {
+ result.addAll(child.flatten());
+ }
+ return result;
+ }
+
+ /**
+ * Check if the node has an ancestor that represents the given value
+ *
+ * @param value the node value
+ * @return <code>true</code> it there's an ancestor that represents the value
+ */
+ public boolean hasAncestor(T value) {
+ if (parent == null) {
+ return false;
+ } else {
+ return value.equals(parent.value) || parent.hasAncestor(value);
+ }
+ }
+
+ public boolean hasChild(T value) {
+ for (Node<T> child : getChildren()) {
+ if (value.equals(child.getValue())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Write this node to the PrintWriter. It should be indented one step
+ * further for every element in the indents array. If an element in the
+ * array is <code>true</code>, there should be a | to connect to the next
+ * sibling.
+ */
+ protected void write(PrintWriter writer, Tree.Converter<T> converter, boolean... indents) {
+ for (boolean indent : indents) {
+ writer.printf("%-3s", indent ? "|" : "");
+ }
+ writer.printf("+- %s%n", converter.toString(this));
+ for (Node<T> child : getChildren()) {
+ child.write(writer, converter, concat(indents, hasNextSibling()));
+ }
+ }
+
+ /*
+ * Is this node the last child node for its parent
+ * or is there a next sibling?
+ */
+ private boolean hasNextSibling() {
+ if (parent == null) {
+ return false;
+ } else {
+ return parent.getChildren().size() > 1
+ && parent.getChildren().indexOf(this) < parent.getChildren().size() - 1;
+ }
+ }
+
+ /*
+ * Add an element to the end of the array
+ */
+ private boolean[] concat(boolean[] array, boolean element) {
+ boolean[] result = new boolean[array.length + 1];
+ for (int i = 0 ; i < array.length ; i++) {
+ result[i] = array[i];
+ }
+ result[array.length] = element;
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
new file mode 100644
index 0000000..7a7b64e
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
@@ -0,0 +1,100 @@
+/*
+ * 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.bundle.command.bundletree;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * Represents a tree that can be written to the console.
+ *
+ * The output will look like this:
+ * <pre>
+ * root
+ * +- child1
+ * | +- grandchild
+ * +- child2
+ * </pre>
+ */
+public class Tree<T> extends Node<T> {
+
+ /**
+ * Creates a new tree with the given root node
+ *
+ * @param root the root node
+ */
+ public Tree(T root) {
+ super(root);
+ }
+
+ /**
+ * Write the tree to a PrintStream, using the default toString() method to output the node values
+ *
+ * @param stream
+ */
+ public void write(PrintStream stream) {
+ write(new PrintWriter(stream));
+ }
+
+ /**
+ * Write the tree to a PrintStream, using the provided converter to output the node values
+ *
+ * @param stream
+ * @param converter
+ */
+ public void write(PrintStream stream, Converter<T> converter) {
+ write(new PrintWriter(stream), converter);
+ }
+
+ /**
+ * Write the tree to a PrintWriter, using the default toString() method to output the node values
+ *
+ * @param writer
+ */
+ public void write(PrintWriter writer) {
+ write(writer, new Converter() {
+ public String toString(Node node) {
+ return node.getValue().toString();
+ }
+ });
+ }
+
+ /**
+ * Write the tree to a PrintWriter, using the provided converter to output the node values
+ *
+ * @param writer
+ * @param converter
+ */
+ public void write(PrintWriter writer, Converter<T> converter) {
+ writer.printf("%s%n", converter.toString(this));
+ for (Node<T> child : getChildren()) {
+ child.write(writer, converter);
+ }
+ writer.flush();
+ }
+
+ /**
+ * Interface to convert node values to string
+ *
+ * @param <T> the object type for the node value
+ */
+ public static interface Converter<T> {
+
+ public String toString(Node<T> node);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java
new file mode 100644
index 0000000..077cfef
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.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.bundle.command.wikidoc;
+
+import java.io.PrintStream;
+
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.Ansi.Attribute;
+import org.fusesource.jansi.Ansi.Color;
+
+/**
+ * Translates the Wiki tags to Ansi escape sequences to display them on the console
+ */
+public class AnsiPrintingWikiVisitor implements WikiVisitor {
+ private PrintStream out;
+
+ public AnsiPrintingWikiVisitor(PrintStream out) {
+ this.out = out;
+ }
+
+ @Override
+ public void heading(int level, String header) {
+ this.out.print(Ansi.ansi().a(Attribute.INTENSITY_BOLD).a(header)
+ .a(Attribute.INTENSITY_BOLD_OFF).toString());
+ }
+
+ @Override
+ public void link(String target, String title) {
+ this.out.print(Ansi.ansi().fg(Color.YELLOW)
+ .a(target).fg(Color.DEFAULT));
+ }
+
+ @Override
+ public void enumeration(String text) {
+ this.out.print(Ansi.ansi().a(" * ").fg(Color.CYAN).a(text).fg(Color.DEFAULT).a(" "));
+ }
+
+ @Override
+ public void text(String text) {
+ this.out.print(text);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
new file mode 100644
index 0000000..8ec3d5b
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
@@ -0,0 +1,86 @@
+/*
+ * 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.bundle.command.wikidoc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.StringTokenizer;
+
+/**
+ * Parses wiki syntax from a reader and calls a Wikivisitor with the
+ * tokens it finds
+ */
+public class WikiParser {
+ WikiVisitor visitor;
+
+ public WikiParser(WikiVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ public void parse(String line) {
+ StringTokenizer tokenizer = new StringTokenizer(line , "[h*", true);
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ if ("[".equals(token)) {
+ parseLink(tokenizer);
+ } else if ("h".equals(token)) {
+ parseHeading(tokenizer);
+ } else if ("*".equals(token)){
+ parseEnumeration(tokenizer);
+ } else {
+ visitor.text(token);
+ }
+ }
+ }
+
+ private void parseEnumeration(StringTokenizer tokenizer) {
+ String text = tokenizer.nextToken("-\n");
+ visitor.enumeration(text.trim());
+ }
+
+ private void parseHeading(StringTokenizer tokenizer) {
+ String level = tokenizer.nextToken("123456789");
+ if (!level.matches("[123456789]")) {
+ visitor.text("h" + level);
+ return;
+ }
+ String dot = tokenizer.nextToken(".\n");
+ if (!".".equals(dot)) {
+ visitor.text("h" + level + dot);
+ return;
+ }
+ String heading = tokenizer.hasMoreTokens() ? tokenizer.nextToken("\n") : "";
+ visitor.heading(new Integer(level), heading.trim());
+ }
+
+ private void parseLink(StringTokenizer tokenizer) {
+ String token = tokenizer.nextToken("]");
+ visitor.link(token, "");
+ tokenizer.nextToken();
+ }
+
+ public void parse(Reader reader) throws IOException {
+ BufferedReader br = new BufferedReader(reader);
+ String line;
+ while ((line = br.readLine()) != null) {
+ parse(line);
+ visitor.text("\n");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
new file mode 100644
index 0000000..b4a5fb3
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.bundle.command.wikidoc;
+
+/**
+ * Will be used by WikiParser to call the respective handler when it recognizes the tag
+ */
+public interface WikiVisitor {
+
+ void link(String target, String title);
+ void heading(int level, String title);
+ void enumeration(String text);
+ void text(String text);
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
new file mode 100644
index 0000000..876f605
--- /dev/null
+++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.bundle.command;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.karaf.bundle.core.internal.BundleServiceImpl;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+public class ListServicesTest {
+
+ private ListBundleServices listServices;
+
+ @SuppressWarnings("unchecked")
+ public ListServicesTest() {
+ listServices = new ListBundleServices();
+ BundleContext bundleContext = new TestBundleFactory().createBundleContext();
+ listServices.setBundleContext(bundleContext);
+ listServices.setBundleService(new BundleServiceImpl(bundleContext));
+ }
+
+ @Test
+ public void listAllShort() throws Exception {
+ System.out.println("listAllShort");
+ listServices.execute();
+ }
+
+
+ @Test
+ public void listAllLong() throws Exception {
+ System.out.println("listAllLong");
+ listServices.ids = Arrays.asList(new String[]{"1", "2"});
+ listServices.execute();
+ }
+
+ @Test
+ public void listAllLongServiceUse() throws Exception {
+ System.out.println("listAllLongServicesUse");
+ listServices.ids = Arrays.asList(new String[]{"1", "2"});
+ listServices.inUse = true;
+ listServices.execute();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
new file mode 100644
index 0000000..27e4a63
--- /dev/null
+++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
@@ -0,0 +1,104 @@
+/*
+ * 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.bundle.command;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class TestBundleFactory {
+ ServiceReference<?> createServiceRef(Object ... keyProp) {
+ ServiceReference<?> serviceRef = createMock(ServiceReference.class);
+ if (keyProp.length % 2 != 0) {
+ throw new IllegalArgumentException("");
+ }
+ Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
+ int c = 0;
+ while (c < keyProp.length) {
+ String key = (String)keyProp[c++];
+ Object value = (Object)keyProp[c++];
+ keyPropMap.put(key, value);
+ expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
+ }
+ expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new String[]{})).anyTimes();
+ return serviceRef;
+ }
+
+ Bundle createBundle(long id, String name) {
+ Bundle bundle = createMock(Bundle.class);
+ expect(bundle.getBundleId()).andReturn(id).anyTimes();
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put(Constants.BUNDLE_NAME, name);
+ expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+ return bundle;
+ }
+
+ private Bundle[] createBundles() {
+ Bundle bundle1 = createBundle(1, "Bundle A");
+ Bundle bundle2 = createBundle(2, "Bundle B");
+ Bundle bundle3 = createBundle(3, "Bundle C");
+
+ ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.MyService"},
+ "key1", "value1");
+ ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.OtherService"}, "key2", 1);
+
+ addRegisteredServices(bundle1, ref1, ref2);
+ addRegisteredServices(bundle2, ref2);
+ expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
+
+ expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
+ addUsedServices(bundle2, ref1);
+ addUsedServices(bundle3, ref1, ref2);
+
+ expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, bundle3}).anyTimes();
+ expect(ref2.getUsingBundles()).andReturn(new Bundle[]{bundle3}).anyTimes();
+
+ replay(bundle1, bundle2, bundle3, ref1, ref2);
+ return new Bundle[] { bundle1, bundle2, bundle3 };
+ }
+
+ private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
+ expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
+ }
+
+ private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... refs) {
+ expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
+ for (ServiceReference<?> ref : refs) {
+ expect(ref.getBundle()).andReturn(bundle);
+ }
+ }
+
+ public BundleContext createBundleContext() {
+ BundleContext bundleContext = createMock(BundleContext.class);
+ Bundle[] bundles = createBundles();
+ expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
+ expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
+ expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
+ expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
+ replay(bundleContext);
+ return bundleContext;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
new file mode 100644
index 0000000..df0d7d6
--- /dev/null
+++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.bundle.command.bundletree;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Set;
+
+import org.apache.karaf.bundle.command.bundletree.Node;
+import org.apache.karaf.bundle.command.bundletree.Tree;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link org.apache.karaf.shell.dev.util.Tree}
+ * and {@link org.apache.karaf.shell.dev.util.Node}
+ */
+public class TreeTest {
+
+ @Test
+ public void writeTreeWithOneChild() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ tree.addChild("child");
+
+ BufferedReader reader = read(tree);
+
+ assertEquals("root" , reader.readLine());
+ assertEquals("+- child" , reader.readLine());
+ }
+
+ @Test
+ public void writeTreeWithOneChildAndNodeConverter() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ tree.addChild("child");
+
+ StringWriter writer = new StringWriter();
+ tree.write(new PrintWriter(writer), new Tree.Converter<String>() {
+ public String toString(Node<String> node) {
+ return "my " + node.getValue();
+ }
+ });
+
+ BufferedReader reader = new BufferedReader(new StringReader(writer.getBuffer().toString()));
+
+ assertEquals("my root" , reader.readLine());
+ assertEquals("+- my child" , reader.readLine());
+ }
+
+ @Test
+ public void writeTreeWithChildAndGrandChild() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ Node<String> node = tree.addChild("child");
+ node.addChild("grandchild");
+
+ BufferedReader reader = read(tree);
+
+ assertEquals("root" , reader.readLine());
+ assertEquals("+- child" , reader.readLine());
+ assertEquals(" +- grandchild", reader.readLine());
+ }
+
+ @Test
+ public void writeTreeWithTwoChildrenAndOneGrandchild() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ Node<String> child = tree.addChild("child1");
+ child.addChild("grandchild");
+ tree.addChild("child2");
+
+ BufferedReader reader = read(tree);
+
+ assertEquals("root" , reader.readLine());
+ assertEquals("+- child1" , reader.readLine());
+ assertEquals("| +- grandchild", reader.readLine());
+ assertEquals("+- child2" , reader.readLine());
+ }
+
+ @Test
+ public void flattenTree() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ Node<String> child1 = tree.addChild("child1");
+ child1.addChild("grandchild");
+ Node child2 = tree.addChild("child2");
+ child2.addChild("grandchild");
+
+ Set<String> elements = tree.flatten();
+ assertNotNull(elements);
+ assertEquals(4, elements.size());
+ assertTrue(elements.contains("root"));
+ assertTrue(elements.contains("child1"));
+ assertTrue(elements.contains("child2"));
+ assertTrue(elements.contains("grandchild"));
+ }
+
+ @Test
+ public void hasAncestor() throws IOException {
+ Tree<String> tree = new Tree<String>("root");
+ Node<String> child1 = tree.addChild("child1");
+ child1.addChild("grandchild");
+ Node child2 = tree.addChild("child2");
+ Node node = child2.addChild("grandchild2");
+
+ assertTrue(node.hasAncestor("child2"));
+ assertTrue(node.hasAncestor("root"));
+ assertFalse(node.hasAncestor("child1"));
+ }
+
+ private BufferedReader read(Tree<String> tree) {
+ StringWriter writer = new StringWriter();
+ tree.write(new PrintWriter(writer));
+
+ BufferedReader reader = new BufferedReader(new StringReader(writer.getBuffer().toString()));
+ return reader;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java b/bundle/core/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
new file mode 100644
index 0000000..37101c3
--- /dev/null
+++ b/bundle/core/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.bundle.command.wikidoc;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class WikiParserTest {
+
+ private static final String TESTDOC =
+ "h1. myTestdoc\n" +
+ "\n" +
+ "Some text\n" +
+ "* enumeration\n" +
+ " some text [a link] some more text\n" +
+ "h1 is no heading";
+
+ private static final String HEADINGCASES =
+ "h1.\n" +
+ "hf.";
+
+ @Test
+ public void parseTestDoc() throws IOException {
+ WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
+ visitor.heading(1, "myTestdoc");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+ visitor.text("Some text");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+ visitor.enumeration("enumeration");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+ visitor.text(" some text ");
+ EasyMock.expectLastCall();
+ visitor.link("a link", "");
+ EasyMock.expectLastCall();
+ visitor.text(" some more text");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+ visitor.text("h1 is no heading");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(visitor);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(new StringReader(TESTDOC));
+ EasyMock.verify(visitor);
+ }
+
+ @Test
+ public void parseHeadingSpecialCases() throws IOException {
+ WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
+
+ visitor.heading(1, "");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+
+ visitor.text("hf.");
+ EasyMock.expectLastCall();
+ visitor.text("\n");
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(visitor);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(new StringReader(HEADINGCASES));
+ EasyMock.verify(visitor);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/pom.xml
----------------------------------------------------------------------
diff --git a/bundle/pom.xml b/bundle/pom.xml
index 894b64d..9900396 100644
--- a/bundle/pom.xml
+++ b/bundle/pom.xml
@@ -35,7 +35,6 @@
<modules>
<module>core</module>
- <module>command</module>
<module>blueprintstate</module>
<module>springstate</module>
</modules>
[54/59] [abbrv] [KARAF-2852] Merge region/core and region/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
new file mode 100644
index 0000000..22c817b
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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.region.commands;
+
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.eclipse.equinox.region.RegionDigraph;
+
+@Command(scope = "region", name = "region-add", description = "Adds a list of regions to the region digraph service.")
+@Service
+public class AddRegionCommand extends RegionCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "Regions to add to the region digraph service separated by whitespaces.", required = true, multiValued = true)
+ List<String> regions;
+
+ protected void doExecute(RegionDigraph regionDigraph) throws Exception {
+ for (String region : regions) {
+ regionDigraph.createRegion(region);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java b/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
new file mode 100644
index 0000000..7c71e36
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
@@ -0,0 +1,117 @@
+/*
+ * 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.region.commands;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.shell.api.action.Argument;
+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.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.eclipse.equinox.region.RegionFilter;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "region", name = "info", description = "Prints information about region digraph.")
+@Service
+public class InfoCommand extends RegionCommandSupport {
+
+ @Option(name = "-v", aliases = "--verbose", required = false, description = "Show all info.")
+ boolean verbose;
+
+ @Option(name = "-b", aliases = "--bundles", required = false, description = "Show bundles in each region.")
+ boolean bundles;
+
+ @Option(name = "-f", aliases = "--filters", required = false, description = "Show filters.")
+ boolean filters;
+
+ @Option(name = "-n", aliases = "--namespaces", required = false, description = "Show namespaces in each filter.")
+ boolean namespaces;
+
+ @Argument(index = 0, name = "regions", description = "Regions to provide detailed info for.", required = false, multiValued = true)
+ List<String> regions;
+
+ protected void doExecute(RegionDigraph regionDigraph) throws Exception {
+ System.out.println("Regions");
+ if (regions == null) {
+ for (Region region : regionDigraph.getRegions()) {
+ showRegion(region);
+ }
+ } else {
+ bundles = true;
+ filters = true;
+ namespaces = true;
+ for (String regionName : regions) {
+ Region region = regionDigraph.getRegion(regionName);
+ if (region == null) {
+ System.out.println("No region " + regionName);
+ } else {
+ showRegion(region);
+ }
+ }
+ }
+ }
+
+ private void showRegion(Region region) {
+ System.out.println(region.getName());
+ if (verbose || bundles) {
+ for (Long id : region.getBundleIds()) {
+ Bundle b = bundleContext.getBundle(id);
+ System.out.println(" " + id + " " + getStateString(b) + b);
+ }
+ }
+ if (verbose || filters || namespaces) {
+ for (RegionDigraph.FilteredRegion f : region.getEdges()) {
+ System.out.println(" filter to " + f.getRegion().getName());
+ if (verbose || namespaces) {
+ RegionFilter rf = f.getFilter();
+ for (Map.Entry<String, Collection<String>> policy : rf.getSharingPolicy().entrySet()) {
+ String namespace = policy.getKey();
+ System.out.println(" namespace: " + namespace);
+ for (String e : policy.getValue()) {
+ System.out.println(" " + e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public String getStateString(Bundle bundle) {
+ if (bundle == null) {
+ return "Bundle null";
+ }
+ int state = bundle.getState();
+ if (state == Bundle.ACTIVE) {
+ return "Active ";
+ } else if (state == Bundle.INSTALLED) {
+ return "Installed ";
+ } else if (state == Bundle.RESOLVED) {
+ return "Resolved ";
+ } else if (state == Bundle.STARTING) {
+ return "Starting ";
+ } else if (state == Bundle.STOPPING) {
+ return "Stopping ";
+ } else {
+ return "Unknown ";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java b/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
new file mode 100644
index 0000000..bcdfb6c
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
@@ -0,0 +1,79 @@
+/*
+ * 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.region.commands;
+
+import java.io.PrintStream;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+
+public abstract class RegionCommandSupport implements Action {
+
+ protected static final char VERSION_DELIM = ',';
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Override
+ public Object execute() throws Exception {
+ // Get repository instance service.
+ ServiceReference ref = bundleContext.getServiceReference(RegionDigraph.class.getName());
+ if (ref == null) {
+ System.out.println("RegionDigraph service is unavailable.");
+ return null;
+ }
+ try {
+ RegionDigraph admin = (RegionDigraph) bundleContext.getService(ref);
+ if (admin == null) {
+ System.out.println("RegionDigraph service is unavailable.");
+ return null;
+ }
+
+ doExecute(admin);
+ }
+ finally {
+ bundleContext.ungetService(ref);
+ }
+ return null;
+ }
+
+ abstract void doExecute(RegionDigraph admin) throws Exception;
+
+ protected void printUnderline(PrintStream out, int length)
+ {
+ for (int i = 0; i < length; i++)
+ {
+ out.print('-');
+ }
+ out.println("");
+ }
+
+
+ protected Region getRegion(RegionDigraph regionDigraph, String region) throws BundleException {
+ Region r = regionDigraph.getRegion(region);
+ if (r == null) {
+ System.out.println("No region: " + region + ", creating it");
+ r = regionDigraph.createRegion(region);
+ }
+ return r;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java b/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
new file mode 100644
index 0000000..07c39e9
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
@@ -0,0 +1,177 @@
+/*
+ * 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.region.commands.util;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+public class FileUtil
+{
+ public static void downloadSource(
+ PrintStream out, PrintStream err,
+ URL srcURL, String dirStr, boolean extract)
+ {
+ // Get the file name from the URL.
+ String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
+ ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
+ : srcURL.getFile();
+
+ try
+ {
+ out.println("Connecting...");
+
+ File dir = new File(dirStr);
+ if (!dir.exists())
+ {
+ err.println("Destination directory does not exist.");
+ }
+ File file = new File(dir, fileName);
+
+ OutputStream os = new FileOutputStream(file);
+ URLConnection conn = srcURL.openConnection();
+ int total = conn.getContentLength();
+ InputStream is = conn.getInputStream();
+
+ if (total > 0)
+ {
+ out.println("Downloading " + fileName
+ + " ( " + total + " bytes ).");
+ }
+ else
+ {
+ out.println("Downloading " + fileName + ".");
+ }
+ byte[] buffer = new byte[4096];
+ int count = 0;
+ for (int len = is.read(buffer); len > 0; len = is.read(buffer))
+ {
+ count += len;
+ os.write(buffer, 0, len);
+ }
+
+ os.close();
+ is.close();
+
+ if (extract)
+ {
+ is = new FileInputStream(file);
+ JarInputStream jis = new JarInputStream(is);
+ out.println("Extracting...");
+ unjar(jis, dir);
+ jis.close();
+ file.delete();
+ }
+ }
+ catch (Exception ex)
+ {
+ err.println(ex);
+ }
+ }
+
+ public static void unjar(JarInputStream jis, File dir)
+ throws IOException
+ {
+ // Reusable buffer.
+ byte[] buffer = new byte[4096];
+
+ // Loop through JAR entries.
+ for (JarEntry je = jis.getNextJarEntry();
+ je != null;
+ je = jis.getNextJarEntry())
+ {
+ if (je.getName().startsWith("/"))
+ {
+ throw new IOException("JAR resource cannot contain absolute paths.");
+ }
+
+ File target = new File(dir, je.getName());
+
+ // Check to see if the JAR entry is a directory.
+ if (je.isDirectory())
+ {
+ if (!target.exists())
+ {
+ if (!target.mkdirs())
+ {
+ throw new IOException("Unable to create target directory: "
+ + target);
+ }
+ }
+ // Just continue since directories do not have content to copy.
+ continue;
+ }
+
+ int lastIndex = je.getName().lastIndexOf('/');
+ String name = (lastIndex >= 0) ?
+ je.getName().substring(lastIndex + 1) : je.getName();
+ String destination = (lastIndex >= 0) ?
+ je.getName().substring(0, lastIndex) : "";
+
+ // JAR files use '/', so convert it to platform separator.
+ destination = destination.replace('/', File.separatorChar);
+ copy(jis, dir, name, destination, buffer);
+ }
+ }
+
+ public static void copy(
+ InputStream is, File dir, String destName, String destDir, byte[] buffer)
+ throws IOException
+ {
+ if (destDir == null)
+ {
+ destDir = "";
+ }
+
+ // Make sure the target directory exists and
+ // that is actually a directory.
+ File targetDir = new File(dir, destDir);
+ if (!targetDir.exists())
+ {
+ if (!targetDir.mkdirs())
+ {
+ throw new IOException("Unable to create target directory: "
+ + targetDir);
+ }
+ }
+ else if (!targetDir.isDirectory())
+ {
+ throw new IOException("Target is not a directory: "
+ + targetDir);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(new File(targetDir, destName)));
+ int count = 0;
+ while ((count = is.read(buffer)) > 0)
+ {
+ bos.write(buffer, 0, count);
+ }
+ bos.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java b/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
new file mode 100644
index 0000000..aa7215f
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.karaf.region.persist.internal;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.karaf.features.RegionsPersistence;
+import org.apache.karaf.util.tracker.SingleServiceTracker;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator {
+
+ private static final Logger log = LoggerFactory.getLogger(Activator.class);
+
+ private SingleServiceTracker<RegionDigraph> tracker;
+ private final AtomicReference<RegionsPersistenceImpl> persistence = new AtomicReference<RegionsPersistenceImpl>();
+ private final AtomicReference<RegionsBundleTracker> bundleTracker = new AtomicReference<RegionsBundleTracker>();
+ private ServiceRegistration<RegionsPersistence> reg;
+
+ @Override
+ public void start(final BundleContext bundleContext) throws Exception {
+ tracker = new SingleServiceTracker<RegionDigraph>(bundleContext, RegionDigraph.class, new SingleServiceTracker.SingleServiceListener() {
+ public void serviceFound() {
+ log.debug("Found RegionDigraph service, initializing");
+ RegionDigraph regionDigraph = tracker.getService();
+ Bundle framework = bundleContext.getBundle(0);
+ RegionsPersistenceImpl persistence = null;
+ try {
+ persistence = new RegionsPersistenceImpl(regionDigraph, framework);
+ reg = bundleContext.registerService(RegionsPersistence.class, persistence, null);
+
+ RegionsBundleTracker bundleTracker = new RegionsBundleTracker();
+ bundleTracker.start(bundleContext, persistence);
+ Activator.this.bundleTracker.set(bundleTracker);
+ } catch (Exception e) {
+ log.info("Could not create RegionsPersistenceImpl", e);
+ }
+ Activator.this.persistence.set(persistence);
+ }
+
+ public void serviceLost() {
+ if (reg != null) {
+ reg.unregister();
+ reg = null;
+ }
+ Activator.this.persistence.set(null);
+ Activator.this.bundleTracker.set(null);
+ }
+
+ public void serviceReplaced() {
+ //??
+ }
+ });
+ tracker.open();
+ }
+
+ @Override
+ public void stop(BundleContext bundleContext) throws Exception {
+ tracker.close();
+ persistence.set(null);
+ RegionsBundleTracker tracker = bundleTracker.getAndSet(null);
+ if (tracker != null) {
+ tracker.stop();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
new file mode 100644
index 0000000..7035303
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
@@ -0,0 +1,77 @@
+/*
+ * 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.region.persist.internal;
+
+import org.apache.karaf.features.RegionsPersistence;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RegionsBundleTracker {
+ private static final Logger log = LoggerFactory.getLogger(RegionsBundleTracker.class);
+
+ private BundleTracker bundleTracker;
+ private RegionsPersistence regionsPersistence;
+
+ void start(BundleContext bundleContext, RegionsPersistence regionsPersistence) {
+ this.regionsPersistence = regionsPersistence;
+ int stateMask = Bundle.INSTALLED;
+ bundleTracker = new BundleTracker<Bundle>(bundleContext, stateMask, new BundleTrackerCustomizer<Bundle>() {
+ @Override
+ public Bundle addingBundle(Bundle bundle, BundleEvent bundleEvent) {
+ return RegionsBundleTracker.this.addingBundle(bundle);
+ }
+
+ @Override
+ public void modifiedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
+ }
+
+ @Override
+ public void removedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
+ }
+ });
+ bundleTracker.open();
+ }
+
+ private Bundle addingBundle(Bundle bundle) {
+ String region = bundle.getHeaders().get("Region");
+ if (region != null) {
+ try {
+ regionsPersistence.install(bundle, region);
+ log.debug("Installed bundle " + bundle + " in region " + region);
+ return bundle;
+ } catch (BundleException e) {
+ log.info("Could not install bundle " + bundle + " in region " + region, e);
+ }
+ }
+ return null;
+ }
+
+ void stop() {
+ bundleTracker.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
new file mode 100644
index 0000000..dcf5d26
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
@@ -0,0 +1,203 @@
+/*
+ * 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.region.persist.internal;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.karaf.features.RegionsPersistence;
+import org.apache.karaf.region.persist.internal.model.FilterAttributeType;
+import org.apache.karaf.region.persist.internal.model.FilterBundleType;
+import org.apache.karaf.region.persist.internal.model.FilterNamespaceType;
+import org.apache.karaf.region.persist.internal.model.FilterPackageType;
+import org.apache.karaf.region.persist.internal.model.FilterType;
+import org.apache.karaf.region.persist.internal.model.RegionBundleType;
+import org.apache.karaf.region.persist.internal.model.RegionType;
+import org.apache.karaf.region.persist.internal.model.RegionsType;
+import org.apache.karaf.region.persist.internal.util.ManifestHeaderProcessor;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.eclipse.equinox.region.RegionFilterBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RegionsPersistenceImpl implements RegionsPersistence {
+
+ private static final Logger log = LoggerFactory.getLogger(RegionsPersistenceImpl.class);
+
+ private JAXBContext jaxbContext;
+ private RegionDigraph regionDigraph;
+ private Region kernel;
+ private Bundle framework;
+
+ public RegionsPersistenceImpl(RegionDigraph regionDigraph, Bundle framework) throws JAXBException, BundleException, IOException, InvalidSyntaxException {
+ log.info("Loading region digraph persistence");
+ this.framework = framework;
+ this.regionDigraph = regionDigraph;
+ kernel = regionDigraph.getRegion(0);
+ jaxbContext = JAXBContext.newInstance(RegionsType.class);
+ load();
+ }
+
+ @Override
+ public void install(Bundle b, String regionName) throws BundleException {
+ Region region = regionDigraph.getRegion(regionName);
+ if (region == null) {
+ region = regionDigraph.createRegion(regionName);
+ }
+ kernel.removeBundle(b);
+ region.addBundle(b);
+ }
+
+ void save(RegionsType regionsType, Writer out) throws JAXBException {
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.marshal(regionsType, out);
+ }
+
+ void load() throws IOException, BundleException, JAXBException, InvalidSyntaxException {
+ if (this.regionDigraph.getRegions().size() <= 1) {
+ File etc = new File(System.getProperty("karaf.etc"));
+ File regionsConfig = new File(etc, "regions-config.xml");
+ if (regionsConfig.exists()) {
+ log.info("initializing region digraph from etc/regions-config.xml");
+ Reader in = new FileReader(regionsConfig);
+ try {
+ load(this.regionDigraph, in);
+ } finally {
+ in.close();
+ }
+ } else {
+ log.info("no regions config file");
+ }
+ }
+
+ }
+
+ void load(RegionDigraph regionDigraph, Reader in) throws JAXBException, BundleException, InvalidSyntaxException {
+ RegionsType regionsType = load(in);
+ load(regionsType, regionDigraph);
+ }
+
+ RegionsType load(Reader in) throws JAXBException {
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ return (RegionsType) unmarshaller.unmarshal(in);
+ }
+
+ void load(RegionsType regionsType, RegionDigraph regionDigraph) throws BundleException, InvalidSyntaxException {
+ BundleContext frameworkContext = framework.getBundleContext();
+ for (RegionType regionType: regionsType.getRegion()) {
+ String name = regionType.getName();
+ log.debug("Creating region: " + name);
+ Region region = regionDigraph.createRegion(name);
+ for (RegionBundleType bundleType: regionType.getBundle()) {
+ if (bundleType.getId() != null) {
+ region.addBundle(bundleType.getId());
+ } else {
+ Bundle b = frameworkContext.getBundle(bundleType.getLocation());
+ region.addBundle(b);
+ }
+ }
+ }
+ for (FilterType filterType: regionsType.getFilter()) {
+ Region from = regionDigraph.getRegion(filterType.getFrom());
+ Region to = regionDigraph.getRegion(filterType.getTo());
+ log.debug("Creating filter between " + from.getName() + " to " + to.getName());
+ RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
+ for (FilterBundleType bundleType: filterType.getBundle()) {
+ String symbolicName = bundleType.getSymbolicName();
+ String version = bundleType.getVersion();
+ if (bundleType.getId() != null) {
+ Bundle b = frameworkContext.getBundle(bundleType.getId());
+ symbolicName = b.getSymbolicName();
+ version = b.getVersion().toString();
+ }
+ String namespace = BundleRevision.BUNDLE_NAMESPACE;
+ List<FilterAttributeType> attributeTypes = bundleType.getAttribute();
+ buildFilter(symbolicName, version, namespace, attributeTypes, builder);
+ }
+ for (FilterPackageType packageType: filterType.getPackage()) {
+ String packageName = packageType.getName();
+ String version = packageType.getVersion();
+ String namespace = BundleRevision.PACKAGE_NAMESPACE;
+ List<FilterAttributeType> attributeTypes = packageType.getAttribute();
+ buildFilter(packageName, version, namespace, attributeTypes, builder);
+ }
+ if (to == kernel) {
+ //add framework exports
+ BundleRevision rev = framework.adapt(BundleRevision.class);
+ List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
+ for (BundleCapability cap : caps) {
+ String filter = ManifestHeaderProcessor.generateFilter(filter(cap.getAttributes()));
+ builder.allow(BundleRevision.PACKAGE_NAMESPACE, filter);
+ }
+ }
+ //TODO explicit services?
+ for (FilterNamespaceType namespaceType: filterType.getNamespace()) {
+ String namespace = namespaceType.getName();
+ HashMap<String, Object> attributes = new HashMap<String, Object>();
+ for (FilterAttributeType attributeType: namespaceType.getAttribute()) {
+ attributes.put(attributeType.getName(), attributeType.getValue());
+ }
+ String filter = ManifestHeaderProcessor.generateFilter(attributes);
+ builder.allow(namespace, filter);
+ }
+ regionDigraph.connect(from, builder.build(), to);
+ }
+ }
+
+ private Map<String, Object> filter(Map<String, Object> attributes) {
+ Map<String, Object> result = new HashMap<String, Object>(attributes);
+ result.remove("bundle-version");
+ result.remove("bundle-symbolic-name");
+ return result;
+ }
+
+ private void buildFilter(String packageName, String version, String namespace, List<FilterAttributeType> attributeTypes, RegionFilterBuilder builder) throws InvalidSyntaxException {
+ HashMap<String, Object> attributes = new HashMap<String, Object>();
+ if (namespace != null) {
+ attributes.put(namespace, packageName);
+ }
+ if (version != null) {
+ attributes.put("version", version);
+ }
+ for (FilterAttributeType attributeType: attributeTypes) {
+ attributes.put(attributeType.getName(), attributeType.getValue());
+ }
+ String filter = ManifestHeaderProcessor.generateFilter(attributes);
+ builder.allow(namespace, filter);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
new file mode 100644
index 0000000..857c2b3
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterAttributeType.java
@@ -0,0 +1,94 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for filterAttributeType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="filterAttributeType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * </sequence>
+ * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "filterAttributeType")
+public class FilterAttributeType {
+
+ @XmlAttribute(required = true)
+ protected String name;
+ @XmlAttribute(required = true)
+ protected String value;
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
new file mode 100644
index 0000000..a9a9fbb
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterBundleType.java
@@ -0,0 +1,156 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for filterBundleType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="filterBundleType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}long" />
+ * <attribute name="symbolic-name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "filterBundleType", propOrder = {
+ "attribute"
+})
+public class FilterBundleType {
+
+ protected List<FilterAttributeType> attribute;
+ @XmlAttribute
+ protected Long id;
+ @XmlAttribute(name = "symbolic-name")
+ protected String symbolicName;
+ @XmlAttribute
+ protected String version;
+
+ /**
+ * Gets the value of the attribute property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the attribute property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getAttribute().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterAttributeType }
+ *
+ *
+ */
+ public List<FilterAttributeType> getAttribute() {
+ if (attribute == null) {
+ attribute = new ArrayList<FilterAttributeType>();
+ }
+ return this.attribute;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setId(Long value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the symbolicName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ /**
+ * Sets the value of the symbolicName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSymbolicName(String value) {
+ this.symbolicName = value;
+ }
+
+ /**
+ * Gets the value of the version property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the value of the version property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setVersion(String value) {
+ this.version = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
new file mode 100644
index 0000000..52b937a
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterNamespaceType.java
@@ -0,0 +1,102 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for filterNamespaceType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="filterNamespaceType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "filterNamespaceType", propOrder = {
+ "attribute"
+})
+public class FilterNamespaceType {
+
+ protected List<FilterAttributeType> attribute;
+ @XmlAttribute(required = true)
+ protected String name;
+
+ /**
+ * Gets the value of the attribute property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the attribute property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getAttribute().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterAttributeType }
+ *
+ *
+ */
+ public List<FilterAttributeType> getAttribute() {
+ if (attribute == null) {
+ attribute = new ArrayList<FilterAttributeType>();
+ }
+ return this.attribute;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
new file mode 100644
index 0000000..b4216ee
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterPackageType.java
@@ -0,0 +1,129 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for filterPackageType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="filterPackageType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="attribute" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterAttributeType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "filterPackageType", propOrder = {
+ "attribute"
+})
+public class FilterPackageType {
+
+ protected List<FilterAttributeType> attribute;
+ @XmlAttribute
+ protected String name;
+ @XmlAttribute
+ protected String version;
+
+ /**
+ * Gets the value of the attribute property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the attribute property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getAttribute().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterAttributeType }
+ *
+ *
+ */
+ public List<FilterAttributeType> getAttribute() {
+ if (attribute == null) {
+ attribute = new ArrayList<FilterAttributeType>();
+ }
+ return this.attribute;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+ /**
+ * Gets the value of the version property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the value of the version property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setVersion(String value) {
+ this.version = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
new file mode 100644
index 0000000..f4d1352
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
@@ -0,0 +1,195 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for filterType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="filterType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="bundle" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterBundleType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="package" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterPackageType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="namespace" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterNamespaceType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "filterType", propOrder = {
+ "bundle",
+ "_package",
+ "namespace"
+})
+public class FilterType {
+
+ protected List<FilterBundleType> bundle;
+ @XmlElement(name = "package")
+ protected List<FilterPackageType> _package;
+ protected List<FilterNamespaceType> namespace;
+ @XmlAttribute(required = true)
+ protected String from;
+ @XmlAttribute(required = true)
+ protected String to;
+
+ /**
+ * Gets the value of the bundle property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the bundle property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getBundle().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterBundleType }
+ *
+ *
+ */
+ public List<FilterBundleType> getBundle() {
+ if (bundle == null) {
+ bundle = new ArrayList<FilterBundleType>();
+ }
+ return this.bundle;
+ }
+
+ /**
+ * Gets the value of the package property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the package property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getPackage().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterPackageType }
+ *
+ *
+ */
+ public List<FilterPackageType> getPackage() {
+ if (_package == null) {
+ _package = new ArrayList<FilterPackageType>();
+ }
+ return this._package;
+ }
+
+ /**
+ * Gets the value of the namespace property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the namespace property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getNamespace().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterNamespaceType }
+ *
+ *
+ */
+ public List<FilterNamespaceType> getNamespace() {
+ if (namespace == null) {
+ namespace = new ArrayList<FilterNamespaceType>();
+ }
+ return this.namespace;
+ }
+
+ /**
+ * Gets the value of the from property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getFrom() {
+ return from;
+ }
+
+ /**
+ * Sets the value of the from property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setFrom(String value) {
+ this.from = value;
+ }
+
+ /**
+ * Gets the value of the to property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getTo() {
+ return to;
+ }
+
+ /**
+ * Sets the value of the to property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setTo(String value) {
+ this.to = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
new file mode 100644
index 0000000..54f5f3c
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
@@ -0,0 +1,116 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the org.apache.karaf.region.persist.internal.model package.
+ * <p>An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+ private final static QName _Regions_QNAME = new QName("http://karaf.apache.org/xmlns/region/v1.0.0", "regions");
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.karaf.region.persist.internal.model
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link FilterNamespaceType }
+ *
+ */
+ public FilterNamespaceType createFilterNamespaceType() {
+ return new FilterNamespaceType();
+ }
+
+ /**
+ * Create an instance of {@link FilterType }
+ *
+ */
+ public FilterType createFilterType() {
+ return new FilterType();
+ }
+
+ /**
+ * Create an instance of {@link RegionBundleType }
+ *
+ */
+ public RegionBundleType createRegionBundleType() {
+ return new RegionBundleType();
+ }
+
+ /**
+ * Create an instance of {@link FilterBundleType }
+ *
+ */
+ public FilterBundleType createFilterBundleType() {
+ return new FilterBundleType();
+ }
+
+ /**
+ * Create an instance of {@link FilterPackageType }
+ *
+ */
+ public FilterPackageType createFilterPackageType() {
+ return new FilterPackageType();
+ }
+
+ /**
+ * Create an instance of {@link FilterAttributeType }
+ *
+ */
+ public FilterAttributeType createFilterAttributeType() {
+ return new FilterAttributeType();
+ }
+
+ /**
+ * Create an instance of {@link RegionType }
+ *
+ */
+ public RegionType createRegionType() {
+ return new RegionType();
+ }
+
+ /**
+ * Create an instance of {@link RegionsType }
+ *
+ */
+ public RegionsType createRegionsType() {
+ return new RegionsType();
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link RegionsType }{@code >}}
+ *
+ */
+ @XmlElementDecl(namespace = "http://karaf.apache.org/xmlns/region/v1.0.0", name = "regions")
+ public JAXBElement<RegionsType> createRegions(RegionsType value) {
+ return new JAXBElement<RegionsType>(_Regions_QNAME, RegionsType.class, null, value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
new file mode 100644
index 0000000..7ba3585
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
@@ -0,0 +1,94 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for regionBundleType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="regionBundleType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * </sequence>
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}long" />
+ * <attribute name="location" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "regionBundleType")
+public class RegionBundleType {
+
+ @XmlAttribute
+ protected Long id;
+ @XmlAttribute
+ protected String location;
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setId(Long value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the location property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the value of the location property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLocation(String value) {
+ this.location = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
new file mode 100644
index 0000000..f7a810d
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
@@ -0,0 +1,106 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ *
+ * Regions element
+ *
+ *
+ * <p>Java class for regionType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="regionType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="bundle" type="{http://karaf.apache.org/xmlns/region/v1.0.0}regionBundleType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "regionType", propOrder = {
+ "bundle"
+})
+public class RegionType {
+
+ protected List<RegionBundleType> bundle;
+ @XmlAttribute(required = true)
+ protected String name;
+
+ /**
+ * Gets the value of the bundle property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the bundle property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getBundle().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link RegionBundleType }
+ *
+ *
+ */
+ public List<RegionBundleType> getBundle() {
+ if (bundle == null) {
+ bundle = new ArrayList<RegionBundleType>();
+ }
+ return this.bundle;
+ }
+
+ /**
+ * Gets the value of the name property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the value of the name property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setName(String value) {
+ this.name = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
new file mode 100644
index 0000000..be172e4
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
@@ -0,0 +1,112 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+
+package org.apache.karaf.region.persist.internal.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ *
+ * Regions element
+ *
+ *
+ * <p>Java class for regionsType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * <complexType name="regionsType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="region" type="{http://karaf.apache.org/xmlns/region/v1.0.0}regionType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="filter" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlRootElement(name = "regions")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "regionsType", propOrder = {
+ "region",
+ "filter"
+})
+public class RegionsType {
+
+ protected List<RegionType> region;
+ protected List<FilterType> filter;
+
+ /**
+ * Gets the value of the region property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the region property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getRegion().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link RegionType }
+ *
+ *
+ */
+ public List<RegionType> getRegion() {
+ if (region == null) {
+ region = new ArrayList<RegionType>();
+ }
+ return this.region;
+ }
+
+ /**
+ * Gets the value of the filter property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the filter property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getFilter().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link FilterType }
+ *
+ *
+ */
+ public List<FilterType> getFilter() {
+ if (filter == null) {
+ filter = new ArrayList<FilterType>();
+ }
+ return this.filter;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java b/region/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
new file mode 100644
index 0000000..cae062c
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
@@ -0,0 +1,9 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2011.10.28 at 03:20:55 PM PDT
+//
+
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://karaf.apache.org/xmlns/region/v1.0.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.karaf.region.persist.internal.model;
[43/59] [abbrv] git commit: [KARAF-2852] Merge http/core and
http/command
Posted by gn...@apache.org.
[KARAF-2852] Merge http/core and http/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/d5ce026b
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/d5ce026b
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/d5ce026b
Branch: refs/heads/master
Commit: d5ce026b7cb83259d0f2515d9fc090b887ce4d3b
Parents: 0a100d76
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 09:11:33 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:33 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
http/NOTICE | 71 ++++++++++++
http/command/NOTICE | 71 ------------
http/command/pom.xml | 114 -------------------
.../karaf/http/command/ServletListCommand.java | 62 ----------
.../src/main/resources/OSGI-INF/bundle.info | 15 ---
http/core/NOTICE | 71 ------------
http/core/pom.xml | 102 -----------------
.../org/apache/karaf/http/core/HttpMBean.java | 35 ------
.../org/apache/karaf/http/core/ServletInfo.java | 85 --------------
.../apache/karaf/http/core/ServletService.java | 25 ----
.../karaf/http/core/internal/HttpMBeanImpl.java | 72 ------------
.../http/core/internal/ServletEventHandler.java | 41 -------
.../http/core/internal/ServletServiceImpl.java | 68 -----------
.../http/core/internal/osgi/Activator.java | 40 -------
.../src/main/resources/OSGI-INF/bundle.info | 19 ----
.../http/core/internal/HttpMBeanImplTest.java | 37 ------
http/pom.xml | 92 +++++++++++++--
.../karaf/http/command/ServletListCommand.java | 62 ++++++++++
.../org/apache/karaf/http/core/HttpMBean.java | 35 ++++++
.../org/apache/karaf/http/core/ServletInfo.java | 85 ++++++++++++++
.../apache/karaf/http/core/ServletService.java | 25 ++++
.../karaf/http/core/internal/HttpMBeanImpl.java | 72 ++++++++++++
.../http/core/internal/ServletEventHandler.java | 41 +++++++
.../http/core/internal/ServletServiceImpl.java | 68 +++++++++++
.../http/core/internal/osgi/Activator.java | 40 +++++++
http/src/main/resources/OSGI-INF/bundle.info | 19 ++++
.../http/core/internal/HttpMBeanImplTest.java | 37 ++++++
28 files changed, 639 insertions(+), 866 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/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 fae3b4f..4c2be08 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -170,7 +170,6 @@
<feature name="http" version="${project.version}" resolver="(obr)" description="Implementation of the OSGI HTTP Service">
<feature>pax-http</feature>
<bundle start-level="30">mvn:org.apache.karaf.http/org.apache.karaf.http.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.http/org.apache.karaf.http.command/${project.version}</bundle>
</feature>
<feature name="http-whiteboard" description="Provide HTTP Whiteboard pattern support" version="${project.version}" resolver="(obr)">
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/NOTICE
----------------------------------------------------------------------
diff --git a/http/NOTICE b/http/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/http/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/d5ce026b/http/command/NOTICE
----------------------------------------------------------------------
diff --git a/http/command/NOTICE b/http/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/http/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/d5ce026b/http/command/pom.xml
----------------------------------------------------------------------
diff --git a/http/command/pom.xml b/http/command/pom.xml
deleted file mode 100644
index 0cee04f..0000000
--- a/http/command/pom.xml
+++ /dev/null
@@ -1,114 +0,0 @@
-<?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.http</groupId>
- <artifactId>http</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.http.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: HTTP :: Commands</name>
- <description>This bundle provides Karaf shell commands to list details of the http service.</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.http</groupId>
- <artifactId>org.apache.karaf.http.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.web</groupId>
- <artifactId>pax-web-spi</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>${servlet.spec.groupId}</groupId>
- <artifactId>${servlet.spec.artifactId}</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>compile</scope>
- </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>
- <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
- <Export-Package>${project.artifactId}*;version=${project.version}</Export-Package>
- <Private-Package>
- org.apache.felix.utils.version,
- org.apache.felix.utils.manifest,
- org.apache.karaf.util;-split-package:=merge-first
- </Private-Package>
- <Karaf-Commands>*</Karaf-Commands>
- <_versionpolicy>${bnd.version.policy}</_versionpolicy>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/command/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
----------------------------------------------------------------------
diff --git a/http/command/src/main/java/org/apache/karaf/http/command/ServletListCommand.java b/http/command/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
deleted file mode 100644
index 1932499..0000000
--- a/http/command/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.http.command;
-
-import java.util.Arrays;
-
-import org.apache.karaf.http.core.ServletInfo;
-import org.apache.karaf.http.core.ServletService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "http", name = "list", description = "Lists details for servlets.")
-@Service
-public class ServletListCommand implements Action {
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private ServletService servletService;
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
- table.column(new Col("ID"));
- table.column(new Col("Servlet"));
- table.column(new Col("Servlet-Name"));
- table.column(new Col("State"));
- table.column(new Col("Alias"));
- table.column(new Col("Url"));
-
- for (ServletInfo info : servletService.getServlets()) {
- table.addRow().addContent(info.getBundle().getBundleId(), info.getClassName(), info.getName(),
- info.getStateString(), info.getAlias(), Arrays.toString(info.getUrls()));
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
- public void setServletService(ServletService servletService) {
- this.servletService = servletService;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/http/command/src/main/resources/OSGI-INF/bundle.info b/http/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 06c9582..0000000
--- a/http/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,15 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to interact with http servlets.
-
-The following commands are available:
-* http:list - Lists details for servlets.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/NOTICE
----------------------------------------------------------------------
diff --git a/http/core/NOTICE b/http/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/http/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/d5ce026b/http/core/pom.xml
----------------------------------------------------------------------
diff --git a/http/core/pom.xml b/http/core/pom.xml
deleted file mode 100644
index e09d764..0000000
--- a/http/core/pom.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?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.http</groupId>
- <artifactId>http</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.http.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: HTTP :: Core</name>
- <description>This bundle provides HTTP core services</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.ops4j.pax.web</groupId>
- <artifactId>pax-web-spi</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>${servlet.spec.groupId}</groupId>
- <artifactId>${servlet.spec.artifactId}</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <includes>
- <include>**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>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>
- <Export-Package>
- org.apache.karaf.http.core
- </Export-Package>
- <Private-Package>
- org.apache.karaf.http.core.internal,
- org.apache.karaf.http.core.internal.osgi,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.http.core.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/HttpMBean.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/HttpMBean.java b/http/core/src/main/java/org/apache/karaf/http/core/HttpMBean.java
deleted file mode 100644
index bebbd29..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/HttpMBean.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.http.core;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.TabularData;
-
-/**
- * HTTP MBean.
- */
-public interface HttpMBean {
-
- /**
- * List details for servlets.
- *
- * @return a tabular view of the servlets information.
- * @throws Exception
- */
- TabularData getServlets() throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/ServletInfo.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/ServletInfo.java b/http/core/src/main/java/org/apache/karaf/http/core/ServletInfo.java
deleted file mode 100644
index 9fc83df..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/ServletInfo.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.http.core;
-
-import org.ops4j.pax.web.service.spi.WebEvent;
-import org.osgi.framework.Bundle;
-
-public class ServletInfo {
- private String name;
- private Bundle bundle;
- private String className;
- private String alias;
- private int state;
- private String[] urls;
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Bundle getBundle() {
- return bundle;
- }
- public void setBundle(Bundle bundle) {
- this.bundle = bundle;
- }
- public String getClassName() {
- return className;
- }
- public void setClassName(String className) {
- this.className = className;
- }
- public int getState() {
- return state;
- }
- public void setState(int state) {
- this.state = state;
- }
- public String getAlias() {
- return alias;
- }
- public void setAlias(String alias) {
- this.alias = alias;
- }
- public String[] getUrls() {
- return urls;
- }
- public void setUrls(String[] urls) {
- this.urls = urls;
- }
-
- public String getStateString() {
- switch (state) {
- case WebEvent.DEPLOYING:
- return "Deploying ";
- case WebEvent.DEPLOYED:
- return "Deployed ";
- case WebEvent.UNDEPLOYING:
- return "Undeploying";
- case WebEvent.UNDEPLOYED:
- return "Undeployed ";
- case WebEvent.FAILED:
- return "Failed ";
- case WebEvent.WAITING:
- return "Waiting ";
- default:
- return "Failed ";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/ServletService.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/ServletService.java b/http/core/src/main/java/org/apache/karaf/http/core/ServletService.java
deleted file mode 100644
index fd9b24a..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/ServletService.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.http.core;
-
-import java.util.List;
-
-public interface ServletService {
-
- List<ServletInfo> getServlets();
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java b/http/core/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
deleted file mode 100644
index 563af61..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.http.core.internal;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.karaf.http.core.HttpMBean;
-import org.apache.karaf.http.core.ServletInfo;
-import org.apache.karaf.http.core.ServletService;
-
-/**
- * Implementation of the HTTP MBean.
- */
-public class HttpMBeanImpl extends StandardMBean implements HttpMBean {
- private ServletService servletService;
-
- public HttpMBeanImpl(ServletService servletService) throws NotCompliantMBeanException {
- super(HttpMBean.class);
- this.servletService = servletService;
- }
-
- public TabularData getServlets() throws MBeanException {
- try {
- CompositeType servletType = new CompositeType("Servlet", "HTTP Servlet",
- new String[]{"Bundle-ID", "Servlet", "Servlet Name", "State", "Alias", "URL"},
- new String[]{"ID of the bundle that registered the servlet", "Class name of the servlet", "Servlet Name", "Current state of the servlet", "Aliases of the servlet", "URL of the servlet"},
- new OpenType[]{SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
- TabularType tableType = new TabularType("Servlets", "Table of all HTTP servlets", servletType, new String[]{"Bundle-ID", "Servlet Name", "State"});
- TabularData table = new TabularDataSupport(tableType);
- List<ServletInfo> servletInfos = servletService.getServlets();
- for (ServletInfo info : servletInfos) {
-
- CompositeData data = new CompositeDataSupport(servletType,
- new String[]{"Bundle-ID", "Servlet", "Servlet Name", "State", "Alias", "URL"},
- new Object[]{info.getBundle().getBundleId(), info.getClassName(), info.getName(), info.getStateString(), info.getAlias(), Arrays.toString(info.getUrls())});
- table.put(data);
-
- }
- return table;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java b/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
deleted file mode 100644
index 2733175..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.http.core.internal;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.ops4j.pax.web.service.spi.ServletEvent;
-import org.ops4j.pax.web.service.spi.ServletListener;
-
-public class ServletEventHandler implements ServletListener {
-
- Map<String, ServletEvent> servletEvents = new HashMap<String, ServletEvent>();
-
- public void servletEvent(ServletEvent event) {
- servletEvents.put(event.getServletName(), event);
- }
-
- /**
- * @return the servletEvents
- */
- public Collection<ServletEvent> getServletEvents() {
- return servletEvents.values();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java b/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
deleted file mode 100644
index 8733ae4..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.http.core.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.servlet.Servlet;
-
-import org.apache.karaf.http.core.ServletInfo;
-import org.apache.karaf.http.core.ServletService;
-import org.ops4j.pax.web.service.spi.ServletEvent;
-
-public class ServletServiceImpl implements ServletService {
- private ServletEventHandler servletEventHandler;
-
- public ServletServiceImpl(ServletEventHandler servletEventHandler) {
- this.servletEventHandler = servletEventHandler;
- }
-
- @Override
- public List<ServletInfo> getServlets() {
- List<ServletInfo> servletInfos = new ArrayList<ServletInfo>();
- Collection<ServletEvent> events = servletEventHandler.getServletEvents();
- for (ServletEvent event : events) {
- Servlet servlet = event.getServlet();
- String servletClassName = " ";
- if (servlet != null) {
- servletClassName = servlet.getClass().getName();
- servletClassName = servletClassName.substring(servletClassName.lastIndexOf(".") + 1,
- servletClassName.length());
- }
- String servletName = event.getServletName() != null ? event.getServletName() : " ";
- if (servletName.contains(".")) {
- servletName = servletName.substring(servletName.lastIndexOf(".") + 1, servletName.length());
- }
-
- String alias = event.getAlias() != null ? event.getAlias() : " ";
-
- String[] urls = (String[])(event.getUrlParameter() != null ? event.getUrlParameter() : new String[] {""});
- ServletInfo info = new ServletInfo();
- info.setBundle(event.getBundle());
- info.setName(servletName);
- info.setClassName(servletClassName);
- info.setState(event.getType());
- info.setAlias(alias);
- info.setUrls(urls);
- servletInfos.add(info);
- }
- return servletInfos;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/http/core/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java b/http/core/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
deleted file mode 100644
index a294229..0000000
--- a/http/core/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.http.core.internal.osgi;
-
-import org.apache.karaf.http.core.ServletService;
-import org.apache.karaf.http.core.internal.HttpMBeanImpl;
-import org.apache.karaf.http.core.internal.ServletEventHandler;
-import org.apache.karaf.http.core.internal.ServletServiceImpl;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.ops4j.pax.web.service.spi.ServletListener;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doStart() throws Exception {
- ServletEventHandler servletEventHandler = new ServletEventHandler();
- register(ServletListener.class, servletEventHandler);
-
- ServletServiceImpl servletService = new ServletServiceImpl(servletEventHandler);
- register(ServletService.class, servletService);
-
- HttpMBeanImpl httpMBean = new HttpMBeanImpl(servletService);
- registerMBean(httpMBean, "type=http");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/http/core/src/main/resources/OSGI-INF/bundle.info b/http/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 31222c7..0000000
--- a/http/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,19 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-The http mbean management bundle exposes a HTTP MBean that can be used with any JMX client (for instance JConsole).
-
-The HTTP MBean allows quite the same actions that can be performed using http:* commands:
- * list()
-
-h1. See also
-
- * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/core/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
----------------------------------------------------------------------
diff --git a/http/core/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java b/http/core/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
deleted file mode 100644
index cb2f8fd..0000000
--- a/http/core/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.http.core.internal;
-
-import java.lang.management.ManagementFactory;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.openmbean.TabularData;
-
-import org.junit.Test;
-
-public class HttpMBeanImplTest {
-
- @Test
- public void testRegisterMBean() throws Exception {
- HttpMBeanImpl httpMBean = new HttpMBeanImpl(new ServletServiceImpl(new ServletEventHandler()));
- MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
- mbeanServer.registerMBean(httpMBean, new ObjectName("org.apache.karaf:type=http,name=root"));
-
- TabularData data = httpMBean.getServlets();
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/pom.xml
----------------------------------------------------------------------
diff --git a/http/pom.xml b/http/pom.xml
index 0a77680..e162765 100644
--- a/http/pom.xml
+++ b/http/pom.xml
@@ -29,13 +29,89 @@
</parent>
<groupId>org.apache.karaf.http</groupId>
- <artifactId>http</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: HTTP</name>
+ <artifactId>org.apache.karaf.http.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: HTTP :: Core</name>
+ <description>This bundle provides HTTP core services</description>
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <properties>
+ <appendedResourcesDirectory>${basedir}/../../../etc/appended-resources/</appendedResourcesDirectory>
+ </properties>
-</project>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.web</groupId>
+ <artifactId>pax-web-spi</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${servlet.spec.groupId}</groupId>
+ <artifactId>${servlet.spec.artifactId}</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>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>
+ <Export-Package>
+ org.apache.karaf.http.core,
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.http.command,
+ org.apache.karaf.http.core.internal,
+ org.apache.karaf.http.core.internal.osgi,
+ org.apache.karaf.util.tracker,
+ org.apache.felix.utils.version,
+ org.apache.felix.utils.manifest,
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.http.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java b/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
new file mode 100644
index 0000000..1932499
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.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.http.command;
+
+import java.util.Arrays;
+
+import org.apache.karaf.http.core.ServletInfo;
+import org.apache.karaf.http.core.ServletService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.Col;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "http", name = "list", description = "Lists details for servlets.")
+@Service
+public class ServletListCommand implements Action {
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ private ServletService servletService;
+
+ @Override
+ public Object execute() throws Exception {
+ ShellTable table = new ShellTable();
+ table.column(new Col("ID"));
+ table.column(new Col("Servlet"));
+ table.column(new Col("Servlet-Name"));
+ table.column(new Col("State"));
+ table.column(new Col("Alias"));
+ table.column(new Col("Url"));
+
+ for (ServletInfo info : servletService.getServlets()) {
+ table.addRow().addContent(info.getBundle().getBundleId(), info.getClassName(), info.getName(),
+ info.getStateString(), info.getAlias(), Arrays.toString(info.getUrls()));
+ }
+ table.print(System.out, !noFormat);
+ return null;
+ }
+
+ public void setServletService(ServletService servletService) {
+ this.servletService = servletService;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/HttpMBean.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/HttpMBean.java b/http/src/main/java/org/apache/karaf/http/core/HttpMBean.java
new file mode 100644
index 0000000..bebbd29
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/HttpMBean.java
@@ -0,0 +1,35 @@
+/*
+ * 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.http.core;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+
+/**
+ * HTTP MBean.
+ */
+public interface HttpMBean {
+
+ /**
+ * List details for servlets.
+ *
+ * @return a tabular view of the servlets information.
+ * @throws Exception
+ */
+ TabularData getServlets() throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java b/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
new file mode 100644
index 0000000..9fc83df
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
@@ -0,0 +1,85 @@
+/*
+ * 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.http.core;
+
+import org.ops4j.pax.web.service.spi.WebEvent;
+import org.osgi.framework.Bundle;
+
+public class ServletInfo {
+ private String name;
+ private Bundle bundle;
+ private String className;
+ private String alias;
+ private int state;
+ private String[] urls;
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Bundle getBundle() {
+ return bundle;
+ }
+ public void setBundle(Bundle bundle) {
+ this.bundle = bundle;
+ }
+ public String getClassName() {
+ return className;
+ }
+ public void setClassName(String className) {
+ this.className = className;
+ }
+ public int getState() {
+ return state;
+ }
+ public void setState(int state) {
+ this.state = state;
+ }
+ public String getAlias() {
+ return alias;
+ }
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+ public String[] getUrls() {
+ return urls;
+ }
+ public void setUrls(String[] urls) {
+ this.urls = urls;
+ }
+
+ public String getStateString() {
+ switch (state) {
+ case WebEvent.DEPLOYING:
+ return "Deploying ";
+ case WebEvent.DEPLOYED:
+ return "Deployed ";
+ case WebEvent.UNDEPLOYING:
+ return "Undeploying";
+ case WebEvent.UNDEPLOYED:
+ return "Undeployed ";
+ case WebEvent.FAILED:
+ return "Failed ";
+ case WebEvent.WAITING:
+ return "Waiting ";
+ default:
+ return "Failed ";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/ServletService.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/ServletService.java b/http/src/main/java/org/apache/karaf/http/core/ServletService.java
new file mode 100644
index 0000000..fd9b24a
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/ServletService.java
@@ -0,0 +1,25 @@
+/*
+ * 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.http.core;
+
+import java.util.List;
+
+public interface ServletService {
+
+ List<ServletInfo> getServlets();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java b/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
new file mode 100644
index 0000000..563af61
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
@@ -0,0 +1,72 @@
+/*
+ * 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.http.core.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.management.MBeanException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.StandardMBean;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.karaf.http.core.HttpMBean;
+import org.apache.karaf.http.core.ServletInfo;
+import org.apache.karaf.http.core.ServletService;
+
+/**
+ * Implementation of the HTTP MBean.
+ */
+public class HttpMBeanImpl extends StandardMBean implements HttpMBean {
+ private ServletService servletService;
+
+ public HttpMBeanImpl(ServletService servletService) throws NotCompliantMBeanException {
+ super(HttpMBean.class);
+ this.servletService = servletService;
+ }
+
+ public TabularData getServlets() throws MBeanException {
+ try {
+ CompositeType servletType = new CompositeType("Servlet", "HTTP Servlet",
+ new String[]{"Bundle-ID", "Servlet", "Servlet Name", "State", "Alias", "URL"},
+ new String[]{"ID of the bundle that registered the servlet", "Class name of the servlet", "Servlet Name", "Current state of the servlet", "Aliases of the servlet", "URL of the servlet"},
+ new OpenType[]{SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
+ TabularType tableType = new TabularType("Servlets", "Table of all HTTP servlets", servletType, new String[]{"Bundle-ID", "Servlet Name", "State"});
+ TabularData table = new TabularDataSupport(tableType);
+ List<ServletInfo> servletInfos = servletService.getServlets();
+ for (ServletInfo info : servletInfos) {
+
+ CompositeData data = new CompositeDataSupport(servletType,
+ new String[]{"Bundle-ID", "Servlet", "Servlet Name", "State", "Alias", "URL"},
+ new Object[]{info.getBundle().getBundleId(), info.getClassName(), info.getName(), info.getStateString(), info.getAlias(), Arrays.toString(info.getUrls())});
+ table.put(data);
+
+ }
+ return table;
+ } catch (Exception e) {
+ throw new MBeanException(null, e.getMessage());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java b/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
new file mode 100644
index 0000000..2733175
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
@@ -0,0 +1,41 @@
+/*
+ * 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.http.core.internal;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ops4j.pax.web.service.spi.ServletEvent;
+import org.ops4j.pax.web.service.spi.ServletListener;
+
+public class ServletEventHandler implements ServletListener {
+
+ Map<String, ServletEvent> servletEvents = new HashMap<String, ServletEvent>();
+
+ public void servletEvent(ServletEvent event) {
+ servletEvents.put(event.getServletName(), event);
+ }
+
+ /**
+ * @return the servletEvents
+ */
+ public Collection<ServletEvent> getServletEvents() {
+ return servletEvents.values();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java b/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
new file mode 100644
index 0000000..8733ae4
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
@@ -0,0 +1,68 @@
+/*
+ * 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.http.core.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.Servlet;
+
+import org.apache.karaf.http.core.ServletInfo;
+import org.apache.karaf.http.core.ServletService;
+import org.ops4j.pax.web.service.spi.ServletEvent;
+
+public class ServletServiceImpl implements ServletService {
+ private ServletEventHandler servletEventHandler;
+
+ public ServletServiceImpl(ServletEventHandler servletEventHandler) {
+ this.servletEventHandler = servletEventHandler;
+ }
+
+ @Override
+ public List<ServletInfo> getServlets() {
+ List<ServletInfo> servletInfos = new ArrayList<ServletInfo>();
+ Collection<ServletEvent> events = servletEventHandler.getServletEvents();
+ for (ServletEvent event : events) {
+ Servlet servlet = event.getServlet();
+ String servletClassName = " ";
+ if (servlet != null) {
+ servletClassName = servlet.getClass().getName();
+ servletClassName = servletClassName.substring(servletClassName.lastIndexOf(".") + 1,
+ servletClassName.length());
+ }
+ String servletName = event.getServletName() != null ? event.getServletName() : " ";
+ if (servletName.contains(".")) {
+ servletName = servletName.substring(servletName.lastIndexOf(".") + 1, servletName.length());
+ }
+
+ String alias = event.getAlias() != null ? event.getAlias() : " ";
+
+ String[] urls = (String[])(event.getUrlParameter() != null ? event.getUrlParameter() : new String[] {""});
+ ServletInfo info = new ServletInfo();
+ info.setBundle(event.getBundle());
+ info.setName(servletName);
+ info.setClassName(servletClassName);
+ info.setState(event.getType());
+ info.setAlias(alias);
+ info.setUrls(urls);
+ servletInfos.add(info);
+ }
+ return servletInfos;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java b/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..a294229
--- /dev/null
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.http.core.internal.osgi;
+
+import org.apache.karaf.http.core.ServletService;
+import org.apache.karaf.http.core.internal.HttpMBeanImpl;
+import org.apache.karaf.http.core.internal.ServletEventHandler;
+import org.apache.karaf.http.core.internal.ServletServiceImpl;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.ops4j.pax.web.service.spi.ServletListener;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doStart() throws Exception {
+ ServletEventHandler servletEventHandler = new ServletEventHandler();
+ register(ServletListener.class, servletEventHandler);
+
+ ServletServiceImpl servletService = new ServletServiceImpl(servletEventHandler);
+ register(ServletService.class, servletService);
+
+ HttpMBeanImpl httpMBean = new HttpMBeanImpl(servletService);
+ registerMBean(httpMBean, "type=http");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/http/src/main/resources/OSGI-INF/bundle.info b/http/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..31222c7
--- /dev/null
+++ b/http/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,19 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+The http mbean management bundle exposes a HTTP MBean that can be used with any JMX client (for instance JConsole).
+
+The HTTP MBean allows quite the same actions that can be performed using http:* commands:
+ * list()
+
+h1. See also
+
+ * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/d5ce026b/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
----------------------------------------------------------------------
diff --git a/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java b/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
new file mode 100644
index 0000000..cb2f8fd
--- /dev/null
+++ b/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.http.core.internal;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+
+import org.junit.Test;
+
+public class HttpMBeanImplTest {
+
+ @Test
+ public void testRegisterMBean() throws Exception {
+ HttpMBeanImpl httpMBean = new HttpMBeanImpl(new ServletServiceImpl(new ServletEventHandler()));
+ MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+ mbeanServer.registerMBean(httpMBean, new ObjectName("org.apache.karaf:type=http,name=root"));
+
+ TabularData data = httpMBean.getServlets();
+ }
+}
[55/59] [abbrv] [KARAF-2852] Merge region/core and region/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
deleted file mode 100644
index f4d1352..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/FilterType.java
+++ /dev/null
@@ -1,195 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for filterType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="filterType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="bundle" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterBundleType" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="package" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterPackageType" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="namespace" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterNamespaceType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * <attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "filterType", propOrder = {
- "bundle",
- "_package",
- "namespace"
-})
-public class FilterType {
-
- protected List<FilterBundleType> bundle;
- @XmlElement(name = "package")
- protected List<FilterPackageType> _package;
- protected List<FilterNamespaceType> namespace;
- @XmlAttribute(required = true)
- protected String from;
- @XmlAttribute(required = true)
- protected String to;
-
- /**
- * Gets the value of the bundle property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the bundle property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getBundle().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterBundleType }
- *
- *
- */
- public List<FilterBundleType> getBundle() {
- if (bundle == null) {
- bundle = new ArrayList<FilterBundleType>();
- }
- return this.bundle;
- }
-
- /**
- * Gets the value of the package property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the package property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getPackage().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterPackageType }
- *
- *
- */
- public List<FilterPackageType> getPackage() {
- if (_package == null) {
- _package = new ArrayList<FilterPackageType>();
- }
- return this._package;
- }
-
- /**
- * Gets the value of the namespace property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the namespace property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getNamespace().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterNamespaceType }
- *
- *
- */
- public List<FilterNamespaceType> getNamespace() {
- if (namespace == null) {
- namespace = new ArrayList<FilterNamespaceType>();
- }
- return this.namespace;
- }
-
- /**
- * Gets the value of the from property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getFrom() {
- return from;
- }
-
- /**
- * Sets the value of the from property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setFrom(String value) {
- this.from = value;
- }
-
- /**
- * Gets the value of the to property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getTo() {
- return to;
- }
-
- /**
- * Sets the value of the to property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setTo(String value) {
- this.to = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
deleted file mode 100644
index 54f5f3c..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/ObjectFactory.java
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.annotation.XmlElementDecl;
-import javax.xml.bind.annotation.XmlRegistry;
-import javax.xml.namespace.QName;
-
-
-/**
- * This object contains factory methods for each
- * Java content interface and Java element interface
- * generated in the org.apache.karaf.region.persist.internal.model package.
- * <p>An ObjectFactory allows you to programatically
- * construct new instances of the Java representation
- * for XML content. The Java representation of XML
- * content can consist of schema derived interfaces
- * and classes representing the binding of schema
- * type definitions, element declarations and model
- * groups. Factory methods for each of these are
- * provided in this class.
- *
- */
-@XmlRegistry
-public class ObjectFactory {
-
- private final static QName _Regions_QNAME = new QName("http://karaf.apache.org/xmlns/region/v1.0.0", "regions");
-
- /**
- * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.karaf.region.persist.internal.model
- *
- */
- public ObjectFactory() {
- }
-
- /**
- * Create an instance of {@link FilterNamespaceType }
- *
- */
- public FilterNamespaceType createFilterNamespaceType() {
- return new FilterNamespaceType();
- }
-
- /**
- * Create an instance of {@link FilterType }
- *
- */
- public FilterType createFilterType() {
- return new FilterType();
- }
-
- /**
- * Create an instance of {@link RegionBundleType }
- *
- */
- public RegionBundleType createRegionBundleType() {
- return new RegionBundleType();
- }
-
- /**
- * Create an instance of {@link FilterBundleType }
- *
- */
- public FilterBundleType createFilterBundleType() {
- return new FilterBundleType();
- }
-
- /**
- * Create an instance of {@link FilterPackageType }
- *
- */
- public FilterPackageType createFilterPackageType() {
- return new FilterPackageType();
- }
-
- /**
- * Create an instance of {@link FilterAttributeType }
- *
- */
- public FilterAttributeType createFilterAttributeType() {
- return new FilterAttributeType();
- }
-
- /**
- * Create an instance of {@link RegionType }
- *
- */
- public RegionType createRegionType() {
- return new RegionType();
- }
-
- /**
- * Create an instance of {@link RegionsType }
- *
- */
- public RegionsType createRegionsType() {
- return new RegionsType();
- }
-
- /**
- * Create an instance of {@link JAXBElement }{@code <}{@link RegionsType }{@code >}}
- *
- */
- @XmlElementDecl(namespace = "http://karaf.apache.org/xmlns/region/v1.0.0", name = "regions")
- public JAXBElement<RegionsType> createRegions(RegionsType value) {
- return new JAXBElement<RegionsType>(_Regions_QNAME, RegionsType.class, null, value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
deleted file mode 100644
index 7ba3585..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionBundleType.java
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- * <p>Java class for regionBundleType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="regionBundleType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * </sequence>
- * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}long" />
- * <attribute name="location" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "regionBundleType")
-public class RegionBundleType {
-
- @XmlAttribute
- protected Long id;
- @XmlAttribute
- protected String location;
-
- /**
- * Gets the value of the id property.
- *
- * @return
- * possible object is
- * {@link Long }
- *
- */
- public Long getId() {
- return id;
- }
-
- /**
- * Sets the value of the id property.
- *
- * @param value
- * allowed object is
- * {@link Long }
- *
- */
- public void setId(Long value) {
- this.id = value;
- }
-
- /**
- * Gets the value of the location property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getLocation() {
- return location;
- }
-
- /**
- * Sets the value of the location property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setLocation(String value) {
- this.location = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
deleted file mode 100644
index f7a810d..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionType.java
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- *
- * Regions element
- *
- *
- * <p>Java class for regionType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="regionType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="bundle" type="{http://karaf.apache.org/xmlns/region/v1.0.0}regionBundleType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "regionType", propOrder = {
- "bundle"
-})
-public class RegionType {
-
- protected List<RegionBundleType> bundle;
- @XmlAttribute(required = true)
- protected String name;
-
- /**
- * Gets the value of the bundle property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the bundle property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getBundle().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link RegionBundleType }
- *
- *
- */
- public List<RegionBundleType> getBundle() {
- if (bundle == null) {
- bundle = new ArrayList<RegionBundleType>();
- }
- return this.bundle;
- }
-
- /**
- * Gets the value of the name property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the value of the name property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setName(String value) {
- this.name = value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
deleted file mode 100644
index be172e4..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/RegionsType.java
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-
-package org.apache.karaf.region.persist.internal.model;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-
-/**
- *
- * Regions element
- *
- *
- * <p>Java class for regionsType complex type.
- *
- * <p>The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * <complexType name="regionsType">
- * <complexContent>
- * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * <sequence>
- * <element name="region" type="{http://karaf.apache.org/xmlns/region/v1.0.0}regionType" maxOccurs="unbounded" minOccurs="0"/>
- * <element name="filter" type="{http://karaf.apache.org/xmlns/region/v1.0.0}filterType" maxOccurs="unbounded" minOccurs="0"/>
- * </sequence>
- * </restriction>
- * </complexContent>
- * </complexType>
- * </pre>
- *
- *
- */
-@XmlRootElement(name = "regions")
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "regionsType", propOrder = {
- "region",
- "filter"
-})
-public class RegionsType {
-
- protected List<RegionType> region;
- protected List<FilterType> filter;
-
- /**
- * Gets the value of the region property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the region property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getRegion().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link RegionType }
- *
- *
- */
- public List<RegionType> getRegion() {
- if (region == null) {
- region = new ArrayList<RegionType>();
- }
- return this.region;
- }
-
- /**
- * Gets the value of the filter property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the filter property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- * <pre>
- * getFilter().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link FilterType }
- *
- *
- */
- public List<FilterType> getFilter() {
- if (filter == null) {
- filter = new ArrayList<FilterType>();
- }
- return this.filter;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
deleted file mode 100644
index cae062c..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/model/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2011.10.28 at 03:20:55 PM PDT
-//
-
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://karaf.apache.org/xmlns/region/v1.0.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
-package org.apache.karaf.region.persist.internal.model;
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
deleted file mode 100644
index 410121c..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderProcessor.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * 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.region.persist.internal.util;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.osgi.framework.Constants;
-
-public class ManifestHeaderProcessor
-{
- public static final String NESTED_FILTER_ATTRIBUTE = "org.apache.aries.application.filter.attribute";
- private static final Pattern FILTER_ATTR = Pattern.compile("(\\(!)?\\((.*?)([<>]?=)(.*?)\\)\\)?");
- private static final String LESS_EQ_OP = "<=";
- private static final String GREATER_EQ_OP = ">=";
-
- /**
- * A simple class to associate two types.
- *
- */
- public static class NameValuePair {
- private String name;
- private Map<String,String> attributes;
-
- public NameValuePair(String name, Map<String,String> value)
- {
- this.name = name;
- this.attributes = value;
- }
- public String getName()
- {
- return name;
- }
- public void setName(String name)
- {
- this.name = name;
- }
-
- public Map<String,String> getAttributes()
- {
- return attributes;
- }
- public void setAttributes(Map<String,String> value)
- {
- this.attributes = value;
- }
-
- @Override
- public String toString(){
- return "{"+name.toString()+"::"+attributes.toString()+"}";
- }
- @Override
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- final NameValuePair other = (NameValuePair) obj;
- if (name == null) {
- if (other.name != null) return false;
- } else if (!name.equals(other.name)) return false;
- if (attributes == null) {
- if (other.attributes != null) return false;
- } else if (!attributes.equals(other.attributes)) return false;
- return true;
- }
- }
-
- /**
- * Intended to provide a standard way to add Name/Value's to
- * aggregations of Name/Value's.
- *
- */
- public static interface NameValueCollection {
- /**
- * Add this Name & Value to the collection.
- * @param n
- * @param v
- */
- public void addToCollection(String n, Map<String,String> v);
- }
-
- /**
- * Map of Name -> Value.
- *
- */
- public static class NameValueMap extends HashMap<String, Map<String,String>> implements NameValueCollection, Map<String, Map<String,String>>{
- private static final long serialVersionUID = -6446338858542599141L;
-
- public void addToCollection(String n, Map<String,String> v){
- this.put(n,v);
- }
-
- @Override
- public String toString(){
- StringBuilder sb = new StringBuilder();
- sb.append("{");
- boolean first=true;
- for(Map.Entry<String, Map<String,String>> entry : this.entrySet()){
- if(!first)sb.append(",");
- first=false;
- sb.append(entry.getKey()+"->"+entry.getValue());
- }
- sb.append("}");
- return sb.toString();
- }
- }
-
- /**
- * List of Name/Value
- *
- */
- public static class NameValueList extends ArrayList<NameValuePair> implements NameValueCollection, List<NameValuePair> {
- private static final long serialVersionUID = 1808636823825029983L;
-
- public void addToCollection(String n, Map<String,String> v){
- this.add(new NameValuePair(n,v));
- }
- @Override
- public String toString(){
- StringBuffer sb = new StringBuffer();
- sb.append("{");
- boolean first = true;
- for(NameValuePair nvp : this){
- if(!first)sb.append(",");
- first=false;
- sb.append(nvp.toString());
- }
- sb.append("}");
- return sb.toString();
- }
- }
-
- /**
- *
- * Splits a delimiter separated string, tolerating presence of non separator commas
- * within double quoted segments.
- *
- * Eg.
- * com.ibm.ws.eba.helloWorldService;version="[1.0.0, 1.0.0]" &
- * com.ibm.ws.eba.helloWorldService;version="1.0.0"
- * com.ibm.ws.eba.helloWorld;version="2";bundle-version="[2,30)"
- * com.acme.foo;weirdAttr="one;two;three";weirdDir:="1;2;3"
- * @param value the value to be split
- * @param delimiter the delimiter string such as ',' etc.
- * @return List<String> the components of the split String in a list
- */
- public static List<String> split(String value, String delimiter)
- {
- return ManifestHeaderUtils.split(value, delimiter);
- }
-
-
- /**
- * Internal method to parse headers with the format<p>
- * [Name](;[Name])*(;[attribute-name]=[attribute-value])*<br>
- * Eg.<br>
- * rumplestiltskin;thing=value;other=something<br>
- * littleredridinghood
- * bundle1;bundle2;other=things
- * bundle1;bundle2
- *
- * @param s data to parse
- * @return a list of NameValuePair, with the Name being the name component,
- * and the Value being a NameValueMap of key->value mappings.
- */
- private static List<NameValuePair> genericNameWithNameValuePairProcess(String s){
- String name;
- Map<String,String> params = null;
- List<NameValuePair> nameValues = new ArrayList<NameValuePair>();
- List<String> pkgs = new ArrayList<String>();
- int index = s.indexOf(";");
- if(index==-1){
- name = s;
- params = new HashMap<String, String>();
- pkgs.add(name);
- }else{
- name = s.substring(0,index).trim();
- String tail = s.substring(index+1).trim();
-
- pkgs.add(name); // add the first package
- StringBuilder parameters = new StringBuilder();
-
-
- // take into consideration of multiple packages separated by ';'
- // while they share the same attributes or directives
- List<String> tailParts = split(tail, ";");
- boolean firstParameter =false;
-
- for (String part : tailParts) {
- // if it is not a parameter and no parameter appears in front of it, it must a package
- if (!!!(part.contains("="))) {
- // Need to make sure no parameter appears before the package, otherwise ignore this string
- // as this syntax is invalid
- if (!!!(firstParameter))
- pkgs.add(part);
- } else {
- if (!!!(firstParameter))
- firstParameter = true;
-
- parameters.append(part + ";");
- }
- }
-
- if (parameters.length() != 0) {
- //remove the final ';' if there is one
- if (parameters.toString().endsWith(";")) {
-
- parameters = parameters.deleteCharAt(parameters.length() -1);
- }
-
- params = genericNameValueProcess(parameters.toString());
- }
-
- }
- for (String pkg : pkgs) {
- nameValues.add(new NameValuePair(pkg,params));
- }
-
- return nameValues;
-
- }
-
- /**
- * Internal method to parse headers with the format<p>
- * [attribute-name]=[attribute-value](;[attribute-name]=[attribute-value])*<br>
- * Eg.<br>
- * thing=value;other=something<br>
- * <p>
- * Note. Directives (name:=value) are represented in the map with name suffixed by ':'
- *
- * @param s data to parse
- * @return a NameValueMap, with attribute-name -> attribute-value.
- */
- private static Map<String,String> genericNameValueProcess(String s){
- Map<String,String> params = new HashMap<String,String>();
- List<String> parameters = split(s, ";");
- for(String parameter : parameters) {
- List<String> parts = split(parameter,"=");
- // do a check, otherwise we might get NPE
- if (parts.size() ==2) {
- String second = parts.get(1).trim();
- if (second.startsWith("\"") && second.endsWith("\""))
- second = second.substring(1,second.length()-1);
-
- String first = parts.get(0).trim();
-
- // make sure for directives we clear out any space as in "directive :=value"
- if (first.endsWith(":")) {
- first = first.substring(0, first.length()-1).trim()+":";
- }
-
- params.put(first, second);
- }
- }
-
- return params;
- }
-
- /**
- * Processes an import/export style header.. <p>
- * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
- *
- * @param out The collection to add each package name + attrib map to.
- * @param s The data to parse
- */
- private static void genericImportExportProcess(NameValueCollection out, String s){
- List<String> packages = split(s, ",");
- for(String pkg : packages){
- List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
- for (NameValuePair p : ps) {
- out.addToCollection(p.getName(), p.getAttributes());
- }
- }
- }
-
- /**
- * Parse an export style header.<p>
- * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value2
- * <p>
- * Result is returned as a list, as export does allow duplicate package exports.
- *
- * @param s The data to parse.
- * @return List of NameValuePairs, where each Name in the list is an exported package,
- * with its associated Value being a NameValueMap of any attributes declared.
- */
- public static List<NameValuePair> parseExportString(String s){
- NameValueList retval = new NameValueList();
- genericImportExportProcess(retval, s);
- return retval;
- }
-
- /**
- * Parse an export style header in a list.<p>
- * pkg1;attrib=value;attrib=value
- * pkg2;attrib=value
- * pkg3;attrib=value2
- * <p>
- * Result is returned as a list, as export does allow duplicate package exports.
- *
- * @param list The data to parse.
- * @return List of NameValuePairs, where each Name in the list is an exported package,
- * with its associated Value being a NameValueMap of any attributes declared.
- */
- public static List<NameValuePair> parseExportList(List<String> list){
- NameValueList retval = new NameValueList();
- for(String pkg : list){
- List<NameValuePair> ps = genericNameWithNameValuePairProcess(pkg);
- for (NameValuePair p : ps) {
- retval.addToCollection(p.getName(), p.getAttributes());
- }
- }
- return retval;
- }
-
- /**
- * Parse an import style header.<p>
- * pkg1;attrib=value;attrib=value,pkg2;attrib=value,pkg3;attrib=value
- * <p>
- * Result is returned as a set, as import does not allow duplicate package imports.
- *
- * @param s The data to parse.
- * @return Map of NameValuePairs, where each Key in the Map is an imported package,
- * with its associated Value being a NameValueMap of any attributes declared.
- */
- public static Map<String, Map<String, String>> parseImportString(String s){
- NameValueMap retval = new NameValueMap();
- genericImportExportProcess(retval, s);
- return retval;
- }
-
- /**
- * Parse a bundle symbolic name.<p>
- * bundlesymbolicname;attrib=value;attrib=value
- * <p>
- *
- * @param s The data to parse.
- * @return NameValuePair with Name being the BundleSymbolicName,
- * and Value being any attribs declared for the name.
- */
- public static NameValuePair parseBundleSymbolicName(String s){
- return genericNameWithNameValuePairProcess(s).get(0); // should just return the first one
- }
-
- /**
- * Parse a version range..
- *
- * @param s
- * @return VersionRange object.
- * @throws IllegalArgumentException if the String could not be parsed as a VersionRange
- */
- public static VersionRange parseVersionRange(String s) throws IllegalArgumentException{
- return new VersionRange(s);
- }
-
- /**
- * Parse a version range and indicate if the version is an exact version
- *
- * @param s
- * @param exactVersion
- * @return VersionRange object.
- * @throws IllegalArgumentException if the String could not be parsed as a VersionRange
- */
- public static VersionRange parseVersionRange(String s, boolean exactVersion) throws IllegalArgumentException{
- return new VersionRange(s, exactVersion);
- }
-
- /**
- * Generate a filter from a set of attributes. This filter will be suitable
- * for presentation to OBR This means that, due to the way OBR works, it
- * will include a stanza of the form, (mandatory:<*mandatoryAttribute)
- * Filter strings generated by this method will therefore tend to break the
- * standard OSGi Filter class. The OBR stanza can be stripped out later if
- * required.
- *
- * @param attribs
- * @return filter string
- */
- public static String generateFilter(Map<String, Object> attribs) {
- StringBuilder filter = new StringBuilder("(&");
- boolean realAttrib = false;
- StringBuffer realAttribs = new StringBuffer();
-
- if (attribs == null) {
- attribs = new HashMap<String, Object>();
- }
-
- for (Map.Entry<String, Object> attrib : attribs.entrySet()) {
- String attribName = attrib.getKey();
-
- if (attribName.endsWith(":")) {
- // skip all directives. It is used to affect the attribs on the
- // filter xml.
- } else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
- || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
- // version and bundle-version attrib requires special
- // conversion.
- realAttrib = true;
-
- VersionRange vr = ManifestHeaderProcessor
- .parseVersionRange(attrib.getValue().toString());
-
- filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
-
- if (vr.getMaximumVersion() != null) {
- filter.append(")(" + attribName + "<=");
- filter.append(vr.getMaximumVersion());
- }
-
- if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
- filter.append(")(!(" + attribName + "=");
- filter.append(vr.getMinimumVersion());
- filter.append(")");
- }
-
- if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
- filter.append(")(!(" + attribName + "=");
- filter.append(vr.getMaximumVersion());
- filter.append(")");
- }
- filter.append(")");
-
- } else if (NESTED_FILTER_ATTRIBUTE.equals(attribName)) {
- // Filters go in whole, no formatting needed
- realAttrib = true;
- filter.append(attrib.getValue());
-
- } else if (Constants.OBJECTCLASS.equals(attribName)) {
- realAttrib = true;
- // objectClass has a "," separated list of interfaces
- String[] values = attrib.getValue().toString().split(",");
- for (String s : values)
- filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
-
- } else {
- // attribName was not version..
- realAttrib = true;
-
- filter.append("(" + attribName + "=" + attrib.getValue() + ")");
- // store all attributes in order to build up the mandatory
- // filter and separate them with ", "
- // skip bundle-symbolic-name in the mandatory directive query
- if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
- .equals(attribName)) {
- realAttribs.append(attribName);
- realAttribs.append(", ");
- }
- }
- }
-// /*
-// * The following is how OBR makes mandatory attributes work, we require
-// * that the set of mandatory attributes on the export is a subset of (or
-// * equal to) the set of the attributes we supply.
-// */
-//
-// if (realAttribs.length() > 0) {
-// String attribStr = (realAttribs.toString()).trim();
-// // remove the final ,
-// if ((attribStr.length() > 0) && (attribStr.endsWith(","))) {
-// attribStr = attribStr.substring(0, attribStr.length() - 1);
-// }
-// // build the mandatory filter, e.g.(mandatory:<*company, local)
-// filter.append("(" + Constants.MANDATORY_DIRECTIVE + ":" + "<*"
-// + attribStr + ")");
-// }
-
- // Prune (& off the front and ) off end
- String filterString = filter.toString();
- int openBraces = 0;
- for (int i = 0; openBraces < 3; i++) {
- i = filterString.indexOf('(', i);
- if (i == -1) {
- break;
- } else {
- openBraces++;
- }
- }
- if (openBraces < 3 && filterString.length() > 2) {
- filter.delete(0, 2);
- } else {
- filter.append(")");
- }
-
- String result = "";
- if (realAttrib != false) {
- result = filter.toString();
- }
- return result;
- }
-
- /**
- * Generate a filter from a set of attributes. This filter will be suitable
- * for presentation to OBR. This means that, due to the way OBR works, it will
- * include a stanza of the form, (mandatory:<*mandatoryAttribute) Filter
- * strings generated by this method will therefore tend to break the standard
- * OSGi Filter class. The OBR stanza can be stripped out later if required.
- *
- * We may wish to consider relocating this method since VersionRange has its
- * own top level class.
- *
- * @param type
- * @param name
- * @param attribs
- * @return filter string
- */
- public static String generateFilter(String type, String name,
- Map<String, Object> attribs) {
- StringBuffer filter = new StringBuffer();
- String result;
- // shortcut for the simple case with no attribs.
-
- if (attribs == null || attribs.isEmpty())
- filter.append("(" + type + "=" + name + ")");
- else {
- // process all the attribs passed.
- // find out whether there are attributes on the filter
-
- filter.append("(&(" + type + "=" + name + ")");
-
- String filterString = generateFilter(attribs);
-
- int start = 0;
- int end = filterString.length();
- if (filterString.startsWith("(&")) {
- start = 2;
- end--;
- }
-
- if ("".equals(filterString)) {
- filter.delete(0, 2);
- } else {
- filter.append(filterString, start, end);
- filter.append(")");
- }
- }
-
- result = filter.toString();
-
- return result;
- }
-
- private static Map<String, String> parseFilterList(String filter) {
-
- Map<String, String> result = new HashMap<String, String>();
- Set<String> negatedVersions = new HashSet<String>();
- Set<String> negatedBundleVersions = new HashSet<String>();
-
- String lowerVersion = null;
- String upperVersion = null;
- String lowerBundleVersion = null;
- String upperBundleVersion = null;
-
- Matcher m = FILTER_ATTR.matcher(filter);
- while (m.find()) {
- boolean negation = m.group(1) != null;
- String attr = m.group(2);
- String op = m.group(3);
- String value = m.group(4);
-
- if (Constants.VERSION_ATTRIBUTE.equals(attr)) {
- if (negation) {
- negatedVersions.add(value);
- } else {
- if (GREATER_EQ_OP.equals(op))
- lowerVersion = value;
- else if (LESS_EQ_OP.equals(op))
- upperVersion = value;
- else
- throw new IllegalArgumentException();
- }
- } else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attr)) {
- // bundle-version is like version, but may be specified at the
- // same time
- // therefore we have similar code with separate variables
- if (negation) {
- negatedBundleVersions.add(value);
- } else {
- if (GREATER_EQ_OP.equals(op))
- lowerBundleVersion = value;
- else if (LESS_EQ_OP.equals(op))
- upperBundleVersion = value;
- else
- throw new IllegalArgumentException();
- }
- } else {
- result.put(attr, value);
- }
- }
-
- if (lowerVersion != null) {
- StringBuilder versionAttr = new StringBuilder(lowerVersion);
- if (upperVersion != null) {
- versionAttr.append(",").append(upperVersion).insert(0,
- negatedVersions.contains(lowerVersion) ? '(' : '[').append(
- negatedVersions.contains(upperVersion) ? ')' : ']');
- }
-
- result.put(Constants.VERSION_ATTRIBUTE, versionAttr.toString());
- }
- // Do it again for bundle-version
- if (lowerBundleVersion != null) {
- StringBuilder versionAttr = new StringBuilder(lowerBundleVersion);
- if (upperBundleVersion != null) {
- versionAttr.append(",").append(upperBundleVersion).insert(0,
- negatedBundleVersions.contains(lowerBundleVersion) ? '(' : '[')
- .append(
- negatedBundleVersions.contains(upperBundleVersion) ? ')' : ']');
- }
-
- result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, versionAttr.toString());
- }
-
- return result;
- }
-
- public static Map<String,String> parseFilter(String filter)
- {
- Map<String,String> result;
- if (filter.startsWith("(&")) {
- result = parseFilterList(filter.substring(2, filter.length()-1));
- } else {
- result = parseFilterList(filter);
- }
- return result;
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
deleted file mode 100644
index 8c87616..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/ManifestHeaderUtils.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.region.persist.internal.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ManifestHeaderUtils {
-
- /**
- *
- * Splits a delimiter separated string, tolerating presence of non separator commas
- * within double quoted segments.
- *
- * Eg.
- * com.ibm.ws.eba.helloWorldService;version="[1.0.0, 1.0.0]" &
- * com.ibm.ws.eba.helloWorldService;version="1.0.0"
- * com.ibm.ws.eba.helloWorld;version="2";bundle-version="[2,30)"
- * com.acme.foo;weirdAttr="one;two;three";weirdDir:="1;2;3"
- * @param value the value to be split
- * @param delimiter the delimiter string such as ',' etc.
- * @return List<String> the components of the split String in a list
- */
- public static List<String> split(String value, String delimiter)
- {
- List<String> result = new ArrayList<String>();
- if (value != null) {
- String[] packages = value.split(delimiter);
-
- for (int i = 0; i < packages.length; ) {
- String tmp = packages[i++].trim();
- // if there is a odd number of " in a string, we need to append
- while (count(tmp, "\"") % 2 != 0) {
- // check to see if we need to append the next package[i++]
- if (i<packages.length)
- tmp = tmp + delimiter + packages[i++].trim();
- else
- // oops. The double quotes are not paired up. We have reached to the end of the string.
- throw new IllegalArgumentException("Unmatched double quotes: " + tmp);
- }
-
- result.add(tmp);
-
- }
- }
- return result;
- }
-
- /**
- * count the number of characters in a string
- * @param parent The string to be searched
- * @param subString The substring to be found
- * @return the number of occurrence of the subString
- */
- private static int count(String parent, String subString) {
-
- int count = 0 ;
- int i = parent.indexOf(subString);
- while (i > -1) {
- if (parent.length() >= i+1)
- parent = parent.substring(i+1);
- count ++;
- i = parent.indexOf(subString);
- }
- return count;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
----------------------------------------------------------------------
diff --git a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java b/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
deleted file mode 100644
index 19bbc77..0000000
--- a/region/core/src/main/java/org/apache/karaf/region/persist/internal/util/VersionRange.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * 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.region.persist.internal.util;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.osgi.framework.Version;
-
-public final class VersionRange {
-
- /** A string representation of the version. */
- private String version;
-
- /** The minimum desired version for the bundle */
- private Version minimumVersion;
-
- /** The maximum desired version for the bundle */
- private Version maximumVersion;
-
- /** True if the match is exclusive of the minimum version */
- private boolean minimumExclusive;
-
- /** True if the match is exclusive of the maximum version */
- private boolean maximumExclusive;
-
- /** A regexp to select the version */
- private static final Pattern versionCapture = Pattern.compile("\"?(.*?)\"?$");
-
- /**
- *
- * @param version
- * version for the verioninfo
- */
- public VersionRange(String version) {
- this.version = version;
- processVersionAttribute(version);
- }
-
- /**
- * This method should be used to create a version range from a single
- * version string.
- * @param version
- * version for the versioninfo
- * @param exactVersion
- * whether this is an exact version {@code true} or goes to infinity
- * {@code false}
- */
- public VersionRange(String version, boolean exactVersion) {
-
- if (exactVersion) {
- // Do not store this string as it might be just a version, or a range!
- processExactVersionAttribute(version);
- } else {
- this.version = version;
- processVersionAttribute(this.version);
- }
-
- assertInvariants();
- }
-
- /**
- * Constructor designed for internal use only.
- *
- * @param maximumVersion
- * @param maximumExclusive
- * @param minimumVersion
- * @param minimumExclusive
- * @throws IllegalArgumentException
- * if parameters are not valid.
- */
- private VersionRange(Version maximumVersion,
- boolean maximumExclusive,
- Version minimumVersion,
- boolean minimumExclusive) {
- this.maximumVersion = maximumVersion;
- this.maximumExclusive = maximumExclusive;
- this.minimumVersion = minimumVersion;
- this.minimumExclusive = minimumExclusive;
-
- assertInvariants();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.aries.application.impl.VersionRange#toString()
- */
- @Override
- public String toString() {
- // Some constructors don't take in a string that we can return directly,
- // so construct one if needed
- if (version == null) {
- if (maximumVersion == null) {
- version = minimumVersion.toString();
- } else {
- version = (minimumExclusive ? "(" : "[") + minimumVersion + "," + maximumVersion
- + (maximumExclusive ? ")" : "]");
- }
- }
- return this.version;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + minimumVersion.hashCode();
- result = 31 * result + (minimumExclusive ? 1 : 0);
- result = 31 * result + (maximumVersion != null ? maximumVersion.hashCode() : 0);
- result = 31 * result + (maximumExclusive ? 1 : 0);
- return result;
- }
-
- @Override
- public boolean equals(Object other) {
- boolean result = false;
- if (this == other) {
- result = true;
- } else if (other instanceof VersionRange) {
- VersionRange vr = (VersionRange) other;
- result = minimumVersion.equals(vr.minimumVersion)
- && minimumExclusive == vr.minimumExclusive
- && (maximumVersion == null ? vr.maximumVersion == null : maximumVersion
- .equals(vr.maximumVersion)) && maximumExclusive == vr.maximumExclusive;
- }
-
- return result;
- }
-
- /**
- * this method returns the exact version from the versionInfo obj.
- * this is used for DeploymentContent only to return a valid exact version
- * otherwise, null is returned.
- * @return the exact version
- */
- public Version getExactVersion() {
- Version v = null;
- if (isExactVersion()) {
- v = getMinimumVersion();
- }
- return v;
- }
-
- /**
- * get the maximum version
- * @return the maximum version
- */
- public Version getMaximumVersion() {
- return maximumVersion;
- }
-
- /**
- * get the minimum version
- * @return the minimum version
- */
- public Version getMinimumVersion() {
- return minimumVersion;
- }
-
- /**
- * is the maximum version exclusive
- * @return is the max version in the range.
- */
- public boolean isMaximumExclusive() {
- return maximumExclusive;
- }
-
- /**
- * is the maximum version unbounded
- * @return true if no upper bound was specified.
- */
- public boolean isMaximumUnbounded() {
- boolean unbounded = maximumVersion == null;
- return unbounded;
- }
-
- /**
- * is the minimum version exclusive
- * @return true if the min version is in range.
- */
- public boolean isMinimumExclusive() {
- return minimumExclusive;
- }
-
- /**
- * this is designed for deployed-version as that is the exact version.
- *
- * @param version
- * @return
- * @throws IllegalArgumentException
- */
- private boolean processExactVersionAttribute(String version) throws IllegalArgumentException {
- boolean success = processVersionAttribute(version);
-
- if (maximumVersion == null) {
- maximumVersion = minimumVersion;
- }
-
- if (!minimumVersion.equals(maximumVersion)) {
- throw new IllegalArgumentException("Version is not exact: " + version);
- }
-
- if (!!!isExactVersion()) {
- throw new IllegalArgumentException("Version is not exact: " + version);
- }
-
- return success;
- }
-
- /**
- * process the version attribute,
- *
- * @param version
- * the value to be processed
- * @return
- * @throws IllegalArgumentException
- */
- private boolean processVersionAttribute(String version) throws IllegalArgumentException {
- boolean success = false;
-
- if (version == null) {
- throw new IllegalArgumentException("Version is null");
- }
-
- Matcher matches = versionCapture.matcher(version);
-
- if (matches.matches()) {
- String versions = matches.group(1);
-
- if ((versions.startsWith("[") || versions.startsWith("("))
- && (versions.endsWith("]") || versions.endsWith(")"))) {
- if (versions.startsWith("["))
- minimumExclusive = false;
- else if (versions.startsWith("("))
- minimumExclusive = true;
-
- if (versions.endsWith("]"))
- maximumExclusive = false;
- else if (versions.endsWith(")"))
- maximumExclusive = true;
-
- int index = versions.indexOf(',');
- String minVersion = versions.substring(1, index);
- String maxVersion = versions.substring(index + 1, versions.length() - 1);
-
- try {
- minimumVersion = new Version(minVersion.trim());
- maximumVersion = new Version(maxVersion.trim());
- success = true;
- } catch (NumberFormatException nfe) {
- throw new IllegalArgumentException("Version cannot be decoded: " + version, nfe);
- }
- } else {
- try {
- if (versions.trim().length() == 0)
- minimumVersion = new Version(0, 0, 0);
- else
- minimumVersion = new Version(versions.trim());
- success = true;
- } catch (NumberFormatException nfe) {
- throw new IllegalArgumentException("Version cannot be decoded: " + version, nfe);
- }
- }
- } else {
- throw new IllegalArgumentException("Version cannot be decoded: " + version);
- }
-
- return success;
- }
-
- /**
- * Assert object invariants. Called by constructors to verify that arguments
- * were valid.
- *
- * @throws IllegalArgumentException
- * if invariants are violated.
- */
- private void assertInvariants() {
- if (minimumVersion == null
- || !isRangeValid(minimumVersion, minimumExclusive, maximumVersion, maximumExclusive)) {
- IllegalArgumentException e = new IllegalArgumentException();
- throw e;
- }
- }
-
- /**
- * Check if the supplied parameters describe a valid version range.
- *
- * @param min
- * the minimum version.
- * @param minExclusive
- * whether the minimum version is exclusive.
- * @param max
- * the maximum version.
- * @param maxExclusive
- * whether the maximum version is exclusive.
- * @return true is the range is valid; otherwise false.
- */
- private boolean isRangeValid(Version min,
- boolean minExclusive,
- Version max,
- boolean maxExclusive) {
- boolean result;
-
- // A null maximum version is unbounded so means that minimum is smaller
- // than
- // maximum.
- int minMaxCompare = (max == null ? -1 : min.compareTo(max));
- if (minMaxCompare > 0) {
- // Minimum larger than maximum is invalid.
- result = false;
- } else if (minMaxCompare == 0 && (minExclusive || maxExclusive)) {
- // If min and max are the same, and either are exclusive, no valid
- // range
- // exists.
- result = false;
- } else {
- // Range is valid.
- result = true;
- }
-
- return result;
- }
-
- /**
- * This method checks that the provided version matches the desired version.
- *
- * @param version
- * the version.
- * @return true if the version matches, false otherwise.
- */
- public boolean matches(Version version) {
- boolean result;
- if (this.getMaximumVersion() == null) {
- result = this.getMinimumVersion().compareTo(version) <= 0;
- } else {
- int minN = this.isMinimumExclusive() ? 0 : 1;
- int maxN = this.isMaximumExclusive() ? 0 : 1;
-
- result = (this.getMinimumVersion().compareTo(version) < minN)
- && (version.compareTo(this.getMaximumVersion()) < maxN);
- }
- return result;
- }
-
- /**
- * check if the versioninfo is the exact version
- * @return true if the range will match 1 exact version.
- */
- public boolean isExactVersion() {
- return minimumVersion.equals(maximumVersion) && minimumExclusive == maximumExclusive
- && !!!minimumExclusive;
- }
-
- /**
- * Create a new version range that is the intersection of {@code this} and the argument.
- * In other words, the largest version range that lies within both {@code this} and
- * the parameter.
- * @param r a version range to be intersected with {@code this}.
- * @return a new version range, or {@code null} if no intersection is possible.
- */
- public VersionRange intersect(VersionRange r) {
- // Use the highest minimum version.
- final Version newMinimumVersion;
- final boolean newMinimumExclusive;
- int minCompare = minimumVersion.compareTo(r.getMinimumVersion());
- if (minCompare > 0) {
- newMinimumVersion = minimumVersion;
- newMinimumExclusive = minimumExclusive;
- } else if (minCompare < 0) {
- newMinimumVersion = r.getMinimumVersion();
- newMinimumExclusive = r.isMinimumExclusive();
- } else {
- newMinimumVersion = minimumVersion;
- newMinimumExclusive = (minimumExclusive || r.isMinimumExclusive());
- }
-
- // Use the lowest maximum version.
- final Version newMaximumVersion;
- final boolean newMaximumExclusive;
- // null maximum version means unbounded, so the highest possible value.
- if (maximumVersion == null) {
- newMaximumVersion = r.getMaximumVersion();
- newMaximumExclusive = r.isMaximumExclusive();
- } else if (r.getMaximumVersion() == null) {
- newMaximumVersion = maximumVersion;
- newMaximumExclusive = maximumExclusive;
- } else {
- int maxCompare = maximumVersion.compareTo(r.getMaximumVersion());
- if (maxCompare < 0) {
- newMaximumVersion = maximumVersion;
- newMaximumExclusive = maximumExclusive;
- } else if (maxCompare > 0) {
- newMaximumVersion = r.getMaximumVersion();
- newMaximumExclusive = r.isMaximumExclusive();
- } else {
- newMaximumVersion = maximumVersion;
- newMaximumExclusive = (maximumExclusive || r.isMaximumExclusive());
- }
- }
-
- VersionRange result;
- if (isRangeValid(newMinimumVersion, newMinimumExclusive, newMaximumVersion,
- newMaximumExclusive)) {
- result = new VersionRange(newMaximumVersion, newMaximumExclusive, newMinimumVersion,
- newMinimumExclusive);
- } else {
- result = null;
- }
- return result;
- }
-
- /**
- * Parse a version range..
- *
- * @param s
- * @return VersionRange object.
- * @throws IllegalArgumentException
- * if the String could not be parsed as a VersionRange
- */
- public static VersionRange parseVersionRange(String s) throws IllegalArgumentException {
- return new VersionRange(s);
- }
-
- /**
- * Parse a version range and indicate if the version is an exact version
- *
- * @param s
- * @param exactVersion
- * @return VersionRange object.
- * @throws IllegalArgumentException
- * if the String could not be parsed as a VersionRange
- */
- public static VersionRange parseVersionRange(String s, boolean exactVersion)
- throws IllegalArgumentException {
- return new VersionRange(s, exactVersion);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/core/src/main/resources/org/apache/karaf/region/persist/region.xsd
----------------------------------------------------------------------
diff --git a/region/core/src/main/resources/org/apache/karaf/region/persist/region.xsd b/region/core/src/main/resources/org/apache/karaf/region/persist/region.xsd
deleted file mode 100644
index 8ca26e7..0000000
--- a/region/core/src/main/resources/org/apache/karaf/region/persist/region.xsd
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<!-- $Rev$ $Date$ -->
-
-<xsd:schema xmlns="http://karaf.apache.org/xmlns/region/v1.0.0"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://karaf.apache.org/xmlns/region/v1.0.0"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified">
-
-
- <xsd:annotation>
- <xsd:documentation>
- Defines the configuration elements for Apache Karaf region xml configuration.
- </xsd:documentation>
- </xsd:annotation>
-
- <xsd:element name="regions" type="regionsType"/>
-
-
- <xsd:complexType name="regionsType">
- <xsd:annotation>
- <xsd:documentation>
- Regions element
- </xsd:documentation>
- </xsd:annotation>
- <xsd:sequence>
- <xsd:element name="region" type="regionType" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="filter" type="filterType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
-
- <xsd:complexType name="regionType">
- <xsd:annotation>
- <xsd:documentation>
- Region element
- </xsd:documentation>
- </xsd:annotation>
- <xsd:sequence>
- <xsd:element name="bundle" type="regionBundleType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required"/>
- </xsd:complexType>
-
-
- <xsd:complexType name="regionBundleType">
- <xsd:sequence/>
- <xsd:attribute name="id" type="xsd:long"/>
- <xsd:attribute name="location" type="xsd:string"/>
- </xsd:complexType>
-
- <xsd:complexType name="filterBundleType">
- <xsd:sequence>
- <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="id" type="xsd:long"/>
- <xsd:attribute name="symbolic-name" type="xsd:string"/>
- <xsd:attribute name="version" type="xsd:string"/>
- </xsd:complexType>
-
- <xsd:complexType name="filterType">
- <xsd:sequence>
- <xsd:element name="bundle" type="filterBundleType" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="package" type="filterPackageType" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="namespace" type="filterNamespaceType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="from" type="xsd:string" use="required"/>
- <xsd:attribute name="to" type="xsd:string" use="required"/>
- </xsd:complexType>
-
- <xsd:complexType name="filterPackageType">
- <xsd:sequence>
- <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required"/>
- <xsd:attribute name="version" type="xsd:string"/>
- </xsd:complexType>
-
- <xsd:complexType name="filterAttributeType">
- <xsd:sequence/>
- <xsd:attribute name="name" type="xsd:string" use="required"/>
- <xsd:attribute name="value" type="xsd:string" use="required"/>
- </xsd:complexType>
-
- <xsd:complexType name="filterNamespaceType">
- <xsd:sequence>
- <xsd:element name="attribute" type="filterAttributeType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required"/>
- </xsd:complexType>
-</xsd:schema>
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/pom.xml
----------------------------------------------------------------------
diff --git a/region/pom.xml b/region/pom.xml
index 293c908..2375fcc 100644
--- a/region/pom.xml
+++ b/region/pom.xml
@@ -28,91 +28,109 @@
</parent>
<groupId>org.apache.karaf.region</groupId>
- <artifactId>region</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Region</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
-
- <profiles>
-
- <profile>
- <id>fetch-external</id>
- <pluginRepositories>
- <pluginRepository>
- <id>ossrh</id>
- <name>Sonatype OSS Repository</name>
- <url>http://oss.sonatype.org/content/groups/public</url>
- <layout>default</layout>
- </pluginRepository>
- </pluginRepositories>
-
-
- <build>
- <plugins>
-
- <!-- EXTERNAL DEPENDENCY RESOLVER -->
-
- <plugin>
- <groupId>com.savage7.maven.plugins</groupId>
- <artifactId>maven-external-dependency-plugin</artifactId>
- <version>0.5</version>
- <inherited>false</inherited>
- <configuration>
- <createChecksum>true</createChecksum>
- <skipChecksumVerification>false</skipChecksumVerification>
- <force>false</force>
- <artifactItems>
-<!-- used in aries subsystem but not here
- <artifactItem>
- <groupId>org.eclipse</groupId>
- <artifactId>osgi</artifactId>
- <version>3.8.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <downloadUrl>http://www.eclipse.org/downloads/download.php?file=/equinox/drops/I20111018-0850/org.eclipse.osgi_3.8.0.v20111017-1643.jar&url=http://download.eclipse.org/equinox/drops/I20111018-0850/org.eclipse.osgi_3.8.0.v20111017-1643.jar&mirror_id=1</downloadUrl>
- </artifactItem>
- <artifactItem>
- <groupId>org.eclipse.equinox</groupId>
- <artifactId>coordinator</artifactId>
- <version>1.0.0.v20110314</version>
- <packaging>jar</packaging>
- <downloadUrl>http://ftp.osuosl.org/pub/eclipse/equinox/drops/R-3.7.1-201109091335/org.eclipse.equinox.coordinator_1.0.0.v20110502.jar</downloadUrl>
- </artifactItem>
--->
- <artifactItem>
- <groupId>org.eclipse.equinox</groupId>
- <artifactId>region</artifactId>
- <version>1.0.0.v20110506</version>
- <packaging>jar</packaging>
- <downloadUrl>http://ftp.osuosl.org/pub/eclipse/equinox/drops/R-3.7.1-201109091335/org.eclipse.equinox.region_1.0.0.v20110524.jar</downloadUrl>
- </artifactItem>
- </artifactItems>
- </configuration>
- <executions>
- <execution>
- <id>clean-external-dependencies</id>
- <phase>clean</phase>
- <goals>
- <goal>clean-external</goal>
- </goals>
- </execution>
- <execution>
- <id>resolve-install-external-dependencies</id>
- <phase>process-resources</phase>
- <goals>
- <goal>resolve-external</goal>
- <goal>install-external</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
+ <artifactId>org.apache.karaf.region.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Region :: Persistence</name>
+ <description>This bundle provides an xml regions model and install/dump actions.</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.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>region</artifactId>
+ <version>1.0.0.v20110506</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries</groupId>
+ <artifactId>org.apache.aries.util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </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>
+ <Bundle-Activator>
+ org.apache.karaf.region.persist.internal.Activator
+ </Bundle-Activator>
+ <Private-Package>
+ org.apache.karaf.region.commands,
+ org.apache.karaf.region.commands.util,
+ org.apache.karaf.region.persist.internal.*,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
new file mode 100644
index 0000000..30af1e0
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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.region.commands;
+
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.osgi.framework.Bundle;
+
+@Command(scope = "region", name = "bundle-add", description = "Adds a list of known bundles by id to a specified region.")
+@Service
+public class AddBundleCommand extends RegionCommandSupport {
+
+ @Argument(index = 0, name = "region", description = "Region to add the bundles to", required = true, multiValued = false)
+ String region;
+
+ @Argument(index = 1, name = "bundles", description = "Bundles by id to add to the region", required = true, multiValued = true)
+ List<Long> ids;
+
+ protected void doExecute(RegionDigraph regionDigraph) throws Exception {
+ Region r = getRegion(regionDigraph, region);
+ for (Long id : ids) {
+ for (Region existing: regionDigraph.getRegions()) {
+ if (existing.contains(id)) {
+ Bundle b = bundleContext.getBundle(id);
+ System.out.println("Removing bundle " + id + " from region " + existing.getName());
+ existing.removeBundle(b);
+ break;
+ }
+ }
+ r.addBundle(id);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1bcdb173/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
new file mode 100644
index 0000000..ec3766d
--- /dev/null
+++ b/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
@@ -0,0 +1,169 @@
+/*
+ * 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.region.commands;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.util.VersionRange;
+import org.apache.aries.util.manifest.ManifestHeaderProcessor;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.eclipse.equinox.region.RegionFilter;
+import org.eclipse.equinox.region.RegionFilterBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+@Command(scope = "region", name = "filter-add", description = "Adds a filter between two regions.")
+@Service
+public class AddFilterCommand extends RegionCommandSupport {
+
+ @Argument(index = 0, name = "from", description = "The from region.", required = true, multiValued = false)
+ String fromRegion;
+
+ @Argument(index = 1, name = "to", description = "The to region.", required = true, multiValued = false)
+ String toRegion;
+
+ @Argument(index = 2, name = "items", description = "The bundles by id and packages with version to allow.", required = false, multiValued = true)
+ List<String> items;
+
+ protected void doExecute(RegionDigraph regionDigraph) throws Exception {
+ Region rFrom = getRegion(regionDigraph, fromRegion);
+ Region rTo = getRegion(regionDigraph, toRegion);
+ RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
+ BundleContext framework = bundleContext.getBundle(0).getBundleContext();
+ if (items != null) {
+ for (String item : items) {
+ try {
+ long id = Long.parseLong(item);
+ Bundle b = framework.getBundle(id);
+ builder.allow("osgi.wiring.bundle", "(osgi.wiring.bundle=" + b.getSymbolicName() + ")");
+ } catch (NumberFormatException e) {
+ for (Map.Entry<String, Map<String, String>> parsed: ManifestHeaderProcessor.parseImportString(item).entrySet()) {
+ String packageName = parsed.getKey();
+ Map<String, String> attributes = new HashMap<String, String>(parsed.getValue());
+ attributes.put("osgi.wiring.package", packageName);
+ String filter = generateFilter(attributes);
+ System.out.println("adding filter " + filter);
+ builder.allow("osgi.wiring.package", filter);
+ }
+ }
+
+ }
+ }
+ RegionFilter f = builder.build();
+ regionDigraph.connect(rFrom, f, rTo);
+ }
+
+ //from aries util, with obr specific weirdness removed
+ public static String generateFilter(Map<String, String> attribs) {
+ StringBuilder filter = new StringBuilder("(&");
+ boolean realAttrib = false;
+ StringBuffer realAttribs = new StringBuffer();
+
+ if (attribs == null) {
+ attribs = new HashMap<String, String>();
+ }
+
+ for (Map.Entry<String, String> attrib : attribs.entrySet()) {
+ String attribName = attrib.getKey();
+
+ if (attribName.endsWith(":")) {
+ // skip all directives. It is used to affect the attribs on the
+ // filter xml.
+ } else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
+ || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
+ // version and bundle-version attrib requires special
+ // conversion.
+ realAttrib = true;
+
+ VersionRange vr = ManifestHeaderProcessor
+ .parseVersionRange(attrib.getValue());
+
+ filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
+
+ if (vr.getMaximumVersion() != null) {
+ filter.append(")(" + attribName + "<=");
+ filter.append(vr.getMaximumVersion());
+ }
+
+ if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
+ filter.append(")(!(" + attribName + "=");
+ filter.append(vr.getMinimumVersion());
+ filter.append(")");
+ }
+
+ if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
+ filter.append(")(!(" + attribName + "=");
+ filter.append(vr.getMaximumVersion());
+ filter.append(")");
+ }
+ filter.append(")");
+
+ } else if (Constants.OBJECTCLASS.equals(attribName)) {
+ realAttrib = true;
+ // objectClass has a "," separated list of interfaces
+ String[] values = attrib.getValue().split(",");
+ for (String s : values)
+ filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
+
+ } else {
+ // attribName was not version..
+ realAttrib = true;
+
+ filter.append("(" + attribName + "=" + attrib.getValue() + ")");
+ // store all attributes in order to build up the mandatory
+ // filter and separate them with ", "
+ // skip bundle-symbolic-name in the mandatory directive query
+ if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
+ .equals(attribName)) {
+ realAttribs.append(attribName);
+ realAttribs.append(", ");
+ }
+ }
+ }
+
+ // Prune (& off the front and ) off end
+ String filterString = filter.toString();
+ int openBraces = 0;
+ for (int i = 0; openBraces < 3; i++) {
+ i = filterString.indexOf('(', i);
+ if (i == -1) {
+ break;
+ } else {
+ openBraces++;
+ }
+ }
+ if (openBraces < 3 && filterString.length() > 2) {
+ filter.delete(0, 2);
+ } else {
+ filter.append(")");
+ }
+
+ String result = "";
+ if (realAttrib != false) {
+ result = filter.toString();
+ }
+ return result;
+ }
+
+}
[52/59] [abbrv] git commit: [KARAF-2852] Merge web/core and
web/command
Posted by gn...@apache.org.
[KARAF-2852] Merge web/core and web/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/2b7e96df
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/2b7e96df
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/2b7e96df
Branch: refs/heads/master
Commit: 2b7e96df01ae4a1dc56b8e47d0bb915b38aa741b
Parents: 04afd90
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Apr 10 09:59:42 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:02:58 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
web/NOTICE | 71 +++++++
web/command/NOTICE | 71 -------
web/command/pom.xml | 105 ----------
.../org/apache/karaf/web/commands/List.java | 70 -------
.../org/apache/karaf/web/commands/Start.java | 46 -----
.../org/apache/karaf/web/commands/Stop.java | 46 -----
.../src/main/resources/OSGI-INF/bundle.info | 21 --
web/core/NOTICE | 71 -------
web/core/pom.xml | 106 ----------
.../java/org/apache/karaf/web/WebBundle.java | 79 -------
.../apache/karaf/web/WebContainerService.java | 59 ------
.../web/internal/WebContainerServiceImpl.java | 205 -------------------
.../karaf/web/internal/WebEventHandler.java | 40 ----
.../karaf/web/internal/osgi/Activator.java | 55 -----
.../apache/karaf/web/management/WebMBean.java | 70 -------
.../web/management/internal/WebMBeanImpl.java | 116 -----------
.../src/main/resources/OSGI-INF/bundle.info | 16 --
web/pom.xml | 89 +++++++-
.../java/org/apache/karaf/web/WebBundle.java | 79 +++++++
.../apache/karaf/web/WebContainerService.java | 59 ++++++
.../org/apache/karaf/web/commands/List.java | 70 +++++++
.../org/apache/karaf/web/commands/Start.java | 46 +++++
.../org/apache/karaf/web/commands/Stop.java | 46 +++++
.../web/internal/WebContainerServiceImpl.java | 205 +++++++++++++++++++
.../karaf/web/internal/WebEventHandler.java | 40 ++++
.../karaf/web/internal/osgi/Activator.java | 55 +++++
.../apache/karaf/web/management/WebMBean.java | 70 +++++++
.../web/management/internal/WebMBeanImpl.java | 116 +++++++++++
web/src/main/resources/OSGI-INF/bundle.info | 16 ++
30 files changed, 954 insertions(+), 1185 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/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 b6f8dea..fb3dd93 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -177,7 +177,6 @@
<feature>http</feature>
<feature>pax-war</feature>
<bundle start-level="30">mvn:org.apache.karaf.web/org.apache.karaf.web.core/${project.version}</bundle>
- <bundle start-level="30">mvn:org.apache.karaf.web/org.apache.karaf.web.command/${project.version}</bundle>
</feature>
<feature name="jetty" version="8.1.9.v20130131" resolver="(obr)">
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/NOTICE
----------------------------------------------------------------------
diff --git a/web/NOTICE b/web/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/web/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/2b7e96df/web/command/NOTICE
----------------------------------------------------------------------
diff --git a/web/command/NOTICE b/web/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/web/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/2b7e96df/web/command/pom.xml
----------------------------------------------------------------------
diff --git a/web/command/pom.xml b/web/command/pom.xml
deleted file mode 100644
index f053ab7..0000000
--- a/web/command/pom.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?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.web</groupId>
- <artifactId>web</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.web.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Web :: Commands</name>
- <description>
- This bundle provides Karaf shell commands to manipulate the WebContainer service.
- </description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.web</groupId>
- <artifactId>org.apache.karaf.web.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <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</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </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>
- <Export-Package>
- !org.apache.karaf.web.commands
- </Export-Package>
- <Private-Package>
- org.apache.karaf.web.commands
- </Private-Package>
- <Karaf-Commands>*</Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/command/src/main/java/org/apache/karaf/web/commands/List.java
----------------------------------------------------------------------
diff --git a/web/command/src/main/java/org/apache/karaf/web/commands/List.java b/web/command/src/main/java/org/apache/karaf/web/commands/List.java
deleted file mode 100644
index a862a45..0000000
--- a/web/command/src/main/java/org/apache/karaf/web/commands/List.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.web.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-import org.apache.karaf.web.WebBundle;
-import org.apache.karaf.web.WebContainerService;
-
-@Command(scope = "web", name = "list", description = "Lists details for war bundles.")
-@Service
-public class List implements Action {
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private WebContainerService webContainerService;
-
- public void setWebContainerService(WebContainerService webContainerService) {
- this.webContainerService = webContainerService;
- }
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
- table.column(new Col("ID"));
- table.column(new Col("State"));
- table.column(new Col("Web-State"));
- table.column(new Col("Level"));
- table.column(new Col("Web-ContextPath"));
- table.column(new Col("Name"));
-
- java.util.List<WebBundle> webBundles = webContainerService.list();
- if (webBundles != null && !webBundles.isEmpty()) {
- for (WebBundle webBundle : webBundles) {
- table.addRow().addContent(
- webBundle.getBundleId(),
- webBundle.getState(),
- webBundle.getWebState(),
- webBundle.getLevel(),
- webBundle.getContextPath(),
- webBundle.getName());
- }
-
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/command/src/main/java/org/apache/karaf/web/commands/Start.java
----------------------------------------------------------------------
diff --git a/web/command/src/main/java/org/apache/karaf/web/commands/Start.java b/web/command/src/main/java/org/apache/karaf/web/commands/Start.java
deleted file mode 100644
index 41d6634..0000000
--- a/web/command/src/main/java/org/apache/karaf/web/commands/Start.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.web.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.web.WebContainerService;
-
-@Command(scope = "web", name = "start", description = "Start the web context of given bundles.")
-@Service
-public class Start implements Action {
-
- @Argument(index = 0, name = "ids", description = "The list of bundle IDs separated by whitespaces", required = true, multiValued = true)
- java.util.List<Long> ids;
-
- @Reference
- private WebContainerService webContainerService;
-
- public void setWebContainerService(WebContainerService webContainerService) {
- this.webContainerService = webContainerService;
- }
-
- @Override
- public Object execute() throws Exception {
- webContainerService.start(ids);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/command/src/main/java/org/apache/karaf/web/commands/Stop.java
----------------------------------------------------------------------
diff --git a/web/command/src/main/java/org/apache/karaf/web/commands/Stop.java b/web/command/src/main/java/org/apache/karaf/web/commands/Stop.java
deleted file mode 100644
index 76fd141..0000000
--- a/web/command/src/main/java/org/apache/karaf/web/commands/Stop.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.web.commands;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.web.WebContainerService;
-
-@Command(scope = "web", name = "stop", description = "Stop the web context of given bundles.")
-@Service
-public class Stop implements Action {
-
- @Argument(index = 0, name = "ids", description = "The list of bundle IDs separated by whitespaces", required = true, multiValued = true)
- java.util.List<Long> ids;
-
- @Reference
- private WebContainerService webContainerService;
-
- public void setWebContainerService(WebContainerService webContainerService) {
- this.webContainerService = webContainerService;
- }
-
- @Override
- public Object execute() throws Exception {
- webContainerService.stop(ids);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/web/command/src/main/resources/OSGI-INF/bundle.info b/web/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 6acb144..0000000
--- a/web/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,21 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle contains all Karaf shell commands related to the web container.
-
-The following commands are available:
-* web:list - List detail information about web bundles.
-* web:start - Start the web context for the given web bundles.
-* web:stop - Stop the web context for the given web bundles.
-
-h1. See also
-
-Web Container - section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/NOTICE
----------------------------------------------------------------------
diff --git a/web/core/NOTICE b/web/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/web/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/2b7e96df/web/core/pom.xml
----------------------------------------------------------------------
diff --git a/web/core/pom.xml b/web/core/pom.xml
deleted file mode 100644
index a6ec17e..0000000
--- a/web/core/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?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.web</groupId>
- <artifactId>web</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.web.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Web :: Core</name>
- <description>
- This bundle provide the core service to manipulate the web container/bundles.
- </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.ops4j.pax.web</groupId>
- <artifactId>pax-web-spi</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </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>
- <Export-Package>
- org.apache.karaf.web,
- org.apache.karaf.web.management
- </Export-Package>
- <Private-Package>
- org.apache.karaf.web.internal,
- org.apache.karaf.web.internal.osgi,
- org.apache.karaf.web.management.internal,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.web.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/WebBundle.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/WebBundle.java b/web/core/src/main/java/org/apache/karaf/web/WebBundle.java
deleted file mode 100644
index 484495d..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/WebBundle.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.web;
-
-/**
- * Container for WebBundle information.
- */
-public class WebBundle {
-
- private long bundleId;
- private String name;
- private int level;
- private String state;
- private String webState;
- private String contextPath;
-
- public long getBundleId() {
- return bundleId;
- }
-
- public void setBundleId(long bundleId) {
- this.bundleId = bundleId;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getLevel() {
- return level;
- }
-
- public void setLevel(int level) {
- this.level = level;
- }
-
- public String getState() {
- return state;
- }
-
- public void setState(String state) {
- this.state = state;
- }
-
- public String getWebState() {
- return webState;
- }
-
- public void setWebState(String webState) {
- this.webState = webState;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- public void setContextPath(String contextPath) {
- this.contextPath = contextPath;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/WebContainerService.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/WebContainerService.java b/web/core/src/main/java/org/apache/karaf/web/WebContainerService.java
deleted file mode 100644
index 989817b..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/WebContainerService.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.web;
-
-import java.util.List;
-
-/**
- * Describe the WebContainer service.
- */
-public interface WebContainerService {
-
- /**
- * List of web bundles deployed in the web container.
- *
- * @return the list of web bundles.
- * @throws Exception in case of listing failure.
- */
- List<WebBundle> list() throws Exception;
-
- /**
- * Get a string representation of the web state of a bundle (identified by id).
- *
- * @param bundleId the bundle ID.
- * @return the string representation of the bundle web state.
- * @throws Exception in case of "mapping" failure.
- */
- String state(long bundleId) throws Exception;
-
- /**
- * Start the web context of given bundles (identified by an ID).
- *
- * @param bundleIds the list of bundle IDs (TODO use a BundleSelector service).
- * @throws Exception in case of deploy failure.
- */
- void start(List<Long> bundleIds) throws Exception;
-
- /**
- * Stop the web context of given bundles (identified by an ID).
- *
- * @param bundleIds the list of bundle IDs (TODO use a BundleSelector service).
- * @throws Exception in case of undeploy failure.
- */
- void stop(List<Long> bundleIds) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java b/web/core/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
deleted file mode 100644
index 4affc8f..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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.web.internal;
-
-import org.apache.karaf.web.WebBundle;
-import org.apache.karaf.web.WebContainerService;
-import org.ops4j.pax.web.service.spi.WarManager;
-import org.ops4j.pax.web.service.spi.WebEvent;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.startlevel.BundleStartLevel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of the WebContainer service.
- */
-public class WebContainerServiceImpl implements WebContainerService {
-
- private BundleContext bundleContext;
- private WebEventHandler webEventHandler;
- private WarManager warManager;
-
- private static final Logger LOGGER = LoggerFactory.getLogger(WebContainerServiceImpl.class);
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void setWebEventHandler(WebEventHandler webEventHandler) {
- this.webEventHandler = webEventHandler;
- }
-
- public void setWarManager(WarManager warManager) {
- this.warManager = warManager;
- }
-
- public List<WebBundle> list() throws Exception {
- Bundle[] bundles = bundleContext.getBundles();
- Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
- List<WebBundle> webBundles = new ArrayList<WebBundle>();
- if (bundles != null) {
- for (Bundle bundle : bundles) {
- // first check if the bundle is a web bundle
- String contextPath = (String) bundle.getHeaders().get("Web-ContextPath");
- if (contextPath == null) {
- contextPath = (String) bundle.getHeaders().get("Webapp-Context"); // this one used by pax-web but is deprecated
- }
- if (contextPath == null) {
- // the bundle is not a web bundle
- continue;
- }
-
- WebBundle webBundle = new WebBundle();
- contextPath.trim();
-
- // get the bundle name
- String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME);
- // if there is no name, then default to symbolic name
- name = (name == null) ? bundle.getSymbolicName() : name;
- // if there is no symbolic name, resort to location
- name = (name == null) ? bundle.getLocation() : name;
- // get the bundle version
- String version = (String) bundle.getHeaders().get(Constants.BUNDLE_VERSION);
- name = ((version != null)) ? name + " (" + version + ")" : name;
- long bundleId = bundle.getBundleId();
- int level = bundle.adapt(BundleStartLevel.class).getStartLevel();
- if (!contextPath.startsWith("/")) {
- contextPath = "/" + contextPath;
- }
-
- webBundle.setBundleId(bundleId);
- webBundle.setName(name);
- webBundle.setContextPath(contextPath);
- webBundle.setLevel(level);
- webBundle.setState(getStateString(bundle));
- webBundle.setWebState(state(bundle.getBundleId()));
-
- webBundles.add(webBundle);
- }
- }
-
- return webBundles;
- }
-
- public void start(List<Long> bundleIds) throws Exception {
- if (bundleIds != null && !bundleIds.isEmpty()) {
- for (long bundleId : bundleIds) {
- if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
- WebEvent webEvent = webEventHandler.getBundleEvents().get(bundleId);
- Bundle bundle = webEvent.getBundle();
- if (bundle != null) {
- // deploy
- warManager.start(bundleId, null);
- } else {
- System.out.println("Bundle ID " + bundleId + " is invalid");
- LOGGER.warn("Bundle ID {} is invalid", bundleId);
- }
- }
- }
- }
- }
-
- public void stop(List<Long> bundleIds) throws Exception {
- if (bundleIds != null && !bundleIds.isEmpty()) {
- for (long bundleId : bundleIds) {
- if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
- WebEvent webEvent = webEventHandler.getBundleEvents().get(bundleId);
- Bundle bundle = webEvent.getBundle();
- if (bundle != null) {
- // deploy
- warManager.stop(bundleId);
- } else {
- System.out.println("Bundle ID " + bundleId + " is invalid");
- LOGGER.warn("Bundle ID {} is invalid", bundleId);
- }
- }
- }
- }
- }
-
- public String state(long bundleId) {
-
- Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
- String topic = "Unknown ";
-
- if (bundleEvents.containsKey(bundleId)) {
- WebEvent webEvent = bundleEvents.get(bundleId);
-
- switch(webEvent.getType()) {
- case WebEvent.DEPLOYING:
- topic = "Deploying ";
- break;
- case WebEvent.DEPLOYED:
- topic = "Deployed ";
- break;
- case WebEvent.UNDEPLOYING:
- topic = "Undeploying";
- break;
- case WebEvent.UNDEPLOYED:
- topic = "Undeployed ";
- break;
- case WebEvent.FAILED:
- topic = "Failed ";
- break;
- case WebEvent.WAITING:
- topic = "Waiting ";
- break;
- default:
- topic = "Failed ";
- }
- }
-
- while (topic.length() < 11) {
- topic += " ";
- }
-
- return topic;
- }
-
- /**
- * Return a string representation of the bundle state.
- *
- * TODO use an util method provided by bundle core
- *
- * @param bundle the target bundle.
- * @return the string representation of the state
- */
- private String getStateString(Bundle bundle) {
- int state = bundle.getState();
- if (state == Bundle.ACTIVE) {
- return "Active ";
- } else if (state == Bundle.INSTALLED) {
- return "Installed ";
- } else if (state == Bundle.RESOLVED) {
- return "Resolved ";
- } else if (state == Bundle.STARTING) {
- return "Starting ";
- } else if (state == Bundle.STOPPING) {
- return "Stopping ";
- } else {
- return "Unknown ";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java b/web/core/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
deleted file mode 100644
index 01ef52e..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.web.internal;
-
-import org.ops4j.pax.web.service.spi.WebEvent;
-import org.ops4j.pax.web.service.spi.WebListener;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Class implementing {@link WebListener} service to retrieve {@link WebEvent}.
- */
-public class WebEventHandler implements WebListener {
-
- private final Map<Long, WebEvent> bundleEvents = new HashMap<Long, WebEvent>();
-
- public Map<Long, WebEvent> getBundleEvents() {
- return bundleEvents;
- }
-
- public void webEvent(WebEvent event) {
- getBundleEvents().put(event.getBundle().getBundleId(), event);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java b/web/core/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
deleted file mode 100644
index e5bcfe1..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.web.internal.osgi;
-
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.apache.karaf.web.WebContainerService;
-import org.apache.karaf.web.internal.WebContainerServiceImpl;
-import org.apache.karaf.web.internal.WebEventHandler;
-import org.apache.karaf.web.management.internal.WebMBeanImpl;
-import org.ops4j.pax.web.service.spi.WarManager;
-import org.ops4j.pax.web.service.spi.WebListener;
-
-public class Activator extends BaseActivator {
-
- @Override
- protected void doOpen() throws Exception {
- trackService(WarManager.class);
- }
-
- @Override
- protected void doStart() throws Exception {
- WarManager warManager = getTrackedService(WarManager.class);
- if (warManager == null) {
- return;
- }
-
- WebEventHandler webEventHandler = new WebEventHandler();
- register(WebListener.class, webEventHandler);
-
- WebContainerServiceImpl webContainerService = new WebContainerServiceImpl();
- webContainerService.setBundleContext(bundleContext);
- webContainerService.setWarManager(warManager);
- webContainerService.setWebEventHandler(webEventHandler);
- register(WebContainerService.class, webContainerService);
-
- WebMBeanImpl webMBean = new WebMBeanImpl();
- webMBean.setWebContainerService(webContainerService);
- registerMBean(webMBean, "type=web");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/management/WebMBean.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/management/WebMBean.java b/web/core/src/main/java/org/apache/karaf/web/management/WebMBean.java
deleted file mode 100644
index 5c6df22..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/management/WebMBean.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.web.management;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.TabularData;
-import java.util.List;
-
-/**
- * Describe the Web MBean.
- */
-public interface WebMBean {
-
- /**
- * Return the list of web bundles.
- *
- * @return a tabular data of web bundles.
- * @throws Exception in case of lookup failure.
- */
- TabularData getWebBundles() throws MBeanException;
-
- /**
- * Start web context of the given web bundle (identified by ID).
- *
- * @param bundleId the bundle ID.
- * @throws MBeanException
- */
- void start(Long bundleId) throws MBeanException;
-
- /**
- * Start web context of the given web bundles (identified by ID).
- *
- * @param bundleIds the list of bundle IDs.
- * TODO use a BundleSelector service
- * @throws Exception in case of start failure.
- */
- void start(List<Long> bundleIds) throws MBeanException;
-
- /**
- * Stop web context of the given web bundle (identified by ID).
- *
- * @param bundleId the bundle ID.
- * @throws MBeanException
- */
- void stop(Long bundleId) throws MBeanException;
-
- /**
- * Stop web context of the given web bundles (identified by ID).
- *
- * @param bundleIds the list of bundle IDs.
- * TODO use a BundleSelector service
- * @throws Exception in case of stop failure
- */
- void stop(List<Long> bundleIds) throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
----------------------------------------------------------------------
diff --git a/web/core/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java b/web/core/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
deleted file mode 100644
index f1a81bb..0000000
--- a/web/core/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.web.management.internal;
-
-import org.apache.karaf.web.WebBundle;
-import org.apache.karaf.web.WebContainerService;
-import org.apache.karaf.web.management.WebMBean;
-
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-import javax.management.openmbean.*;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of the Web MBean.
- */
-public class WebMBeanImpl extends StandardMBean implements WebMBean {
-
- private WebContainerService webContainerService;
-
- public WebMBeanImpl() throws NotCompliantMBeanException {
- super(WebMBean.class);
- }
-
- public void setWebContainerService(WebContainerService webContainerService) {
- this.webContainerService = webContainerService;
- }
-
- public TabularData getWebBundles() throws MBeanException {
- try {
- CompositeType webType = new CompositeType("Web Bundle", "An OSGi Web bundle",
- new String[]{"ID", "State", "Web-State", "Level", "Web-ContextPath", "Name"},
- new String[]{"ID of the bundle",
- "OSGi state of the bundle",
- "Web state of the bundle",
- "Start level of the bundle",
- "Web context path",
- "Name of the bundle"},
- new OpenType[]{SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING});
- TabularType tableType = new TabularType("Web Bundles", "Table of web bundles", webType,
- new String[]{"ID"});
- TabularData table = new TabularDataSupport(tableType);
- for (WebBundle webBundle : webContainerService.list()) {
- try {
- CompositeData data = new CompositeDataSupport(webType,
- new String[]{"ID", "State", "Web-State", "Level", "Web-ContextPath", "Name"},
- new Object[]{webBundle.getBundleId(),
- webBundle.getState(),
- webBundle.getWebState(),
- webBundle.getLevel(),
- webBundle.getContextPath(),
- webBundle.getName()});
- table.put(data);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return table;
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void start(Long bundleId) throws MBeanException {
- try {
- List<Long> list = new ArrayList<Long>();
- list.add(bundleId);
- webContainerService.start(list);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void start(List<Long> bundleIds) throws MBeanException {
- try {
- webContainerService.start(bundleIds);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void stop(Long bundleId) throws MBeanException {
- try {
- List<Long> list = new ArrayList<Long>();
- list.add(bundleId);
- webContainerService.stop(list);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
- public void stop(List<Long> bundleIds) throws MBeanException {
- try {
- webContainerService.stop(bundleIds);
- } catch (Exception e) {
- throw new MBeanException(null, e.getMessage());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/web/core/src/main/resources/OSGI-INF/bundle.info b/web/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 650fee9..0000000
--- a/web/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,16 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides support of the WebContainer service, which allows to manipulate the Karaf embedded web container.
-
-h1. See also
-
-Web Container - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/pom.xml
----------------------------------------------------------------------
diff --git a/web/pom.xml b/web/pom.xml
index 6284a5c..037ee5f 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -29,13 +29,86 @@
</parent>
<groupId>org.apache.karaf.web</groupId>
- <artifactId>web</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Web</name>
-
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <artifactId>org.apache.karaf.web.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Web :: Core</name>
+ <description>
+ This bundle provide the core service to manipulate the web container/bundles.
+ </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.ops4j.pax.web</groupId>
+ <artifactId>pax-web-spi</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </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>
+ <Export-Package>
+ org.apache.karaf.web,
+ org.apache.karaf.web.management
+ </Export-Package>
+ <Private-Package>
+ org.apache.karaf.web.commands,
+ org.apache.karaf.web.internal,
+ org.apache.karaf.web.internal.osgi,
+ org.apache.karaf.web.management.internal,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.web.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/WebBundle.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/WebBundle.java b/web/src/main/java/org/apache/karaf/web/WebBundle.java
new file mode 100644
index 0000000..484495d
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/WebBundle.java
@@ -0,0 +1,79 @@
+/*
+ * 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.web;
+
+/**
+ * Container for WebBundle information.
+ */
+public class WebBundle {
+
+ private long bundleId;
+ private String name;
+ private int level;
+ private String state;
+ private String webState;
+ private String contextPath;
+
+ public long getBundleId() {
+ return bundleId;
+ }
+
+ public void setBundleId(long bundleId) {
+ this.bundleId = bundleId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getWebState() {
+ return webState;
+ }
+
+ public void setWebState(String webState) {
+ this.webState = webState;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/WebContainerService.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/WebContainerService.java b/web/src/main/java/org/apache/karaf/web/WebContainerService.java
new file mode 100644
index 0000000..989817b
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/WebContainerService.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.web;
+
+import java.util.List;
+
+/**
+ * Describe the WebContainer service.
+ */
+public interface WebContainerService {
+
+ /**
+ * List of web bundles deployed in the web container.
+ *
+ * @return the list of web bundles.
+ * @throws Exception in case of listing failure.
+ */
+ List<WebBundle> list() throws Exception;
+
+ /**
+ * Get a string representation of the web state of a bundle (identified by id).
+ *
+ * @param bundleId the bundle ID.
+ * @return the string representation of the bundle web state.
+ * @throws Exception in case of "mapping" failure.
+ */
+ String state(long bundleId) throws Exception;
+
+ /**
+ * Start the web context of given bundles (identified by an ID).
+ *
+ * @param bundleIds the list of bundle IDs (TODO use a BundleSelector service).
+ * @throws Exception in case of deploy failure.
+ */
+ void start(List<Long> bundleIds) throws Exception;
+
+ /**
+ * Stop the web context of given bundles (identified by an ID).
+ *
+ * @param bundleIds the list of bundle IDs (TODO use a BundleSelector service).
+ * @throws Exception in case of undeploy failure.
+ */
+ void stop(List<Long> bundleIds) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/commands/List.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/commands/List.java b/web/src/main/java/org/apache/karaf/web/commands/List.java
new file mode 100644
index 0000000..a862a45
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/commands/List.java
@@ -0,0 +1,70 @@
+/*
+ * 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.web.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.Col;
+import org.apache.karaf.shell.support.table.ShellTable;
+import org.apache.karaf.web.WebBundle;
+import org.apache.karaf.web.WebContainerService;
+
+@Command(scope = "web", name = "list", description = "Lists details for war bundles.")
+@Service
+public class List implements Action {
+
+ @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ @Reference
+ private WebContainerService webContainerService;
+
+ public void setWebContainerService(WebContainerService webContainerService) {
+ this.webContainerService = webContainerService;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ ShellTable table = new ShellTable();
+ table.column(new Col("ID"));
+ table.column(new Col("State"));
+ table.column(new Col("Web-State"));
+ table.column(new Col("Level"));
+ table.column(new Col("Web-ContextPath"));
+ table.column(new Col("Name"));
+
+ java.util.List<WebBundle> webBundles = webContainerService.list();
+ if (webBundles != null && !webBundles.isEmpty()) {
+ for (WebBundle webBundle : webBundles) {
+ table.addRow().addContent(
+ webBundle.getBundleId(),
+ webBundle.getState(),
+ webBundle.getWebState(),
+ webBundle.getLevel(),
+ webBundle.getContextPath(),
+ webBundle.getName());
+ }
+
+ }
+ table.print(System.out, !noFormat);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/commands/Start.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/commands/Start.java b/web/src/main/java/org/apache/karaf/web/commands/Start.java
new file mode 100644
index 0000000..41d6634
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/commands/Start.java
@@ -0,0 +1,46 @@
+/*
+ * 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.web.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.web.WebContainerService;
+
+@Command(scope = "web", name = "start", description = "Start the web context of given bundles.")
+@Service
+public class Start implements Action {
+
+ @Argument(index = 0, name = "ids", description = "The list of bundle IDs separated by whitespaces", required = true, multiValued = true)
+ java.util.List<Long> ids;
+
+ @Reference
+ private WebContainerService webContainerService;
+
+ public void setWebContainerService(WebContainerService webContainerService) {
+ this.webContainerService = webContainerService;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ webContainerService.start(ids);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/commands/Stop.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/commands/Stop.java b/web/src/main/java/org/apache/karaf/web/commands/Stop.java
new file mode 100644
index 0000000..76fd141
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/commands/Stop.java
@@ -0,0 +1,46 @@
+/*
+ * 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.web.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.web.WebContainerService;
+
+@Command(scope = "web", name = "stop", description = "Stop the web context of given bundles.")
+@Service
+public class Stop implements Action {
+
+ @Argument(index = 0, name = "ids", description = "The list of bundle IDs separated by whitespaces", required = true, multiValued = true)
+ java.util.List<Long> ids;
+
+ @Reference
+ private WebContainerService webContainerService;
+
+ public void setWebContainerService(WebContainerService webContainerService) {
+ this.webContainerService = webContainerService;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ webContainerService.stop(ids);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java b/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
new file mode 100644
index 0000000..4affc8f
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
@@ -0,0 +1,205 @@
+/*
+ * 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.web.internal;
+
+import org.apache.karaf.web.WebBundle;
+import org.apache.karaf.web.WebContainerService;
+import org.ops4j.pax.web.service.spi.WarManager;
+import org.ops4j.pax.web.service.spi.WebEvent;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of the WebContainer service.
+ */
+public class WebContainerServiceImpl implements WebContainerService {
+
+ private BundleContext bundleContext;
+ private WebEventHandler webEventHandler;
+ private WarManager warManager;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(WebContainerServiceImpl.class);
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setWebEventHandler(WebEventHandler webEventHandler) {
+ this.webEventHandler = webEventHandler;
+ }
+
+ public void setWarManager(WarManager warManager) {
+ this.warManager = warManager;
+ }
+
+ public List<WebBundle> list() throws Exception {
+ Bundle[] bundles = bundleContext.getBundles();
+ Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
+ List<WebBundle> webBundles = new ArrayList<WebBundle>();
+ if (bundles != null) {
+ for (Bundle bundle : bundles) {
+ // first check if the bundle is a web bundle
+ String contextPath = (String) bundle.getHeaders().get("Web-ContextPath");
+ if (contextPath == null) {
+ contextPath = (String) bundle.getHeaders().get("Webapp-Context"); // this one used by pax-web but is deprecated
+ }
+ if (contextPath == null) {
+ // the bundle is not a web bundle
+ continue;
+ }
+
+ WebBundle webBundle = new WebBundle();
+ contextPath.trim();
+
+ // get the bundle name
+ String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME);
+ // if there is no name, then default to symbolic name
+ name = (name == null) ? bundle.getSymbolicName() : name;
+ // if there is no symbolic name, resort to location
+ name = (name == null) ? bundle.getLocation() : name;
+ // get the bundle version
+ String version = (String) bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+ name = ((version != null)) ? name + " (" + version + ")" : name;
+ long bundleId = bundle.getBundleId();
+ int level = bundle.adapt(BundleStartLevel.class).getStartLevel();
+ if (!contextPath.startsWith("/")) {
+ contextPath = "/" + contextPath;
+ }
+
+ webBundle.setBundleId(bundleId);
+ webBundle.setName(name);
+ webBundle.setContextPath(contextPath);
+ webBundle.setLevel(level);
+ webBundle.setState(getStateString(bundle));
+ webBundle.setWebState(state(bundle.getBundleId()));
+
+ webBundles.add(webBundle);
+ }
+ }
+
+ return webBundles;
+ }
+
+ public void start(List<Long> bundleIds) throws Exception {
+ if (bundleIds != null && !bundleIds.isEmpty()) {
+ for (long bundleId : bundleIds) {
+ if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
+ WebEvent webEvent = webEventHandler.getBundleEvents().get(bundleId);
+ Bundle bundle = webEvent.getBundle();
+ if (bundle != null) {
+ // deploy
+ warManager.start(bundleId, null);
+ } else {
+ System.out.println("Bundle ID " + bundleId + " is invalid");
+ LOGGER.warn("Bundle ID {} is invalid", bundleId);
+ }
+ }
+ }
+ }
+ }
+
+ public void stop(List<Long> bundleIds) throws Exception {
+ if (bundleIds != null && !bundleIds.isEmpty()) {
+ for (long bundleId : bundleIds) {
+ if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
+ WebEvent webEvent = webEventHandler.getBundleEvents().get(bundleId);
+ Bundle bundle = webEvent.getBundle();
+ if (bundle != null) {
+ // deploy
+ warManager.stop(bundleId);
+ } else {
+ System.out.println("Bundle ID " + bundleId + " is invalid");
+ LOGGER.warn("Bundle ID {} is invalid", bundleId);
+ }
+ }
+ }
+ }
+ }
+
+ public String state(long bundleId) {
+
+ Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
+ String topic = "Unknown ";
+
+ if (bundleEvents.containsKey(bundleId)) {
+ WebEvent webEvent = bundleEvents.get(bundleId);
+
+ switch(webEvent.getType()) {
+ case WebEvent.DEPLOYING:
+ topic = "Deploying ";
+ break;
+ case WebEvent.DEPLOYED:
+ topic = "Deployed ";
+ break;
+ case WebEvent.UNDEPLOYING:
+ topic = "Undeploying";
+ break;
+ case WebEvent.UNDEPLOYED:
+ topic = "Undeployed ";
+ break;
+ case WebEvent.FAILED:
+ topic = "Failed ";
+ break;
+ case WebEvent.WAITING:
+ topic = "Waiting ";
+ break;
+ default:
+ topic = "Failed ";
+ }
+ }
+
+ while (topic.length() < 11) {
+ topic += " ";
+ }
+
+ return topic;
+ }
+
+ /**
+ * Return a string representation of the bundle state.
+ *
+ * TODO use an util method provided by bundle core
+ *
+ * @param bundle the target bundle.
+ * @return the string representation of the state
+ */
+ private String getStateString(Bundle bundle) {
+ int state = bundle.getState();
+ if (state == Bundle.ACTIVE) {
+ return "Active ";
+ } else if (state == Bundle.INSTALLED) {
+ return "Installed ";
+ } else if (state == Bundle.RESOLVED) {
+ return "Resolved ";
+ } else if (state == Bundle.STARTING) {
+ return "Starting ";
+ } else if (state == Bundle.STOPPING) {
+ return "Stopping ";
+ } else {
+ return "Unknown ";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java b/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
new file mode 100644
index 0000000..01ef52e
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
@@ -0,0 +1,40 @@
+/*
+ * 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.web.internal;
+
+import org.ops4j.pax.web.service.spi.WebEvent;
+import org.ops4j.pax.web.service.spi.WebListener;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class implementing {@link WebListener} service to retrieve {@link WebEvent}.
+ */
+public class WebEventHandler implements WebListener {
+
+ private final Map<Long, WebEvent> bundleEvents = new HashMap<Long, WebEvent>();
+
+ public Map<Long, WebEvent> getBundleEvents() {
+ return bundleEvents;
+ }
+
+ public void webEvent(WebEvent event) {
+ getBundleEvents().put(event.getBundle().getBundleId(), event);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
new file mode 100644
index 0000000..e5bcfe1
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.web.internal.osgi;
+
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.web.WebContainerService;
+import org.apache.karaf.web.internal.WebContainerServiceImpl;
+import org.apache.karaf.web.internal.WebEventHandler;
+import org.apache.karaf.web.management.internal.WebMBeanImpl;
+import org.ops4j.pax.web.service.spi.WarManager;
+import org.ops4j.pax.web.service.spi.WebListener;
+
+public class Activator extends BaseActivator {
+
+ @Override
+ protected void doOpen() throws Exception {
+ trackService(WarManager.class);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ WarManager warManager = getTrackedService(WarManager.class);
+ if (warManager == null) {
+ return;
+ }
+
+ WebEventHandler webEventHandler = new WebEventHandler();
+ register(WebListener.class, webEventHandler);
+
+ WebContainerServiceImpl webContainerService = new WebContainerServiceImpl();
+ webContainerService.setBundleContext(bundleContext);
+ webContainerService.setWarManager(warManager);
+ webContainerService.setWebEventHandler(webEventHandler);
+ register(WebContainerService.class, webContainerService);
+
+ WebMBeanImpl webMBean = new WebMBeanImpl();
+ webMBean.setWebContainerService(webContainerService);
+ registerMBean(webMBean, "type=web");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/2b7e96df/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/management/WebMBean.java b/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
new file mode 100644
index 0000000..5c6df22
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
@@ -0,0 +1,70 @@
+/*
+ * 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.web.management;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+import java.util.List;
+
+/**
+ * Describe the Web MBean.
+ */
+public interface WebMBean {
+
+ /**
+ * Return the list of web bundles.
+ *
+ * @return a tabular data of web bundles.
+ * @throws Exception in case of lookup failure.
+ */
+ TabularData getWebBundles() throws MBeanException;
+
+ /**
+ * Start web context of the given web bundle (identified by ID).
+ *
+ * @param bundleId the bundle ID.
+ * @throws MBeanException
+ */
+ void start(Long bundleId) throws MBeanException;
+
+ /**
+ * Start web context of the given web bundles (identified by ID).
+ *
+ * @param bundleIds the list of bundle IDs.
+ * TODO use a BundleSelector service
+ * @throws Exception in case of start failure.
+ */
+ void start(List<Long> bundleIds) throws MBeanException;
+
+ /**
+ * Stop web context of the given web bundle (identified by ID).
+ *
+ * @param bundleId the bundle ID.
+ * @throws MBeanException
+ */
+ void stop(Long bundleId) throws MBeanException;
+
+ /**
+ * Stop web context of the given web bundles (identified by ID).
+ *
+ * @param bundleIds the list of bundle IDs.
+ * TODO use a BundleSelector service
+ * @throws Exception in case of stop failure
+ */
+ void stop(List<Long> bundleIds) throws MBeanException;
+
+}
[12/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
deleted file mode 100644
index 380848a..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.karaf.features.BootFinished;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BootFeaturesInstaller {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(BootFeaturesInstaller.class);
-
- public static String VERSION_PREFIX = "version=";
-
- private final FeaturesServiceImpl featuresService;
- private final BundleContext bundleContext;
- private final String repositories;
- private final String features;
- private final boolean asynchronous;
-
- /**
- *
- * @param features list of boot features separated by comma. Optionally contains ;version=x.x.x to specify a specific feature version
- */
- public BootFeaturesInstaller(BundleContext bundleContext,
- FeaturesServiceImpl featuresService,
- String repositories,
- String features,
- boolean asynchronous) {
- this.bundleContext = bundleContext;
- this.featuresService = featuresService;
- this.repositories = repositories;
- this.features = features;
- this.asynchronous = asynchronous;
- }
-
- /**
- * Install boot features
- */
- public void start() {
- if (featuresService.isBootDone()) {
- publishBootFinished();
- return;
- }
- if (asynchronous) {
- new Thread("Initial Features Provisioning") {
- public void run() {
- installBootFeatures();
- }
- }.start();
- } else {
- installBootFeatures();
- }
- }
-
- protected void installBootFeatures() {
- try {
- for (String repo : repositories.split(",")) {
- repo = repo.trim();
- if (!repo.isEmpty()) {
- try {
- featuresService.addRepository(URI.create(repo));
- } catch (Exception e) {
- LOGGER.error("Error installing boot feature repository " + repo);
- }
- }
- }
-
- List<Set<String>> stagedFeatures = parseBootFeatures(features);
- for (Set<String> features : stagedFeatures) {
- featuresService.installFeatures(features, EnumSet.of(FeaturesService.Option.NoFailOnFeatureNotFound));
- }
- featuresService.bootDone();
- publishBootFinished();
- } catch (Exception e) {
- // Special handling in case the bundle has been refreshed.
- // In such a case, simply exits without logging any exception
- // as the restart should cause the feature service to finish
- // the work.
- if (e instanceof IllegalStateException) {
- try {
- bundleContext.getBundle();
- } catch (IllegalStateException ies) {
- return;
- }
- }
- LOGGER.error("Error installing boot features", e);
- }
- }
-
- /**
- *
- * @param featureSt either feature name or <featurename>;version=<version>
- * @return feature matching the feature string
- * @throws Exception
- */
- private Feature getFeature(String featureSt) throws Exception {
- String[] parts = featureSt.trim().split(";");
- String featureName = parts[0];
- String featureVersion = null;
- for (String part : parts) {
- // if the part starts with "version=" it contains the version info
- if (part.startsWith(VERSION_PREFIX)) {
- featureVersion = part.substring(VERSION_PREFIX.length());
- }
- }
- if (featureVersion == null) {
- // no version specified - use default version
- featureVersion = org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION;
- }
- return featuresService.getFeature(featureName, featureVersion);
- }
-
- protected List<Set<String>> parseBootFeatures(String bootFeatures) {
- Pattern pattern = Pattern.compile("(\\((.+))\\),|.+");
- Matcher matcher = pattern.matcher(bootFeatures);
- List<Set<String>> result = new ArrayList<Set<String>>();
- while (matcher.find()) {
- String group = matcher.group(2) != null ? matcher.group(2) : matcher.group();
- result.add(parseFeatureList(group));
- }
- return result;
- }
-
- protected Set<String> parseFeatureList(String group) {
- HashSet<String> features = new HashSet<String>();
- for (String feature : Arrays.asList(group.trim().split("\\s*,\\s*"))) {
- if (feature.length() > 0) {
- features.add(feature);
- }
- }
- return features;
- }
-
- private void publishBootFinished() {
- if (bundleContext != null) {
- BootFinished bootFinished = new BootFinished() {};
- bundleContext.registerService(BootFinished.class, bootFinished, new Hashtable<String, String>());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
deleted file mode 100644
index b6eaae5..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.karaf.features.EventConstants;
-import org.apache.karaf.features.FeatureEvent;
-import org.apache.karaf.features.FeaturesListener;
-import org.apache.karaf.features.RepositoryEvent;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * A listener to publish events to EventAdmin
- */
-public class EventAdminListener implements FeaturesListener {
-
- private final ServiceTracker<EventAdmin, EventAdmin> tracker;
-
- public EventAdminListener(BundleContext context) {
- tracker = new ServiceTracker<EventAdmin, EventAdmin>(context, EventAdmin.class.getName(), null);
- tracker.open();
- }
-
- public void featureEvent(FeatureEvent event) {
- EventAdmin eventAdmin = tracker.getService();
- if (eventAdmin == null) {
- return;
- }
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(EventConstants.TYPE, event.getType());
- props.put(EventConstants.EVENT, event);
- props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
- props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
- props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
- String topic;
- switch (event.getType()) {
- case FeatureInstalled:
- topic = EventConstants.TOPIC_FEATURES_INSTALLED;
- break;
- case FeatureUninstalled:
- topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
- break;
- default:
- throw new IllegalStateException("Unknown features event type: " + event.getType());
- }
- eventAdmin.postEvent(new Event(topic, props));
- }
-
- public void repositoryEvent(RepositoryEvent event) {
- EventAdmin eventAdmin = tracker.getService();
- if (eventAdmin == null) {
- return;
- }
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(EventConstants.TYPE, event.getType());
- props.put(EventConstants.EVENT, event);
- props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
- props.put(EventConstants.REPOSITORY_URI, event.getRepository().getURI().toString());
- String topic;
- switch (event.getType()) {
- case RepositoryAdded:
- topic = EventConstants.TOPIC_REPOSITORY_ADDED;
- break;
- case RepositoryRemoved:
- topic = EventConstants.TOPIC_REPOSITORY_REMOVED;
- break;
- default:
- throw new IllegalStateException("Unknown repository event type: " + event.getType());
- }
- eventAdmin.postEvent(new Event(topic, props));
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
deleted file mode 100644
index 0e9038d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.karaf.features.ConfigFileInfo;
-import org.apache.karaf.features.Feature;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FeatureConfigInstaller {
- private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
- private static final String CONFIG_KEY = "org.apache.karaf.features.configKey";
-
- private final ConfigurationAdmin configAdmin;
-
- public FeatureConfigInstaller(ConfigurationAdmin configAdmin) {
- this.configAdmin = configAdmin;
- }
-
- private String[] parsePid(String pid) {
- int n = pid.indexOf('-');
- if (n > 0) {
- String factoryPid = pid.substring(n + 1);
- pid = pid.substring(0, n);
- return new String[]{pid, factoryPid};
- } else {
- return new String[]{pid, null};
- }
- }
-
- private Configuration createConfiguration(ConfigurationAdmin configurationAdmin,
- String pid, String factoryPid) throws IOException, InvalidSyntaxException {
- if (factoryPid != null) {
- return configurationAdmin.createFactoryConfiguration(factoryPid, null);
- } else {
- return configurationAdmin.getConfiguration(pid, null);
- }
- }
-
- private Configuration findExistingConfiguration(ConfigurationAdmin configurationAdmin,
- String pid, String factoryPid) throws IOException, InvalidSyntaxException {
- String filter;
- if (factoryPid == null) {
- filter = "(" + Constants.SERVICE_PID + "=" + pid + ")";
- } else {
- String key = createConfigurationKey(pid, factoryPid);
- filter = "(" + CONFIG_KEY + "=" + key + ")";
- }
- Configuration[] configurations = configurationAdmin.listConfigurations(filter);
- if (configurations != null && configurations.length > 0) {
- return configurations[0];
- }
- return null;
- }
-
- void installFeatureConfigs(Feature feature) throws IOException, InvalidSyntaxException {
- for (String config : feature.getConfigurations().keySet()) {
- Dictionary<String,String> props = new Hashtable<String, String>(feature.getConfigurations().get(config));
- String[] pid = parsePid(config);
- Configuration cfg = findExistingConfiguration(configAdmin, pid[0], pid[1]);
- if (cfg == null) {
- cfg = createConfiguration(configAdmin, pid[0], pid[1]);
- String key = createConfigurationKey(pid[0], pid[1]);
- props.put(CONFIG_KEY, key);
- if (cfg.getBundleLocation() != null) {
- cfg.setBundleLocation(null);
- }
- cfg.update(props);
- }
- }
- for (ConfigFileInfo configFile : feature.getConfigurationFiles()) {
- installConfigurationFile(configFile.getLocation(), configFile.getFinalname(), configFile.isOverride());
- }
- }
-
- private String createConfigurationKey(String pid, String factoryPid) {
- return factoryPid == null ? pid : pid + "-" + factoryPid;
- }
-
- private void installConfigurationFile(String fileLocation, String finalname, boolean override) throws IOException {
- String basePath = System.getProperty("karaf.base");
-
- if (finalname.contains("${")) {
- //remove any placeholder or variable part, this is not valid.
- int marker = finalname.indexOf("}");
- finalname = finalname.substring(marker+1);
- }
-
- finalname = basePath + File.separator + finalname;
-
- File file = new File(finalname);
- if (file.exists()) {
- if (!override) {
- LOGGER.debug("Configuration file {} already exist, don't override it", finalname);
- return;
- } else {
- LOGGER.info("Configuration file {} already exist, overriding it", finalname);
- }
- } else {
- LOGGER.info("Creating configuration file {}", finalname);
- }
-
- InputStream is = null;
- FileOutputStream fop = null;
- try {
- is = new BufferedInputStream(new URL(fileLocation).openStream());
-
- if (!file.exists()) {
- File parentFile = file.getParentFile();
- if (parentFile != null)
- parentFile.mkdirs();
- file.createNewFile();
- }
-
- fop = new FileOutputStream(file);
-
- int bytesRead;
- byte[] buffer = new byte[1024];
-
- while ((bytesRead = is.read(buffer)) != -1) {
- fop.write(buffer, 0, bytesRead);
- }
- } catch (RuntimeException e) {
- LOGGER.error(e.getMessage());
- throw e;
- } catch (MalformedURLException e) {
- LOGGER.error(e.getMessage());
- throw e;
- } finally {
- if (is != null)
- is.close();
- if (fop != null) {
- fop.flush();
- fop.close();
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
deleted file mode 100644
index d6defe0..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureFinder.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.net.URI;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
-
-public class FeatureFinder implements ManagedService {
-
- final Map<String, String> nameToArtifactMap = new HashMap<String, String>();
-
- public String[] getNames() {
- synchronized (nameToArtifactMap) {
- Set<String> strings = nameToArtifactMap.keySet();
- return strings.toArray(new String[strings.size()]);
- }
- }
-
- public URI getUriFor(String name, String version) {
- String coords;
- synchronized (nameToArtifactMap) {
- coords = nameToArtifactMap.get(name);
- }
- if (coords == null) {
- return null;
- }
- Artifact artifact = new Artifact(coords);
- return artifact.getMavenUrl(version);
- }
-
- @SuppressWarnings("rawtypes")
- public void updated(Dictionary properties) throws ConfigurationException {
- synchronized (nameToArtifactMap) {
- if (properties != null) {
- nameToArtifactMap.clear();
- Enumeration keys = properties.keys();
- while (keys.hasMoreElements()) {
- String key = (String) keys.nextElement();
- if (!"felix.fileinstall.filename".equals(key) && !"service.pid".equals(key)) {
- nameToArtifactMap.put(key, (String) properties.get(key));
- }
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
deleted file mode 100644
index 8fb161e..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureValidationUtil.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URLConnection;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-
-import org.apache.karaf.features.FeaturesNamespaces;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-/**
- * Utility class which fires XML Schema validation.
- */
-public class FeatureValidationUtil {
-
- public static final QName FEATURES_0_0 = new QName("features");
- public static final QName FEATURES_1_0 = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features");
- public static final QName FEATURES_1_1 = new QName("http://karaf.apache.org/xmlns/features/v1.1.0", "features");
- public static final QName FEATURES_1_2 = new QName("http://karaf.apache.org/xmlns/features/v1.2.0", "features");
- private static final Logger LOGGER = LoggerFactory.getLogger(FeatureValidationUtil.class);
-
- /**
- * Runs schema validation.
- *
- * @param uri Uri to validate.
- * @throws Exception When validation fails.
- */
- public static void validate(URI uri) throws Exception {
- Document doc = load(uri);
-
- QName name = new QName(doc.getDocumentElement().getNamespaceURI(), doc.getDocumentElement().getLocalName());
-
- if (FeaturesNamespaces.FEATURES_0_0_0.equals(name)) {
- LOGGER.warn("Old style feature file without namespace found (URI: {}). This format is deprecated and support for it will soon be removed", uri);
- return;
- } else if (FeaturesNamespaces.FEATURES_1_0_0.equals(name)) {
- validate(doc, "/org/apache/karaf/features/karaf-features-1.0.0.xsd");
- } else if (FeaturesNamespaces.FEATURES_1_1_0.equals(name)) {
- validate(doc, "/org/apache/karaf/features/karaf-features-1.1.0.xsd");
- } else if (FeaturesNamespaces.FEATURES_1_2_0.equals(name)) {
- validate(doc, "/org/apache/karaf/features/karaf-features-1.2.0.xsd");
- } else if (FeaturesNamespaces.FEATURES_1_3_0.equals(name)) {
- validate(doc, "/org/apache/karaf/features/karaf-features-1.3.0.xsd");
- }
- else {
- throw new IllegalArgumentException("Unrecognized root element: " + name);
- }
- }
-
- private static Document load(URI uri) throws IOException, SAXException, ParserConfigurationException {
- InputStream stream = null;
- try {
- URLConnection conn;
- try {
- conn = uri.toURL().openConnection();
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("invalid URI: " + uri, e);
- }
- conn.setDefaultUseCaches(false);
- stream = conn.getInputStream();
- // load document and check the root element for namespace declaration
- DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
- dFactory.setNamespaceAware(true);
- return dFactory.newDocumentBuilder().parse(stream);
- } finally {
- if (stream != null) {
- stream.close();
- }
- }
- }
-
- private static void validate(Document doc, String schemaLocation) throws SAXException {
- SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- // root element has namespace - we can use schema validation
- Schema schema = factory.newSchema(new StreamSource(FeatureValidationUtil.class.getResourceAsStream(schemaLocation)));
- // create schema by reading it from an XSD file:
- Validator validator = schema.newValidator();
- try {
- validator.validate(new DOMSource(doc));
- } catch (Exception e) {
- throw new IllegalArgumentException("Unable to validate " + doc.getDocumentURI(), e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
deleted file mode 100644
index 495f3f8..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * 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.internal.service;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeatureEvent;
-import org.apache.karaf.features.FeaturesListener;
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.features.Repository;
-import org.apache.karaf.features.RepositoryEvent;
-import org.apache.karaf.features.internal.deployment.DeploymentBuilder;
-import org.apache.karaf.features.internal.deployment.StreamProvider;
-import org.apache.karaf.features.internal.resolver.FeatureNamespace;
-import org.apache.karaf.features.internal.resolver.UriNamespace;
-import org.apache.karaf.features.internal.util.ChecksumUtils;
-import org.apache.karaf.features.internal.util.Macro;
-import org.apache.karaf.features.internal.util.MultiException;
-import org.apache.karaf.util.collections.CopyOnWriteArrayIdentityList;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.PackageNamespace;
-import org.osgi.framework.startlevel.BundleStartLevel;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.FrameworkWiring;
-import org.osgi.resource.Resource;
-import org.osgi.resource.Wire;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.felix.resolver.Util.getSymbolicName;
-import static org.apache.felix.resolver.Util.getVersion;
-
-/**
- *
- */
-public class FeaturesServiceImpl implements FeaturesService {
-
- public static final String UPDATE_SNAPSHOTS_NONE = "none";
- public static final String UPDATE_SNAPSHOTS_CRC = "crc";
- public static final String UPDATE_SNAPSHOTS_ALWAYS = "always";
- public static final String DEFAULT_UPDATE_SNAPSHOTS = UPDATE_SNAPSHOTS_CRC;
-
- public static final String DEFAULT_FEATURE_RESOLUTION_RANGE = "${range;[====,====]}";
- public static final String DEFAULT_BUNDLE_UPDATE_RANGE = "${range;[==,=+)}";
-
- private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
- private static final String SNAPSHOT = "SNAPSHOT";
- private static final String MAVEN = "mvn:";
-
- /**
- * Our bundle.
- * We use it to check bundle operations affecting our own bundle.
- */
- private final Bundle bundle;
-
- /**
- * The system bundle context.
- * For all bundles related operations, we use the system bundle context
- * to allow this bundle to be stopped and still allow the deployment to
- * take place.
- */
- private final BundleContext systemBundleContext;
- /**
- * Used to load and save the {@link State} of this service.
- */
- private final StateStorage storage;
- private final FeatureFinder featureFinder;
- private final EventAdminListener eventAdminListener;
- private final FeatureConfigInstaller configInstaller;
- private final String overrides;
- /**
- * Range to use when a version is specified on a feature dependency.
- * The default is {@link FeaturesServiceImpl#DEFAULT_FEATURE_RESOLUTION_RANGE}
- */
- private final String featureResolutionRange;
- /**
- * Range to use when verifying if a bundle should be updated or
- * new bundle installed.
- * The default is {@link FeaturesServiceImpl#DEFAULT_BUNDLE_UPDATE_RANGE}
- */
- private final String bundleUpdateRange;
- /**
- * Use CRC to check snapshot bundles and update them if changed.
- * Either:
- * - none : never update snapshots
- * - always : always update snapshots
- * - crc : use CRC to detect changes
- */
- private final String updateSnaphots;
-
- private final List<FeaturesListener> listeners = new CopyOnWriteArrayIdentityList<FeaturesListener>();
-
- // Synchronized on lock
- private final Object lock = new Object();
- private final State state = new State();
- private final Map<String, Repository> repositoryCache = new HashMap<String, Repository>();
- private Map<String, Map<String, Feature>> featureCache;
-
-
- public FeaturesServiceImpl(Bundle bundle,
- BundleContext systemBundleContext,
- StateStorage storage,
- FeatureFinder featureFinder,
- EventAdminListener eventAdminListener,
- FeatureConfigInstaller configInstaller,
- String overrides,
- String featureResolutionRange,
- String bundleUpdateRange,
- String updateSnaphots) {
- this.bundle = bundle;
- this.systemBundleContext = systemBundleContext;
- this.storage = storage;
- this.featureFinder = featureFinder;
- this.eventAdminListener = eventAdminListener;
- this.configInstaller = configInstaller;
- this.overrides = overrides;
- this.featureResolutionRange = featureResolutionRange;
- this.bundleUpdateRange = bundleUpdateRange;
- this.updateSnaphots = updateSnaphots;
- loadState();
- }
-
- //
- // State support
- //
-
- protected void loadState() {
- try {
- synchronized (lock) {
- storage.load(state);
- }
- } catch (IOException e) {
- LOGGER.warn("Error loading FeaturesService state", e);
- }
- }
-
- protected void saveState() {
- try {
- synchronized (lock) {
- // Make sure we don't store bundle checksums if
- // it has been disabled through configadmin
- // so that we don't keep out-of-date checksums.
- if (!UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
- state.bundleChecksums.clear();
- }
- storage.save(state);
- }
- } catch (IOException e) {
- LOGGER.warn("Error saving FeaturesService state", e);
- }
- }
-
- boolean isBootDone() {
- synchronized (lock) {
- return state.bootDone.get();
- }
- }
-
- void bootDone() {
- synchronized (lock) {
- state.bootDone.set(true);
- saveState();
- }
- }
-
- //
- // Listeners support
- //
-
- public void registerListener(FeaturesListener listener) {
- listeners.add(listener);
- try {
- Set<String> repositories = new TreeSet<String>();
- Set<String> installedFeatures = new TreeSet<String>();
- synchronized (lock) {
- repositories.addAll(state.repositories);
- installedFeatures.addAll(state.installedFeatures);
- }
- for (String uri : repositories) {
- Repository repository = new RepositoryImpl(URI.create(uri));
- listener.repositoryEvent(new RepositoryEvent(repository, RepositoryEvent.EventType.RepositoryAdded, true));
- }
- for (String id : installedFeatures) {
- Feature feature = org.apache.karaf.features.internal.model.Feature.valueOf(id);
- listener.featureEvent(new FeatureEvent(feature, FeatureEvent.EventType.FeatureInstalled, true));
- }
- } catch (Exception e) {
- LOGGER.error("Error notifying listener about the current state", e);
- }
- }
-
- public void unregisterListener(FeaturesListener listener) {
- listeners.remove(listener);
- }
-
- protected void callListeners(FeatureEvent event) {
- if (eventAdminListener != null) {
- eventAdminListener.featureEvent(event);
- }
- for (FeaturesListener listener : listeners) {
- listener.featureEvent(event);
- }
- }
-
- protected void callListeners(RepositoryEvent event) {
- if (eventAdminListener != null) {
- eventAdminListener.repositoryEvent(event);
- }
- for (FeaturesListener listener : listeners) {
- listener.repositoryEvent(event);
- }
- }
-
- //
- // Feature Finder support
- //
-
- @Override
- public URI getRepositoryUriFor(String name, String version) {
- return featureFinder.getUriFor(name, version);
- }
-
- @Override
- public String[] getRepositoryNames() {
- return featureFinder.getNames();
- }
-
-
- //
- // Repositories support
- //
-
- public Repository loadRepository(URI uri) throws Exception {
- // TODO: merge validation and loading by loading the DOM, validating, unmarshalling
- FeatureValidationUtil.validate(uri);
- RepositoryImpl repo = new RepositoryImpl(uri);
- repo.load();
- return repo;
- }
-
- @Override
- public void validateRepository(URI uri) throws Exception {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addRepository(URI uri) throws Exception {
- addRepository(uri, false);
- }
-
- @Override
- public void addRepository(URI uri, boolean install) throws Exception {
- if (install) {
- // TODO: implement
- throw new UnsupportedOperationException();
- }
- Repository repository = loadRepository(uri);
- synchronized (lock) {
- // Clean cache
- repositoryCache.put(uri.toString(), repository);
- featureCache = null;
- // Add repo
- if (!state.repositories.add(uri.toString())) {
- return;
- }
- saveState();
- }
- callListeners(new RepositoryEvent(repository, RepositoryEvent.EventType.RepositoryAdded, false));
- }
-
- @Override
- public void removeRepository(URI uri) throws Exception {
- removeRepository(uri, true);
- }
-
- @Override
- public void removeRepository(URI uri, boolean uninstall) throws Exception {
- // TODO: check we don't have any feature installed from this repository
- Repository repo;
- synchronized (lock) {
- // Remove repo
- if (!state.repositories.remove(uri.toString())) {
- return;
- }
- // Clean cache
- featureCache = null;
- repo = repositoryCache.get(uri.toString());
- List<String> toRemove = new ArrayList<String>();
- toRemove.add(uri.toString());
- while (!toRemove.isEmpty()) {
- Repository rep = repositoryCache.remove(toRemove.remove(0));
- if (rep != null) {
- for (URI u : rep.getRepositories()) {
- toRemove.add(u.toString());
- }
- }
- }
- saveState();
- }
- if (repo == null) {
- repo = new RepositoryImpl(uri);
- }
- callListeners(new RepositoryEvent(repo, RepositoryEvent.EventType.RepositoryRemoved, false));
- }
-
- @Override
- public void restoreRepository(URI uri) throws Exception {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void refreshRepository(URI uri) throws Exception {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Repository[] listRepositories() throws Exception {
- // Make sure the cache is loaded
- getFeatures();
- synchronized (lock) {
- return repositoryCache.values().toArray(new Repository[repositoryCache.size()]);
- }
- }
-
- @Override
- public Repository[] listRequiredRepositories() throws Exception {
- // Make sure the cache is loaded
- getFeatures();
- synchronized (lock) {
- List<Repository> repos = new ArrayList<Repository>();
- for (Map.Entry<String, Repository> entry : repositoryCache.entrySet()) {
- if (state.repositories.contains(entry.getKey())) {
- repos.add(entry.getValue());
- }
- }
- return repos.toArray(new Repository[repos.size()]);
- }
- }
-
- @Override
- public Repository getRepository(String name) throws Exception {
- // Make sure the cache is loaded
- getFeatures();
- synchronized (lock) {
- for (Repository repo : this.repositoryCache.values()) {
- if (name.equals(repo.getName())) {
- return repo;
- }
- }
- return null;
- }
- }
-
- //
- // Features support
- //
-
- public Feature getFeature(String name) throws Exception {
- return getFeature(name, null);
- }
-
- public Feature getFeature(String name, String version) throws Exception {
- Map<String, Feature> versions = getFeatures().get(name);
- return getFeatureMatching(versions, version);
- }
-
- protected Feature getFeatureMatching(Map<String, Feature> versions, String version) {
- if (version != null) {
- version = version.trim();
- if (version.equals(org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION)) {
- version = "";
- }
- } else {
- version = "";
- }
- if (versions == null || versions.isEmpty()) {
- return null;
- } else {
- Feature feature = version.isEmpty() ? null : versions.get(version);
- if (feature == null) {
- // Compute version range. If an version has been given, assume exact range
- VersionRange versionRange = version.isEmpty() ?
- new VersionRange(Version.emptyVersion) :
- new VersionRange(version, true, true);
- Version latest = Version.emptyVersion;
- for (String available : versions.keySet()) {
- Version availableVersion = VersionTable.getVersion(available);
- if (availableVersion.compareTo(latest) >= 0 && versionRange.contains(availableVersion)) {
- feature = versions.get(available);
- latest = availableVersion;
- }
- }
- }
- return feature;
- }
- }
-
- public Feature[] listFeatures() throws Exception {
- Set<Feature> features = new HashSet<Feature>();
- for (Map<String, Feature> featureWithDifferentVersion : getFeatures().values()) {
- for (Feature f : featureWithDifferentVersion.values()) {
- features.add(f);
- }
- }
- return features.toArray(new Feature[features.size()]);
- }
-
- protected Map<String, Map<String, Feature>> getFeatures() throws Exception {
- List<String> uris;
- synchronized (lock) {
- if (featureCache != null) {
- return featureCache;
- }
- uris = new ArrayList<String>(state.repositories);
- }
- //the outer map's key is feature name, the inner map's key is feature version
- Map<String, Map<String, Feature>> map = new HashMap<String, Map<String, Feature>>();
- // Two phase load:
- // * first load dependent repositories
- List<String> toLoad = new ArrayList<String>(uris);
- while (!toLoad.isEmpty()) {
- String uri = toLoad.remove(0);
- Repository repo;
- synchronized (lock) {
- repo = repositoryCache.get(uri);
- }
- if (repo == null) {
- RepositoryImpl rep = new RepositoryImpl(URI.create(uri));
- rep.load();
- repo = rep;
- synchronized (lock) {
- repositoryCache.put(uri, repo);
- }
- }
- for (URI u : repo.getRepositories()) {
- toLoad.add(u.toString());
- }
- }
- List<Repository> repos;
- synchronized (lock) {
- repos = new ArrayList<Repository>(repositoryCache.values());
- }
- // * then load all features
- for (Repository repo : repos) {
- for (Feature f : repo.getFeatures()) {
- if (map.get(f.getName()) == null) {
- Map<String, Feature> versionMap = new HashMap<String, Feature>();
- versionMap.put(f.getVersion(), f);
- map.put(f.getName(), versionMap);
- } else {
- map.get(f.getName()).put(f.getVersion(), f);
- }
- }
- }
- synchronized (lock) {
- if (uris.size() == state.repositories.size() &&
- state.repositories.containsAll(uris)) {
- featureCache = map;
- }
- }
- return map;
- }
-
- //
- // Installed features
- //
-
- @Override
- public Feature[] listInstalledFeatures() throws Exception {
- Set<Feature> features = new HashSet<Feature>();
- Map<String, Map<String, Feature>> allFeatures = getFeatures();
- synchronized (lock) {
- for (Map<String, Feature> featureWithDifferentVersion : allFeatures.values()) {
- for (Feature f : featureWithDifferentVersion.values()) {
- if (isInstalled(f)) {
- features.add(f);
- }
- }
- }
- }
- return features.toArray(new Feature[features.size()]);
- }
-
- @Override
- public Feature[] listRequiredFeatures() throws Exception {
- Set<Feature> features = new HashSet<Feature>();
- Map<String, Map<String, Feature>> allFeatures = getFeatures();
- synchronized (lock) {
- for (Map<String, Feature> featureWithDifferentVersion : allFeatures.values()) {
- for (Feature f : featureWithDifferentVersion.values()) {
- if (isRequired(f)) {
- features.add(f);
- }
- }
- }
- }
- return features.toArray(new Feature[features.size()]);
- }
-
-
- @Override
- public boolean isInstalled(Feature f) {
- String id = normalize(f.getId());
- synchronized (lock) {
- return state.installedFeatures.contains(id);
- }
- }
-
- @Override
- public boolean isRequired(Feature f) {
- String id = normalize(f.getId());
- synchronized (lock) {
- return state.features.contains(id);
- }
- }
-
- //
- // Installation and uninstallation of features
- //
-
- public void installFeature(String name) throws Exception {
- installFeature(name, EnumSet.noneOf(Option.class));
- }
-
- public void installFeature(String name, String version) throws Exception {
- installFeature(version != null ? name + "/" + version : name, EnumSet.noneOf(Option.class));
- }
-
- public void installFeature(String name, EnumSet<Option> options) throws Exception {
- installFeatures(Collections.singleton(name), options);
- }
-
- public void installFeature(String name, String version, EnumSet<Option> options) throws Exception {
- installFeature(version != null ? name + "/" + version : name, options);
- }
-
- public void installFeature(Feature feature, EnumSet<Option> options) throws Exception {
- installFeature(feature.getId());
- }
-
- @Override
- public void uninstallFeature(String name, String version) throws Exception {
- uninstallFeature(version != null ? name + "/" + version : name);
- }
-
- @Override
- public void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception {
- uninstallFeature(version != null ? name + "/" + version : name, options);
- }
-
- @Override
- public void uninstallFeature(String name) throws Exception {
- uninstallFeature(name, EnumSet.noneOf(Option.class));
- }
-
- @Override
- public void uninstallFeature(String name, EnumSet<Option> options) throws Exception {
- uninstallFeatures(Collections.singleton(name), options);
- }
-
-
- //
- //
- //
- // RESOLUTION
- //
- //
- //
-
-
-
-
-
-
- public void installFeatures(Set<String> features, EnumSet<Option> options) throws Exception {
- Set<String> required;
- Set<String> installed;
- Set<Long> managed;
- synchronized (lock) {
- required = new HashSet<String>(state.features);
- installed = new HashSet<String>(state.installedFeatures);
- managed = new HashSet<Long>(state.managedBundles);
- }
- List<String> featuresToAdd = new ArrayList<String>();
- Map<String, Map<String, Feature>> featuresMap = getFeatures();
- for (String feature : features) {
- feature = normalize(feature);
- String name = feature.substring(0, feature.indexOf("/"));
- String version = feature.substring(feature.indexOf("/") + 1);
- Feature f = getFeatureMatching(featuresMap.get(name), version);
- if (f == null) {
- if (!options.contains(Option.NoFailOnFeatureNotFound)) {
- throw new IllegalArgumentException("No matching features for " + feature);
- }
- } else {
- featuresToAdd.add(normalize(f.getId()));
- }
- }
- featuresToAdd = new ArrayList<String>(new LinkedHashSet<String>(featuresToAdd));
- StringBuilder sb = new StringBuilder();
- sb.append("Adding features: ");
- for (int i = 0; i < featuresToAdd.size(); i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(featuresToAdd.get(i));
- }
- print(sb.toString(), options.contains(Option.Verbose));
- required.addAll(featuresToAdd);
- doInstallFeaturesInThread(required, installed, managed, options);
- }
-
- public void uninstallFeatures(Set<String> features, EnumSet<Option> options) throws Exception {
- Set<String> required;
- Set<String> installed;
- Set<Long> managed;
- synchronized (lock) {
- required = new HashSet<String>(state.features);
- installed = new HashSet<String>(state.installedFeatures);
- managed = new HashSet<Long>(state.managedBundles);
- }
- List<String> featuresToRemove = new ArrayList<String>();
- for (String feature : new HashSet<String>(features)) {
- List<String> toRemove = new ArrayList<String>();
- feature = normalize(feature);
- if (feature.endsWith("/0.0.0")) {
- String nameSep = feature.substring(0, feature.indexOf("/") + 1);
- for (String f : required) {
- if (normalize(f).startsWith(nameSep)) {
- toRemove.add(f);
- }
- }
- } else {
- toRemove.add(feature);
- }
- toRemove.retainAll(required);
- if (toRemove.isEmpty()) {
- throw new IllegalArgumentException("Feature named '" + feature + "' is not installed");
- } else if (toRemove.size() > 1) {
- String name = feature.substring(0, feature.indexOf("/"));
- StringBuilder sb = new StringBuilder();
- sb.append("Feature named '").append(name).append("' has multiple versions installed (");
- for (int i = 0; i < toRemove.size(); i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(toRemove.get(i));
- }
- sb.append("). Please specify the version to uninstall.");
- throw new IllegalArgumentException(sb.toString());
- }
- featuresToRemove.addAll(toRemove);
- }
- featuresToRemove = new ArrayList<String>(new LinkedHashSet<String>(featuresToRemove));
- StringBuilder sb = new StringBuilder();
- sb.append("Removing features: ");
- for (int i = 0; i < featuresToRemove.size(); i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(featuresToRemove.get(i));
- }
- print(sb.toString(), options.contains(Option.Verbose));
- required.removeAll(featuresToRemove);
- doInstallFeaturesInThread(required, installed, managed, options);
- }
-
- protected String normalize(String feature) {
- if (!feature.contains("/")) {
- feature += "/0.0.0";
- }
- int idx = feature.indexOf("/");
- String name = feature.substring(0, idx);
- String version = feature.substring(idx + 1);
- return name + "/" + VersionTable.getVersion(version).toString();
- }
-
- /**
- * Actual deployment needs to be done in a separate thread.
- * The reason is that if the console is refreshed, the current thread which is running
- * the command may be interrupted while waiting for the refresh to be done, leading
- * to bundles not being started after the refresh.
- */
- public void doInstallFeaturesInThread(final Set<String> features,
- final Set<String> installed,
- final Set<Long> managed,
- final EnumSet<Option> options) throws Exception {
- ExecutorService executor = Executors.newCachedThreadPool();
- try {
- executor.submit(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- doInstallFeatures(features, installed, managed, options);
- return null;
- }
- }).get();
- } catch (ExecutionException e) {
- Throwable t = e.getCause();
- if (t instanceof RuntimeException) {
- throw ((RuntimeException) t);
- } else if (t instanceof Error) {
- throw ((Error) t);
- } else if (t instanceof Exception) {
- throw (Exception) t;
- } else {
- throw e;
- }
- } finally {
- executor.shutdown();
- }
- }
-
- public void doInstallFeatures(Set<String> features, // all request features
- Set<String> installed, // installed features
- Set<Long> managed, // currently managed bundles
- EnumSet<Option> options // installation options
- ) throws Exception {
-
- boolean noRefreshUnmanaged = options.contains(Option.NoAutoRefreshUnmanagedBundles);
- boolean noRefreshManaged = options.contains(Option.NoAutoRefreshManagedBundles);
- boolean noRefresh = options.contains(Option.NoAutoRefreshBundles);
- boolean noStart = options.contains(Option.NoAutoStartBundles);
- boolean verbose = options.contains(Option.Verbose);
- boolean simulate = options.contains(Option.Simulate);
-
- // Get a list of resolved and unmanaged bundles to use as capabilities during resolution
- List<Resource> systemBundles = new ArrayList<Resource>();
- Bundle[] bundles = systemBundleContext.getBundles();
- for (Bundle bundle : bundles) {
- if (bundle.getState() >= Bundle.RESOLVED && !managed.contains(bundle.getBundleId())) {
- Resource res = bundle.adapt(BundleRevision.class);
- systemBundles.add(res);
- }
- }
- // Resolve
- // TODO: requirements
- // TODO: bundles
- // TODO: regions: on isolated regions, we may need different resolution for each region
- Set<String> overrides = Overrides.loadOverrides(this.overrides);
- Repository[] repositories = listRepositories();
- DeploymentBuilder builder = createDeploymentBuilder(repositories);
- builder.setFeatureRange(featureResolutionRange);
- builder.download(features,
- Collections.<String>emptySet(),
- Collections.<String>emptySet(),
- overrides,
- Collections.<String>emptySet());
- Map<Resource, List<Wire>> resolution = builder.resolve(systemBundles, false);
- Collection<Resource> allResources = resolution.keySet();
- Map<String, StreamProvider> providers = builder.getProviders();
-
- // Install conditionals
- List<String> installedFeatureIds = getFeatureIds(allResources);
- List<Feature> installedFeatures = getFeatures(repositories, installedFeatureIds);
-
- //
- // Compute list of installable resources (those with uris)
- //
- List<Resource> resources = getBundles(allResources);
-
- // Compute information for each bundle
- Map<String, BundleInfo> bundleInfos = new HashMap<String, BundleInfo>();
- for (Feature feature : getFeatures(repositories, getFeatureIds(allResources))) {
- for (BundleInfo bi : feature.getBundles()) {
- BundleInfo oldBi = bundleInfos.get(bi.getLocation());
- if (oldBi != null) {
- bi = mergeBundleInfo(bi, oldBi);
- }
- bundleInfos.put(bi.getLocation(), bi);
- }
- }
-
- // TODO: handle bundleInfo.isStart()
-
- // Get all resources that will be used to satisfy the old features set
- Set<Resource> resourceLinkedToOldFeatures = new HashSet<Resource>();
- if (noStart) {
- for (Resource resource : resolution.keySet()) {
- String name = FeatureNamespace.getName(resource);
- if (name != null) {
- Version version = FeatureNamespace.getVersion(resource);
- String id = version != null ? name + "/" + version : name;
- if (installed.contains(id)) {
- addTransitive(resource, resourceLinkedToOldFeatures, resolution);
- }
- }
- }
- }
-
- //
- // Compute deployment
- //
- Map<String, Long> bundleChecksums = new HashMap<String, Long>();
- synchronized (lock) {
- bundleChecksums.putAll(state.bundleChecksums);
- }
- Deployment deployment = computeDeployment(managed, bundles, providers, resources, bundleChecksums);
-
- if (deployment.toDelete.isEmpty() &&
- deployment.toUpdate.isEmpty() &&
- deployment.toInstall.isEmpty()) {
- print("No deployment change.", verbose);
- return;
- }
- //
- // Log deployment
- //
- logDeployment(deployment, verbose);
-
- if (simulate) {
- // TODO: it would be nice to print bundles that will be refreshed
- // TODO: it could be done by checking the differences between
- // TODO: the resolution result and the actual wiring state
- return;
- }
-
- Set<Bundle> toRefresh = new HashSet<Bundle>();
- Set<Bundle> toStart = new HashSet<Bundle>();
-
- //
- // Execute deployment
- //
-
- // TODO: handle update on the features service itself
- if (deployment.toUpdate.containsKey(bundle) ||
- deployment.toDelete.contains(bundle)) {
-
- LOGGER.warn("Updating or uninstalling of the FeaturesService is not supported");
- deployment.toUpdate.remove(bundle);
- deployment.toDelete.remove(bundle);
-
- }
-
- //
- // Perform bundle operations
- //
-
- // Stop bundles by chunks
- Set<Bundle> toStop = new HashSet<Bundle>();
- toStop.addAll(deployment.toUpdate.keySet());
- toStop.addAll(deployment.toDelete);
- removeFragmentsAndBundlesInState(toStop, Bundle.UNINSTALLED | Bundle.RESOLVED | Bundle.STOPPING);
- if (!toStop.isEmpty()) {
- print("Stopping bundles:", verbose);
- while (!toStop.isEmpty()) {
- List<Bundle> bs = getBundlesToStop(toStop);
- for (Bundle bundle : bs) {
- print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- bundle.stop(Bundle.STOP_TRANSIENT);
- toStop.remove(bundle);
- }
- }
- }
- if (!deployment.toDelete.isEmpty()) {
- print("Uninstalling bundles:", verbose);
- for (Bundle bundle : deployment.toDelete) {
- print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- bundle.uninstall();
- managed.remove(bundle.getBundleId());
- toRefresh.add(bundle);
- }
- }
- if (!deployment.toUpdate.isEmpty()) {
- print("Updating bundles:", verbose);
- for (Map.Entry<Bundle, Resource> entry : deployment.toUpdate.entrySet()) {
- Bundle bundle = entry.getKey();
- Resource resource = entry.getValue();
- String uri = UriNamespace.getUri(resource);
- print(" " + uri, verbose);
- InputStream is = getBundleInputStream(resource, providers);
- bundle.update(is);
- toRefresh.add(bundle);
- toStart.add(bundle);
- BundleInfo bi = bundleInfos.get(uri);
- if (bi != null && bi.getStartLevel() > 0) {
- bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
- }
- // TODO: handle region
- }
- }
- if (!deployment.toInstall.isEmpty()) {
- print("Installing bundles:", verbose);
- for (Resource resource : deployment.toInstall) {
- String uri = UriNamespace.getUri(resource);
- print(" " + uri, verbose);
- InputStream is = getBundleInputStream(resource, providers);
- Bundle bundle = systemBundleContext.installBundle(uri, is);
- managed.add(bundle.getBundleId());
- if (!noStart || resourceLinkedToOldFeatures.contains(resource)) {
- toStart.add(bundle);
- }
- deployment.resToBnd.put(resource, bundle);
- // save a checksum of installed snapshot bundle
- if (UPDATE_SNAPSHOTS_CRC.equals(updateSnaphots)
- && isUpdateable(resource) && !deployment.newCheckums.containsKey(bundle.getLocation())) {
- deployment.newCheckums.put(bundle.getLocation(), ChecksumUtils.checksum(getBundleInputStream(resource, providers)));
- }
- BundleInfo bi = bundleInfos.get(uri);
- if (bi != null && bi.getStartLevel() > 0) {
- bundle.adapt(BundleStartLevel.class).setStartLevel(bi.getStartLevel());
- }
- // TODO: handle region
- }
- }
-
- //
- // Update and save state
- //
- List<String> newFeatures = new ArrayList<String>();
- synchronized (lock) {
- List<String> allFeatures = new ArrayList<String>();
- for (Resource resource : allResources) {
- String name = FeatureNamespace.getName(resource);
- if (name != null) {
- Version version = FeatureNamespace.getVersion(resource);
- String id = version != null ? name + "/" + version : name;
- allFeatures.add(id);
- if (!state.installedFeatures.contains(id)) {
- newFeatures.add(id);
- }
- }
- }
- state.bundleChecksums.putAll(deployment.newCheckums);
- state.features.clear();
- state.features.addAll(features);
- state.installedFeatures.clear();
- state.installedFeatures.addAll(allFeatures);
- state.managedBundles.clear();
- state.managedBundles.addAll(managed);
- saveState();
- }
-
- //
- // Install configurations
- //
- if (configInstaller != null && !newFeatures.isEmpty()) {
- for (Repository repository : repositories) {
- for (Feature feature : repository.getFeatures()) {
- if (newFeatures.contains(feature.getId())) {
- configInstaller.installFeatureConfigs(feature);
- }
- }
- }
- }
-
- if (!noRefreshManaged) {
- findBundlesWithOptionalPackagesToRefresh(toRefresh);
- findBundlesWithFragmentsToRefresh(toRefresh);
- }
-
- if (noRefreshUnmanaged) {
- Set<Bundle> newSet = new HashSet<Bundle>();
- for (Bundle bundle : toRefresh) {
- if (managed.contains(bundle.getBundleId())) {
- newSet.add(bundle);
- }
- }
- toRefresh = newSet;
- }
-
- // TODO: remove this hack, but it avoids loading the class after the bundle is refreshed
- RequirementSort sort = new RequirementSort();
-
- if (!noRefresh) {
- toStop = new HashSet<Bundle>();
- toStop.addAll(toRefresh);
- removeFragmentsAndBundlesInState(toStop, Bundle.UNINSTALLED | Bundle.RESOLVED | Bundle.STOPPING);
- if (!toStop.isEmpty()) {
- print("Stopping bundles:", verbose);
- while (!toStop.isEmpty()) {
- List<Bundle> bs = getBundlesToStop(toStop);
- for (Bundle bundle : bs) {
- print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- bundle.stop(Bundle.STOP_TRANSIENT);
- toStop.remove(bundle);
- toStart.add(bundle);
- }
- }
- }
-
- if (!toRefresh.isEmpty()) {
- print("Refreshing bundles:", verbose);
- for (Bundle bundle : toRefresh) {
- print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- }
- if (!toRefresh.isEmpty()) {
- refreshPackages(toRefresh);
- }
- }
- }
-
- // Compute bundles to start
- removeFragmentsAndBundlesInState(toStart, Bundle.UNINSTALLED | Bundle.ACTIVE | Bundle.STARTING);
- if (!toStart.isEmpty()) {
- // Compute correct start order
- List<Exception> exceptions = new ArrayList<Exception>();
- print("Starting bundles:", verbose);
- while (!toStart.isEmpty()) {
- List<Bundle> bs = getBundlesToStart(toStart);
- for (Bundle bundle : bs) {
- LOGGER.info(" " + bundle.getSymbolicName() + " / " + bundle.getVersion());
- try {
- bundle.start();
- } catch (BundleException e) {
- exceptions.add(e);
- }
- toStart.remove(bundle);
- }
- }
- if (!exceptions.isEmpty()) {
- throw new MultiException("Error restarting bundles", exceptions);
- }
- }
-
- // TODO: call listeners for features added and removed
-
- print("Done.", verbose);
- }
-
- private void addTransitive(Resource resource, Set<Resource> resources, Map<Resource, List<Wire>> resolution) {
- if (resources.add(resource)) {
- for (Wire wire : resolution.get(resource)) {
- addTransitive(wire.getProvider(), resources, resolution);
- }
- }
- }
-
- protected BundleInfo mergeBundleInfo(BundleInfo bi, BundleInfo oldBi) {
- // TODO: we need a proper merge strategy when a bundle
- // TODO: comes from different features
- return bi;
- }
-
- private void print(String message, boolean verbose) {
- LOGGER.info(message);
- if (verbose) {
- System.out.println(message);
- }
- }
-
- private void removeFragmentsAndBundlesInState(Collection<Bundle> bundles, int state) {
- for (Bundle bundle : new ArrayList<Bundle>(bundles)) {
- if ((bundle.getState() & state) != 0
- || bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null) {
- bundles.remove(bundle);
- }
- }
- }
-
- protected void logDeployment(Deployment deployment, boolean verbose) {
- print("Changes to perform:", verbose);
- if (!deployment.toDelete.isEmpty()) {
- print(" Bundles to uninstall:", verbose);
- for (Bundle bundle : deployment.toDelete) {
- print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion(), verbose);
- }
- }
- if (!deployment.toUpdate.isEmpty()) {
- print(" Bundles to update:", verbose);
- for (Map.Entry<Bundle, Resource> entry : deployment.toUpdate.entrySet()) {
- print(" " + entry.getKey().getSymbolicName() + " / " + entry.getKey().getVersion() + " with " + UriNamespace.getUri(entry.getValue()), verbose);
- }
- }
- if (!deployment.toInstall.isEmpty()) {
- print(" Bundles to install:", verbose);
- for (Resource resource : deployment.toInstall) {
- print(" " + UriNamespace.getUri(resource), verbose);
- }
- }
- }
-
- protected Deployment computeDeployment(
- Set<Long> managed,
- Bundle[] bundles,
- Map<String, StreamProvider> providers,
- List<Resource> resources,
- Map<String, Long> bundleChecksums) throws IOException {
- Deployment deployment = new Deployment();
-
- // TODO: regions
- List<Resource> toDeploy = new ArrayList<Resource>(resources);
-
- // First pass: go through all installed bundles and mark them
- // as either to ignore or delete
- for (Bundle bundle : bundles) {
- if (bundle.getSymbolicName() != null && bundle.getBundleId() != 0) {
- Resource resource = null;
- for (Resource res : toDeploy) {
- if (bundle.getSymbolicName().equals(getSymbolicName(res))) {
- if (bundle.getVersion().equals(getVersion(res))) {
- resource = res;
- break;
- }
- }
- }
- // We found a matching bundle
- if (resource != null) {
- // In case of snapshots, check if the snapshot is out of date
- // and flag it as to update
- if (managed.contains(bundle.getBundleId()) && isUpdateable(resource)) {
- // Always update snapshots
- if (UPDATE_SNAPSHOTS_ALWAYS.equalsIgnoreCase(updateSnaphots)) {
- LOGGER.debug("Update snapshot for " + bundle.getLocation());
- deployment.toUpdate.put(bundle, resource);
- }
- else if (UPDATE_SNAPSHOTS_CRC.equalsIgnoreCase(updateSnaphots)) {
- // if the checksum are different
- InputStream is = null;
- try {
- is = getBundleInputStream(resource, providers);
- long newCrc = ChecksumUtils.checksum(is);
- long oldCrc = bundleChecksums.containsKey(bundle.getLocation()) ? bundleChecksums.get(bundle.getLocation()) : 0l;
- if (newCrc != oldCrc) {
- LOGGER.debug("New snapshot available for " + bundle.getLocation());
- deployment.toUpdate.put(bundle, resource);
- deployment.newCheckums.put(bundle.getLocation(), newCrc);
- }
- } finally {
- if (is != null) {
- is.close();
- }
- }
- }
- }
- // We're done for this resource
- toDeploy.remove(resource);
- deployment.resToBnd.put(resource, bundle);
- // There's no matching resource
- // If the bundle is managed, we need to delete it
- } else if (managed.contains(bundle.getBundleId())) {
- deployment.toDelete.add(bundle);
- }
- }
- }
-
- // Second pass on remaining resources
- for (Resource resource : toDeploy) {
- TreeMap<Version, Bundle> matching = new TreeMap<Version, Bundle>();
- VersionRange range = new VersionRange(Macro.transform(bundleUpdateRange, getVersion(resource).toString()));
- for (Bundle bundle : deployment.toDelete) {
- if (bundle.getSymbolicName().equals(getSymbolicName(resource)) && range.contains(bundle.getVersion())) {
- matching.put(bundle.getVersion(), bundle);
- }
- }
- if (!matching.isEmpty()) {
- Bundle bundle = matching.lastEntry().getValue();
- deployment.toUpdate.put(bundle, resource);
- deployment.toDelete.remove(bundle);
- deployment.resToBnd.put(resource, bundle);
- } else {
- deployment.toInstall.add(resource);
- }
- }
- return deployment;
- }
-
- protected List<Resource> getBundles(Collection<Resource> allResources) {
- Map<String, Resource> deploy = new TreeMap<String, Resource>();
- for (Resource res : allResources) {
- String uri = UriNamespace.getUri(res);
- if (uri != null) {
- deploy.put(uri, res);
- }
- }
- return new ArrayList<Resource>(deploy.values());
- }
-
- protected List<Feature> getFeatures(Repository[] repositories, List<String> featureIds) throws Exception {
- List<Feature> installedFeatures = new ArrayList<Feature>();
- for (Repository repository : repositories) {
- for (Feature feature : repository.getFeatures()) {
- String id = feature.getName() + "/" + VersionTable.getVersion(feature.getVersion());
- if (featureIds.contains(id)) {
- installedFeatures.add(feature);
- }
- }
- }
- return installedFeatures;
- }
-
- protected List<String> getFeatureIds(Collection<Resource> allResources) {
- List<String> installedFeatureIds = new ArrayList<String>();
- for (Resource resource : allResources) {
- String name = FeatureNamespace.getName(resource);
- if (name != null) {
- Version version = FeatureNamespace.getVersion(resource);
- String id = version != null ? name + "/" + version : name;
- installedFeatureIds.add(id);
- }
- }
- return installedFeatureIds;
- }
-
- protected DeploymentBuilder createDeploymentBuilder(Repository[] repositories) {
- return new DeploymentBuilder(new SimpleDownloader(), Arrays.asList(repositories));
- }
-
-
- protected boolean isUpdateable(Resource resource) {
- return (getVersion(resource).getQualifier().endsWith(SNAPSHOT) ||
- UriNamespace.getUri(resource).contains(SNAPSHOT) ||
- !UriNamespace.getUri(resource).contains(MAVEN));
- }
-
- protected List<Bundle> getBundlesToStart(Collection<Bundle> bundles) {
- // TODO: make this pluggable ?
- // TODO: honor respectStartLvlDuringFeatureStartup
-
- // We hit FELIX-2949 if we don't use the correct order as Felix resolver isn't greedy.
- // In order to minimize that, we make sure we resolve the bundles in the order they
- // are given back by the resolution, meaning that all root bundles (i.e. those that were
- // not flagged as dependencies in features) are started before the others. This should
- // make sure those important bundles are started first and minimize the problem.
-
- // Restart the features service last, regardless of any other consideration
- // so that we don't end up with the service trying to do stuff before we're done
- boolean restart = bundles.remove(bundle);
-
- List<BundleRevision> revs = new ArrayList<BundleRevision>();
- for (Bundle bundle : bundles) {
- revs.add(bundle.adapt(BundleRevision.class));
- }
- List<Bundle> sorted = new ArrayList<Bundle>();
- for (BundleRevision rev : RequirementSort.sort(revs)) {
- sorted.add(rev.getBundle());
- }
- if (restart) {
- sorted.add(bundle);
- }
- return sorted;
- }
-
- protected List<Bundle> getBundlesToStop(Collection<Bundle> bundles) {
- // TODO: make this pluggable ?
- // TODO: honor respectStartLvlDuringFeatureUninstall
-
- List<Bundle> bundlesToDestroy = new ArrayList<Bundle>();
- for (Bundle bundle : bundles) {
- ServiceReference[] references = bundle.getRegisteredServices();
- int usage = 0;
- if (references != null) {
- for (ServiceReference reference : references) {
- usage += getServiceUsage(reference, bundles);
- }
- }
- LOGGER.debug("Usage for bundle {} is {}", bundle, usage);
- if (usage == 0) {
- bundlesToDestroy.add(bundle);
- }
- }
- if (!bundlesToDestroy.isEmpty()) {
- Collections.sort(bundlesToDestroy, new Comparator<Bundle>() {
- public int compare(Bundle b1, Bundle b2) {
- return (int) (b2.getLastModified() - b1.getLastModified());
- }
- });
- LOGGER.debug("Selected bundles {} for destroy (no services in use)", bundlesToDestroy);
- } else {
- ServiceReference ref = null;
- for (Bundle bundle : bundles) {
- ServiceReference[] references = bundle.getRegisteredServices();
- for (ServiceReference reference : references) {
- if (getServiceUsage(reference, bundles) == 0) {
- continue;
- }
- if (ref == null || reference.compareTo(ref) < 0) {
- LOGGER.debug("Currently selecting bundle {} for destroy (with reference {})", bundle, reference);
- ref = reference;
- }
- }
- }
- if (ref != null) {
- bundlesToDestroy.add(ref.getBundle());
- }
- LOGGER.debug("Selected bundle {} for destroy (lowest ranking service)", bundlesToDestroy);
- }
- return bundlesToDestroy;
- }
-
- private static int getServiceUsage(ServiceReference ref, Collection<Bundle> bundles) {
- Bundle[] usingBundles = ref.getUsingBundles();
- int nb = 0;
- if (usingBundles != null) {
- for (Bundle bundle : usingBundles) {
- if (bundles.contains(bundle)) {
- nb++;
- }
- }
- }
- return nb;
- }
-
- protected InputStream getBundleInputStream(Resource resource, Map<String, StreamProvider> providers) throws IOException {
- String uri = UriNamespace.getUri(resource);
- if (uri == null) {
- throw new IllegalStateException("Resource has no uri");
- }
- StreamProvider provider = providers.get(uri);
- if (provider == null) {
- throw new IllegalStateException("Resource " + uri + " has no StreamProvider");
- }
- return provider.open();
- }
-
- protected void findBundlesWithOptionalPackagesToRefresh(Set<Bundle> toRefresh) {
- // First pass: include all bundles contained in these features
- if (toRefresh.isEmpty()) {
- return;
- }
- Set<Bundle> bundles = new HashSet<Bundle>(Arrays.asList(systemBundleContext.getBundles()));
- bundles.removeAll(toRefresh);
- if (bundles.isEmpty()) {
- return;
- }
- // Second pass: for each bundle, check if there is any unresolved optional package that could be resolved
- for (Bundle bundle : bundles) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- boolean matches = false;
- if (rev != null) {
- for (BundleRequirement req : rev.getDeclaredRequirements(null)) {
- if (PackageNamespace.PACKAGE_NAMESPACE.equals(req.getNamespace())
- && PackageNamespace.RESOLUTION_OPTIONAL.equals(req.getDirectives().get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE))) {
- // This requirement is an optional import package
- for (Bundle provider : toRefresh) {
- BundleRevision providerRev = provider.adapt(BundleRevision.class);
- if (providerRev != null) {
- for (BundleCapability cap : providerRev.getDeclaredCapabilities(null)) {
- if (req.matches(cap)) {
- matches = true;
- break;
- }
- }
- }
- if (matches) {
- break;
- }
- }
- }
- if (matches) {
- break;
- }
- }
- }
- if (matches) {
- toRefresh.add(bundle);
- }
- }
- }
-
- protected void findBundlesWithFragmentsToRefresh(Set<Bundle> toRefresh) {
- if (toRefresh.isEmpty()) {
- return;
- }
- Set<Bundle> bundles = new HashSet<Bundle>(Arrays.asList(systemBundleContext.getBundles()));
- bundles.removeAll(toRefresh);
- if (bundles.isEmpty()) {
- return;
- }
- for (Bundle bundle : new ArrayList<Bundle>(toRefresh)) {
- BundleRevision rev = bundle.adapt(BundleRevision.class);
- if (rev != null) {
- for (BundleRequirement req : rev.getDeclaredRequirements(null)) {
- if (BundleRevision.HOST_NAMESPACE.equals(req.getNamespace())) {
- for (Bundle hostBundle : bundles) {
- if (!toRefresh.contains(hostBundle)) {
- BundleRevision hostRev = hostBundle.adapt(BundleRevision.class);
- if (hostRev != null) {
- for (BundleCapability cap : hostRev.getDeclaredCapabilities(null)) {
- if (req.matches(cap)) {
- toRefresh.add(hostBundle);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- protected void refreshPackages(Collection<Bundle> bundles) throws InterruptedException {
- final CountDownLatch latch = new CountDownLatch(1);
- FrameworkWiring fw = systemBundleContext.getBundle().adapt(FrameworkWiring.class);
- fw.refreshBundles(bundles, new FrameworkListener() {
- @Override
- public void frameworkEvent(FrameworkEvent event) {
- if (event.getType() == FrameworkEvent.ERROR) {
- LOGGER.error("Framework error", event.getThrowable());
- }
- latch.countDown();
- }
- });
- latch.await();
- }
-
-
- static class Deployment {
- Map<String, Long> newCheckums = new HashMap<String, Long>();
- Map<Resource, Bundle> resToBnd = new HashMap<Resource, Bundle>();
- List<Resource> toInstall = new ArrayList<Resource>();
- List<Bundle> toDelete = new ArrayList<Bundle>();
- Map<Bundle, Resource> toUpdate = new HashMap<Bundle, Resource>();
- }
-
-}
[20/59] [abbrv] [KARAF-2852] Merge bundle/command into bundle/core
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Refresh.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Refresh.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Refresh.java
deleted file mode 100644
index 53adaeb..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Refresh.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.FrameworkWiring;
-
-@Command(scope = "bundle", name = "refresh", description = "Refresh bundles.")
-@Service
-public class Refresh extends BundlesCommandWithConfirmation {
-
- public Refresh() {
- this.defaultAllBundles = false;
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- FrameworkWiring wiring = bundleContext.getBundle(0).adapt(FrameworkWiring.class);
- wiring.refreshBundles(bundles == null || bundles.isEmpty() ? null : bundles);
- }
-
- @Override
- protected void executeOnBundle(Bundle bundle) throws Exception {
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Requirements.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Requirements.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Requirements.java
deleted file mode 100644
index c87d4d4..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Requirements.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-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.ShellUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-@Command(scope = "bundle", name = "requirements", description = "Displays OSGi requirements of a given bundles.")
-@Service
-public class Requirements extends BundlesCommand {
-
- public static final String NONSTANDARD_SERVICE_NAMESPACE = "service";
-
- private static final String EMPTY_MESSAGE = "[EMPTY]";
- private static final String UNRESOLVED_MESSAGE = "[UNRESOLVED]";
-
- @Option(name = "--namespace")
- String namespace = "*";
-
- public Requirements() {
- super(true);
- }
-
- @Override
- protected void doExecute(List<Bundle> bundles) throws Exception {
- boolean separatorNeeded = false;
- Pattern ns = Pattern.compile(namespace.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*"));
- for (Bundle b : bundles) {
- if (separatorNeeded) {
- System.out.println("");
- }
-
- // Print out any matching generic requirements.
- BundleWiring wiring = b.adapt(BundleWiring.class);
- if (wiring != null) {
- String title = b + " requires:";
- System.out.println(title);
- System.out.println(ShellUtil.getUnderlineString(title));
- boolean matches = printMatchingRequirements(wiring, ns);
-
- // Handle service requirements separately, since they aren't part
- // of the generic model in OSGi.
- if (matchNamespace(ns, NONSTANDARD_SERVICE_NAMESPACE)) {
- matches |= printServiceRequirements(b);
- }
-
- // If there were no requirements for the specified namespace,
- // then say so.
- if (!matches) {
- System.out.println(namespace + " " + EMPTY_MESSAGE);
- }
- } else {
- System.out.println("Bundle " + b.getBundleId() + " is not resolved.");
- }
-
- separatorNeeded = true;
- }
- }
-
- private static boolean printMatchingRequirements(BundleWiring wiring, Pattern namespace) {
- List<BundleWire> wires = wiring.getRequiredWires(null);
- Map<BundleRequirement, List<BundleWire>> aggregateReqs = aggregateRequirements(namespace, wires);
- List<BundleRequirement> allReqs = wiring.getRequirements(null);
- boolean matches = false;
- for (BundleRequirement req : allReqs) {
- if (matchNamespace(namespace, req.getNamespace())) {
- matches = true;
- List<BundleWire> providers = aggregateReqs.get(req);
- if (providers != null) {
- System.out.println(req.getNamespace() + "; "
- + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " resolved by:");
- for (BundleWire wire : providers) {
- String msg;
- Object keyAttr = wire.getCapability().getAttributes().get(wire.getCapability().getNamespace());
- if (keyAttr != null) {
- msg = wire.getCapability().getNamespace() + "; "
- + keyAttr + " " + getVersionFromCapability(wire.getCapability());
- } else {
- msg = wire.getCapability().toString();
- }
- msg = " " + msg + " from " + wire.getProviderWiring().getBundle();
- System.out.println(msg);
- }
- } else {
- System.out.println(req.getNamespace() + "; "
- + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " " + UNRESOLVED_MESSAGE);
- }
- }
- }
- return matches;
- }
-
- private static Map<BundleRequirement, List<BundleWire>> aggregateRequirements(
- Pattern namespace, List<BundleWire> wires) {
- // Aggregate matching capabilities.
- Map<BundleRequirement, List<BundleWire>> map = new HashMap<BundleRequirement, List<BundleWire>>();
- for (BundleWire wire : wires) {
- if (matchNamespace(namespace, wire.getRequirement().getNamespace())) {
- List<BundleWire> providers = map.get(wire.getRequirement());
- if (providers == null) {
- providers = new ArrayList<BundleWire>();
- map.put(wire.getRequirement(), providers);
- }
- providers.add(wire);
- }
- }
- return map;
- }
-
- static boolean printServiceRequirements(Bundle b) {
- boolean matches = false;
-
- try {
- ServiceReference<?>[] refs = b.getServicesInUse();
-
- if ((refs != null) && (refs.length > 0)) {
- matches = true;
- // Print properties for each service.
- for (ServiceReference<?> ref : refs) {
- // Print object class with "namespace".
- System.out.println(
- NONSTANDARD_SERVICE_NAMESPACE
- + "; "
- + ShellUtil.getValueString(ref.getProperty("objectClass"))
- + " provided by:");
- System.out.println(" " + ref.getBundle());
- }
- }
- } catch (Exception ex) {
- System.err.println(ex.toString());
- }
-
- return matches;
- }
-
- private static String getVersionFromCapability(BundleCapability c) {
- Object o = c.getAttributes().get(Constants.VERSION_ATTRIBUTE);
- if (o == null) {
- o = c.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- }
- return (o == null) ? "" : o.toString();
- }
-
- private static boolean matchNamespace(Pattern namespace, String actual) {
- return namespace.matcher(actual).matches();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Resolve.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Resolve.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Resolve.java
deleted file mode 100644
index 720f118..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Resolve.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.FrameworkWiring;
-
-@Command(scope = "bundle", name = "resolve", description = "Resolve bundles.")
-@Service
-public class Resolve extends BundlesCommand {
-
- public Resolve() {
- super(true);
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- FrameworkWiring wiring = bundleContext.getBundle(0).adapt(FrameworkWiring.class);
- wiring.resolveBundles(bundles == null || bundles.isEmpty() ? null : bundles);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Restart.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Restart.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Restart.java
deleted file mode 100644
index 95d5dfe..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Restart.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.MultiException;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "restart", description = "Restarts bundles.")
-@Service
-public class Restart extends BundlesCommandWithConfirmation {
-
- public Restart() {
- errorMessage = "Error restarting bundle";
- }
-
- protected void doExecute(List<Bundle> bundles) throws Exception {
- if (bundles.isEmpty()) {
- System.err.println("No bundles specified.");
- return;
- }
- List<Exception> exceptions = new ArrayList<Exception>();
- for (Bundle bundle : bundles) {
- try {
- bundle.stop();
- } catch (Exception e) {
- exceptions.add(new Exception("Unable to stop bundle " + bundle.getBundleId() + ": " + e.getMessage(), e));
- }
- }
- for (Bundle bundle : bundles) {
- try {
- bundle.start();
- } catch (Exception e) {
- exceptions.add(new Exception("Unable to start bundle " + bundle.getBundleId() + ": " + e.getMessage(), e));
- }
- }
- MultiException.throwIf("Error restarting bundles", exceptions);
- }
-
- @Override
- protected void executeOnBundle(Bundle bundle) throws Exception {
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
deleted file mode 100644
index a83ce39..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/ShowBundleTree.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.bundle.command.bundletree.Node;
-import org.apache.karaf.bundle.command.bundletree.Tree;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleRevisions;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static java.lang.String.format;
-
-/**
- * Command for showing the full tree of bundles that have been used to resolve
- * a given bundle.
- */
-@Command(scope = "bundle", name = "tree-show", description = "Shows the tree of bundles based on the wiring information.")
-@Service
-public class ShowBundleTree extends BundleCommand {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ShowBundleTree.class);
- private Tree<Bundle> tree;
-
- public ShowBundleTree() {
- super(false);
- }
-
- @Override
- protected void doExecute(Bundle bundle) throws Exception {
- long start = System.currentTimeMillis();
- // let's do the real work here
- printHeader(bundle);
- tree = new Tree<Bundle>(bundle);
- createTree(bundle);
- printTree(tree);
- printDuplicatePackages(tree);
- LOGGER.debug(format("Dependency tree calculated in %d ms",
- System.currentTimeMillis() - start));
- }
-
- /**
- * Return a String representation of a bundle state
- */
- private String getState(Bundle bundle) {
- switch (bundle.getState()) {
- case Bundle.UNINSTALLED : return "UNINSTALLED";
- case Bundle.INSTALLED : return "INSTALLED";
- case Bundle.RESOLVED: return "RESOLVED";
- case Bundle.STARTING : return "STARTING";
- case Bundle.STOPPING : return "STOPPING";
- case Bundle.ACTIVE : return "ACTIVE";
- default : return "UNKNOWN";
- }
- }
-
- /*
- * Print the header
- */
- private void printHeader(Bundle bundle) {
- System.out.printf("Bundle %s [%s] is currently %s%n",
- bundle.getSymbolicName(),
- bundle.getBundleId(),
- getState(bundle));
- }
-
- /*
- * Print the dependency tree
- */
- private void printTree(Tree<Bundle> tree) {
- System.out.printf("%n");
- tree.write(System.out, new Tree.Converter<Bundle>() {
-
- public String toString(Node<Bundle> node) {
- return String.format("%s [%s]",
- node.getValue().getSymbolicName(),
- node.getValue().getBundleId());
- }
- });
- }
-
- /*
- * Check for bundles in the tree exporting the same package
- * as a possible cause for 'Unresolved constraint...' on a uses-conflict
- */
- private void printDuplicatePackages(Tree<Bundle> tree) {
- Set<Bundle> bundles = tree.flatten();
- Map<String, Set<Bundle>> exports = new HashMap<String, Set<Bundle>>();
-
- for (Bundle bundle : bundles) {
- for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions()) {
- BundleWiring wiring = revision.getWiring();
- if (wiring != null) {
- List<BundleWire> wires = wiring.getProvidedWires(BundleRevision.PACKAGE_NAMESPACE);
- if (wires != null) {
- for (BundleWire wire : wires) {
- String name = wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString();
- if (exports.get(name) == null) {
- exports.put(name, new HashSet<Bundle>());
- }
- exports.get(name).add(bundle);
- }
- }
- }
- }
- }
-
- for (String pkg : exports.keySet()) {
- if (exports.get(pkg).size() > 1) {
- System.out.printf("%n");
- System.out.printf("WARNING: multiple bundles are exporting package %s%n", pkg);
- for (Bundle bundle : exports.get(pkg)) {
- System.out.printf("- %s%n", bundle);
- }
- }
- }
- }
-
- /*
- * Creates the bundle tree
- */
- protected void createTree(Bundle bundle) {
- if (bundle.getState() >= Bundle.RESOLVED) {
- createNode(tree);
- } else {
- createNodesForImports(tree, bundle);
- System.out.print("\nWarning: the below tree is a rough approximation of a possible resolution");
- }
- }
-
- /*
- * Creates nodes for the imports of the bundle (instead of reporting wiring information
- */
- private void createNodesForImports(Node<Bundle> node, Bundle bundle) {
- Clause[] imports = Parser.parseHeader(bundle.getHeaders().get("Import-Package"));
- Clause[] exports = Parser.parseHeader(bundle.getHeaders().get("Export-Package"));
- for (Clause i : imports) {
- boolean exported = false;
- for (Clause e : exports) {
- if (e.getName().equals(i.getName())) {
- exported = true;
- break;
- }
- }
- if (!exported) {
- createNodeForImport(node, bundle, i);
- }
- }
- }
-
- /*
- * Create a child node for a given import (by finding a matching export in the currently installed bundles)
- */
- private void createNodeForImport(Node<Bundle> node, Bundle bundle, Clause i) {
- VersionRange range = VersionRange.parseVersionRange(i.getAttribute(Constants.VERSION_ATTRIBUTE));
- boolean foundMatch = false;
- for (Bundle b : bundleContext.getBundles()) {
- BundleWiring wiring = b.adapt(BundleWiring.class);
- if (wiring != null) {
- List<BundleCapability> caps = wiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE);
- if (caps != null) {
- for (BundleCapability cap : caps) {
- String n = getAttribute(cap, BundleRevision.PACKAGE_NAMESPACE);
- String v = getAttribute(cap, Constants.VERSION_ATTRIBUTE);
- if (i.getName().equals(n) && range.contains(VersionTable.getVersion(v))) {
- boolean existing = tree.flatten().contains(b);
- System.out.printf("- import %s: resolved using %s%n", i, b);
- foundMatch = true;
- if (!node.hasChild(b)) {
- Node<Bundle> child = node.addChild(b);
- if (!existing) {
- createNode(child);
- }
- }
- }
- }
- }
- }
- }
- if (!foundMatch) {
- System.out.printf("- import %s: WARNING - unable to find matching export%n", i);
- }
- }
-
- private String getAttribute(BundleCapability capability, String name) {
- Object o = capability.getAttributes().get(name);
- return o != null ? o.toString() : null;
- }
-
- /*
- * Creates a node in the bundle tree
- */
- private void createNode(Node<Bundle> node) {
- Bundle bundle = node.getValue();
- Collection<Bundle> exporters = new HashSet<Bundle>();
- exporters.addAll(bundleService.getWiredBundles(bundle).values());
-
- for (Bundle exporter : exporters) {
- if (node.hasAncestor(exporter)) {
- LOGGER.debug(format("Skipping %s (already exists in the current branch)", exporter));
- } else {
- boolean existing = tree.flatten().contains(exporter);
- LOGGER.debug(format("Adding %s as a dependency for %s", exporter, bundle));
- Node<Bundle> child = node.addChild(exporter);
- if (existing) {
- LOGGER.debug(format("Skipping children of %s (already exists in another branch)", exporter));
- } else {
- createNode(child);
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Start.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Start.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Start.java
deleted file mode 100644
index 48e90fa..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Start.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "start", description = "Starts bundles.")
-@Service
-public class Start extends BundlesCommandWithConfirmation {
-
- @Override
- protected void executeOnBundle(Bundle bundle) throws Exception {
- bundle.start();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/StartLevel.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
deleted file mode 100644
index 30bec0f..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/StartLevel.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.startlevel.BundleStartLevel;
-
-@Command(scope = "bundle", name = "start-level", description = "Gets or sets the start level of a bundle.")
-@Service
-public class StartLevel extends BundleCommandWithConfirmation {
-
- @Argument(index = 1, name = "startLevel", description = "The bundle's new start level", required = false, multiValued = false)
- Integer level;
-
- @Reference
- Session session;
-
- protected void doExecute(Bundle bundle) throws Exception {
- // Get package instance service.
- BundleStartLevel bsl = bundle.adapt(BundleStartLevel.class);
- if (bsl == null) {
- System.out.println("StartLevel service is unavailable.");
- return;
- }
- if (level == null) {
- System.out.println("Level " + bsl.getStartLevel());
- }
- else if ((level < 50) && (bsl.getStartLevel() > 50) && !force){
- for (;;) {
- String msg = "You are about to designate bundle as a system bundle. Do you wish to continue (yes/no): ";
- String str = session.readLine(msg, null);
- if ("yes".equalsIgnoreCase(str)) {
- bsl.setStartLevel(level);
- break;
- } else if ("no".equalsIgnoreCase(str)) {
- break;
- }
- }
-
- } else {
- bsl.setStartLevel(level);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Stop.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Stop.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Stop.java
deleted file mode 100644
index 0b0fed2..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Stop.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.bundle.command;
-
-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.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "stop", description = "Stop bundles.")
-@Service
-public class Stop extends BundlesCommandWithConfirmation {
-
- @Option(name = "-t", aliases={"--transient"}, description="Keep the bundle as auto-start", required = false, multiValued = false)
- boolean transientStop;
-
- public Stop() {
- this.errorMessage = "Unable to stop bundle";
- }
-
- @Override
- protected void executeOnBundle(Bundle bundle) throws Exception {
- if (transientStop) {
- bundle.stop(Bundle.STOP_TRANSIENT);
- } else {
- bundle.stop();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Uninstall.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
deleted file mode 100644
index 67b5b14..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Uninstall.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.bundle.command;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "uninstall", description = "Uninstall bundles.")
-@Service
-public class Uninstall extends BundlesCommandWithConfirmation {
-
- public Uninstall() {
- this.errorMessage = "Unable to uninstall bundle";
- }
-
- @Override
- protected void executeOnBundle(Bundle bundle) throws Exception {
- bundle.uninstall();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Update.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Update.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Update.java
deleted file mode 100644
index 71ae74d..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Update.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.io.InputStream;
-import java.net.URL;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "bundle", name = "update", description = "Update bundle.")
-@Service
-public class Update extends BundleCommandWithConfirmation {
-
- @Argument(index = 1, name = "location", description = "The bundles update location", required = false, multiValued = false)
- String location;
-
- protected void doExecute(Bundle bundle) throws Exception {
- InputStream is = null;
- if (location != null) {
- try {
- is = new URL(location).openStream();
- bundle.update(is);
- } finally {
- is.close();
- }
- } else {
- bundle.update();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/Watch.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Watch.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/Watch.java
deleted file mode 100644
index 9203f59..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/Watch.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.List;
-
-import org.apache.karaf.bundle.core.BundleWatcher;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-
-@Command(scope = "bundle", name = "watch", description = "Watches and updates bundles", detailedDescription = "Watches the local maven repo for changes in snapshot jars and redploys changed jars")
-@Service
-public class Watch implements Action {
-
- @Argument(index = 0, name = "urls", description = "The bundle IDs or URLs", required = false, multiValued = true)
- List<String> urls;
-
- @Option(name = "-i", aliases = {}, description = "Watch interval", required = false, multiValued = false)
- private long interval;
-
- @Option(name = "--start", description = "Starts watching the selected bundles", required = false, multiValued = false)
- protected boolean start;
-
- @Option(name = "--stop", description = "Stops watching all bundles", required = false, multiValued = false)
- protected boolean stop;
-
- @Option(name = "--remove", description = "Removes bundles from the watch list", required = false, multiValued = false)
- protected boolean remove;
-
- @Option(name = "--list", description = "Displays the watch list", required = false, multiValued = false)
- protected boolean list;
-
- @Reference
- private BundleWatcher bundleWatcher;
-
- public void setBundleWatcher(BundleWatcher bundleWatcher) {
- this.bundleWatcher = bundleWatcher;
- }
-
- @Override
- public Object execute() throws Exception {
- if (start && stop) {
- System.err.println("Please use only one of --start and --stop options!");
- return null;
- }
-
- if (interval > 0) {
- System.out.println("Setting watch interval to " + interval + " ms");
- bundleWatcher.setInterval(interval);
- }
- if (stop) {
- System.out.println("Stopping watch");
- bundleWatcher.stop();
- }
- if (urls != null) {
- if (remove) {
- for (String url : urls) {
- bundleWatcher.remove(url);
- }
- } else {
- for (String url : urls) {
- bundleWatcher.add(url);
- }
- }
- }
- if (start) {
- System.out.println("Starting watch");
- bundleWatcher.start();
- }
-
- if (list) { //List the watched bundles.
- String format = "%-40s %6s %-80s";
- System.out.println(String.format(format, "URL", "ID", "Bundle Name"));
- for (String url : bundleWatcher.getWatchURLs()) {
-
- List<Bundle> bundleList = bundleWatcher.getBundlesByURL(url);
- if (bundleList != null && bundleList.size() > 0) {
- for (Bundle bundle : bundleList) {
- System.out.println(String.format(format, url, bundle.getBundleId(), bundle.getHeaders().get(Constants.BUNDLE_NAME)));
- }
- } else {
- System.out.println(String.format(format, url, "", ""));
- }
- }
- } else {
- List<String> urls = bundleWatcher.getWatchURLs();
- if (urls != null && urls.size()>0) {
- System.out.println("Watched URLs/IDs: ");
- for (String url : bundleWatcher.getWatchURLs()) {
- System.out.println(url);
- }
- } else {
- System.out.println("No watched URLs/IDs");
- }
- }
-
- return null;
- }
-
-}
-
-
-
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
deleted file mode 100644
index fe4dc2a..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Node.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.bundle.command.bundletree;
-
-import java.io.PrintWriter;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Represents a node in a {@link Tree}
- */
-public class Node<T> {
-
- private final T value;
- private Node<T> parent;
- private List<Node<T>> children = new LinkedList<Node<T>>();
-
- /**
- * Creates a new node. Only meant for wrapper use,
- * new nodes should be added using the {@link #addChild(Object)} method
- *
- * @param value the node value
- */
- protected Node(T value) {
- super();
- this.value = value;
- }
-
- /**
- * Creates a new node. Only meant for wrapper use,
- * new nodes should be added using the {@link #addChild(Object)} method
- *
- * @param value the node value
- */
- protected Node(T value, Node<T> parent) {
- this(value);
- this.parent = parent;
- }
-
- /**
- * Access the node's value
- */
- public T getValue() {
- return value;
- }
-
- /**
- * Access the node's child nodes
- */
- public List<Node<T>> getChildren() {
- return children;
- }
-
- /**
- * Adds a child to this node
- *
- * @param value the child's value
- * @return the child node
- */
- public Node<T> addChild(T value) {
- Node<T> node = new Node<T>(value, this);
- children.add(node);
- return node;
- }
-
- /**
- * Give a set of values in the tree.
- *
- * @return
- */
- public Set<T> flatten() {
- Set<T> result = new HashSet<T>();
- result.add(getValue());
- for (Node<T> child : getChildren()) {
- result.addAll(child.flatten());
- }
- return result;
- }
-
- /**
- * Check if the node has an ancestor that represents the given value
- *
- * @param value the node value
- * @return <code>true</code> it there's an ancestor that represents the value
- */
- public boolean hasAncestor(T value) {
- if (parent == null) {
- return false;
- } else {
- return value.equals(parent.value) || parent.hasAncestor(value);
- }
- }
-
- public boolean hasChild(T value) {
- for (Node<T> child : getChildren()) {
- if (value.equals(child.getValue())) {
- return true;
- }
- }
- return false;
- }
-
- /*
- * Write this node to the PrintWriter. It should be indented one step
- * further for every element in the indents array. If an element in the
- * array is <code>true</code>, there should be a | to connect to the next
- * sibling.
- */
- protected void write(PrintWriter writer, Tree.Converter<T> converter, boolean... indents) {
- for (boolean indent : indents) {
- writer.printf("%-3s", indent ? "|" : "");
- }
- writer.printf("+- %s%n", converter.toString(this));
- for (Node<T> child : getChildren()) {
- child.write(writer, converter, concat(indents, hasNextSibling()));
- }
- }
-
- /*
- * Is this node the last child node for its parent
- * or is there a next sibling?
- */
- private boolean hasNextSibling() {
- if (parent == null) {
- return false;
- } else {
- return parent.getChildren().size() > 1
- && parent.getChildren().indexOf(this) < parent.getChildren().size() - 1;
- }
- }
-
- /*
- * Add an element to the end of the array
- */
- private boolean[] concat(boolean[] array, boolean element) {
- boolean[] result = new boolean[array.length + 1];
- for (int i = 0 ; i < array.length ; i++) {
- result[i] = array[i];
- }
- result[array.length] = element;
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
deleted file mode 100644
index 7a7b64e..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/bundletree/Tree.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.bundle.command.bundletree;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Represents a tree that can be written to the console.
- *
- * The output will look like this:
- * <pre>
- * root
- * +- child1
- * | +- grandchild
- * +- child2
- * </pre>
- */
-public class Tree<T> extends Node<T> {
-
- /**
- * Creates a new tree with the given root node
- *
- * @param root the root node
- */
- public Tree(T root) {
- super(root);
- }
-
- /**
- * Write the tree to a PrintStream, using the default toString() method to output the node values
- *
- * @param stream
- */
- public void write(PrintStream stream) {
- write(new PrintWriter(stream));
- }
-
- /**
- * Write the tree to a PrintStream, using the provided converter to output the node values
- *
- * @param stream
- * @param converter
- */
- public void write(PrintStream stream, Converter<T> converter) {
- write(new PrintWriter(stream), converter);
- }
-
- /**
- * Write the tree to a PrintWriter, using the default toString() method to output the node values
- *
- * @param writer
- */
- public void write(PrintWriter writer) {
- write(writer, new Converter() {
- public String toString(Node node) {
- return node.getValue().toString();
- }
- });
- }
-
- /**
- * Write the tree to a PrintWriter, using the provided converter to output the node values
- *
- * @param writer
- * @param converter
- */
- public void write(PrintWriter writer, Converter<T> converter) {
- writer.printf("%s%n", converter.toString(this));
- for (Node<T> child : getChildren()) {
- child.write(writer, converter);
- }
- writer.flush();
- }
-
- /**
- * Interface to convert node values to string
- *
- * @param <T> the object type for the node value
- */
- public static interface Converter<T> {
-
- public String toString(Node<T> node);
-
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java
deleted file mode 100644
index 077cfef..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/AnsiPrintingWikiVisitor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.bundle.command.wikidoc;
-
-import java.io.PrintStream;
-
-import org.fusesource.jansi.Ansi;
-import org.fusesource.jansi.Ansi.Attribute;
-import org.fusesource.jansi.Ansi.Color;
-
-/**
- * Translates the Wiki tags to Ansi escape sequences to display them on the console
- */
-public class AnsiPrintingWikiVisitor implements WikiVisitor {
- private PrintStream out;
-
- public AnsiPrintingWikiVisitor(PrintStream out) {
- this.out = out;
- }
-
- @Override
- public void heading(int level, String header) {
- this.out.print(Ansi.ansi().a(Attribute.INTENSITY_BOLD).a(header)
- .a(Attribute.INTENSITY_BOLD_OFF).toString());
- }
-
- @Override
- public void link(String target, String title) {
- this.out.print(Ansi.ansi().fg(Color.YELLOW)
- .a(target).fg(Color.DEFAULT));
- }
-
- @Override
- public void enumeration(String text) {
- this.out.print(Ansi.ansi().a(" * ").fg(Color.CYAN).a(text).fg(Color.DEFAULT).a(" "));
- }
-
- @Override
- public void text(String text) {
- this.out.print(text);
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
deleted file mode 100644
index 8ec3d5b..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiParser.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.bundle.command.wikidoc;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.StringTokenizer;
-
-/**
- * Parses wiki syntax from a reader and calls a Wikivisitor with the
- * tokens it finds
- */
-public class WikiParser {
- WikiVisitor visitor;
-
- public WikiParser(WikiVisitor visitor) {
- this.visitor = visitor;
- }
-
- public void parse(String line) {
- StringTokenizer tokenizer = new StringTokenizer(line , "[h*", true);
- while (tokenizer.hasMoreTokens()) {
- String token = tokenizer.nextToken();
- if ("[".equals(token)) {
- parseLink(tokenizer);
- } else if ("h".equals(token)) {
- parseHeading(tokenizer);
- } else if ("*".equals(token)){
- parseEnumeration(tokenizer);
- } else {
- visitor.text(token);
- }
- }
- }
-
- private void parseEnumeration(StringTokenizer tokenizer) {
- String text = tokenizer.nextToken("-\n");
- visitor.enumeration(text.trim());
- }
-
- private void parseHeading(StringTokenizer tokenizer) {
- String level = tokenizer.nextToken("123456789");
- if (!level.matches("[123456789]")) {
- visitor.text("h" + level);
- return;
- }
- String dot = tokenizer.nextToken(".\n");
- if (!".".equals(dot)) {
- visitor.text("h" + level + dot);
- return;
- }
- String heading = tokenizer.hasMoreTokens() ? tokenizer.nextToken("\n") : "";
- visitor.heading(new Integer(level), heading.trim());
- }
-
- private void parseLink(StringTokenizer tokenizer) {
- String token = tokenizer.nextToken("]");
- visitor.link(token, "");
- tokenizer.nextToken();
- }
-
- public void parse(Reader reader) throws IOException {
- BufferedReader br = new BufferedReader(reader);
- String line;
- while ((line = br.readLine()) != null) {
- parse(line);
- visitor.text("\n");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java b/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
deleted file mode 100644
index b4a5fb3..0000000
--- a/bundle/command/src/main/java/org/apache/karaf/bundle/command/wikidoc/WikiVisitor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.bundle.command.wikidoc;
-
-/**
- * Will be used by WikiParser to call the respective handler when it recognizes the tag
- */
-public interface WikiVisitor {
-
- void link(String target, String title);
- void heading(int level, String title);
- void enumeration(String text);
- void text(String text);
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/bundle/command/src/main/resources/OSGI-INF/bundle.info b/bundle/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index af2c24f..0000000
--- a/bundle/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,32 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
- [mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides the low level OSGi shell commands.
-
-The following commands are available:
-* bundle:classes - Displays a list of classes contained in the bundle
-* bundle:find-class - Locates a specified class in any deployed bundle
-* bundle:headers - Display OSGi headers of a given bundle.
-* bundle:info - Display detailed information of a given bundle.
-* bundle:install - Install one or more bundles.
-* bundle:list - List all installed bundles.
-* bundle:refresh - Refresh bundles.
-* bundle:resolve - Resolve bundles.
-* bundle:restart - Stop and restart bundles.
-* bundle:start - Starts bundles.
-* bundlestart-level - Get or set the start level of a bundle.
-* bundle:stop - Stop bundles.
-* bundle:uninstall - Uninstall bundles.
-* bundle:update - Update a bundle.
-
-h1. See also
-
-Commands and Using the console sections of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java b/bundle/command/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
deleted file mode 100644
index 876f605..0000000
--- a/bundle/command/src/test/java/org/apache/karaf/bundle/command/ListServicesTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.bundle.command;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.apache.karaf.bundle.core.internal.BundleServiceImpl;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-public class ListServicesTest {
-
- private ListBundleServices listServices;
-
- @SuppressWarnings("unchecked")
- public ListServicesTest() {
- listServices = new ListBundleServices();
- BundleContext bundleContext = new TestBundleFactory().createBundleContext();
- listServices.setBundleContext(bundleContext);
- listServices.setBundleService(new BundleServiceImpl(bundleContext));
- }
-
- @Test
- public void listAllShort() throws Exception {
- System.out.println("listAllShort");
- listServices.execute();
- }
-
-
- @Test
- public void listAllLong() throws Exception {
- System.out.println("listAllLong");
- listServices.ids = Arrays.asList(new String[]{"1", "2"});
- listServices.execute();
- }
-
- @Test
- public void listAllLongServiceUse() throws Exception {
- System.out.println("listAllLongServicesUse");
- listServices.ids = Arrays.asList(new String[]{"1", "2"});
- listServices.inUse = true;
- listServices.execute();
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java b/bundle/command/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
deleted file mode 100644
index 27e4a63..0000000
--- a/bundle/command/src/test/java/org/apache/karaf/bundle/command/TestBundleFactory.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.bundle.command;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class TestBundleFactory {
- ServiceReference<?> createServiceRef(Object ... keyProp) {
- ServiceReference<?> serviceRef = createMock(ServiceReference.class);
- if (keyProp.length % 2 != 0) {
- throw new IllegalArgumentException("");
- }
- Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
- int c = 0;
- while (c < keyProp.length) {
- String key = (String)keyProp[c++];
- Object value = (Object)keyProp[c++];
- keyPropMap.put(key, value);
- expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
- }
- expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new String[]{})).anyTimes();
- return serviceRef;
- }
-
- Bundle createBundle(long id, String name) {
- Bundle bundle = createMock(Bundle.class);
- expect(bundle.getBundleId()).andReturn(id).anyTimes();
- Dictionary<String, String> headers = new Hashtable<String, String>();
- headers.put(Constants.BUNDLE_NAME, name);
- expect(bundle.getHeaders()).andReturn(headers).anyTimes();
- return bundle;
- }
-
- private Bundle[] createBundles() {
- Bundle bundle1 = createBundle(1, "Bundle A");
- Bundle bundle2 = createBundle(2, "Bundle B");
- Bundle bundle3 = createBundle(3, "Bundle C");
-
- ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.MyService"},
- "key1", "value1");
- ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new String[]{"org.example.OtherService"}, "key2", 1);
-
- addRegisteredServices(bundle1, ref1, ref2);
- addRegisteredServices(bundle2, ref2);
- expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
-
- expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
- addUsedServices(bundle2, ref1);
- addUsedServices(bundle3, ref1, ref2);
-
- expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, bundle3}).anyTimes();
- expect(ref2.getUsingBundles()).andReturn(new Bundle[]{bundle3}).anyTimes();
-
- replay(bundle1, bundle2, bundle3, ref1, ref2);
- return new Bundle[] { bundle1, bundle2, bundle3 };
- }
-
- private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
- expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
- }
-
- private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... refs) {
- expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
- for (ServiceReference<?> ref : refs) {
- expect(ref.getBundle()).andReturn(bundle);
- }
- }
-
- public BundleContext createBundleContext() {
- BundleContext bundleContext = createMock(BundleContext.class);
- Bundle[] bundles = createBundles();
- expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
- expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
- expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
- expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
- replay(bundleContext);
- return bundleContext;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java b/bundle/command/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
deleted file mode 100644
index df0d7d6..0000000
--- a/bundle/command/src/test/java/org/apache/karaf/bundle/command/bundletree/TreeTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.bundle.command.bundletree;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Set;
-
-import org.apache.karaf.bundle.command.bundletree.Node;
-import org.apache.karaf.bundle.command.bundletree.Tree;
-import org.junit.Test;
-
-/**
- * Test cases for {@link org.apache.karaf.shell.dev.util.Tree}
- * and {@link org.apache.karaf.shell.dev.util.Node}
- */
-public class TreeTest {
-
- @Test
- public void writeTreeWithOneChild() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- tree.addChild("child");
-
- BufferedReader reader = read(tree);
-
- assertEquals("root" , reader.readLine());
- assertEquals("+- child" , reader.readLine());
- }
-
- @Test
- public void writeTreeWithOneChildAndNodeConverter() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- tree.addChild("child");
-
- StringWriter writer = new StringWriter();
- tree.write(new PrintWriter(writer), new Tree.Converter<String>() {
- public String toString(Node<String> node) {
- return "my " + node.getValue();
- }
- });
-
- BufferedReader reader = new BufferedReader(new StringReader(writer.getBuffer().toString()));
-
- assertEquals("my root" , reader.readLine());
- assertEquals("+- my child" , reader.readLine());
- }
-
- @Test
- public void writeTreeWithChildAndGrandChild() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- Node<String> node = tree.addChild("child");
- node.addChild("grandchild");
-
- BufferedReader reader = read(tree);
-
- assertEquals("root" , reader.readLine());
- assertEquals("+- child" , reader.readLine());
- assertEquals(" +- grandchild", reader.readLine());
- }
-
- @Test
- public void writeTreeWithTwoChildrenAndOneGrandchild() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- Node<String> child = tree.addChild("child1");
- child.addChild("grandchild");
- tree.addChild("child2");
-
- BufferedReader reader = read(tree);
-
- assertEquals("root" , reader.readLine());
- assertEquals("+- child1" , reader.readLine());
- assertEquals("| +- grandchild", reader.readLine());
- assertEquals("+- child2" , reader.readLine());
- }
-
- @Test
- public void flattenTree() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- Node<String> child1 = tree.addChild("child1");
- child1.addChild("grandchild");
- Node child2 = tree.addChild("child2");
- child2.addChild("grandchild");
-
- Set<String> elements = tree.flatten();
- assertNotNull(elements);
- assertEquals(4, elements.size());
- assertTrue(elements.contains("root"));
- assertTrue(elements.contains("child1"));
- assertTrue(elements.contains("child2"));
- assertTrue(elements.contains("grandchild"));
- }
-
- @Test
- public void hasAncestor() throws IOException {
- Tree<String> tree = new Tree<String>("root");
- Node<String> child1 = tree.addChild("child1");
- child1.addChild("grandchild");
- Node child2 = tree.addChild("child2");
- Node node = child2.addChild("grandchild2");
-
- assertTrue(node.hasAncestor("child2"));
- assertTrue(node.hasAncestor("root"));
- assertFalse(node.hasAncestor("child1"));
- }
-
- private BufferedReader read(Tree<String> tree) {
- StringWriter writer = new StringWriter();
- tree.write(new PrintWriter(writer));
-
- BufferedReader reader = new BufferedReader(new StringReader(writer.getBuffer().toString()));
- return reader;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/command/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
----------------------------------------------------------------------
diff --git a/bundle/command/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java b/bundle/command/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
deleted file mode 100644
index 37101c3..0000000
--- a/bundle/command/src/test/java/org/apache/karaf/bundle/command/wikidoc/WikiParserTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.bundle.command.wikidoc;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import org.easymock.EasyMock;
-import org.junit.Test;
-
-public class WikiParserTest {
-
- private static final String TESTDOC =
- "h1. myTestdoc\n" +
- "\n" +
- "Some text\n" +
- "* enumeration\n" +
- " some text [a link] some more text\n" +
- "h1 is no heading";
-
- private static final String HEADINGCASES =
- "h1.\n" +
- "hf.";
-
- @Test
- public void parseTestDoc() throws IOException {
- WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
- visitor.heading(1, "myTestdoc");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
- visitor.text("Some text");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
- visitor.enumeration("enumeration");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
- visitor.text(" some text ");
- EasyMock.expectLastCall();
- visitor.link("a link", "");
- EasyMock.expectLastCall();
- visitor.text(" some more text");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
- visitor.text("h1 is no heading");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
-
- EasyMock.replay(visitor);
- WikiParser parser = new WikiParser(visitor);
- parser.parse(new StringReader(TESTDOC));
- EasyMock.verify(visitor);
- }
-
- @Test
- public void parseHeadingSpecialCases() throws IOException {
- WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
-
- visitor.heading(1, "");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
-
- visitor.text("hf.");
- EasyMock.expectLastCall();
- visitor.text("\n");
- EasyMock.expectLastCall();
-
- EasyMock.replay(visitor);
- WikiParser parser = new WikiParser(visitor);
- parser.parse(new StringReader(HEADINGCASES));
- EasyMock.verify(visitor);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/pom.xml
----------------------------------------------------------------------
diff --git a/bundle/core/pom.xml b/bundle/core/pom.xml
index f3cccd8..b698d48 100644
--- a/bundle/core/pom.xml
+++ b/bundle/core/pom.xml
@@ -79,6 +79,12 @@
</dependency>
<dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
@@ -111,6 +117,7 @@
org.apache.karaf.bundle.core;-noimport:=true
</Export-Package>
<Private-Package>
+ org.apache.karaf.bundle.command*,
org.apache.karaf.bundle.core.internal,
org.apache.karaf.bundle.core.internal.osgi,
org.apache.karaf.util.maven,
@@ -121,6 +128,7 @@
<Bundle-Activator>
org.apache.karaf.bundle.core.internal.osgi.Activator
</Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.bundle.command.*</Karaf-Commands>
</instructions>
</configuration>
</plugin>
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommand.java
new file mode 100644
index 0000000..dce0ca8
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommand.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.bundle.command;
+
+import org.apache.karaf.bundle.core.BundleService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Unique bundle command.
+ */
+public abstract class BundleCommand implements Action {
+
+ @Argument(index = 0, name = "id", description = "The bundle ID or name or name/version", required = true, multiValued = false)
+ String id;
+
+ boolean defaultAllBundles = true;
+
+ @Reference
+ BundleService bundleService;
+
+ @Reference
+ BundleContext bundleContext;
+
+ public BundleCommand(boolean defaultAllBundles) {
+ this.defaultAllBundles = defaultAllBundles;
+ }
+
+ public Object execute() throws Exception {
+ return doExecute(true);
+ }
+
+ protected Object doExecute(boolean force) throws Exception {
+ Bundle bundle = bundleService.getBundle(id, defaultAllBundles);
+ if (bundle != null) {
+ if (force || !ShellUtil.isASystemBundle(bundleContext, bundle)) {
+ doExecute(bundle);
+ } else {
+ System.err.println("Access to system bundle " + id + " is discouraged. You may override with -f");
+ }
+ }
+ return null;
+ }
+
+ protected abstract void doExecute(Bundle bundle) throws Exception;
+
+ public void setBundleService(BundleService bundleService) {
+ this.bundleService = bundleService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
new file mode 100644
index 0000000..c07a357
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundleCommandWithConfirmation.java
@@ -0,0 +1,37 @@
+/*
+ * 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.bundle.command;
+
+import org.apache.karaf.shell.api.action.Option;
+
+/**
+ * Unique bundle command with confirmation while accessing system bundle.
+ */
+public abstract class BundleCommandWithConfirmation extends BundleCommand {
+
+ @Option(name = "--force", aliases = {"-f"}, description = "Forces the command to execute", required = false, multiValued = false)
+ boolean force;
+
+ public BundleCommandWithConfirmation() {
+ super(true);
+ }
+
+ public Object execute() throws Exception {
+ return doExecute(force);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d0180939/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
new file mode 100644
index 0000000..ff4dd53
--- /dev/null
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/BundlesCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.bundle.command;
+
+import java.util.List;
+
+import org.apache.karaf.bundle.core.BundleService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public abstract class BundlesCommand implements Action {
+
+ @Argument(index = 0, name = "ids", description = "The list of bundle (identified by IDs or name or name/version) separated by whitespaces", required = false, multiValued = true)
+ List<String> ids;
+
+ boolean defaultAllBundles = true;
+
+ @Reference
+ BundleContext bundleContext;
+
+ @Reference
+ BundleService bundleService;
+
+ public BundlesCommand(boolean defaultAllBundles) {
+ this.defaultAllBundles = defaultAllBundles;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ doExecute(true);
+ return null;
+ }
+
+ protected Object doExecute(boolean force) throws Exception {
+ List<Bundle> bundles = bundleService.selectBundles(ids, defaultAllBundles);
+ if (!force) {
+ assertNoSystemBundles(bundles);
+ }
+ doExecute(bundles);
+ return null;
+ }
+
+ private void assertNoSystemBundles(List<Bundle> bundles) {
+ for (Bundle bundle : bundles) {
+ if (ShellUtil.isASystemBundle(bundleContext, bundle)) {
+ throw new RuntimeException("Access to system bundle " + bundle.getBundleId() + " denied. You can override with -f");
+ }
+ }
+ }
+
+ protected abstract void doExecute(List<Bundle> bundles) throws Exception;
+
+ public void setBundleService(BundleService bundleService) {
+ this.bundleService = bundleService;
+ }
+
+}
[29/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/pom.xml
----------------------------------------------------------------------
diff --git a/instance/core/pom.xml b/instance/core/pom.xml
deleted file mode 100644
index 0180bd3..0000000
--- a/instance/core/pom.xml
+++ /dev/null
@@ -1,181 +0,0 @@
-<?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.instance</groupId>
- <artifactId>instance</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.instance.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Instance :: Core</name>
- <description>Core implementation of the instance feature to manipulate Karaf child instances.</description>
-
- <properties>
- <appendedResourcesDirectory>${project.basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-jdk14</artifactId>
- <scope>test</scope>
- </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>
- <resource>
- <directory>${project.build.directory}/generated-resources</directory>
- <includes>
- <include>**/*.*</include>
- </includes>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <executions>
- <execution>
- <id>copy-resources</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}/generated-resources/org/apache/karaf/instance/</outputDirectory>
- <resources>
- <resource>
- <directory>${project.basedir}/../../assemblies/features/framework/src/main/resources</directory>
- <excludes>
- <exclude>**/org.apache.karaf.management.cfg</exclude>
- <exclude>**/org.apache.karaf.shell.cfg</exclude>
- <exclude>**/system.properties</exclude>
- </excludes>
- </resource>
- <resource>
- <directory>${project.basedir}/../../assemblies/features/framework/src/main/filtered-resources</directory>
- <filtering>true</filtering>
- <includes>
- <include>**/*.properties</include>
- <include>**/*.cfg</include>
- <include>**/*.xml</include>
- <include>**/*.info</include>
- </includes>
- </resource>
- <resource>
- <directory>${project.basedir}/../../assemblies/features/framework/src/main/snapshot</directory>
- <filtering>true</filtering>
- <includes>
- <include>**/*.cfg</include>
- </includes>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.karaf.instance.core,
- </Export-Package>
- <Provide-Capability>
- service-reference;effective:=active;objectClass=org.apache.karaf.instance.core.InstanceService
- </Provide-Capability>
- <Private-Package>
- org.apache.karaf.jpm,
- org.apache.karaf.jpm.impl,
- org.apache.karaf.instance.core.internal,
- org.apache.karaf.instance.core.internal.osgi,
- org.apache.felix.utils.properties;-split-package:=merge-first,
- org.apache.karaf.util.locks,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.instance.core.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <excludes>
- <!-- this is not a unit test but an application used for testing -->
- <exclude>**/MainTest.java</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/Instance.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/Instance.java b/instance/core/src/main/java/org/apache/karaf/instance/core/Instance.java
deleted file mode 100644
index 5e78bb2..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/Instance.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.instance.core;
-
-public interface Instance {
-
- String STOPPED = "Stopped";
- String STARTING = "Starting";
- String STARTED = "Started";
- String ERROR = "Error";
-
- String getName();
-
- @Deprecated
- void setName(String name);
-
- boolean isRoot();
-
- String getLocation();
-
- @Deprecated
- void setLocation(String location);
-
- int getPid();
-
- int getSshPort();
-
- void changeSshPort(int port) throws Exception;
-
- int getRmiRegistryPort();
-
- void changeRmiRegistryPort(int port) throws Exception;
-
- int getRmiServerPort();
-
- void changeRmiServerPort(int port) throws Exception;
-
- String getJavaOpts();
-
- void changeJavaOpts(String javaOpts) throws Exception;
-
- void start(String javaOpts) throws Exception;
-
- void stop() throws Exception;
-
- void destroy() throws Exception;
-
- String getState() throws Exception;
-
- @Deprecated
- boolean isAttached();
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceService.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceService.java b/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceService.java
deleted file mode 100644
index cc6c10c..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.instance.core;
-
-public interface InstanceService {
-
- Instance createInstance(String name, InstanceSettings settings, boolean printOutput) throws Exception;
-
- void renameInstance(String name, String newName, boolean printOutput) throws Exception;
-
- @Deprecated
- void refreshInstance() throws Exception;
-
- Instance cloneInstance(String name, String cloneName, InstanceSettings settings, boolean printOutput) throws Exception;
-
- Instance[] getInstances();
-
- Instance getInstance(String name);
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java b/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
deleted file mode 100644
index 0f9cf97..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.instance.core;
-
-import java.util.List;
-
-public class InstanceSettings {
-
- private final int sshPort;
- private final int rmiRegistryPort;
- private final int rmiServerPort;
- private final String location;
- private final String javaOpts;
- private final List<String> featureURLs;
- private final List<String> features;
-
- public InstanceSettings(int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, List<String> featureURLs, List<String> features) {
- this.sshPort = sshPort;
- this.rmiRegistryPort = rmiRegistryPort;
- this.rmiServerPort = rmiServerPort;
- this.location = location;
- this.javaOpts = javaOpts;
- this.featureURLs = featureURLs;
- this.features = features;
- }
-
- public int getSshPort() {
- return sshPort;
- }
-
- public int getRmiRegistryPort() {
- return rmiRegistryPort;
- }
-
- public int getRmiServerPort() {
- return rmiServerPort;
- }
-
- public String getLocation() {
- return location;
- }
-
- public String getJavaOpts() {
- return javaOpts;
- }
-
- public List<String> getFeatureURLs() {
- return featureURLs;
- }
-
- public List<String> getFeatures() {
- return features;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof InstanceSettings)) {
- return false;
- }
- InstanceSettings is = (InstanceSettings) o;
- return is.sshPort == sshPort &&
- is.rmiRegistryPort == rmiRegistryPort &&
- is.rmiServerPort == rmiServerPort &&
- (location == null ? is.location == null : location.equals(is.location)) &&
- (javaOpts == null ? is.javaOpts == null : javaOpts.equals(is.javaOpts)) &&
- (featureURLs == null ? is.featureURLs == null : featureURLs.equals(is.featureURLs)) &&
- (features == null ? is.features == null : features.equals(is.features));
- }
-
- @Override
- public int hashCode() {
- int result = sshPort + rmiRegistryPort + rmiServerPort;
- result = 31 * result + (location != null ? location.hashCode() : 0);
- result = 31 * result + (javaOpts != null ? javaOpts.hashCode() : 0);
- result = 31 * result + (featureURLs != null ? featureURLs.hashCode() : 0);
- result = 31 * result + (features != null ? features.hashCode() : 0);
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java b/instance/core/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
deleted file mode 100644
index f75e099..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.instance.core;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.TabularData;
-
-public interface InstancesMBean {
-
- String INSTANCE_PID = "Pid";
- String INSTANCE_NAME = "Name";
- String INSTANCE_IS_ROOT = "Is Root";
- String INSTANCE_SSH_PORT = "SSH Port";
- String INSTANCE_RMI_REGISTRY_PORT = "RMI Registry Port";
- String INSTANCE_RMI_SERVER_PORT = "RMI Server Port";
- String INSTANCE_STATE = "State";
- String INSTANCE_LOCATION = "Location";
- String INSTANCE_JAVAOPTS = "JavaOpts";
-
- String[] INSTANCE = {INSTANCE_PID, INSTANCE_NAME, INSTANCE_IS_ROOT, INSTANCE_SSH_PORT, INSTANCE_RMI_REGISTRY_PORT,
- INSTANCE_RMI_SERVER_PORT, INSTANCE_STATE, INSTANCE_LOCATION, INSTANCE_JAVAOPTS };
-
- // Operations
- int createInstance(String name, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, String features, String featureURLs) throws MBeanException;
- void changeSshPort(String name, int port) throws MBeanException;
- void changeRmiRegistryPort(String name, int port) throws MBeanException;
- void changeRmiServerPort(String name, int port) throws MBeanException;
- void changeJavaOpts(String name, String javaopts) throws MBeanException;
- void destroyInstance(String name) throws MBeanException;
- void startInstance(String name) throws MBeanException;
- void startInstance(String name, String opts) throws MBeanException;
- void startInstance(String name, String opts, boolean wait, boolean debug) throws MBeanException;
- void stopInstance(String name) throws MBeanException;
- void renameInstance(String originalName, String newName) throws MBeanException;
- void renameInstance(String originalName, String newName, boolean verbose) throws MBeanException;
- void cloneInstance(String name, String cloneName, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts) throws MBeanException;
-
- // Attributes
- TabularData getInstances() throws MBeanException;
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java b/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
deleted file mode 100644
index edc4ec5..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.instance.core.internal;
-
-import org.apache.karaf.instance.core.Instance;
-
-public class InstanceImpl implements Instance {
-
- private final InstanceServiceImpl service;
- private String name;
-
- public InstanceImpl(InstanceServiceImpl service, String name) {
- this.service = service;
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- throw new UnsupportedOperationException();
- }
-
- void doSetName(String name) {
- this.name = name;
- }
-
- public boolean isRoot() {
- return service.isInstanceRoot(name);
- }
-
- public String getLocation() {
- return service.getInstanceLocation(name);
- }
-
- public void setLocation(String location) {
- throw new UnsupportedOperationException();
- }
-
- public int getPid() {
- return service.getInstancePid(name);
- }
-
- public int getSshPort() {
- return service.getInstanceSshPort(name);
- }
-
- public void changeSshPort(int port) throws Exception {
- service.changeInstanceSshPort(name, port);
- }
-
- public int getRmiRegistryPort() {
- return service.getInstanceRmiRegistryPort(name);
- }
-
- public void changeRmiRegistryPort(int port) throws Exception {
- service.changeInstanceRmiRegistryPort(name, port);
- }
-
- public int getRmiServerPort() {
- return service.getInstanceRmiServerPort(name);
- }
-
- public void changeRmiServerPort(int port) throws Exception {
- service.changeInstanceRmiServerPort(name, port);
- }
-
- public String getJavaOpts() {
- return service.getInstanceJavaOpts(name);
- }
-
- public void changeJavaOpts(String javaOpts) throws Exception {
- service.changeInstanceJavaOpts(name, javaOpts);
- }
-
- public void start(String javaOpts) throws Exception {
- service.startInstance(name, javaOpts);
- }
-
- public void stop() throws Exception {
- service.stopInstance(name);
- }
-
- public void destroy() throws Exception {
- service.destroyInstance(name);
- }
-
- public String getState() throws Exception {
- return service.getInstanceState(name);
- }
-
- public boolean isAttached() {
- return getPid() != 0;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java b/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
deleted file mode 100644
index 535c2a0..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- * 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.instance.core.internal;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstanceService;
-import org.apache.karaf.instance.core.InstanceSettings;
-import org.apache.karaf.jpm.Process;
-import org.apache.karaf.jpm.impl.ProcessBuilderFactoryImpl;
-import org.apache.karaf.jpm.impl.ScriptUtils;
-import org.apache.karaf.util.locks.FileLockUtils;
-import org.fusesource.jansi.Ansi;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.Socket;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Scanner;
-
-public class InstanceServiceImpl implements InstanceService {
-
- public static final String STORAGE_FILE = "instance.properties";
- public static final String BACKUP_EXTENSION = ".bak";
- private static final String FEATURES_CFG = "etc/org.apache.karaf.features.cfg";
-
- private static final Logger LOGGER = LoggerFactory.getLogger(InstanceServiceImpl.class);
-
- private static final String CONFIG_PROPERTIES_FILE_NAME = "config.properties";
-
- private static final String KARAF_SHUTDOWN_PORT = "karaf.shutdown.port";
-
- private static final String KARAF_SHUTDOWN_HOST = "karaf.shutdown.host";
-
- private static final String KARAF_SHUTDOWN_PORT_FILE = "karaf.shutdown.port.file";
-
- private static final String KARAF_SHUTDOWN_COMMAND = "karaf.shutdown.command";
-
- private static final String KARAF_SHUTDOWN_PID_FILE = "karaf.shutdown.pid.file";
-
- private static final String DEFAULT_SHUTDOWN_COMMAND = "SHUTDOWN";
-
- public static final String DEFAULT_JAVA_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass";
-
- private LinkedHashMap<String, InstanceImpl> proxies = new LinkedHashMap<String, InstanceImpl>();
-
- private File storageLocation;
-
- private long stopTimeout = 30000;
-
- static class InstanceState {
- String name;
- String loc;
- String opts;
- int pid;
- boolean root;
- }
-
- static class State {
- int defaultSshPortStart = 8101;
- int defaultRmiRegistryPortStart = 1099;
- int defaultRmiServerPortStart = 44444;
- Map<String, InstanceState> instances;
- }
-
- public InstanceServiceImpl() {
- String prop = System.getProperty("karaf.instances");
- if (prop != null) {
- storageLocation = new File(prop);
- }
- }
-
- public File getStorageLocation() {
- return storageLocation;
- }
-
- public void setStorageLocation(File storage) {
- this.storageLocation = storage;
- }
-
- public long getStopTimeout() {
- return stopTimeout;
- }
-
- public void setStopTimeout(long stopTimeout) {
- this.stopTimeout = stopTimeout;
- }
-
- private State loadData(org.apache.felix.utils.properties.Properties storage) {
- State state = new State();
- int count = getInt(storage, "count", 0);
- state.defaultSshPortStart = getInt(storage, "ssh.port", state.defaultSshPortStart);
- state.defaultRmiRegistryPortStart = getInt(storage, "rmi.registry.port", state.defaultRmiRegistryPortStart);
- state.defaultRmiServerPortStart = getInt(storage, "rmi.server.port", state.defaultRmiServerPortStart);
- state.instances = new LinkedHashMap<String, InstanceState>();
-
- for (int i = 0; i < count; i++) {
- InstanceState instance = new InstanceState();
- instance.name = getString(storage, "item." + i + ".name", null);
- instance.loc = getString(storage, "item." + i + ".loc", null);
- instance.opts = getString(storage, "item." + i + ".opts", null);
- instance.pid = getInt(storage, "item." + i + ".pid", 0);
- instance.root = getBool(storage, "item." + i + ".root", false);
- state.instances.put(instance.name, instance);
- }
- // Update proxies list
- for (InstanceState instance : state.instances.values()) {
- if (!this.proxies.containsKey(instance.name)) {
- proxies.put(instance.name, new InstanceImpl(this, instance.name));
- }
- }
- List<String> names = new ArrayList<String>(this.proxies.keySet());
- for (String name : names) {
- if (!state.instances.containsKey(name)) {
- this.proxies.remove(name);
- }
- }
- return state;
- }
-
- private void saveData(State state, org.apache.felix.utils.properties.Properties storage) {
- storage.put("ssh.port", Integer.toString(state.defaultSshPortStart));
- storage.put("rmi.registry.port", Integer.toString(state.defaultRmiRegistryPortStart));
- storage.put("rmi.server.port", Integer.toString(state.defaultRmiServerPortStart));
- storage.put("count", Integer.toString(state.instances.size()));
- int i = 0;
- for (InstanceState instance : state.instances.values()) {
- storage.put("item." + i + ".name", instance.name);
- storage.put("item." + i + ".root", Boolean.toString(instance.root));
- storage.put("item." + i + ".loc", instance.loc);
- storage.put("item." + i + ".pid", Integer.toString(instance.pid));
- storage.put("item." + i + ".opts", instance.opts != null ? instance.opts : "");
- i++;
- }
- while (storage.containsKey("item." + i + ".name")) {
- storage.remove("item." + i + ".name");
- storage.remove("item." + i + ".root");
- storage.remove("item." + i + ".loc");
- storage.remove("item." + i + ".pid");
- storage.remove("item." + i + ".opts");
- i++;
- }
- }
-
- private boolean getBool(org.apache.felix.utils.properties.Properties storage, String name, boolean def) {
- Object value = storage.get(name);
- if (value != null) {
- return Boolean.parseBoolean(value.toString());
- } else {
- return def;
- }
- }
-
- private int getInt(org.apache.felix.utils.properties.Properties storage, String name, int def) {
- Object value = storage.get(name);
- if (value != null) {
- return Integer.parseInt(value.toString());
- } else {
- return def;
- }
- }
-
- private String getString(org.apache.felix.utils.properties.Properties storage, String name, String def) {
- Object value = storage.get(name);
- return value != null ? value.toString() : def;
- }
-
- interface Task<T> {
- T call(State state) throws IOException;
- }
-
- synchronized <T> T execute(final Task<T> callback) {
- final File storageFile = new File(storageLocation, STORAGE_FILE);
- if (!storageFile.exists()) {
- storageFile.getParentFile().mkdirs();
- try {
- storageFile.createNewFile();
- } catch (IOException e) {
- // Ignore
- }
- }
- if (storageFile.exists()) {
- if (!storageFile.isFile()) {
- throw new IllegalStateException("Instance storage location should be a file: " + storageFile);
- }
- try {
- return FileLockUtils.execute(storageFile, new FileLockUtils.CallableWithProperties<T>() {
- public T call(org.apache.felix.utils.properties.Properties properties) throws IOException {
- State state = loadData(properties);
- T t = callback.call(state);
- saveData(state, properties);
- return t;
- }
- });
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- } else {
- throw new IllegalStateException("Instance storage location does not exist: " + storageFile);
- }
- }
-
- public synchronized void refreshInstance() throws Exception {
- }
-
- private void logInfo(String message, boolean printOutput, Object... args) {
- if (LOGGER.isInfoEnabled() || printOutput) {
- String formatted = String.format(message, args);
- LOGGER.info(formatted);
- if (printOutput) {
- println(formatted);
- }
- }
- }
-
- public synchronized Instance createInstance(final String name, final InstanceSettings settings, final boolean printOutput) throws Exception {
- return execute(new Task<Instance>() {
- public Instance call(State state) throws IOException {
- if (state.instances.get(name) != null) {
- throw new IllegalArgumentException("Instance '" + name + "' already exists");
- }
- String loc = settings.getLocation() != null ? settings.getLocation() : name;
- File karafBase = new File(loc);
- if (!karafBase.isAbsolute()) {
- karafBase = new File(storageLocation, loc);
- }
- int sshPort = settings.getSshPort();
- if (sshPort <= 0) {
- sshPort = ++state.defaultSshPortStart;
- }
- int rmiRegistryPort = settings.getRmiRegistryPort();
- if (rmiRegistryPort <= 0) {
- rmiRegistryPort = ++state.defaultRmiRegistryPortStart;
- }
- int rmiServerPort = settings.getRmiServerPort();
- if (rmiServerPort <= 0) {
- rmiServerPort = ++state.defaultRmiServerPortStart;
- }
- logInfo("Creating new instance on SSH port %d and registry port %d / RMI server port %d at: %s",
- printOutput, sshPort, rmiRegistryPort, rmiServerPort, karafBase);
-
- mkdir(karafBase, "bin", printOutput);
- mkdir(karafBase, "etc", printOutput);
- mkdir(karafBase, "system", printOutput);
- mkdir(karafBase, "deploy", printOutput);
- mkdir(karafBase, "data", printOutput);
-
- copyResourceToDir(karafBase, "etc/all.policy", printOutput);
- copyResourceToDir(karafBase, "etc/config.properties", printOutput);
- copyResourceToDir(karafBase, "etc/custom.properties", printOutput);
- copyResourceToDir(karafBase, "etc/distribution.info", printOutput);
- copyResourceToDir(karafBase, "etc/equinox-debug.properties", printOutput);
- copyResourceToDir(karafBase, "etc/java.util.logging.properties", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.java.lang.Memory.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.bundle.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.config.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.org.apache.karaf.security.jmx.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jmx.acl.osgi.compendium.cm.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/jre.properties", printOutput);
- copyResourceToDir(karafBase, "etc/keys.properties", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.felix.fileinstall-deploy.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.bundle.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.config.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.feature.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.jaas.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.kar.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.shell.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.command.acl.system.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.features.obr.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.features.repos.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.jaas.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.kar.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.apache.karaf.log.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.ops4j.pax.logging.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/org.ops4j.pax.url.mvn.cfg", printOutput);
- copyResourceToDir(karafBase, "etc/regions-config.xml", printOutput);
- copyResourceToDir(karafBase, "etc/shell.init.script", printOutput);
- copyResourceToDir(karafBase, "etc/users.properties", printOutput);
-
- copyResourceToDir(karafBase, FEATURES_CFG, printOutput);
- addFeaturesFromSettings(new File(karafBase, FEATURES_CFG), settings);
-
- // The startup.properties is now generated by the karaf maven plugin, so
- // we use the one from the root instance instead of embedding it
- File rootEtc = new File(System.getProperty("karaf.etc"));
- copy(new File(rootEtc, "startup.properties"), new File(karafBase, "etc/startup.properties"));
-
- HashMap<String, String> props = new HashMap<String, String>();
- props.put("${SUBST-KARAF-NAME}", name);
- props.put("${SUBST-KARAF-HOME}", System.getProperty("karaf.home"));
- props.put("${SUBST-KARAF-BASE}", karafBase.getPath());
- props.put("${SUBST-SSH-PORT}", Integer.toString(sshPort));
- props.put("${SUBST-RMI-REGISTRY-PORT}", Integer.toString(rmiRegistryPort));
- props.put("${SUBST-RMI-SERVER-PORT}", Integer.toString(rmiServerPort));
- copyFilteredResourceToDir(karafBase, "etc/system.properties", props, printOutput);
- copyFilteredResourceToDir(karafBase, "etc/org.apache.karaf.shell.cfg", props, printOutput);
- copyFilteredResourceToDir(karafBase, "etc/org.apache.karaf.management.cfg", props, printOutput);
-
- copyFilteredResourceToDir(karafBase, "bin/karaf", props, printOutput);
- copyFilteredResourceToDir(karafBase, "bin/start", props, printOutput);
- copyFilteredResourceToDir(karafBase, "bin/stop", props, printOutput);
-
- copyFilteredResourceToDir(karafBase, "bin/karaf.bat", props, printOutput);
- copyFilteredResourceToDir(karafBase, "bin/start.bat", props, printOutput);
- copyFilteredResourceToDir(karafBase, "bin/stop.bat", props, printOutput);
-
- try {
- chmod(new File(karafBase, "bin/karaf"), "a+x");
- chmod(new File(karafBase, "bin/start"), "a+x");
- chmod(new File(karafBase, "bin/stop"), "a+x");
- } catch (IOException e) {
- LOGGER.debug("Could not set file mode on scripts.", e);
- }
-
- String javaOpts = settings.getJavaOpts();
- if (javaOpts == null || javaOpts.length() == 0) {
- javaOpts = DEFAULT_JAVA_OPTS;
- }
- InstanceState is = new InstanceState();
- is.name = name;
- is.loc = karafBase.toString();
- is.opts = javaOpts;
- state.instances.put(name, is);
- InstanceImpl instance = new InstanceImpl(InstanceServiceImpl.this, name);
- InstanceServiceImpl.this.proxies.put(name, instance);
- return instance;
- }
- });
- }
-
- void addFeaturesFromSettings(File featuresCfg, final InstanceSettings settings) throws IOException {
- FileLockUtils.execute(featuresCfg, new FileLockUtils.RunnableWithProperties() {
- public void run(org.apache.felix.utils.properties.Properties properties) throws IOException {
- appendToPropList(properties, "featuresBoot", settings.getFeatures());
- appendToPropList(properties, "featuresRepositories", settings.getFeatureURLs());
- }
- });
- }
-
- private void appendToPropList(org.apache.felix.utils.properties.Properties p, String key, List<String> elements) {
- if (elements == null) {
- return;
- }
- StringBuilder sb = new StringBuilder(p.get(key).toString().trim());
- for (String f : elements) {
- if (sb.length() > 0) {
- sb.append(',');
- }
- sb.append(f);
- }
- p.put(key, sb.toString());
- }
-
- public Instance[] getInstances() {
- return execute(new Task<Instance[]>() {
- public Instance[] call(State state) throws IOException {
- return proxies.values().toArray(new Instance[proxies.size()]);
- }
- });
- }
-
- public Instance getInstance(final String name) {
- return execute(new Task<Instance>() {
- public Instance call(State state) throws IOException {
- return proxies.get(name);
- }
- });
- }
-
- public void startInstance(final String name, final String javaOpts) {
- execute(new Task<Object>() {
- public Object call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- checkPid(instance);
- if (instance.pid != 0) {
- throw new IllegalStateException("Instance already started");
- }
- String opts = javaOpts;
- if (opts == null || opts.length() == 0) {
- opts = instance.opts;
- }
- if (opts == null || opts.length() == 0) {
- opts = DEFAULT_JAVA_OPTS;
- }
-
- // fallback and read karafOpts from KARAF_OPTS environment if no System property present
- String karafOptsEnv = System.getenv("KARAF_OPTS");
- String karafOpts = System.getProperty("karaf.opts", karafOptsEnv != null ? karafOptsEnv : "");
-
- String location = instance.loc;
-
- File libDir = new File(System.getProperty("karaf.home"), "lib");
- File childLibDir = new File(location, "lib");
-
- StringBuilder classpath = classpathFromLibDir(libDir);
- StringBuilder childClasspath = classpathFromLibDir(childLibDir);
- if (childClasspath.length() > 0 && !libDir.equals(childLibDir)) {
- classpath.append(System.getProperty("path.separator"));
- classpath.append(childClasspath);
- }
-
- String command = "\""
- + new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath()
- + "\" " + opts
- + " " + karafOpts
- + " -Djava.util.logging.config.file=\"" + new File(location, "etc/java.util.logging.properties").getCanonicalPath() + "\""
- + " -Djava.endorsed.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(libDir, "endorsed").getCanonicalPath() + "\""
- + " -Djava.ext.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "ext") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "ext") + System.getProperty("path.separator") + new File(libDir, "ext").getCanonicalPath() + "\""
- + " -Dkaraf.home=\"" + System.getProperty("karaf.home") + "\""
- + " -Dkaraf.base=\"" + new File(location).getCanonicalPath() + "\""
- + " -Dkaraf.data=\"" + new File(new File(location).getCanonicalPath(), "data") + "\""
- + " -Dkaraf.etc=\"" + new File(new File(location).getCanonicalPath(), "etc") + "\""
- + " -Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder"
- + " -Dkaraf.startLocalConsole=false"
- + " -Dkaraf.startRemoteShell=true"
- + " -classpath \"" + classpath.toString() + "\""
- + " org.apache.karaf.main.Main";
- LOGGER.debug("Starting instance " + name + " with command: " + command);
- org.apache.karaf.jpm.Process process = new ProcessBuilderFactoryImpl().newBuilder()
- .directory(new File(location))
- .command(command)
- .start();
- instance.pid = process.getPid();
- return null;
- }
-
- private StringBuilder classpathFromLibDir(File libDir) throws IOException {
- File[] jars = libDir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".jar");
- }
- });
- StringBuilder classpath = new StringBuilder();
- if (jars != null) {
- for (File jar : jars) {
- if (classpath.length() > 0) {
- classpath.append(System.getProperty("path.separator"));
- }
- classpath.append(jar.getCanonicalPath());
- }
- }
- return classpath;
- }
- });
- }
-
- public void stopInstance(final String name) {
- execute(new Task<Object>() {
- public Object call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- checkPid(instance);
- if (instance.pid == 0) {
- throw new IllegalStateException("Instance already stopped");
- }
- cleanShutdown(instance);
- if (instance.pid > 0) {
- Process process = new ProcessBuilderFactoryImpl().newBuilder().attach(instance.pid);
- process.destroy();
- }
- return null;
- }
- });
- }
-
- public void destroyInstance(final String name) {
- execute(new Task<Object>() {
- public Object call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- checkPid(instance);
- if (instance.pid != 0) {
- throw new IllegalStateException("Instance not stopped");
- }
- deleteFile(new File(instance.loc));
- state.instances.remove(name);
- InstanceServiceImpl.this.proxies.remove(name);
- return null;
- }
- });
- }
-
- public void renameInstance(final String oldName, final String newName, final boolean printOutput) throws Exception {
- execute(new Task<Object>() {
- public Object call(State state) throws IOException {
- if (state.instances.get(newName) != null) {
- throw new IllegalArgumentException("Instance " + newName + " already exists");
- }
- InstanceState instance = state.instances.get(oldName);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + oldName + " not found");
- }
- if (instance.root) {
- throw new IllegalArgumentException("Root instance cannot be renamed");
- }
- checkPid(instance);
- if (instance.pid != 0) {
- throw new IllegalStateException("Instance not stopped");
- }
-
- println(Ansi.ansi().a("Renaming instance ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(oldName).a(Ansi.Attribute.RESET)
- .a(" to ")
- .a(Ansi.Attribute.INTENSITY_BOLD).a(newName).a(Ansi.Attribute.RESET).toString());
- // rename directory
- String oldLocationPath = instance.loc;
- File oldLocation = new File(oldLocationPath);
- String basedir = oldLocation.getParent();
- File newLocation = new File(basedir, newName);
- oldLocation.renameTo(newLocation);
- // create the properties map including the instance name and instance location
- // TODO: replacing is bad, we should re-extract the needed files
- HashMap<String, String> props = new HashMap<String, String>();
- props.put(oldName, newName);
- props.put(oldLocationPath, newLocation.getPath());
- // replace all references to the "old" name by the new one in etc/system.properties
- // NB: it's replacement to avoid to override the user's changes
- filterResource(newLocation, "etc/system.properties", props);
- // replace all references to the "old" name by the new one in bin/karaf
- filterResource(newLocation, "bin/karaf", props);
- filterResource(newLocation, "bin/start", props);
- filterResource(newLocation, "bin/stop", props);
- filterResource(newLocation, "bin/karaf.bat", props);
- filterResource(newLocation, "bin/start.bat", props);
- filterResource(newLocation, "bin/stop.bat", props);
- // update instance
- instance.name = newName;
- instance.loc = newLocation.getPath();
- state.instances.put(newName, instance);
- state.instances.remove(oldName);
- InstanceImpl proxy = InstanceServiceImpl.this.proxies.remove(oldName);
- if (proxy == null) {
- proxy = new InstanceImpl(InstanceServiceImpl.this, newName);
- } else {
- proxy.doSetName(newName);
- }
- InstanceServiceImpl.this.proxies.put(newName, proxy);
- return null;
- }
- });
- }
-
- public synchronized Instance cloneInstance(final String name, final String cloneName, final InstanceSettings settings, final boolean printOutput) throws Exception {
- final int instanceSshPort = getInstanceSshPort(name);
- final int instanceRmiRegistryPort = getInstanceRmiRegistryPort(name);
- final int instanceRmiServerPort = getInstanceRmiServerPort(name);
-
- return execute(new Task<Instance>() {
- public Instance call(State state) throws IOException {
- if (state.instances.get(cloneName) != null) {
- throw new IllegalArgumentException("Instance " + cloneName + " already exists");
- }
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
-
- // define the clone instance location
- String cloneLocationPath = settings.getLocation() != null ? settings.getLocation() : cloneName;
- File cloneLocation = new File(cloneLocationPath);
- if (!cloneLocation.isAbsolute()) {
- cloneLocation = new File(storageLocation, cloneLocationPath);
- }
- // copy instance directory
- String locationPath = instance.loc;
- File location = new File(locationPath);
- copy(location, cloneLocation);
- // create the properties map including the instance name, location, ssh and rmi port numbers
- // TODO: replacing stuff anywhere is not really good, we might end up replacing unwanted stuff
- // TODO: if no ports are overriden, shouldn't we choose new ports ?
- HashMap<String, String> props = new HashMap<String, String>();
- props.put(name, cloneName);
- props.put(locationPath, cloneLocationPath);
- if (settings.getSshPort() > 0)
- props.put(Integer.toString(instanceSshPort), Integer.toString(settings.getSshPort()));
- if (settings.getRmiRegistryPort() > 0)
- props.put(Integer.toString(instanceRmiRegistryPort), Integer.toString(settings.getRmiRegistryPort()));
- if (settings.getRmiServerPort() > 0)
- props.put(Integer.toString(instanceRmiServerPort), Integer.toString(settings.getRmiServerPort()));
-
- // filtering clone files
- filterResource(cloneLocation, "etc/custom.properties", props);
- filterResource(cloneLocation, "etc/org.apache.karaf.management.cfg", props);
- filterResource(cloneLocation, "etc/org.apache.karaf.shell.cfg", props);
- filterResource(cloneLocation, "etc/system.properties", props);
- filterResource(cloneLocation, "bin/karaf", props);
- filterResource(cloneLocation, "bin/start", props);
- filterResource(cloneLocation, "bin/stop", props);
- filterResource(cloneLocation, "bin/karaf.bat", props);
- filterResource(cloneLocation, "bin/start.bat", props);
- filterResource(cloneLocation, "bin/stop.bat", props);
- // create and add the clone instance in the registry
- String javaOpts = settings.getJavaOpts();
- if (javaOpts == null || javaOpts.length() == 0) {
- javaOpts = DEFAULT_JAVA_OPTS;
- }
- InstanceState is = new InstanceState();
- is.name = cloneName;
- is.loc = cloneLocation.toString();
- is.opts = javaOpts;
- state.instances.put(cloneName, is);
- InstanceImpl cloneInstance = new InstanceImpl(InstanceServiceImpl.this, cloneName);
- InstanceServiceImpl.this.proxies.put(cloneName, cloneInstance);
- return cloneInstance;
- }
- });
- }
-
- private void checkPid(InstanceState instance) throws IOException {
- if (instance.pid != 0) {
- Process process = new ProcessBuilderFactoryImpl().newBuilder().attach(instance.pid);
- if (!process.isRunning()) {
- instance.pid = 0;
- }
- }
- }
-
- protected void cleanShutdown(InstanceState instance) {
- try {
- File file = new File(new File(instance.loc, "etc"), CONFIG_PROPERTIES_FILE_NAME);
- URL configPropURL = file.toURI().toURL();
- Properties props = loadPropertiesFile(configPropURL);
- props.put("karaf.base", new File(instance.loc).getCanonicalPath());
- props.put("karaf.home", System.getProperty("karaf.home"));
- props.put("karaf.data", new File(new File(instance.loc), "data").getCanonicalPath());
- props.put("karaf.etc", new File(new File(instance.loc), "etc").getCanonicalPath());
- for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- props.setProperty(key,
- substVars(props.getProperty(key), key, null, props));
- }
- int port = Integer.parseInt(props.getProperty(KARAF_SHUTDOWN_PORT, "0"));
- String host = props.getProperty(KARAF_SHUTDOWN_HOST, "localhost");
- String portFile = props.getProperty(KARAF_SHUTDOWN_PORT_FILE);
- String shutdown = props.getProperty(KARAF_SHUTDOWN_COMMAND, DEFAULT_SHUTDOWN_COMMAND);
- if (port == 0 && portFile != null) {
- BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(portFile)));
- String portStr = r.readLine();
- port = Integer.parseInt(portStr);
- r.close();
- }
- // We found the port, try to send the command
- if (port > 0) {
- Socket s = new Socket(host, port);
- s.getOutputStream().write(shutdown.getBytes());
- s.close();
- long t = System.currentTimeMillis() + getStopTimeout();
- do {
- Thread.sleep(100);
- checkPid(instance);
- } while (System.currentTimeMillis() < t && instance.pid > 0);
- }
- } catch (Exception e) {
- LOGGER.debug("Unable to cleanly shutdown instance " + instance.name, e);
- }
- }
-
- int getInstanceSshPort(String name) {
- return getKarafPort(name, "etc/org.apache.karaf.shell.cfg", "sshPort");
- }
-
- void changeInstanceSshPort(String name, final int port) throws Exception {
- setKarafPort(name, "etc/org.apache.karaf.shell.cfg", "sshPort", port);
- }
-
- int getInstanceRmiRegistryPort(String name) {
- return getKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiRegistryPort");
- }
-
- void changeInstanceRmiRegistryPort(String name, final int port) throws Exception {
- setKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiRegistryPort", port);
- }
-
- int getInstanceRmiServerPort(String name) {
- return getKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiServerPort");
- }
-
- void changeInstanceRmiServerPort(String name, int port) throws Exception {
- setKarafPort(name, "etc/org.apache.karaf.management.cfg", "rmiServerPort", port);
- }
-
- private int getKarafPort(final String name, final String path, final String key) {
- return execute(new Task<Integer>() {
- public Integer call(State state) throws IOException {
- return InstanceServiceImpl.this.getKarafPort(state, name, path, key);
- }
- });
- }
-
- private Integer getKarafPort(State state, String name, String path, final String key) {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- File f = new File(instance.loc, path);
- try {
- return FileLockUtils.execute(f, new FileLockUtils.CallableWithProperties<Integer>() {
- public Integer call(org.apache.felix.utils.properties.Properties properties) throws IOException {
- return Integer.parseInt(properties.get(key).toString());
- }
- });
- } catch (IOException e) {
- return 0;
- }
- }
-
- private void setKarafPort(final String name, final String path, final String key, final int port) throws IOException {
- execute(new Task<Object>() {
- public Object call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- checkPid(instance);
- if (instance.pid != 0) {
- throw new IllegalStateException("Instance is not stopped");
- }
- File f = new File(instance.loc, path);
- FileLockUtils.execute(f, new FileLockUtils.RunnableWithProperties() {
- public void run(org.apache.felix.utils.properties.Properties properties) throws IOException {
- properties.put(key, Integer.toString(port));
- }
- });
- return null;
- }
- });
- }
-
- boolean isInstanceRoot(final String name) {
- return execute(new Task<Boolean>() {
- public Boolean call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- return instance.root;
- }
- });
- }
-
- String getInstanceLocation(final String name) {
- return execute(new Task<String>() {
- public String call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- return instance.loc;
- }
- });
- }
-
- int getInstancePid(final String name) {
- return execute(new Task<Integer>() {
- public Integer call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- checkPid(instance);
- return instance.pid;
- }
- });
- }
-
- String getInstanceJavaOpts(final String name) {
- return execute(new Task<String>() {
- public String call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- return instance.opts;
- }
- });
- }
-
- void changeInstanceJavaOpts(final String name, final String opts) {
- execute(new Task<String>() {
- public String call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- instance.opts = opts;
- return null;
- }
- });
- }
-
- String getInstanceState(final String name) {
- return execute(new Task<String>() {
- public String call(State state) throws IOException {
- InstanceState instance = state.instances.get(name);
- if (instance == null) {
- throw new IllegalArgumentException("Instance " + name + " not found");
- }
- int port = getKarafPort(state, name, "etc/org.apache.karaf.shell.cfg", "sshPort");
- if (!new File(instance.loc).isDirectory() || port <= 0) {
- return Instance.ERROR;
- }
- checkPid(instance);
- if (instance.pid == 0) {
- return Instance.STOPPED;
- } else {
- try {
- Socket s = new Socket("localhost", port);
- s.close();
- return Instance.STARTED;
- } catch (Exception e) {
- // ignore
- }
- return Instance.STARTING;
- }
- }
- });
- }
-
- private boolean deleteFile(File fileToDelete) {
- if (fileToDelete == null || !fileToDelete.exists()) {
- return true;
- }
- boolean result = true;
- if (fileToDelete.isDirectory()) {
- File[] files = fileToDelete.listFiles();
- if (files == null) {
- result = false;
- } else {
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- if (file.getName().equals(".") || file.getName().equals("..")) {
- continue;
- }
- if (file.isDirectory()) {
- result &= deleteFile(file);
- } else {
- result &= file.delete();
- }
- }
- }
- }
- result &= fileToDelete.delete();
- return result;
- }
-
- private void copyResourceToDir(File target, String resource, boolean printOutput) throws IOException {
- File outFile = new File(target, resource);
- if( !outFile.exists() ) {
- logInfo("Creating file: %s", printOutput, outFile.getPath());
- InputStream is = getClass().getClassLoader().getResourceAsStream("org/apache/karaf/instance/resources/" + resource);
- try {
- // Read it line at a time so that we can use the platform line ending when we write it out.
- PrintStream out = new PrintStream(new FileOutputStream(outFile));
- try {
- Scanner scanner = new Scanner(is);
- while (scanner.hasNextLine() ) {
- String line = scanner.nextLine();
- out.println(line);
- }
- } finally {
- safeClose(out);
- }
- } finally {
- safeClose(is);
- }
- }
- }
-
- private void println(String st) {
- System.out.println(st);
- }
-
- protected static Properties loadPropertiesFile(URL configPropURL) throws Exception {
- // Read the properties file.
- Properties configProps = new Properties();
- InputStream is = null;
- try {
- is = configPropURL.openConnection().getInputStream();
- configProps.load(is);
- is.close();
- }
- catch (Exception ex) {
- System.err.println(
- "Error loading config properties from " + configPropURL);
- System.err.println("Main: " + ex);
- try {
- if (is != null) is.close();
- }
- catch (IOException ex2) {
- // Nothing we can do.
- }
- return null;
- }
- return configProps;
- }
-
- private void filterResource(File basedir, String path, HashMap<String, String> props) throws IOException {
- File file = new File(basedir, path);
- File bak = new File(basedir, path + BACKUP_EXTENSION);
- if (!file.exists()) {
- return;
- }
- // rename the file to the backup one
- file.renameTo(bak);
- // copy and filter the bak file back to the original name
- copyAndFilterResource(new FileInputStream(bak), new FileOutputStream(file), props);
- // remove the bak file
- bak.delete();
- }
-
- private void copyFilteredResourceToDir(File target, String resource, HashMap<String, String> props, boolean printOutput) throws IOException {
- File outFile = new File(target, resource);
- if( !outFile.exists() ) {
- logInfo("Creating file: %s", printOutput, outFile.getPath());
- InputStream is = getClass().getClassLoader().getResourceAsStream("org/apache/karaf/instance/resources/" + resource);
- copyAndFilterResource(is, new FileOutputStream(outFile), props);
- }
- }
-
- private void copyAndFilterResource(InputStream source, OutputStream target, HashMap<String, String> props) throws IOException {
- try {
- // read it line at a time so that we can use the platform line ending when we write it out.
- PrintStream out = new PrintStream(target);
- try {
- Scanner scanner = new Scanner(source);
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- line = filter(line, props);
- out.println(line);
- }
- } finally {
- safeClose(out);
- }
- } finally {
- safeClose(source);
- }
- }
-
- private void safeClose(InputStream is) throws IOException {
- if (is == null) {
- return;
- }
- try {
- is.close();
- } catch (Throwable ignore) {
- }
- }
-
- private void safeClose(OutputStream is) throws IOException {
- if (is == null) {
- return;
- }
- try {
- is.close();
- } catch (Throwable ignore) {
- }
- }
-
- private String filter(String line, HashMap<String, String> props) {
- for (Map.Entry<String, String> i : props.entrySet()) {
- int p1 = line.indexOf(i.getKey());
- if( p1 >= 0 ) {
- String l1 = line.substring(0, p1);
- String l2 = line.substring(p1+i.getKey().length());
- line = l1+i.getValue()+l2;
- }
- }
- return line;
- }
-
- private void mkdir(File karafBase, String path, boolean printOutput) {
- File file = new File(karafBase, path);
- if( !file.exists() ) {
- logInfo("Creating dir: %s", printOutput, file.getPath());
- file.mkdirs();
- }
- }
-
- private int chmod(File serviceFile, String mode) throws IOException {
- java.lang.ProcessBuilder builder = new java.lang.ProcessBuilder();
- builder.command("chmod", mode, serviceFile.getCanonicalPath());
- java.lang.Process p = builder.start();
-
- // gnodet: Fix SMX4KNL-46: cpu goes to 100% after running the 'admin create' command
- // Not sure exactly what happens, but commenting the process io redirection seems
- // to work around the problem.
- //
- //PumpStreamHandler handler = new PumpStreamHandler(io.inputStream, io.outputStream, io.errorStream);
- //handler.attach(p);
- //handler.start();
- try {
- return p.waitFor();
- } catch (InterruptedException e) {
- throw (IOException) new InterruptedIOException().initCause(e);
- }
- //handler.stop();
- }
-
- private void copy(File source, File destination) throws IOException {
- if (source.getName().equals("cache.lock")) {
- // ignore cache.lock file
- return;
- }
- if (source.getName().equals("lock")) {
- // ignore lock file
- return;
- }
- if (source.getName().matches("transaction_\\d+\\.log")) {
- // ignore active txlog files
- return;
- }
- if (source.isDirectory()) {
- if (!destination.exists()) {
- destination.mkdirs();
- }
- String[] children = source.list();
- for (String child : children) {
- if (!child.contains("instances") && !child.contains("lib"))
- copy(new File(source, child), new File(destination, child));
- }
- } else {
- InputStream in = new FileInputStream(source);
- OutputStream out = new FileOutputStream(destination);
- byte[] buffer = new byte[1024];
- int length;
- while ((length = in.read(buffer)) > 0) {
- out.write(buffer, 0, length);
- }
- in.close();
- out.close();
- }
- }
-
- private static final String DELIM_START = "${";
- private static final String DELIM_STOP = "}";
-
- protected static String substVars(String val, String currentKey,
- Map<String, String> cycleMap, Properties configProps)
- throws IllegalArgumentException {
- // If there is currently no cycle map, then create
- // one for detecting cycles for this invocation.
- if (cycleMap == null) {
- cycleMap = new HashMap<String, String>();
- }
-
- // Put the current key in the cycle map.
- cycleMap.put(currentKey, currentKey);
-
- // Assume we have a value that is something like:
- // "leading ${foo.${bar}} middle ${baz} trailing"
-
- // Find the first ending '}' variable delimiter, which
- // will correspond to the first deepest nested variable
- // placeholder.
- int stopDelim = val.indexOf(DELIM_STOP);
-
- // Find the matching starting "${" variable delimiter
- // by looping until we find a start delimiter that is
- // greater than the stop delimiter we have found.
- int startDelim = val.indexOf(DELIM_START);
- while (stopDelim >= 0) {
- int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
- if ((idx < 0) || (idx > stopDelim)) {
- break;
- } else if (idx < stopDelim) {
- startDelim = idx;
- }
- }
-
- // If we do not have a start or stop delimiter, then just
- // return the existing value.
- if ((startDelim < 0) && (stopDelim < 0)) {
- return val;
- }
- // At this point, we found a stop delimiter without a start,
- // so throw an exception.
- else if (((startDelim < 0) || (startDelim > stopDelim))
- && (stopDelim >= 0)) {
- throw new IllegalArgumentException(
- "stop delimiter with no start delimiter: "
- + val);
- }
-
- // At this point, we have found a variable placeholder so
- // we must perform a variable substitution on it.
- // Using the start and stop delimiter indices, extract
- // the first, deepest nested variable placeholder.
- String variable =
- val.substring(startDelim + DELIM_START.length(), stopDelim);
-
- // Verify that this is not a recursive variable reference.
- if (cycleMap.get(variable) != null) {
- throw new IllegalArgumentException(
- "recursive variable reference: " + variable);
- }
-
- // Get the value of the deepest nested variable placeholder.
- // Try to configuration properties first.
- String substValue = (configProps != null)
- ? configProps.getProperty(variable, null)
- : null;
- if (substValue == null) {
- // Ignore unknown property values.
- substValue = System.getProperty(variable, "");
- }
-
- // Remove the found variable from the cycle map, since
- // it may appear more than once in the value and we don't
- // want such situations to appear as a recursive reference.
- cycleMap.remove(variable);
-
- // Append the leading characters, the substituted value of
- // the variable, and the trailing characters to get the new
- // value.
- val = val.substring(0, startDelim)
- + substValue
- + val.substring(stopDelim + DELIM_STOP.length(), val.length());
-
- // Now perform substitution again, since there could still
- // be substitutions to make.
- val = substVars(val, currentKey, cycleMap, configProps);
-
- // Return the value.
- return val;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
----------------------------------------------------------------------
diff --git a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java b/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
deleted file mode 100644
index baaedaf..0000000
--- a/instance/core/src/main/java/org/apache/karaf/instance/core/internal/InstanceToTableMapper.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.instance.core.internal;
-
-import java.util.List;
-
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.InstancesMBean;
-
-public class InstanceToTableMapper {
-
- private InstanceToTableMapper() {
- }
-
- private static CompositeDataSupport mapInstance(Instance instance, CompositeType comp) throws OpenDataException {
- String state;
- try {
- state = instance.getState();
- } catch (Exception e) {
- state = "Error";
- }
- Object[] itemValues = new Object[] {instance.getPid(), instance.getName(), instance.isRoot(),
- instance.getSshPort(), instance.getRmiRegistryPort(),
- instance.getRmiServerPort(), state, instance.getLocation(),
- instance.getJavaOpts()};
- return new CompositeDataSupport(comp, InstancesMBean.INSTANCE, itemValues);
- }
-
- private static CompositeType createRowType() throws OpenDataException {
- String desc = "This type describes Karaf instance";
- OpenType<?>[] itemTypes = new OpenType[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN,
- SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.INTEGER,
- SimpleType.STRING, SimpleType.STRING, SimpleType.STRING};
- String[] descriptions = new String[] {"The Process ID of the instance or 0 if not running",
- "The name of the instance", "Whether the instance is root",
- "The SSH port that can be used to connect to the instance",
- "The RMI registry port that can be used to manage the instance",
- "The RMI server port that can be used to manage the instance",
- "The state of the instance", "The location of the instance",
- "The Java options of the instance"};
- CompositeType comp = new CompositeType("Instances", desc, InstancesMBean.INSTANCE, descriptions, itemTypes);
- return comp;
- }
-
- public static TabularData tableFrom(List<Instance> instances) {
- try {
- CompositeType rowType = createRowType();
- TabularType tableType = new TabularType("Instances", "Table of all Karaf instances", rowType,
- new String[] {InstancesMBean.INSTANCE_NAME});
- TabularDataSupport table = new TabularDataSupport(tableType);
- for (Instance instance : instances) {
- CompositeDataSupport row = mapInstance(instance, rowType);
- table.put(row);
- }
- return table;
- } catch (OpenDataException e) {
- throw new IllegalStateException("Error building instance table", e);
- }
- }
-}
[35/59] [abbrv] [KARAF-2852] Merge log/core and log/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java b/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java
new file mode 100644
index 0000000..ea51b34
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java
@@ -0,0 +1,124 @@
+/*
+ * 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.log.core.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.ops4j.pax.logging.spi.PaxAppender;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+/**
+ * A list that only keep the last N elements added
+ */
+public class LruList implements PaxAppender {
+
+ private PaxLoggingEvent[] elements;
+ private transient int start = 0;
+ private transient int end = 0;
+ private transient boolean full = false;
+ private final int maxElements;
+ private final List<PaxAppender> appenders;
+
+ public LruList(int size) {
+ if (size <= 0) {
+ throw new IllegalArgumentException("The size must be greater than 0");
+ }
+ elements = new PaxLoggingEvent[size];
+ maxElements = elements.length;
+ appenders = new ArrayList<PaxAppender>();
+ }
+
+ public synchronized int size() {
+ int size = 0;
+ if (end < start) {
+ size = maxElements - start + end;
+ } else if (end == start) {
+ size = (full ? maxElements : 0);
+ } else {
+ size = end - start;
+ }
+ return size;
+ }
+
+ public synchronized void clear() {
+ start = 0;
+ end = 0;
+ elements = new PaxLoggingEvent[maxElements];
+ }
+
+ public synchronized void add(PaxLoggingEvent element) {
+ if (null == element) {
+ throw new NullPointerException("Attempted to add null object to buffer");
+ }
+ if (size() == maxElements) {
+ Object e = elements[start];
+ if (null != e) {
+ elements[start++] = null;
+ if (start >= maxElements) {
+ start = 0;
+ }
+ full = false;
+ }
+ }
+ elements[end++] = element;
+ if (end >= maxElements) {
+ end = 0;
+ }
+ if (end == start) {
+ full = true;
+ }
+ for (PaxAppender appender : appenders) {
+ try {
+ appender.doAppend(element);
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+
+ public synchronized Iterable<PaxLoggingEvent> getElements() {
+ return getElements(size());
+ }
+
+ public synchronized Iterable<PaxLoggingEvent> getElements(int nb) {
+ int s = size();
+ nb = Math.min(Math.max(0, nb), s);
+ PaxLoggingEvent[] e = new PaxLoggingEvent[nb];
+ for (int i = 0; i < nb; i++) {
+ e[i] = elements[(i + s - nb + start) % maxElements];
+ }
+ return Arrays.asList(e);
+ }
+
+ public synchronized void addAppender(PaxAppender appender) {
+ this.appenders.add(appender);
+ }
+
+ public synchronized void removeAppender(PaxAppender appender) {
+ this.appenders.remove(appender);
+ }
+
+ public void doAppend(PaxLoggingEvent event) {
+ event.getProperties(); // ensure MDC properties are copied
+ add(event);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
new file mode 100644
index 0000000..8bb3ff3
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
@@ -0,0 +1,142 @@
+/*
+ * 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.log.core.internal.layout;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Copied from log4j
+ */
+/**
+ Formats a {@link Date} in the format "HH:mm:ss,SSS" for example,
+ "15:49:37,459".
+
+ @since 0.7.5
+*/
+public class AbsoluteTimeDateFormat extends DateFormat {
+
+ /**
+ String constant used to specify {@link
+ org.apache.log4j.helpers.AbsoluteTimeDateFormat} in layouts. Current
+ value is <b>ABSOLUTE</b>. */
+ public final static String ABS_TIME_DATE_FORMAT = "ABSOLUTE";
+
+ /**
+ String constant used to specify {@link
+ org.apache.log4j.helpers.DateTimeDateFormat} in layouts. Current
+ value is <b>DATE</b>.
+ */
+ public final static String DATE_AND_TIME_DATE_FORMAT = "DATE";
+
+ /**
+ String constant used to specify {@link
+ org.apache.log4j.helpers.ISO8601DateFormat} in layouts. Current
+ value is <b>ISO8601</b>.
+ */
+ public final static String ISO8601_DATE_FORMAT = "ISO8601";
+
+ public
+ AbsoluteTimeDateFormat() {
+ setCalendar(Calendar.getInstance());
+ }
+
+ public
+ AbsoluteTimeDateFormat(TimeZone timeZone) {
+ setCalendar(Calendar.getInstance(timeZone));
+ }
+
+ private static long previousTime;
+ private static char[] previousTimeWithoutMillis = new char[9]; // "HH:mm:ss."
+
+ /**
+ Appends to <code>sbuf</code> the time in the format
+ "HH:mm:ss,SSS" for example, "15:49:37,459"
+
+ @param date the date to format
+ @param sbuf the string buffer to write to
+ @param fieldPosition remains untouched
+ */
+ public
+ StringBuffer format(Date date, StringBuffer sbuf,
+ FieldPosition fieldPosition) {
+
+ long now = date.getTime();
+ int millis = (int)(now % 1000);
+
+ if ((now - millis) != previousTime) {
+ // We reach this point at most once per second
+ // across all threads instead of each time format()
+ // is called. This saves considerable CPU time.
+
+ calendar.setTime(date);
+
+ int start = sbuf.length();
+
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ if(hour < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(hour);
+ sbuf.append(':');
+
+ int mins = calendar.get(Calendar.MINUTE);
+ if(mins < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(mins);
+ sbuf.append(':');
+
+ int secs = calendar.get(Calendar.SECOND);
+ if(secs < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(secs);
+ sbuf.append(',');
+
+ // store the time string for next time to avoid recomputation
+ sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0);
+
+ previousTime = now - millis;
+ }
+ else {
+ sbuf.append(previousTimeWithoutMillis);
+ }
+
+
+
+ if(millis < 100)
+ sbuf.append('0');
+ if(millis < 10)
+ sbuf.append('0');
+
+ sbuf.append(millis);
+ return sbuf;
+ }
+
+ /**
+ This method does not do anything but return <code>null</code>.
+ */
+ public
+ Date parse(String s, ParsePosition pos) {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
new file mode 100644
index 0000000..1aa884d
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
@@ -0,0 +1,85 @@
+/*
+ * 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.log.core.internal.layout;
+
+import java.text.DateFormatSymbols;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Copied from log4j
+ */
+/**
+ Formats a {@link Date} in the format "dd MMM yyyy HH:mm:ss,SSS" for example,
+ "06 Nov 1994 15:49:37,459".
+
+ @since 0.7.5
+*/
+public class DateTimeDateFormat extends AbsoluteTimeDateFormat {
+
+ String[] shortMonths;
+
+ public
+ DateTimeDateFormat() {
+ super();
+ shortMonths = new DateFormatSymbols().getShortMonths();
+ }
+
+ public
+ DateTimeDateFormat(TimeZone timeZone) {
+ this();
+ setCalendar(Calendar.getInstance(timeZone));
+ }
+
+ /**
+ Appends to <code>sbuf</code> the date in the format "dd MMM yyyy
+ HH:mm:ss,SSS" for example, "06 Nov 1994 08:49:37,459".
+
+ @param sbuf the string buffer to write to
+ */
+ public
+ StringBuffer format(Date date, StringBuffer sbuf,
+ FieldPosition fieldPosition) {
+
+ calendar.setTime(date);
+
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ if(day < 10)
+ sbuf.append('0');
+ sbuf.append(day);
+ sbuf.append(' ');
+ sbuf.append(shortMonths[calendar.get(Calendar.MONTH)]);
+ sbuf.append(' ');
+
+ int year = calendar.get(Calendar.YEAR);
+ sbuf.append(year);
+ sbuf.append(' ');
+
+ return super.format(date, sbuf, fieldPosition);
+ }
+
+ /**
+ This method does not do anything but return <code>null</code>.
+ */
+ public
+ Date parse(java.lang.String s, ParsePosition pos) {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
new file mode 100644
index 0000000..6fd728f
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
@@ -0,0 +1,44 @@
+/*
+ * 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.log.core.internal.layout;
+
+
+/**
+ * Copied from log4j
+ */
+/**
+ FormattingInfo instances contain the information obtained when parsing
+ formatting modifiers in conversion modifiers.
+
+ @since 0.8.2
+ */
+public class FormattingInfo {
+ int min = -1;
+ int max = 0x7FFFFFFF;
+ boolean leftAlign = false;
+
+ void reset() {
+ min = -1;
+ max = 0x7FFFFFFF;
+ leftAlign = false;
+ }
+
+ void dump() {
+ //LogLog.debug("min="+min+", max="+max+", leftAlign="+leftAlign);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
new file mode 100644
index 0000000..80155a0
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/ISO8601DateFormat.java
@@ -0,0 +1,152 @@
+/*
+ * 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.log.core.internal.layout;
+
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Copied from log4j
+ */
+// Contributors: Arndt Schoenewald <ar...@ibm23093i821.mc.schoenewald.de>
+/**
+ Formats a {@link Date} in the format "yyyy-MM-dd HH:mm:ss,SSS" for example
+ "1999-11-27 15:49:37,459".
+
+ <p>Refer to the <a
+ href=http://www.cl.cam.ac.uk/~mgk25/iso-time.html>summary of the
+ International Standard Date and Time Notation</a> for more
+ information on this format.
+
+ @since 0.7.5
+*/
+public class ISO8601DateFormat extends AbsoluteTimeDateFormat {
+
+ public
+ ISO8601DateFormat() {
+ }
+
+ public
+ ISO8601DateFormat(TimeZone timeZone) {
+ super(timeZone);
+ }
+
+ static private long lastTime;
+ static private char[] lastTimeString = new char[20];
+
+ /**
+ Appends a date in the format "YYYY-mm-dd HH:mm:ss,SSS"
+ to <code>sbuf</code>. For example: "1999-11-27 15:49:37,459".
+
+ @param sbuf the <code>StringBuffer</code> to write to
+ */
+ public
+ StringBuffer format(Date date, StringBuffer sbuf,
+ FieldPosition fieldPosition) {
+
+ long now = date.getTime();
+ int millis = (int)(now % 1000);
+
+ if ((now - millis) != lastTime) {
+ // We reach this point at most once per second
+ // across all threads instead of each time format()
+ // is called. This saves considerable CPU time.
+
+ calendar.setTime(date);
+
+ int start = sbuf.length();
+
+ int year = calendar.get(Calendar.YEAR);
+ sbuf.append(year);
+
+ String month;
+ switch(calendar.get(Calendar.MONTH)) {
+ case Calendar.JANUARY: month = "-01-"; break;
+ case Calendar.FEBRUARY: month = "-02-"; break;
+ case Calendar.MARCH: month = "-03-"; break;
+ case Calendar.APRIL: month = "-04-"; break;
+ case Calendar.MAY: month = "-05-"; break;
+ case Calendar.JUNE: month = "-06-"; break;
+ case Calendar.JULY: month = "-07-"; break;
+ case Calendar.AUGUST: month = "-08-"; break;
+ case Calendar.SEPTEMBER: month = "-09-"; break;
+ case Calendar.OCTOBER: month = "-10-"; break;
+ case Calendar.NOVEMBER: month = "-11-"; break;
+ case Calendar.DECEMBER: month = "-12-"; break;
+ default: month = "-NA-"; break;
+ }
+ sbuf.append(month);
+
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ if(day < 10)
+ sbuf.append('0');
+ sbuf.append(day);
+
+ sbuf.append(' ');
+
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ if(hour < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(hour);
+ sbuf.append(':');
+
+ int mins = calendar.get(Calendar.MINUTE);
+ if(mins < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(mins);
+ sbuf.append(':');
+
+ int secs = calendar.get(Calendar.SECOND);
+ if(secs < 10) {
+ sbuf.append('0');
+ }
+ sbuf.append(secs);
+
+ sbuf.append(',');
+
+ // store the time string for next time to avoid recomputation
+ sbuf.getChars(start, sbuf.length(), lastTimeString, 0);
+ lastTime = now - millis;
+ }
+ else {
+ sbuf.append(lastTimeString);
+ }
+
+
+ if (millis < 100)
+ sbuf.append('0');
+ if (millis < 10)
+ sbuf.append('0');
+
+ sbuf.append(millis);
+ return sbuf;
+ }
+
+ /**
+ This method does not do anything but return <code>null</code>.
+ */
+ public
+ Date parse(java.lang.String s, ParsePosition pos) {
+ return null;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.java
new file mode 100644
index 0000000..0d91e8c
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternConverter.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.log.core.internal.layout;
+
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+/**
+ <p>PatternConverter is an abtract class that provides the
+ formatting functionality that derived classes need.
+
+ <p>Conversion specifiers in a conversion patterns are parsed to
+ individual PatternConverters. Each of which is responsible for
+ converting a logging event in a converter specific manner.
+
+ @since 0.8.2
+ */
+public abstract class PatternConverter {
+ public PatternConverter next;
+ int min = -1;
+ int max = 0x7FFFFFFF;
+ boolean leftAlign = false;
+
+ protected
+ PatternConverter() { }
+
+ protected
+ PatternConverter(FormattingInfo fi) {
+ min = fi.min;
+ max = fi.max;
+ leftAlign = fi.leftAlign;
+ }
+
+ /**
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the correct way.
+ */
+ abstract
+ protected
+ String convert(PaxLoggingEvent event);
+
+ /**
+ A template method for formatting in a converter specific way.
+ */
+ public
+ void format(StringBuffer sbuf, PaxLoggingEvent e) {
+ String s = convert(e);
+
+ if(s == null) {
+ if(0 < min)
+ spacePad(sbuf, min);
+ return;
+ }
+
+ int len = s.length();
+
+ if(len > max)
+ sbuf.append(s.substring(len-max));
+ else if(len < min) {
+ if(leftAlign) {
+ sbuf.append(s);
+ spacePad(sbuf, min-len);
+ }
+ else {
+ spacePad(sbuf, min-len);
+ sbuf.append(s);
+ }
+ }
+ else
+ sbuf.append(s);
+ }
+
+ static String[] SPACES = {" ", " ", " ", " ", //1,2,4,8 spaces
+ " ", // 16 spaces
+ " " }; // 32 spaces
+
+ /**
+ Fast space padding method.
+ */
+ public
+ void spacePad(StringBuffer sbuf, int length) {
+ while(length >= 32) {
+ sbuf.append(SPACES[5]);
+ length -= 32;
+ }
+
+ for(int i = 4; i >= 0; i--) {
+ if((length & (1<<i)) != 0) {
+ sbuf.append(SPACES[i]);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java b/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
new file mode 100644
index 0000000..f61b278
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/layout/PatternParser.java
@@ -0,0 +1,560 @@
+/*
+ * 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.log.core.internal.layout;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.ops4j.pax.logging.spi.PaxLocationInfo;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+/**
+ * Copied from log4j
+ */
+/**
+ Most of the work of the {@link org.apache.log4j.PatternLayout} class
+ is delegated to the PatternParser class.
+
+ @since 0.8.2
+*/
+public class PatternParser {
+
+ private static final String LINE_SEP = System.getProperty("line.separator");
+
+ private static final char ESCAPE_CHAR = '%';
+
+ private static final int LITERAL_STATE = 0;
+ private static final int CONVERTER_STATE = 1;
+ private static final int MINUS_STATE = 2;
+ private static final int DOT_STATE = 3;
+ private static final int MIN_STATE = 4;
+ private static final int MAX_STATE = 5;
+
+ static final int FULL_LOCATION_CONVERTER = 1000;
+ static final int METHOD_LOCATION_CONVERTER = 1001;
+ static final int CLASS_LOCATION_CONVERTER = 1002;
+ static final int LINE_LOCATION_CONVERTER = 1003;
+ static final int FILE_LOCATION_CONVERTER = 1004;
+
+ static final int RELATIVE_TIME_CONVERTER = 2000;
+ static final int THREAD_CONVERTER = 2001;
+ static final int LEVEL_CONVERTER = 2002;
+ static final int NDC_CONVERTER = 2003;
+ static final int MESSAGE_CONVERTER = 2004;
+
+ int state;
+ protected StringBuffer currentLiteral = new StringBuffer(32);
+ protected int patternLength;
+ protected int i;
+ PatternConverter head;
+ PatternConverter tail;
+ protected FormattingInfo formattingInfo = new FormattingInfo();
+ protected String pattern;
+
+ public
+ PatternParser(String pattern) {
+ this.pattern = pattern;
+ patternLength = pattern.length();
+ state = LITERAL_STATE;
+ }
+
+ private
+ void addToList(PatternConverter pc) {
+ if(head == null) {
+ head = tail = pc;
+ } else {
+ tail.next = pc;
+ tail = pc;
+ }
+ }
+
+ protected
+ String extractOption() {
+ if((i < patternLength) && (pattern.charAt(i) == '{')) {
+ int end = pattern.indexOf('}', i);
+ if (end > i) {
+ String r = pattern.substring(i + 1, end);
+ i = end+1;
+ return r;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ The option is expected to be in decimal and positive. In case of
+ error, zero is returned. */
+ protected
+ int extractPrecisionOption() {
+ String opt = extractOption();
+ int r = 0;
+ if(opt != null) {
+ try {
+ r = Integer.parseInt(opt);
+ if(r <= 0) {
+ //LogLog.error("Precision option (" + opt + ") isn't a positive integer.");
+ r = 0;
+ }
+ }
+ catch (NumberFormatException e) {
+ //LogLog.error("Category option \""+opt+"\" not a decimal integer.", e);
+ }
+ }
+ return r;
+ }
+
+ public
+ PatternConverter parse() {
+ char c;
+ i = 0;
+ while(i < patternLength) {
+ c = pattern.charAt(i++);
+ switch(state) {
+ case LITERAL_STATE:
+ // In literal state, the last char is always a literal.
+ if(i == patternLength) {
+ currentLiteral.append(c);
+ continue;
+ }
+ if(c == ESCAPE_CHAR) {
+ // peek at the next char.
+ switch(pattern.charAt(i)) {
+ case ESCAPE_CHAR:
+ currentLiteral.append(c);
+ i++; // move pointer
+ break;
+ case 'n':
+ currentLiteral.append(LINE_SEP);
+ i++; // move pointer
+ break;
+ default:
+ if(currentLiteral.length() != 0) {
+ addToList(new LiteralPatternConverter(
+ currentLiteral.toString()));
+ //LogLog.debug("Parsed LITERAL converter: \""
+ // +currentLiteral+"\".");
+ }
+ currentLiteral.setLength(0);
+ currentLiteral.append(c); // append %
+ state = CONVERTER_STATE;
+ formattingInfo.reset();
+ }
+ }
+ else {
+ currentLiteral.append(c);
+ }
+ break;
+ case CONVERTER_STATE:
+ currentLiteral.append(c);
+ switch(c) {
+ case '-':
+ formattingInfo.leftAlign = true;
+ break;
+ case '.':
+ state = DOT_STATE;
+ break;
+ default:
+ if(c >= '0' && c <= '9') {
+ formattingInfo.min = c - '0';
+ state = MIN_STATE;
+ }
+ else
+ finalizeConverter(c);
+ } // switch
+ break;
+ case MIN_STATE:
+ currentLiteral.append(c);
+ if(c >= '0' && c <= '9')
+ formattingInfo.min = formattingInfo.min*10 + (c - '0');
+ else if(c == '.')
+ state = DOT_STATE;
+ else {
+ finalizeConverter(c);
+ }
+ break;
+ case DOT_STATE:
+ currentLiteral.append(c);
+ if(c >= '0' && c <= '9') {
+ formattingInfo.max = c - '0';
+ state = MAX_STATE;
+ }
+ else {
+ //LogLog.error("Error occured in position "+i+".\n Was expecting digit, instead got char \""+c+"\".");
+ state = LITERAL_STATE;
+ }
+ break;
+ case MAX_STATE:
+ currentLiteral.append(c);
+ if(c >= '0' && c <= '9')
+ formattingInfo.max = formattingInfo.max*10 + (c - '0');
+ else {
+ finalizeConverter(c);
+ state = LITERAL_STATE;
+ }
+ break;
+ } // switch
+ } // while
+ if(currentLiteral.length() != 0) {
+ addToList(new LiteralPatternConverter(currentLiteral.toString()));
+ //LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
+ }
+ return head;
+ }
+
+ protected
+ void finalizeConverter(char c) {
+ PatternConverter pc = null;
+ switch(c) {
+ case 'c':
+ pc = new CategoryPatternConverter(formattingInfo,
+ extractPrecisionOption());
+ //LogLog.debug("CATEGORY converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'C':
+ pc = new ClassNamePatternConverter(formattingInfo,
+ extractPrecisionOption());
+ //LogLog.debug("CLASS_NAME converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'd':
+ String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT;
+ DateFormat df;
+ String dOpt = extractOption();
+ if(dOpt != null)
+ dateFormatStr = dOpt;
+
+ if(dateFormatStr.equalsIgnoreCase(
+ AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT))
+ df = new ISO8601DateFormat();
+ else if(dateFormatStr.equalsIgnoreCase(
+ AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT))
+ df = new AbsoluteTimeDateFormat();
+ else if(dateFormatStr.equalsIgnoreCase(
+ AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT))
+ df = new DateTimeDateFormat();
+ else {
+ try {
+ df = new SimpleDateFormat(dateFormatStr);
+ }
+ catch (IllegalArgumentException e) {
+ //LogLog.error("Could not instantiate SimpleDateFormat with " + dateFormatStr, e);
+ df = new ISO8601DateFormat();
+ }
+ }
+ pc = new DatePatternConverter(formattingInfo, df);
+ //LogLog.debug("DATE converter {"+dateFormatStr+"}.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'F':
+ pc = new LocationPatternConverter(formattingInfo,
+ FILE_LOCATION_CONVERTER);
+ //LogLog.debug("File name converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ /*case 'l':
+ pc = new LocationPatternConverter(formattingInfo,
+ FULL_LOCATION_CONVERTER);
+ //LogLog.debug("Location converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;*/
+ case 'L':
+ pc = new LocationPatternConverter(formattingInfo,
+ LINE_LOCATION_CONVERTER);
+ //LogLog.debug("LINE NUMBER converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'm':
+ pc = new BasicPatternConverter(formattingInfo, MESSAGE_CONVERTER);
+ //LogLog.debug("MESSAGE converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'M':
+ pc = new LocationPatternConverter(formattingInfo,
+ METHOD_LOCATION_CONVERTER);
+ //LogLog.debug("METHOD converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'p':
+ pc = new BasicPatternConverter(formattingInfo, LEVEL_CONVERTER);
+ //LogLog.debug("LEVEL converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 'r':
+ pc = new BasicPatternConverter(formattingInfo,
+ RELATIVE_TIME_CONVERTER);
+ //LogLog.debug("RELATIVE time converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ case 't':
+ pc = new BasicPatternConverter(formattingInfo, THREAD_CONVERTER);
+ //LogLog.debug("THREAD converter.");
+ //formattingInfo.dump();
+ currentLiteral.setLength(0);
+ break;
+ /*case 'u':
+ if(i < patternLength) {
+ char cNext = pattern.charAt(i);
+ if(cNext >= '0' && cNext <= '9') {
+ pc = new UserFieldPatternConverter(formattingInfo, cNext - '0');
+ LogLog.debug("USER converter ["+cNext+"].");
+ formattingInfo.dump();
+ currentLiteral.setLength(0);
+ i++;
+ }
+ else
+ LogLog.error("Unexpected char" +cNext+" at position "+i);
+ }
+ break;*/
+ /*case 'x':
+ pc = new BasicPatternConverter(formattingInfo, NDC_CONVERTER);
+ //LogLog.debug("NDC converter.");
+ currentLiteral.setLength(0);
+ break;*/
+ case 'X':
+ String xOpt = extractOption();
+ pc = new MDCPatternConverter(formattingInfo, xOpt);
+ currentLiteral.setLength(0);
+ break;
+ default:
+ //LogLog.error("Unexpected char [" +c+"] at position "+i+" in conversion patterrn.");
+ pc = new LiteralPatternConverter(currentLiteral.toString());
+ currentLiteral.setLength(0);
+ }
+
+ addConverter(pc);
+ }
+
+ protected
+ void addConverter(PatternConverter pc) {
+ currentLiteral.setLength(0);
+ // Add the pattern converter to the list.
+ addToList(pc);
+ // Next pattern is assumed to be a literal.
+ state = LITERAL_STATE;
+ // Reset formatting info
+ formattingInfo.reset();
+ }
+
+ // ---------------------------------------------------------------------
+ // PatternConverters
+ // ---------------------------------------------------------------------
+
+ private static class BasicPatternConverter extends PatternConverter {
+ int type;
+
+ BasicPatternConverter(FormattingInfo formattingInfo, int type) {
+ super(formattingInfo);
+ this.type = type;
+ }
+
+ public
+ String convert(PaxLoggingEvent event) {
+ switch(type) {
+ case RELATIVE_TIME_CONVERTER:
+ return (Long.toString(event.getTimeStamp() - LoggingEvent.getStartTime()));
+ case THREAD_CONVERTER:
+ return event.getThreadName();
+ case LEVEL_CONVERTER:
+ return event.getLevel().toString();
+ // case NDC_CONVERTER:
+ //return event.getNDC();
+ case MESSAGE_CONVERTER: {
+ return event.getRenderedMessage();
+ }
+ default: return null;
+ }
+ }
+ }
+
+ private static class LiteralPatternConverter extends PatternConverter {
+ private String literal;
+
+ LiteralPatternConverter(String value) {
+ literal = value;
+ }
+
+ public
+ final
+ void format(StringBuffer sbuf, LoggingEvent event) {
+ sbuf.append(literal);
+ }
+
+ public
+ String convert(PaxLoggingEvent event) {
+ return literal;
+ }
+ }
+
+ private static class DatePatternConverter extends PatternConverter {
+ private DateFormat df;
+ private Date date;
+
+ DatePatternConverter(FormattingInfo formattingInfo, DateFormat df) {
+ super(formattingInfo);
+ date = new Date();
+ this.df = df;
+ }
+
+ public
+ String convert(PaxLoggingEvent event) {
+ date.setTime(event.getTimeStamp());
+ String converted = null;
+ try {
+ converted = df.format(date);
+ }
+ catch (Exception ex) {
+ //LogLog.error("Error occured while converting date.", ex);
+ }
+ return converted;
+ }
+ }
+
+ private class LocationPatternConverter extends PatternConverter {
+ int type;
+
+ LocationPatternConverter(FormattingInfo formattingInfo, int type) {
+ super(formattingInfo);
+ this.type = type;
+ }
+
+ public
+ String convert(PaxLoggingEvent event) {
+ PaxLocationInfo locationInfo = event.getLocationInformation();
+ switch(type) {
+ /*case FULL_LOCATION_CONVERTER:
+ return locationInfo.fullInfo;*/
+ case METHOD_LOCATION_CONVERTER:
+ return locationInfo.getMethodName();
+ case LINE_LOCATION_CONVERTER:
+ return locationInfo.getLineNumber();
+ case FILE_LOCATION_CONVERTER:
+ return locationInfo.getFileName();
+ default: return null;
+ }
+ }
+ }
+
+ private static abstract class NamedPatternConverter extends PatternConverter {
+ int precision;
+
+ NamedPatternConverter(FormattingInfo formattingInfo, int precision) {
+ super(formattingInfo);
+ this.precision = precision;
+ }
+
+ abstract
+ String getFullyQualifiedName(PaxLoggingEvent event);
+
+ public
+ String convert(PaxLoggingEvent event) {
+ String n = getFullyQualifiedName(event);
+ if(precision <= 0)
+ return n;
+ else {
+ int len = n.length();
+
+ // We substract 1 from 'len' when assigning to 'end' to avoid out of
+ // bounds exception in return r.substring(end+1, len). This can happen if
+ // precision is 1 and the category name ends with a dot.
+ int end = len -1 ;
+ for(int i = precision; i > 0; i--) {
+ end = n.lastIndexOf('.', end-1);
+ if(end == -1)
+ return n;
+ }
+ return n.substring(end+1, len);
+ }
+ }
+ }
+
+ private class ClassNamePatternConverter extends NamedPatternConverter {
+
+ ClassNamePatternConverter(FormattingInfo formattingInfo, int precision) {
+ super(formattingInfo, precision);
+ }
+
+ String getFullyQualifiedName(PaxLoggingEvent event) {
+ return event.getLocationInformation().getClassName();
+ }
+ }
+
+ private class CategoryPatternConverter extends NamedPatternConverter {
+
+ CategoryPatternConverter(FormattingInfo formattingInfo, int precision) {
+ super(formattingInfo, precision);
+ }
+
+ String getFullyQualifiedName(PaxLoggingEvent event) {
+ return event.getLoggerName();
+ }
+ }
+
+ private class MDCPatternConverter extends PatternConverter {
+ String key;
+
+ MDCPatternConverter(FormattingInfo formattingInfo, String key) {
+ super(formattingInfo);
+ this.key = key;
+ }
+
+ public
+ String convert(PaxLoggingEvent event) {
+ if (key == null) {
+ StringBuffer buf = new StringBuffer("{");
+ Map properties = event.getProperties();
+ if (properties.size() > 0) {
+ Object[] keys = properties.keySet().toArray();
+ Arrays.sort(keys);
+ for (int i = 0; i < keys.length; i++) {
+ buf.append('{');
+ buf.append(keys[i]);
+ buf.append(',');
+ buf.append(properties.get(keys[i]));
+ buf.append('}');
+ }
+ }
+ buf.append('}');
+ return buf.toString();
+ } else {
+ Object val = event.getProperties().get(key);
+ if(val == null) {
+ return null;
+ } else {
+ return val.toString();
+ }
+ }
+ }
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java b/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
new file mode 100644
index 0000000..2e8c4d8
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
@@ -0,0 +1,77 @@
+/*
+ * 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.log.core.internal.osgi;
+
+import java.util.Hashtable;
+
+import org.apache.karaf.log.core.LogEventFormatter;
+import org.apache.karaf.log.core.LogService;
+import org.apache.karaf.log.core.internal.LogEventFormatterImpl;
+import org.apache.karaf.log.core.internal.LogMBeanImpl;
+import org.apache.karaf.log.core.internal.LogServiceImpl;
+import org.apache.karaf.log.core.internal.LruList;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.ops4j.pax.logging.spi.PaxAppender;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
+
+public class Activator extends BaseActivator implements ManagedService {
+
+ @Override
+ protected void doOpen() throws Exception {
+ manage("org.apache.karaf.log");
+ trackService(ConfigurationAdmin.class);
+ }
+
+ protected void doStart() throws Exception {
+ ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
+ if (configurationAdmin == null) {
+ return;
+ }
+
+ int size = getInt("size", 500);
+ String pattern = getString("pattern", "%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n");
+ String fatalColor = getString("fatalColor", "31");
+ String errorColor = getString("errorColor", "31");
+ String warnColor = getString("warnColor", "35");
+ String infoColor = getString("infoColor", "36");
+ String debugColor = getString("debugColor", "39");
+ String traceColor = getString("traceColor", "39");
+
+ LruList events = new LruList(size);
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put("org.ops4j.pax.logging.appender.name", "VmLogAppender");
+ register(PaxAppender.class, events, props);
+
+ LogEventFormatterImpl formatter = new LogEventFormatterImpl();
+ formatter.setPattern(pattern);
+ formatter.setFatalColor(fatalColor);
+ formatter.setErrorColor(errorColor);
+ formatter.setWarnColor(warnColor);
+ formatter.setInfoColor(infoColor);
+ formatter.setDebugColor(debugColor);
+ formatter.setTraceColor(traceColor);
+ register(LogEventFormatter.class, formatter);
+
+ LogServiceImpl logService = new LogServiceImpl(configurationAdmin, events);
+ register(LogService.class, logService);
+
+ LogMBeanImpl securityMBean = new LogMBeanImpl(logService);
+ registerMBean(securityMBean, "type=log");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/log/src/main/resources/OSGI-INF/bundle.info b/log/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..2bd45bd
--- /dev/null
+++ b/log/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,24 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+The log mbean management bundle exposes a Log MBean that can be used with any JMX client (for instance JConsole).
+
+The Log MBean allows quite the same actions that can be performed using log:* commands:
+ * display()
+ * display(logger)
+ * get()
+ * get(logger)
+ * set(level)
+ * list(level, logger)
+
+h1. See also
+
+ * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/resources/OSGI-INF/metatype/metatype.properties
----------------------------------------------------------------------
diff --git a/log/src/main/resources/OSGI-INF/metatype/metatype.properties b/log/src/main/resources/OSGI-INF/metatype/metatype.properties
new file mode 100644
index 0000000..713283f
--- /dev/null
+++ b/log/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor
+
+log.name = Apache Karaf Log
+log.description = Configuration of Apache Karaf Log
+
+size.name = Size
+size.description = size of the log to keep in memory
+
+pattern.name = Pattern
+pattern.description = Pattern used to display log entries
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/main/resources/OSGI-INF/metatype/metatype.xml
----------------------------------------------------------------------
diff --git a/log/src/main/resources/OSGI-INF/metatype/metatype.xml b/log/src/main/resources/OSGI-INF/metatype/metatype.xml
new file mode 100644
index 0000000..147cb82
--- /dev/null
+++ b/log/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0" localization="OSGI-INF/metatype/metatype">
+ <OCD id="org.apache.karaf.log" name="%log.name" description="%log.description">
+ <AD id="size" type="Integer" default="500" name="%size.name"
+ description="%size.description"/>
+ <AD id="pattern" type="String" default="%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n" name="%pattern.name"
+ description="%pattern.description"/>
+ </OCD>
+ <Designate pid="org.apache.karaf.log">
+ <Object ocdref="org.apache.karaf.log"/>
+ </Designate>
+</metatype:MetaData>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
----------------------------------------------------------------------
diff --git a/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java b/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
new file mode 100644
index 0000000..73459d3
--- /dev/null
+++ b/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.log.core.internal;
+
+import java.util.Hashtable;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.log.core.LogMBean;
+import org.apache.karaf.log.core.LogService;
+import org.easymock.EasyMock;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Test cases for {@link SetLogLevel}
+ */
+@SuppressWarnings("unchecked")
+public class SetLogLevelTest extends TestCase {
+
+ private static final String ROOT_LOGGER = "log4j.rootLogger";
+ private static final String PACKAGE_LOGGER = "log4j.logger.org.apache.karaf.test";
+
+ private LogService logService;
+ private LogMBean logMBean;
+ @SuppressWarnings("rawtypes")
+ private Hashtable properties;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ properties = new Hashtable<String, String>();
+ final Configuration configuration = EasyMock.createMock(Configuration.class);
+ EasyMock.expect(configuration.getProperties()).andReturn(properties);
+ configuration.update(properties);
+ ConfigurationAdmin configAdmin = EasyMock.createMock(ConfigurationAdmin.class);
+ EasyMock.expect(configAdmin.getConfiguration(LogServiceImpl.CONFIGURATION_PID, null)).andReturn(configuration);
+ logService = new LogServiceImpl(configAdmin, new LruList(100));
+ logMBean = new LogMBeanImpl(logService);
+ EasyMock.replay(configAdmin);
+ EasyMock.replay(configuration);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testInvalidLogLevel() throws Exception {
+ try {
+ logMBean.setLevel("INVALID");
+ fail("Exception expected");
+ } catch(IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void testSetLogLevel() throws Exception {
+ logMBean.setLevel("org.apache.karaf.test", "INFO");
+ assertEquals("INFO", properties.get(PACKAGE_LOGGER));
+ }
+
+ public void testSetRootLogLevel() throws Exception {
+ logMBean.setLevel("INFO");
+ assertEquals("INFO", properties.get(ROOT_LOGGER));
+ }
+
+ public void testSetLogLevelLowerCase() throws Exception {
+ logMBean.setLevel("org.apache.karaf.test", "info");
+ assertEquals("INFO", properties.get(PACKAGE_LOGGER));
+ }
+
+ public void testSetRootLogLevelLowerCase() throws Exception {
+ logMBean.setLevel("info");
+ assertEquals("INFO", properties.get(ROOT_LOGGER));
+ }
+
+ public void testChangeLogLevel() throws Exception {
+ properties.put(PACKAGE_LOGGER, "DEBUG");
+ logMBean.setLevel("org.apache.karaf.test", "INFO");
+ assertEquals("INFO", properties.get(PACKAGE_LOGGER));
+ }
+
+ public void testChangeRootLogLevel() throws Exception {
+ properties.put(ROOT_LOGGER, "DEBUG");
+ logMBean.setLevel("INFO");
+ assertEquals("INFO", properties.get(ROOT_LOGGER));
+ }
+
+ public void testChangeLogLevelWithAppender() throws Exception {
+ properties.put(PACKAGE_LOGGER, "DEBUG, APPENDER1");
+ logMBean.setLevel("org.apache.karaf.test", "INFO");
+ assertEquals("INFO, APPENDER1", properties.get(PACKAGE_LOGGER));
+ }
+
+ public void testChangeRootLogLevelWithAppender() throws Exception {
+ properties.put(ROOT_LOGGER, "DEBUG, APPENDER1");
+ logMBean.setLevel("INFO");
+ assertEquals("INFO, APPENDER1", properties.get(ROOT_LOGGER));
+ }
+
+ public void testUnsetLogLevel() throws Exception {
+ properties.put(PACKAGE_LOGGER, "DEBUG");
+ logMBean.setLevel("org.apache.karaf.test", "DEFAULT");
+ assertFalse("Configuration for logger org.apache.karaf.test has been removed", properties.containsKey(PACKAGE_LOGGER));
+ }
+
+ public void testUnsetRootLogLevel() throws Exception {
+ properties.put(ROOT_LOGGER, "INFO");
+ logMBean.setLevel("org.apache.karaf.test", "DEFAULT");
+ assertEquals("Configuration for root logger should not be removed", "INFO", properties.get(ROOT_LOGGER));
+ }
+
+}
[03/59] [abbrv] [KARAF-2852] Merge features/core and features/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/Overrides.java b/features/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
new file mode 100644
index 0000000..233a8a2
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/Overrides.java
@@ -0,0 +1,132 @@
+/*
+ * 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.internal.service;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.version.VersionRange;
+import org.osgi.framework.Version;
+import org.osgi.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.felix.resolver.Util.getSymbolicName;
+import static org.apache.felix.resolver.Util.getVersion;
+
+/**
+ * Helper class to deal with overriden bundles at feature installation time.
+ */
+public class Overrides {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Overrides.class);
+
+ protected static final String OVERRIDE_RANGE = "range";
+
+ /**
+ * Compute a list of bundles to install, taking into account overrides.
+ *
+ * The file containing the overrides will be loaded from the given url.
+ * Blank lines and lines starting with a '#' will be ignored, all other lines
+ * are considered as urls to override bundles.
+ *
+ * The list of resources to resolve will be scanned and for each bundle,
+ * if a bundle override matches that resource, it will be used instead.
+ *
+ * Matching is done on bundle symbolic name (they have to be the same)
+ * and version (the bundle override version needs to be greater than the
+ * resource to be resolved, and less than the next minor version. A range
+ * directive can be added to the override url in which case, the matching
+ * will succeed if the resource to be resolved is within the given range.
+ *
+ * @param resources the list of resources to resolve
+ * @param overrides list of bundle overrides
+ */
+ public static void override(Map<String, Resource> resources, Collection<String> overrides) {
+ // Do override replacement
+ for (Clause override : Parser.parseClauses(overrides.toArray(new String[overrides.size()]))) {
+ String url = override.getName();
+ String vr = override.getAttribute(OVERRIDE_RANGE);
+ Resource over = resources.get(url);
+ if (over == null) {
+ // Ignore invalid overrides
+ continue;
+ }
+ for (String uri : new ArrayList<String>(resources.keySet())) {
+ Resource res = resources.get(uri);
+ if (getSymbolicName(res).equals(getSymbolicName(over))) {
+ VersionRange range;
+ if (vr == null) {
+ // default to micro version compatibility
+ Version v1 = getVersion(res);
+ Version v2 = new Version(v1.getMajor(), v1.getMinor() + 1, 0);
+ range = new VersionRange(false, v1, v2, true);
+ } else {
+ range = VersionRange.parseVersionRange(vr);
+ }
+ // The resource matches, so replace it with the overridden resource
+ // if the override is actually a newer version than what we currently have
+ if (range.contains(getVersion(over)) && getVersion(res).compareTo(getVersion(over)) < 0) {
+ resources.put(uri, over);
+ }
+ }
+ }
+ }
+ }
+
+ public static Set<String> loadOverrides(String overridesUrl) {
+ Set<String> overrides = new HashSet<String>();
+ try {
+ if (overridesUrl != null) {
+ InputStream is = new URL(overridesUrl).openStream();
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (!line.isEmpty() && !line.startsWith("#")) {
+ overrides.add(line);
+ }
+ }
+ } finally {
+ is.close();
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.debug("Unable to load overrides bundles list", e);
+ }
+ return overrides;
+ }
+
+ public static String extractUrl(String override) {
+ Clause[] cs = Parser.parseClauses(new String[] { override });
+ if (cs.length != 1) {
+ throw new IllegalStateException("Override contains more than one clause: " + override);
+ }
+ return cs[0].getName();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java b/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
new file mode 100644
index 0000000..4bf1502
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/RepositoryImpl.java
@@ -0,0 +1,103 @@
+/*
+ * 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.internal.service;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.net.URI;
+
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
+
+/**
+ * The repository implementation.
+ */
+public class RepositoryImpl implements Repository {
+
+ private final URI uri;
+ private Features features;
+
+ public RepositoryImpl(URI uri) {
+ this.uri = uri;
+ }
+
+ public URI getURI() {
+ return uri;
+ }
+
+ public String getName() {
+ // TODO: catching this exception is ugly
+ try {
+ load();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to load repository", e);
+ }
+ return features.getName();
+ }
+
+ public URI[] getRepositories() throws Exception {
+ load();
+ URI[] result = new URI[features.getRepository().size()];
+ for (int i = 0; i < features.getRepository().size(); i++) {
+ String uri = features.getRepository().get(i);
+ uri = uri.trim();
+ result[i] = URI.create(uri);
+ }
+ return result;
+ }
+
+ public org.apache.karaf.features.Feature[] getFeatures() throws Exception {
+ load();
+ return features.getFeature().toArray(new org.apache.karaf.features.Feature[features.getFeature().size()]);
+ }
+
+
+ public void load() throws IOException {
+ if (features == null) {
+ try {
+ InputStream inputStream = uri.toURL().openStream();
+ inputStream = new FilterInputStream(inputStream) {
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (Thread.currentThread().isInterrupted()) {
+ throw new InterruptedIOException();
+ }
+ return super.read(b, off, len);
+ }
+ };
+ try {
+ features = JaxbUtil.unmarshal(inputStream, false);
+ } finally {
+ inputStream.close();
+ }
+ } catch (IllegalArgumentException e) {
+ throw (IOException) new IOException(e.getMessage() + " : " + uri).initCause(e);
+ } catch (Exception e) {
+ throw (IOException) new IOException(e.getMessage() + " : " + uri).initCause(e);
+ }
+ }
+ }
+
+ @Override
+ public boolean isValid() {
+ throw new UnsupportedOperationException();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java b/features/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
new file mode 100644
index 0000000..e9ecece
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/RequirementSort.java
@@ -0,0 +1,107 @@
+/*
+ * 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.internal.service;
+
+
+import org.apache.karaf.features.internal.resolver.RequirementImpl;
+import org.apache.karaf.features.internal.resolver.SimpleFilter;
+import org.osgi.framework.Constants;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+public class RequirementSort {
+
+ /**
+ * Sorts {@link Resource} based on their {@link Requirement}s and {@link Capability}s.
+ * @param resources
+ * @return
+ */
+ public static <T extends Resource> Collection<T> sort(Collection<T> resources) {
+ Set<T> sorted = new LinkedHashSet<T>();
+ Set<T> visited = new LinkedHashSet<T>();
+ for (T r : resources) {
+ visit(r, resources, visited, sorted);
+ }
+ return sorted;
+ }
+
+
+ private static <T extends Resource> void visit(T resource, Collection<T> resources, Set<T> visited, Set<T> sorted) {
+ if (visited.contains(resource)) {
+ return;
+ }
+ visited.add(resource);
+ for (T r : collectDependencies(resource, resources)) {
+ visit(r, resources, visited, sorted);
+ }
+ sorted.add(resource);
+ }
+
+ /**
+ * Finds the dependencies of the current resource.
+ * @param resource
+ * @param allResources
+ * @return
+ */
+ private static <T extends Resource> Set<T> collectDependencies(T resource, Collection<T> allResources) {
+ Set<T> result = new LinkedHashSet<T>();
+ List<Requirement> requirements = resource.getRequirements(null);
+ for (Requirement requirement : requirements) {
+ boolean isSatisfied = false;
+ for (Resource r : result) {
+ for (Capability capability : r.getCapabilities(null)) {
+ if (isSatisfied(requirement, capability)) {
+ isSatisfied = true;
+ break;
+ }
+ }
+ }
+
+ for (T r : allResources) {
+ if (!isSatisfied) {
+ for (Capability capability : r.getCapabilities(null)) {
+ if (isSatisfied(requirement, capability)) {
+ result.add(r);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private static boolean isSatisfied(Requirement requirement, Capability capability) {
+ RequirementImpl br;
+ if (requirement instanceof RequirementImpl) {
+ br = (RequirementImpl) requirement;
+ } else {
+ String filter = requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
+ SimpleFilter sf = (filter != null)
+ ? SimpleFilter.parse(filter)
+ : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+ br = new RequirementImpl(null, requirement.getNamespace(), requirement.getDirectives(), requirement.getAttributes(), sf);
+ }
+ return br.matches(capability);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java b/features/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
new file mode 100644
index 0000000..d1f16b9
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/SimpleDownloader.java
@@ -0,0 +1,51 @@
+/*
+ * 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.internal.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.karaf.features.internal.deployment.Downloader;
+import org.apache.karaf.features.internal.deployment.StreamProvider;
+import org.apache.karaf.features.internal.util.MultiException;
+
+public class SimpleDownloader implements Downloader {
+
+ private final MultiException exception = new MultiException("Error");
+
+ @Override
+ public void await() throws InterruptedException, MultiException {
+ exception.throwIfExceptions();
+ }
+
+ @Override
+ public void download(final String location, final DownloadCallback downloadCallback) throws MalformedURLException {
+ final URL url = new URL(location);
+ try {
+ downloadCallback.downloaded(new StreamProvider() {
+ @Override
+ public InputStream open() throws IOException {
+ return url.openStream();
+ }
+ });
+ } catch (Exception e) {
+ exception.addException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/State.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/State.java b/features/src/main/java/org/apache/karaf/features/internal/service/State.java
new file mode 100644
index 0000000..c84f4e0
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/State.java
@@ -0,0 +1,34 @@
+/*
+ * 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.internal.service;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class State {
+
+ public final AtomicBoolean bootDone = new AtomicBoolean();
+ public final Set<String> repositories = new TreeSet<String>();
+ public final Set<String> features = new TreeSet<String>();
+ public final Set<String> installedFeatures = new TreeSet<String>();
+ public final Set<Long> managedBundles = new TreeSet<Long>();
+ public final Map<String, Long> bundleChecksums = new HashMap<String, Long>();
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java b/features/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
new file mode 100644
index 0000000..574e52e
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/service/StateStorage.java
@@ -0,0 +1,174 @@
+/*
+ * 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.internal.service;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.karaf.features.Feature;
+
+public abstract class StateStorage {
+
+ public void load(State state) throws IOException {
+ state.repositories.clear();
+ state.features.clear();
+ state.installedFeatures.clear();
+ state.managedBundles.clear();
+ InputStream is = getInputStream();
+ if (is != null) {
+ try {
+ Properties props = new Properties();
+ props.load(is);
+ state.bootDone.set(loadBool(props, "bootDone"));
+ state.repositories.addAll(loadSet(props, "repositories."));
+ state.features.addAll(loadSet(props, "features."));
+ state.installedFeatures.addAll(loadSet(props, "installed."));
+ state.managedBundles.addAll(toLongSet(loadSet(props, "managed.")));
+ state.bundleChecksums.putAll(toStringLongMap(loadMap(props, "checksums.")));
+ } finally {
+ close(is);
+ }
+ }
+ }
+
+ public void save(State state) throws IOException {
+ OutputStream os = getOutputStream();
+ if (os != null) {
+ try {
+ Properties props = new Properties();
+ saveBool(props, "bootDone", state.bootDone.get());
+ saveSet(props, "repositories.", state.repositories);
+ saveSet(props, "features.", state.features);
+ saveSet(props, "installed.", state.installedFeatures);
+ saveSet(props, "managed.", toStringSet(state.managedBundles));
+ saveMap(props, "checksums.", toStringStringMap(state.bundleChecksums));
+ props.store(os, "FeaturesService State");
+ } finally {
+ close(os);
+ }
+ }
+ }
+
+ protected abstract InputStream getInputStream() throws IOException;
+ protected abstract OutputStream getOutputStream() throws IOException;
+
+ protected boolean loadBool(Properties props, String key) {
+ return Boolean.parseBoolean(props.getProperty(key));
+ }
+
+ protected void saveBool(Properties props, String key, boolean val) {
+ props.setProperty(key, Boolean.toString(val));
+ }
+
+ protected Set<String> toStringSet(Set<Long> set) {
+ Set<String> ns = new TreeSet<String>();
+ for (long l : set) {
+ ns.add(Long.toString(l));
+ }
+ return ns;
+ }
+
+ protected Set<Long> toLongSet(Set<String> set) {
+ Set<Long> ns = new TreeSet<Long>();
+ for (String s : set) {
+ ns.add(Long.parseLong(s));
+ }
+ return ns;
+ }
+
+ protected void saveSet(Properties props, String prefix, Set<String> set) {
+ List<String> l = new ArrayList<String>(set);
+ props.put(prefix + "count", Integer.toString(l.size()));
+ for (int i = 0; i < l.size(); i++) {
+ props.put(prefix + "item." + i, l.get(i));
+ }
+ }
+
+ protected Set<String> loadSet(Properties props, String prefix) {
+ Set<String> l = new HashSet<String>();
+ String countStr = (String) props.get(prefix + "count");
+ if (countStr != null) {
+ int count = Integer.parseInt(countStr);
+ for (int i = 0; i < count; i++) {
+ l.add((String) props.get(prefix + "item." + i));
+ }
+ }
+ return l;
+ }
+
+ protected Map<String, String> toStringStringMap(Map<String, Long> map) {
+ Map<String, String> nm = new HashMap<String, String>();
+ for (Map.Entry<String, Long> entry : map.entrySet()) {
+ nm.put(entry.getKey(), Long.toString(entry.getValue()));
+ }
+ return nm;
+ }
+
+ protected Map<String, Long> toStringLongMap(Map<String, String> map) {
+ Map<String, Long> nm = new HashMap<String, Long>();
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ nm.put(entry.getKey(), Long.parseLong(entry.getValue()));
+ }
+ return nm;
+ }
+
+
+ protected void saveMap(Properties props, String prefix, Map<String, String> map) {
+ List<Map.Entry<String, String>> l = new ArrayList<Map.Entry<String, String>>(map.entrySet());
+ props.put(prefix + "count", Integer.toString(l.size()));
+ for (int i = 0; i < l.size(); i++) {
+ props.put(prefix + "key." + i, l.get(i).getKey());
+ props.put(prefix + "val." + i, l.get(i).getValue());
+ }
+ }
+
+ protected Map<String, String> loadMap(Properties props, String prefix) {
+ Map<String, String> l = new HashMap<String, String>();
+ String countStr = (String) props.get(prefix + "count");
+ if (countStr != null) {
+ int count = Integer.parseInt(countStr);
+ for (int i = 0; i < count; i++) {
+ String key = (String) props.get(prefix + "key." + i);
+ String val = (String) props.get(prefix + "val." + i);
+ l.put(key, val);
+ }
+ }
+ return l;
+ }
+
+
+ protected void close(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java b/features/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.java
new file mode 100644
index 0000000..19fc706
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/util/ChecksumUtils.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.internal.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.CRC32;
+
+public class ChecksumUtils {
+
+ private ChecksumUtils() {
+ }
+
+ /**
+ * Compute a cheksum for the file or directory that consists of the name, length and the last modified date
+ * for a file and its children in case of a directory
+ *
+ * @param is the input stream
+ * @return a checksum identifying any change
+ */
+ public static long checksum(InputStream is) throws IOException
+ {
+ try {
+ CRC32 crc = new CRC32();
+ byte[] buffer = new byte[8192];
+ int l;
+ while ((l = is.read(buffer)) > 0) {
+ crc.update(buffer, 0, l);
+ }
+ return crc.getValue();
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java b/features/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
new file mode 100644
index 0000000..a53d8a5
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/util/JsonReader.java
@@ -0,0 +1,349 @@
+/*
+ * 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.internal.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ */
+public class JsonReader {
+
+ public static Object read(Reader reader) throws IOException {
+ return new JsonReader(reader).parse();
+ }
+
+ public static Object read(InputStream is) throws IOException {
+ return new JsonReader(new InputStreamReader(is)).parse();
+ }
+
+ //
+ // Implementation
+ //
+
+ private final Reader reader;
+ private final StringBuilder recorder;
+ private int current;
+ private int line = 1;
+ private int column = 0;
+
+ JsonReader(Reader reader) {
+ this.reader = reader;
+ recorder = new StringBuilder();
+ }
+
+ public Object parse() throws IOException {
+ read();
+ skipWhiteSpace();
+ Object result = readValue();
+ skipWhiteSpace();
+ if (!endOfText()) {
+ throw error("Unexpected character");
+ }
+ return result;
+ }
+
+ private Object readValue() throws IOException {
+ switch (current) {
+ case 'n':
+ return readNull();
+ case 't':
+ return readTrue();
+ case 'f':
+ return readFalse();
+ case '"':
+ return readString();
+ case '[':
+ return readArray();
+ case '{':
+ return readObject();
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return readNumber();
+ default:
+ throw expected("value");
+ }
+ }
+
+ private Collection<?> readArray() throws IOException {
+ read();
+ Collection<Object> array = new ArrayList<Object>();
+ skipWhiteSpace();
+ if (readChar(']')) {
+ return array;
+ }
+ do {
+ skipWhiteSpace();
+ array.add(readValue());
+ skipWhiteSpace();
+ } while (readChar(','));
+ if (!readChar(']')) {
+ throw expected("',' or ']'");
+ }
+ return array;
+ }
+
+ private Map<String, Object> readObject() throws IOException {
+ read();
+ Map<String, Object> object = new HashMap<String, Object>();
+ skipWhiteSpace();
+ if (readChar('}')) {
+ return object;
+ }
+ do {
+ skipWhiteSpace();
+ String name = readName();
+ skipWhiteSpace();
+ if (!readChar(':')) {
+ throw expected("':'");
+ }
+ skipWhiteSpace();
+ object.put(name, readValue());
+ skipWhiteSpace();
+ } while (readChar(','));
+ if (!readChar('}')) {
+ throw expected("',' or '}'");
+ }
+ return object;
+ }
+
+ private Object readNull() throws IOException {
+ read();
+ readRequiredChar('u');
+ readRequiredChar('l');
+ readRequiredChar('l');
+ return null;
+ }
+
+ private Boolean readTrue() throws IOException {
+ read();
+ readRequiredChar('r');
+ readRequiredChar('u');
+ readRequiredChar('e');
+ return Boolean.TRUE;
+ }
+
+ private Boolean readFalse() throws IOException {
+ read();
+ readRequiredChar('a');
+ readRequiredChar('l');
+ readRequiredChar('s');
+ readRequiredChar('e');
+ return Boolean.FALSE;
+ }
+
+ private void readRequiredChar(char ch) throws IOException {
+ if (!readChar(ch)) {
+ throw expected("'" + ch + "'");
+ }
+ }
+
+ private String readString() throws IOException {
+ read();
+ recorder.setLength(0);
+ while (current != '"') {
+ if (current == '\\') {
+ readEscape();
+ } else if (current < 0x20) {
+ throw expected("valid string character");
+ } else {
+ recorder.append((char) current);
+ read();
+ }
+ }
+ read();
+ return recorder.toString();
+ }
+
+ private void readEscape() throws IOException {
+ read();
+ switch (current) {
+ case '"':
+ case '/':
+ case '\\':
+ recorder.append((char) current);
+ break;
+ case 'b':
+ recorder.append('\b');
+ break;
+ case 'f':
+ recorder.append('\f');
+ break;
+ case 'n':
+ recorder.append('\n');
+ break;
+ case 'r':
+ recorder.append('\r');
+ break;
+ case 't':
+ recorder.append('\t');
+ break;
+ case 'u':
+ char[] hexChars = new char[4];
+ for (int i = 0; i < 4; i++) {
+ read();
+ if (!isHexDigit(current)) {
+ throw expected("hexadecimal digit");
+ }
+ hexChars[i] = (char) current;
+ }
+ recorder.append((char) Integer.parseInt(String.valueOf(hexChars), 16));
+ break;
+ default:
+ throw expected("valid escape sequence");
+ }
+ read();
+ }
+
+ private Number readNumber() throws IOException {
+ recorder.setLength(0);
+ readAndAppendChar('-');
+ int firstDigit = current;
+ if (!readAndAppendDigit()) {
+ throw expected("digit");
+ }
+ if (firstDigit != '0') {
+ while (readAndAppendDigit()) {
+ }
+ }
+ readFraction();
+ readExponent();
+ return Double.parseDouble(recorder.toString());
+ }
+
+ private boolean readFraction() throws IOException {
+ if (!readAndAppendChar('.')) {
+ return false;
+ }
+ if (!readAndAppendDigit()) {
+ throw expected("digit");
+ }
+ while (readAndAppendDigit()) {
+ }
+ return true;
+ }
+
+ private boolean readExponent() throws IOException {
+ if (!readAndAppendChar('e') && !readAndAppendChar('E')) {
+ return false;
+ }
+ if (!readAndAppendChar('+')) {
+ readAndAppendChar('-');
+ }
+ if (!readAndAppendDigit()) {
+ throw expected("digit");
+ }
+ while (readAndAppendDigit()) {
+ }
+ return true;
+ }
+
+ private String readName() throws IOException {
+ if (current != '"') {
+ throw expected("name");
+ }
+ readString();
+ return recorder.toString();
+ }
+
+ private boolean readAndAppendChar(char ch) throws IOException {
+ if (current != ch) {
+ return false;
+ }
+ recorder.append(ch);
+ read();
+ return true;
+ }
+
+ private boolean readChar(char ch) throws IOException {
+ if (current != ch) {
+ return false;
+ }
+ read();
+ return true;
+ }
+
+ private boolean readAndAppendDigit() throws IOException {
+ if (!isDigit(current)) {
+ return false;
+ }
+ recorder.append((char) current);
+ read();
+ return true;
+ }
+
+ private void skipWhiteSpace() throws IOException {
+ while (isWhiteSpace(current) && !endOfText()) {
+ read();
+ }
+ }
+
+ private void read() throws IOException {
+ if (endOfText()) {
+ throw error("Unexpected end of input");
+ }
+ column++;
+ if (current == '\n') {
+ line++;
+ column = 0;
+ }
+ current = reader.read();
+ }
+
+ private boolean endOfText() {
+ return current == -1;
+ }
+
+ private IOException expected(String expected) {
+ if (endOfText()) {
+ return error("Unexpected end of input");
+ }
+ return error("Expected " + expected);
+ }
+
+ private IOException error(String message) {
+ return new IOException(message + " at " + line + ":" + column);
+ }
+
+ private static boolean isWhiteSpace(int ch) {
+ return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
+ }
+
+ private static boolean isDigit(int ch) {
+ return ch >= '0' && ch <= '9';
+ }
+
+ private static boolean isHexDigit(int ch) {
+ return ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F';
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java b/features/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
new file mode 100644
index 0000000..cba27fb
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
@@ -0,0 +1,120 @@
+/*
+ * 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.internal.util;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ */
+public class JsonWriter {
+
+ public static void write(Writer writer, Object value) throws IOException {
+ if (value instanceof Map) {
+ writeObject(writer, (Map) value);
+ } else if (value instanceof Collection) {
+ writeArray(writer, (Collection) value);
+ } else if (value instanceof Number) {
+ writeNumber(writer, (Number) value);
+ } else if (value instanceof String) {
+ writeString(writer, (String) value);
+ } else if (value instanceof Boolean) {
+ writeBoolean(writer, (Boolean) value);
+ } else if (value == null) {
+ writeNull(writer);
+ } else {
+ throw new IllegalArgumentException("Unsupported value: " + value);
+ }
+ }
+
+ private static void writeObject(Writer writer, Map<?, ?> value) throws IOException {
+ writer.append('{');
+ boolean first = true;
+ for (Map.Entry entry : value.entrySet()) {
+ if (!first) {
+ writer.append(',');
+ } else {
+ first = false;
+ }
+ writeString(writer, (String) entry.getKey());
+ writer.append(':');
+ write(writer, entry.getValue());
+ }
+ writer.append('}');
+ }
+
+ private static void writeString(Writer writer, String value) throws IOException {
+ writer.append('"');
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '\"':
+ case '\\':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ writer.append('\\');
+ writer.append(c);
+ break;
+ default:
+ if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
+ String s = Integer.toHexString(c);
+ writer.append('\\');
+ writer.append('u');
+ for (int j = s.length(); j < 4; j++) {
+ writer.append('0');
+ }
+ writer.append(s);
+ } else {
+ writer.append(c);
+ }
+ break;
+ }
+ }
+ writer.append('"');
+ }
+
+ private static void writeNumber(Writer writer, Number value) throws IOException {
+ writer.append(value.toString());
+ }
+
+ private static void writeBoolean(Writer writer, Boolean value) throws IOException {
+ writer.append(Boolean.toString(value));
+ }
+
+ private static void writeArray(Writer writer, Collection<?> value) throws IOException {
+ writer.append('[');
+ boolean first = true;
+ for (Object obj : value) {
+ if (!first) {
+ writer.append(',');
+ } else {
+ first = false;
+ }
+ write(writer, obj);
+ }
+ writer.append(']');
+ }
+
+ private static void writeNull(Writer writer) throws IOException {
+ writer.append("null");
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/util/Macro.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/util/Macro.java b/features/src/main/java/org/apache/karaf/features/internal/util/Macro.java
new file mode 100644
index 0000000..d30b7b5
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/util/Macro.java
@@ -0,0 +1,142 @@
+/*
+ * 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.internal.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.utils.version.VersionTable;
+import org.osgi.framework.Version;
+
+public class Macro {
+
+ public static String transform(String macro, String value) {
+ if (macro.startsWith("${") && macro.endsWith("}")) {
+ String[] args = macro.substring(2, macro.length() - 1).split(";");
+ if ("version".equals(args[0])) {
+ if (args.length != 2) {
+ throw new IllegalArgumentException("Invalid syntax for macro: " + macro);
+ }
+ return version(args[1], VersionTable.getVersion(value));
+ } else if ("range".equals(args[0])) {
+ if (args.length != 2) {
+ throw new IllegalArgumentException("Invalid syntax for macro: " + macro);
+ }
+ return range(args[1], VersionTable.getVersion(value));
+ } else {
+ throw new IllegalArgumentException("Unknown macro: " + macro);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Modify a version to set a version policy. Thed policy is a mask that is
+ * mapped to a version.
+ *
+ * <pre>
+ * + increment
+ * - decrement
+ * = maintain
+ * ˜ discard
+ *
+ * ==+ = maintain major, minor, increment micro, discard qualifier
+ * ˜˜˜= = just get the qualifier
+ * version="[${version;==;${@}},${version;=+;${@}})"
+ * </pre>
+ *
+ * @param args
+ * @return
+ */
+ final static String MASK_STRING = "[\\-+=~0123456789]{0,3}[=~]?";
+
+ static String version(String mask, Version version) {
+ StringBuilder sb = new StringBuilder();
+ String del = "";
+
+ for (int i = 0; i < mask.length(); i++) {
+ char c = mask.charAt(i);
+ String result = null;
+ if (c != '~') {
+ if (i > 3) {
+ throw new IllegalArgumentException("Version mask can only specify 3 digits");
+ } else if (i == 3) {
+ result = version.getQualifier();
+ if (result.isEmpty()) {
+ result = null;
+ }
+ } else if (Character.isDigit(c)) {
+ // Handle masks like +00, =+0
+ result = String.valueOf(c);
+ } else {
+ int x = 0;
+ switch (i) {
+ case 0: x = version.getMajor(); break;
+ case 1: x = version.getMinor(); break;
+ case 2: x = version.getMicro(); break;
+ }
+ switch (c) {
+ case '+' :
+ x++;
+ break;
+ case '-' :
+ x--;
+ break;
+ case '=' :
+ break;
+ }
+ result = Integer.toString(x);
+ }
+ if (result != null) {
+ sb.append(del);
+ del = ".";
+ sb.append(result);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Schortcut for version policy
+ *
+ * <pre>
+ * -provide-policy : ${policy;[==,=+)}
+ * -consume-policy : ${policy;[==,+)}
+ * </pre>
+ *
+ * @param args
+ * @return
+ */
+
+ static Pattern RANGE_MASK = Pattern.compile("(\\[|\\()(" + MASK_STRING + "),(" + MASK_STRING + ")(\\]|\\))");
+
+ static String range(String spec, Version version) {
+ Matcher m = RANGE_MASK.matcher(spec);
+ m.matches();
+ String floor = m.group(1);
+ String floorMask = m.group(2);
+ String ceilingMask = m.group(3);
+ String ceiling = m.group(4);
+
+ String left = version(floorMask, version);
+ String right = version(ceilingMask, version);
+
+ return floor + left + "," + right + ceiling;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/internal/util/MultiException.java b/features/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
new file mode 100644
index 0000000..36af452
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/internal/util/MultiException.java
@@ -0,0 +1,95 @@
+/*
+ * 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.internal.util;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+@SuppressWarnings("serial")
+public class MultiException extends Exception {
+
+ private List<Exception> exceptions = new ArrayList<Exception>();
+
+ public MultiException(String message) {
+ super(message);
+ }
+
+ public MultiException(String message, List<Exception> exceptions) {
+ super(message);
+ this.exceptions = exceptions;
+ }
+
+ public void addException(Exception e) {
+ exceptions.add(e);
+ }
+
+ public void throwIfExceptions() throws MultiException {
+ if (!exceptions.isEmpty()) {
+ throw this;
+ }
+ }
+
+ public Throwable[] getCauses() {
+ return exceptions.toArray(new Throwable[exceptions.size()]);
+ }
+
+ @Override
+ public void printStackTrace()
+ {
+ super.printStackTrace();
+ for (Exception e : exceptions) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /* ------------------------------------------------------------------------------- */
+ /**
+ * @see Throwable#printStackTrace(java.io.PrintStream)
+ */
+ @Override
+ public void printStackTrace(PrintStream out)
+ {
+ super.printStackTrace(out);
+ for (Exception e : exceptions) {
+ e.printStackTrace(out);
+ }
+ }
+
+ @Override
+ public void printStackTrace(PrintWriter out)
+ {
+ super.printStackTrace(out);
+ for (Exception e : exceptions) {
+ e.printStackTrace(out);
+ }
+ }
+
+ public static void throwIf(String message, List<Exception> exceptions) throws MultiException {
+ if (exceptions != null && !exceptions.isEmpty()) {
+ StringBuilder sb = new StringBuilder(message);
+ sb.append(":");
+ for (Exception e : exceptions) {
+ sb.append("\n\t");
+ sb.append(e.getMessage());
+ }
+ throw new MultiException(sb.toString(), exceptions);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java b/features/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
new file mode 100644
index 0000000..6afbbed
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/management/FeaturesServiceMBean.java
@@ -0,0 +1,142 @@
+/*
+ * 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.management;
+
+import javax.management.openmbean.TabularData;
+
+public interface FeaturesServiceMBean {
+
+ TabularData getFeatures() throws Exception;
+
+ TabularData getRepositories() throws Exception;
+
+ void addRepository(String url) throws Exception;
+
+ void addRepository(String url, boolean install) throws Exception;
+
+ void removeRepository(String url) throws Exception;
+
+ void removeRepository(String url, boolean uninstall) throws Exception;
+
+ void installFeature(String name) throws Exception;
+
+ void installFeature(String name, boolean noRefresh) throws Exception;
+
+ void installFeature(String name, boolean noRefresh, boolean noStart) throws Exception;
+
+ void installFeature(String name, String version) throws Exception;
+
+ void installFeature(String name, String version, boolean noRefresh) throws Exception;
+
+ void installFeature(String name, String version, boolean noRefresh, boolean noStart) throws Exception;
+
+ TabularData infoFeature(String name) throws Exception;
+
+ TabularData infoFeature(String name, String version) throws Exception;
+
+ void uninstallFeature(String name) throws Exception;
+
+ void uninstallFeature(String name, boolean noRefresh) throws Exception;
+
+ void uninstallFeature(String name, String version) throws Exception;
+
+ void uninstallFeature(String name, String version, boolean noRefresh) throws Exception;
+
+ String FEATURE_NAME = "Name";
+
+ String FEATURE_VERSION = "Version";
+
+ String FEATURE_DEPENDENCIES = "Dependencies";
+
+ String FEATURE_BUNDLES = "Bundles";
+
+ String FEATURE_CONFIGURATIONS = "Configurations";
+
+ String FEATURE_CONFIGURATIONFILES = "Configuration Files";
+
+ String FEATURE_INSTALLED = "Installed";
+
+ String FEATURE_CONFIG_PID = "Pid";
+ String FEATURE_CONFIG_ELEMENTS = "Elements";
+ String FEATURE_CONFIG_ELEMENT_KEY = "Key";
+ String FEATURE_CONFIG_ELEMENT_VALUE = "Value";
+
+ String FEATURE_CONFIG_FILES_ELEMENTS = "Files";
+
+ /**
+ * The type of the event which is emitted for features events
+ */
+ String FEATURE_EVENT_TYPE = "org.apache.karaf.features.featureEvent";
+
+ String FEATURE_EVENT_EVENT_TYPE = "Type";
+
+ String FEATURE_EVENT_EVENT_TYPE_INSTALLED = "Installed";
+
+ String FEATURE_EVENT_EVENT_TYPE_UNINSTALLED = "Uninstalled";
+
+ /**
+ * The item names in the CompositeData representing a feature
+ */
+ String[] FEATURE = { FEATURE_NAME, FEATURE_VERSION, FEATURE_DEPENDENCIES, FEATURE_BUNDLES,
+ FEATURE_CONFIGURATIONS, FEATURE_CONFIGURATIONFILES, FEATURE_INSTALLED };
+
+ String[] FEATURE_IDENTIFIER = { FEATURE_NAME, FEATURE_VERSION };
+
+ String[] FEATURE_CONFIG = { FEATURE_CONFIG_PID, FEATURE_CONFIG_ELEMENTS };
+
+ String[] FEATURE_CONFIG_FILES = { FEATURE_CONFIG_FILES_ELEMENTS };
+
+ String[] FEATURE_CONFIG_ELEMENT = { FEATURE_CONFIG_ELEMENT_KEY, FEATURE_CONFIG_ELEMENT_VALUE };
+
+ /**
+ * The item names in the CompositeData representing the event raised for
+ * feature events within the OSGi container by this bean
+ */
+ String[] FEATURE_EVENT = { FEATURE_NAME, FEATURE_VERSION, FEATURE_EVENT_EVENT_TYPE };
+
+
+ String REPOSITORY_NAME = "Name";
+
+ String REPOSITORY_URI = "Uri";
+
+ String REPOSITORY_REPOSITORIES = "Repositories";
+
+ String REPOSITORY_FEATURES = "Features";
+
+ /**
+ * The type of the event which is emitted for repositories events
+ */
+ String REPOSITORY_EVENT_TYPE = "org.apache.karaf.features.repositoryEvent";
+
+ String REPOSITORY_EVENT_EVENT_TYPE = "Type";
+
+ String REPOSITORY_EVENT_EVENT_TYPE_ADDED = "Added";
+
+ String REPOSITORY_EVENT_EVENT_TYPE_REMOVED = "Removed";
+
+ /**
+ * The item names in the CompositeData representing a feature
+ */
+ String[] REPOSITORY = { REPOSITORY_NAME, REPOSITORY_URI, REPOSITORY_REPOSITORIES, REPOSITORY_FEATURES };
+
+ /**
+ * The item names in the CompositeData representing the event raised for
+ * feature events within the OSGi container by this bean
+ */
+ String[] REPOSITORY_EVENT = { REPOSITORY_URI, REPOSITORY_EVENT_EVENT_TYPE };
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java b/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
new file mode 100644
index 0000000..54fa3c0
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeature.java
@@ -0,0 +1,323 @@
+/*
+ * 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.management.codec;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+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.management.FeaturesServiceMBean;
+
+public class JmxFeature {
+
+ /**
+ * The CompositeType which represents a single feature
+ */
+ public final static CompositeType FEATURE;
+
+ /**
+ * The TabularType which represents a list of features
+ */
+ public final static TabularType FEATURE_TABLE;
+
+ public final static CompositeType FEATURE_IDENTIFIER;
+
+ public final static TabularType FEATURE_IDENTIFIER_TABLE;
+
+ public final static CompositeType FEATURE_CONFIG_ELEMENT;
+
+ public final static TabularType FEATURE_CONFIG_ELEMENT_TABLE;
+
+ public final static CompositeType FEATURE_CONFIG;
+
+ public final static TabularType FEATURE_CONFIG_TABLE;
+
+ public final static CompositeType FEATURE_CONFIG_FILES;
+
+ public final static TabularType FEATURE_CONFIG_FILES_TABLE;
+
+ private final CompositeData data;
+
+ public JmxFeature(Feature feature, boolean installed) {
+ try {
+ String[] itemNames = FeaturesServiceMBean.FEATURE;
+ Object[] itemValues = new Object[itemNames.length];
+ itemValues[0] = feature.getName();
+ itemValues[1] = feature.getVersion();
+ itemValues[2] = getDependencyIdentifierTable(feature.getDependencies());
+ itemValues[3] = getBundleUris(feature.getBundles());
+ itemValues[4] = getConfigTable(feature.getConfigurations());
+ itemValues[5] = getConfigFileList(feature.getConfigurationFiles());
+ itemValues[6] = installed;
+ data = new CompositeDataSupport(FEATURE, itemNames, itemValues);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Cannot form feature open data", e);
+ }
+ }
+
+ public CompositeData asCompositeData() {
+ return data;
+ }
+
+ public static TabularData tableFrom(Collection<JmxFeature> features) {
+ TabularDataSupport table = new TabularDataSupport(FEATURE_TABLE);
+ for (JmxFeature feature : features) {
+ table.put(feature.asCompositeData());
+ }
+ return table;
+ }
+
+ private static TabularData getDependencyIdentifierTable(List<Dependency> features) throws OpenDataException {
+ TabularDataSupport table = new TabularDataSupport(FEATURE_IDENTIFIER_TABLE);
+ Set<String> featureSet = new HashSet<String>();
+ for (Dependency feature : features) {
+ if (featureSet.contains(feature.getName() + feature.getVersion())) {
+ continue;
+ } else {
+ featureSet.add(feature.getName() + feature.getVersion());
+ }
+ String[] itemNames = new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION };
+ Object[] itemValues = new Object[] { feature.getName(), feature.getVersion() };
+ CompositeData ident = new CompositeDataSupport(FEATURE_IDENTIFIER, itemNames, itemValues);
+ table.put(ident);
+ }
+ return table;
+ }
+
+ static String[] getBundleUris(List<BundleInfo> infos) {
+ String[] array = new String[infos.size()];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = infos.get(i).getLocation();
+ }
+ return array;
+ }
+
+ static TabularData getConfigTable(Map<String, Map<String, String>> configs) throws OpenDataException {
+ TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_TABLE);
+ for (Map.Entry<String, Map<String, String>> entry : configs.entrySet()) {
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG;
+ Object[] itemValues = new Object[2];
+ itemValues[0] = entry.getKey();
+ itemValues[1] = getConfigElementTable(entry.getValue());
+ CompositeData config = new CompositeDataSupport(FEATURE_CONFIG, itemNames, itemValues);
+ table.put(config);
+ }
+ return table;
+ }
+
+ static TabularData getConfigFileList(List<ConfigFileInfo> configFiles) throws OpenDataException {
+ TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_FILES_TABLE);
+ for (ConfigFileInfo configFile : configFiles) {
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_FILES;
+ Object[] itemValues = { configFile.getFinalname() };
+ CompositeData config = new CompositeDataSupport(FEATURE_CONFIG_FILES, itemNames, itemValues);
+ table.put(config);
+ }
+ return table;
+ }
+
+ static TabularData getConfigElementTable(Map<String, String> config) throws OpenDataException {
+ TabularDataSupport table = new TabularDataSupport(FEATURE_CONFIG_ELEMENT_TABLE);
+ for (Map.Entry<String, String> entry : config.entrySet()) {
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT;
+ Object[] itemValues = { entry.getKey(), entry.getValue() };
+ CompositeData element = new CompositeDataSupport(FEATURE_CONFIG_ELEMENT, itemNames, itemValues);
+ table.put(element);
+ }
+ return table;
+ }
+
+
+ static {
+ FEATURE_IDENTIFIER = createFeatureIdentifierType();
+ FEATURE_IDENTIFIER_TABLE = createFeatureIdentifierTableType();
+ FEATURE_CONFIG_ELEMENT = createFeatureConfigElementType();
+ FEATURE_CONFIG_ELEMENT_TABLE = createFeatureConfigElementTableType();
+ FEATURE_CONFIG = createFeatureConfigType();
+ FEATURE_CONFIG_TABLE = createFeatureConfigTableType();
+ FEATURE_CONFIG_FILES = createFeatureConfigFilesType();
+ FEATURE_CONFIG_FILES_TABLE = createFeatureConfigFilesTableType();
+ FEATURE = createFeatureType();
+ FEATURE_TABLE = createFeatureTableType();
+ }
+
+ private static CompositeType createFeatureIdentifierType() {
+ try {
+ String description = "This type identify a Karaf features";
+ String[] itemNames = FeaturesServiceMBean.FEATURE_IDENTIFIER;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+
+ itemDescriptions[0] = "The id of the feature";
+ itemDescriptions[1] = "The version of the feature";
+
+ return new CompositeType("FeatureIdentifier", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build featureIdentifier type", e);
+ }
+ }
+
+ private static TabularType createFeatureIdentifierTableType() {
+ try {
+ return new TabularType("Features", "The table of featureIdentifiers",
+ FEATURE_IDENTIFIER, new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION });
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build featureIdentifier table type", e);
+ }
+ }
+
+ private static CompositeType createFeatureConfigElementType() {
+ try {
+ String description = "This type encapsulates Karaf feature config element";
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+
+ itemDescriptions[0] = "The key";
+ itemDescriptions[1] = "The value";
+
+ return new CompositeType("ConfigElement", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build configElement type", e);
+ }
+ }
+
+ private static TabularType createFeatureConfigElementTableType() {
+ try {
+ return new TabularType("ConfigElement", "The table of configurations elements",
+ FEATURE_CONFIG_ELEMENT, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_ELEMENT_KEY});
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build feature table type", e);
+ }
+ }
+
+ private static CompositeType createFeatureConfigType() {
+ try {
+ String description = "This type encapsulates Karaf feature config";
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = FEATURE_CONFIG_ELEMENT_TABLE;
+
+ itemDescriptions[0] = "The PID of the config";
+ itemDescriptions[1] = "The configuration elements";
+
+ return new CompositeType("Config", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build configElement type", e);
+ }
+ }
+
+ private static CompositeType createFeatureConfigFilesType() {
+ try {
+ String description = "This type encapsulates Karaf feature config files";
+ String[] itemNames = FeaturesServiceMBean.FEATURE_CONFIG_FILES;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+
+ itemDescriptions[0] = "The configuration file";
+
+ return new CompositeType("Config", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build configElement type", e);
+ }
+ }
+
+ private static TabularType createFeatureConfigTableType() {
+ try {
+ return new TabularType("Features", "The table of configurations",
+ FEATURE_CONFIG, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_PID});
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build feature table type", e);
+ }
+ }
+
+ private static TabularType createFeatureConfigFilesTableType() {
+ try {
+ return new TabularType("Features", "The table of configuration files",
+ FEATURE_CONFIG_FILES, new String[] { FeaturesServiceMBean.FEATURE_CONFIG_FILES_ELEMENTS });
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build feature table type", e);
+ }
+ }
+
+ private static CompositeType createFeatureType() {
+ try {
+ String description = "This type encapsulates Karaf features";
+ String[] itemNames = FeaturesServiceMBean.FEATURE;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+ itemTypes[2] = FEATURE_IDENTIFIER_TABLE;
+ itemTypes[3] = new ArrayType(1, SimpleType.STRING);
+ itemTypes[4] = FEATURE_CONFIG_TABLE;
+ itemTypes[5] = FEATURE_CONFIG_FILES_TABLE;
+ itemTypes[6] = SimpleType.BOOLEAN;
+
+ itemDescriptions[0] = "The name of the feature";
+ itemDescriptions[1] = "The version of the feature";
+ itemDescriptions[2] = "The feature dependencies";
+ itemDescriptions[3] = "The feature bundles";
+ itemDescriptions[4] = "The feature configurations";
+ itemDescriptions[5] = "The feature configuration files";
+ itemDescriptions[6] = "Whether the feature is installed";
+
+ return new CompositeType("Feature", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build feature type", e);
+ }
+ }
+
+ private static TabularType createFeatureTableType() {
+ try {
+ return new TabularType("Features", "The table of all features",
+ FEATURE, new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION });
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build feature table type", e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java b/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
new file mode 100644
index 0000000..81f446b
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/management/codec/JmxFeatureEvent.java
@@ -0,0 +1,80 @@
+/*
+ * 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.management.codec;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+import org.apache.karaf.features.FeatureEvent;
+import org.apache.karaf.features.management.FeaturesServiceMBean;
+
+public class JmxFeatureEvent {
+
+ public static final CompositeType FEATURE_EVENT;
+
+ private final CompositeData data;
+
+ public JmxFeatureEvent(FeatureEvent event) {
+ try {
+ String[] itemNames = FeaturesServiceMBean.FEATURE_EVENT;
+ Object[] itemValues = new Object[itemNames.length];
+ itemValues[0] = event.getFeature().getName();
+ itemValues[1] = event.getFeature().getVersion();
+ switch (event.getType()) {
+ case FeatureInstalled: itemValues[2] = FeaturesServiceMBean.FEATURE_EVENT_EVENT_TYPE_INSTALLED; break;
+ case FeatureUninstalled: itemValues[2] = FeaturesServiceMBean.FEATURE_EVENT_EVENT_TYPE_UNINSTALLED; break;
+ default: throw new IllegalStateException("Unsupported event type: " + event.getType());
+ }
+ data = new CompositeDataSupport(FEATURE_EVENT, itemNames, itemValues);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Cannot form feature event open data", e);
+ }
+ }
+
+ public CompositeData asCompositeData() {
+ return data;
+ }
+
+ static {
+ FEATURE_EVENT = createFeatureEventType();
+ }
+
+ private static CompositeType createFeatureEventType() {
+ try {
+ String description = "This type identify a Karaf feature event";
+ String[] itemNames = FeaturesServiceMBean.FEATURE_EVENT;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+ itemTypes[2] = SimpleType.STRING;
+
+ itemDescriptions[0] = "The id of the feature";
+ itemDescriptions[1] = "The version of the feature";
+ itemDescriptions[2] = "The type of the event";
+
+ return new CompositeType("FeatureEvent", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build featureEvent type", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java b/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
new file mode 100644
index 0000000..fee1ab2
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepository.java
@@ -0,0 +1,132 @@
+/*
+ * 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.management.codec;
+
+import java.util.Collection;
+import java.util.Arrays;
+import java.net.URI;
+import java.util.List;
+
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.TabularType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.CompositeDataSupport;
+
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.management.FeaturesServiceMBean;
+
+public class JmxRepository {
+
+ public final static CompositeType REPOSITORY;
+
+ public final static TabularType REPOSITORY_TABLE;
+
+ private final CompositeData data;
+
+ public JmxRepository(Repository repository) {
+ try {
+ String[] itemNames = FeaturesServiceMBean.REPOSITORY;
+ Object[] itemValues = new Object[itemNames.length];
+ itemValues[0] = repository.getName();
+ itemValues[1] = repository.getURI().toString();
+ itemValues[2] = toStringArray(repository.getRepositories());
+ itemValues[3] = getFeatureIdentifierTable(Arrays.asList(repository.getFeatures()));
+ data = new CompositeDataSupport(REPOSITORY, itemNames, itemValues);
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot form repository open data", e);
+ }
+ }
+
+ public CompositeData asCompositeData() {
+ return data;
+ }
+
+ public static TabularData tableFrom(Collection<JmxRepository> repositories) {
+ TabularDataSupport table = new TabularDataSupport(REPOSITORY_TABLE);
+ for (JmxRepository repository : repositories) {
+ table.put(repository.asCompositeData());
+ }
+ return table;
+ }
+
+ private static String[] toStringArray(URI[] uris) {
+ if (uris == null) {
+ return null;
+ }
+ String[] res = new String[uris.length];
+ for (int i = 0; i < res.length; i++) {
+ res[i] = uris[i].toString();
+ }
+ return res;
+ }
+
+ static TabularData getFeatureIdentifierTable(List<Feature> features) throws OpenDataException {
+ TabularDataSupport table = new TabularDataSupport(JmxFeature.FEATURE_IDENTIFIER_TABLE);
+ for (Feature feature : features) {
+ String[] itemNames = new String[] { FeaturesServiceMBean.FEATURE_NAME, FeaturesServiceMBean.FEATURE_VERSION };
+ Object[] itemValues = new Object[] { feature.getName(), feature.getVersion() };
+ CompositeData ident = new CompositeDataSupport(JmxFeature.FEATURE_IDENTIFIER, itemNames, itemValues);
+ table.put(ident);
+ }
+ return table;
+ }
+
+ static {
+ REPOSITORY = createRepositoryType();
+ REPOSITORY_TABLE = createRepositoryTableType();
+ }
+
+ private static CompositeType createRepositoryType() {
+ try {
+ String description = "This type identify a Karaf repository";
+ String[] itemNames = FeaturesServiceMBean.REPOSITORY;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+ itemTypes[2] = new ArrayType(1, SimpleType.STRING);
+ itemTypes[3] = JmxFeature.FEATURE_IDENTIFIER_TABLE;
+
+ itemDescriptions[0] = "The name of the repository";
+ itemDescriptions[1] = "The uri of the repository";
+ itemDescriptions[2] = "The dependent repositories";
+ itemDescriptions[3] = "The list of included features";
+
+ return new CompositeType("Repository", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build repository type", e);
+ }
+ }
+
+ private static TabularType createRepositoryTableType() {
+ try {
+ return new TabularType("Features", "The table of repositories",
+ REPOSITORY, new String[] { FeaturesServiceMBean.REPOSITORY_URI });
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build repository table type", e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
----------------------------------------------------------------------
diff --git a/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java b/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
new file mode 100644
index 0000000..e00e85d
--- /dev/null
+++ b/features/src/main/java/org/apache/karaf/features/management/codec/JmxRepositoryEvent.java
@@ -0,0 +1,77 @@
+/*
+ * 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.management.codec;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+import org.apache.karaf.features.RepositoryEvent;
+import org.apache.karaf.features.management.FeaturesServiceMBean;
+
+public class JmxRepositoryEvent {
+
+ public static final CompositeType REPOSITORY_EVENT;
+
+ private final CompositeData data;
+
+ public JmxRepositoryEvent(RepositoryEvent event) {
+ try {
+ String[] itemNames = FeaturesServiceMBean.REPOSITORY_EVENT;
+ Object[] itemValues = new Object[itemNames.length];
+ itemValues[0] = event.getRepository().getURI().toString();
+ switch (event.getType()) {
+ case RepositoryAdded: itemValues[1] = FeaturesServiceMBean.REPOSITORY_EVENT_EVENT_TYPE_ADDED; break;
+ case RepositoryRemoved: itemValues[1] = FeaturesServiceMBean.REPOSITORY_EVENT_EVENT_TYPE_REMOVED; break;
+ default: throw new IllegalStateException("Unsupported event type: " + event.getType());
+ }
+ data = new CompositeDataSupport(REPOSITORY_EVENT, itemNames, itemValues);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Cannot form repository event open data", e);
+ }
+ }
+
+ public CompositeData asCompositeData() {
+ return data;
+ }
+
+ static {
+ REPOSITORY_EVENT = createRepositoryEventType();
+ }
+
+ private static CompositeType createRepositoryEventType() {
+ try {
+ String description = "This type identify a Karaf repository event";
+ String[] itemNames = FeaturesServiceMBean.REPOSITORY_EVENT;
+ OpenType[] itemTypes = new OpenType[itemNames.length];
+ String[] itemDescriptions = new String[itemNames.length];
+ itemTypes[0] = SimpleType.STRING;
+ itemTypes[1] = SimpleType.STRING;
+
+ itemDescriptions[0] = "The uri of the repository";
+ itemDescriptions[1] = "The type of event";
+
+ return new CompositeType("RepositoryEvent", description, itemNames,
+ itemDescriptions, itemTypes);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException("Unable to build repositoryEvent type", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/999f4970/features/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/features/src/main/resources/OSGI-INF/bundle.info b/features/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..d5b4180
--- /dev/null
+++ b/features/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,20 @@
+h1. Synopsis
+
+${project.name}
+
+${project.description}
+
+Maven URL:
+[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+This bundle is the core implementation of the Karaf features support.
+
+Karaf provides a simple, yet flexible, way to provision applications or "features". Such a mechanism is mainly
+provided by a set of commands available in the features shell. The provisioning system uses xml "repositories"
+that define a set of features.
+
+h1. See also
+
+Provisioning - section of the Karaf User Guide
[22/59] [abbrv] [KARAF-2852] Merge config/core and config/command
Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
----------------------------------------------------------------------
diff --git a/config/src/test/java/org/apache/karaf/config/command/EditCommandTest.java b/config/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
new file mode 100644
index 0000000..09dc000
--- /dev/null
+++ b/config/src/test/java/org/apache/karaf/config/command/EditCommandTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+import org.apache.karaf.config.core.impl.ConfigRepositoryImpl;
+import org.apache.karaf.shell.api.console.Session;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * Test cases for {@link EditCommand}
+ */
+public class EditCommandTest extends TestCase {
+
+ private static final String PID = "my.test.persistent.id";
+
+ private EditCommand command;
+ private BundleContext context;
+ private ConfigurationAdmin admin;
+ private Session session;
+
+ @Override
+ protected void setUp() throws Exception {
+ command = new EditCommand();
+
+ admin = createMock(ConfigurationAdmin.class);
+ command.setConfigRepository(new ConfigRepositoryImpl(admin));
+
+ session = new MockCommandSession();
+ command.setSession(session);
+ }
+
+ public void testExecuteOnExistingPid() throws Exception {
+ Configuration config = createMock(Configuration.class);
+ expect(admin.getConfiguration(PID)).andReturn(config);
+ replay(admin);
+
+ // the ConfigAdmin service returns a Dictionary for an existing PID
+ Dictionary props = new Properties();
+ expect(config.getProperties()).andReturn(props);
+ replay(config);
+
+ command.pid = PID;
+ command.execute();
+
+ // the PID and Dictionary should have been set on the session
+ assertEquals("The PID should be set on the session",
+ PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
+ assertSame("The Dictionary returned by the ConfigAdmin service should be set on the session",
+ props, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS));
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void testExecuteOnNewPid() throws Exception {
+ Configuration config = createMock(Configuration.class);
+ expect(admin.getConfiguration(PID)).andReturn(config);
+ replay(admin);
+
+ // the ConfigAdmin service does not return a Dictionary for a new PID
+ expect(config.getProperties()).andReturn(null);
+ replay(config);
+
+ command.pid = PID;
+ command.execute();
+
+ // the PID and an empty Dictionary should have been set on the session
+ assertEquals("The PID should be set on the session",
+ PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
+ Dictionary props = (Dictionary) session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS);
+ assertNotNull("Should have a Dictionary on the session", props);
+ assertTrue("Should have an empty Dictionary on the session", props.isEmpty());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
----------------------------------------------------------------------
diff --git a/config/src/test/java/org/apache/karaf/config/command/MockCommandSession.java b/config/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
new file mode 100644
index 0000000..7fa430b
--- /dev/null
+++ b/config/src/test/java/org/apache/karaf/config/command/MockCommandSession.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.karaf.shell.api.console.History;
+import org.apache.karaf.shell.api.console.Registry;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.console.SessionFactory;
+import org.apache.karaf.shell.api.console.Terminal;
+
+/*
+ * A mock CommandSession implementation that only cares about the properties set on the session
+ */
+class MockCommandSession implements Session {
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ public void close() {
+ // not implemented
+ }
+
+ public Object execute(CharSequence commandline) throws Exception {
+ // not implemented
+ return null;
+ }
+
+ public Object get(String name) {
+ return properties.get(name);
+ }
+
+ public PrintStream getConsole() {
+ // not implemented
+ return null;
+ }
+
+ public InputStream getKeyboard() {
+ // not implemented
+ return null;
+ }
+
+ public void put(String name, Object value) {
+ properties.put(name, value);
+ }
+
+ @Override
+ public String readLine(String prompt, Character mask) throws IOException {
+ return null;
+ }
+
+ @Override
+ public Terminal getTerminal() {
+ return null;
+ }
+
+ @Override
+ public History getHistory() {
+ return null;
+ }
+
+ @Override
+ public Registry getRegistry() {
+ return null;
+ }
+
+ @Override
+ public SessionFactory getFactory() {
+ return null;
+ }
+
+ @Override
+ public String resolveCommand(String name) {
+ return null;
+ }
+
+ @Override
+ public void run() {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/d33e0955/config/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
----------------------------------------------------------------------
diff --git a/config/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java b/config/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
new file mode 100644
index 0000000..e3f58b5
--- /dev/null
+++ b/config/src/test/java/org/apache/karaf/config/command/UpdateCommandTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.config.command;
+
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import junit.framework.TestCase;
+
+import org.apache.karaf.config.core.ConfigRepository;
+import org.easymock.EasyMock;
+
+/**
+ * Test cases for {@link EditCommand}
+ */
+public class UpdateCommandTest extends TestCase {
+
+ private static final String FACTORY_PID = "myFactoryPid";
+ private static final String PID = "myPid";
+
+ public void testupdateRegularConfig() throws Exception {
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+
+ UpdateCommand command = new UpdateCommand();
+ ConfigRepository configRepo = EasyMock.createMock(ConfigRepository.class);
+ configRepo.update(EasyMock.eq(PID), EasyMock.eq(props));
+ EasyMock.expectLastCall();
+ command.setConfigRepository(configRepo);
+
+ MockCommandSession session = createMockSessionForFactoryEdit(PID, false, props);
+ command.setSession(session);
+ replay(configRepo);
+
+ command.execute();
+ EasyMock.verify(configRepo);
+ }
+
+ public void testupdateOnNewFactoryPid() throws Exception {
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+
+ UpdateCommand command = new UpdateCommand();
+ ConfigRepository configRepo = EasyMock.createMock(ConfigRepository.class);
+ expect(configRepo.createFactoryConfiguration(EasyMock.eq(FACTORY_PID), EasyMock.eq(props)))
+ .andReturn(PID + ".35326647");
+ command.setConfigRepository(configRepo);
+
+ MockCommandSession session = createMockSessionForFactoryEdit(FACTORY_PID, true, props);
+ command.setSession(session);
+ replay(configRepo);
+
+ command.execute();
+ EasyMock.verify(configRepo);
+ }
+
+ private MockCommandSession createMockSessionForFactoryEdit(String pid, boolean isFactory,
+ Dictionary<String, Object> props) {
+ MockCommandSession session = new MockCommandSession();
+ session.put(ConfigCommandSupport.PROPERTY_CONFIG_PID, pid);
+ session.put(ConfigCommandSupport.PROPERTY_FACTORY, isFactory);
+ session.put(ConfigCommandSupport.PROPERTY_CONFIG_PROPS, props);
+ return session;
+ }
+
+}
[37/59] [abbrv] git commit: [KARAF-2852] Merge log/core and
log/command
Posted by gn...@apache.org.
[KARAF-2852] Merge log/core and log/command
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/7f1463c5
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/7f1463c5
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/7f1463c5
Branch: refs/heads/master
Commit: 7f1463c517a55d6be85091fd2bed61f46b4236e1
Parents: f13d140
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Apr 9 23:13:37 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Apr 10 16:01:42 2014 +0200
----------------------------------------------------------------------
.../standard/src/main/feature/feature.xml | 1 -
log/NOTICE | 71 +++
log/command/NOTICE | 71 ---
log/command/pom.xml | 113 ----
.../org/apache/karaf/log/command/ClearLog.java | 41 --
.../karaf/log/command/DisplayException.java | 49 --
.../apache/karaf/log/command/DisplayLog.java | 83 ---
.../apache/karaf/log/command/GetLogLevel.java | 63 ---
.../org/apache/karaf/log/command/LogEntry.java | 69 ---
.../org/apache/karaf/log/command/LogTail.java | 129 -----
.../apache/karaf/log/command/SetLogLevel.java | 52 --
.../src/main/resources/OSGI-INF/bundle.info | 24 -
.../OSGI-INF/metatype/metatype.properties | 31 -
.../resources/OSGI-INF/metatype/metatype.xml | 30 -
log/core/NOTICE | 71 ---
log/core/pom.xml | 112 ----
.../java/org/apache/karaf/log/core/Level.java | 54 --
.../karaf/log/core/LogEventFormatter.java | 25 -
.../org/apache/karaf/log/core/LogMBean.java | 32 --
.../org/apache/karaf/log/core/LogService.java | 38 --
.../core/internal/LogEventFormatterImpl.java | 157 ------
.../karaf/log/core/internal/LogMBeanImpl.java | 59 --
.../karaf/log/core/internal/LogServiceImpl.java | 261 ---------
.../apache/karaf/log/core/internal/LruList.java | 124 ----
.../internal/layout/AbsoluteTimeDateFormat.java | 142 -----
.../internal/layout/DateTimeDateFormat.java | 85 ---
.../core/internal/layout/FormattingInfo.java | 44 --
.../core/internal/layout/ISO8601DateFormat.java | 152 -----
.../core/internal/layout/PatternConverter.java | 106 ----
.../log/core/internal/layout/PatternParser.java | 560 -------------------
.../karaf/log/core/internal/osgi/Activator.java | 77 ---
.../src/main/resources/OSGI-INF/bundle.info | 24 -
.../log/core/internal/SetLogLevelTest.java | 129 -----
log/pom.xml | 97 +++-
.../org/apache/karaf/log/command/ClearLog.java | 41 ++
.../karaf/log/command/DisplayException.java | 49 ++
.../apache/karaf/log/command/DisplayLog.java | 83 +++
.../apache/karaf/log/command/GetLogLevel.java | 63 +++
.../org/apache/karaf/log/command/LogEntry.java | 69 +++
.../org/apache/karaf/log/command/LogTail.java | 129 +++++
.../apache/karaf/log/command/SetLogLevel.java | 52 ++
.../java/org/apache/karaf/log/core/Level.java | 54 ++
.../karaf/log/core/LogEventFormatter.java | 25 +
.../org/apache/karaf/log/core/LogMBean.java | 32 ++
.../org/apache/karaf/log/core/LogService.java | 38 ++
.../core/internal/LogEventFormatterImpl.java | 157 ++++++
.../karaf/log/core/internal/LogMBeanImpl.java | 59 ++
.../karaf/log/core/internal/LogServiceImpl.java | 261 +++++++++
.../apache/karaf/log/core/internal/LruList.java | 124 ++++
.../internal/layout/AbsoluteTimeDateFormat.java | 142 +++++
.../internal/layout/DateTimeDateFormat.java | 85 +++
.../core/internal/layout/FormattingInfo.java | 44 ++
.../core/internal/layout/ISO8601DateFormat.java | 152 +++++
.../core/internal/layout/PatternConverter.java | 106 ++++
.../log/core/internal/layout/PatternParser.java | 560 +++++++++++++++++++
.../karaf/log/core/internal/osgi/Activator.java | 77 +++
log/src/main/resources/OSGI-INF/bundle.info | 24 +
.../OSGI-INF/metatype/metatype.properties | 31 +
.../resources/OSGI-INF/metatype/metatype.xml | 30 +
.../log/core/internal/SetLogLevelTest.java | 129 +++++
60 files changed, 2776 insertions(+), 3016 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/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 99554c2..6fa3319 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -147,7 +147,6 @@
<feature name="log" description="Provide Log support" version="${project.version}">
<bundle start-level="30" start="true">mvn:org.apache.karaf.log/org.apache.karaf.log.core/${project.version}</bundle>
- <bundle start-level="30" start="true">mvn:org.apache.karaf.log/org.apache.karaf.log.command/${project.version}</bundle>
</feature>
<feature name="region" description="Provide Region Support" version="${project.version}">
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/NOTICE
----------------------------------------------------------------------
diff --git a/log/NOTICE b/log/NOTICE
new file mode 100644
index 0000000..b70f1f9
--- /dev/null
+++ b/log/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/7f1463c5/log/command/NOTICE
----------------------------------------------------------------------
diff --git a/log/command/NOTICE b/log/command/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/log/command/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/7f1463c5/log/command/pom.xml
----------------------------------------------------------------------
diff --git a/log/command/pom.xml b/log/command/pom.xml
deleted file mode 100644
index b0b3791..0000000
--- a/log/command/pom.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?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.log</groupId>
- <artifactId>log</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.log.command</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Log :: Command</name>
- <description>Shell commands to manipulate Log service</description>
-
- <properties>
- <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.karaf.log</groupId>
- <artifactId>org.apache.karaf.log.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.core</artifactId>
- </dependency>
-
- <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.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-service</artifactId>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-api</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>
- <Import-Package>
- *
- </Import-Package>
- <Export-Package>
- !*
- </Export-Package>
- <Private-Package>
- org.apache.karaf.log.command*
- </Private-Package>
- <Karaf-Commands>
- org.apache.karaf.log.command*
- </Karaf-Commands>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/ClearLog.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/ClearLog.java b/log/command/src/main/java/org/apache/karaf/log/command/ClearLog.java
deleted file mode 100644
index 75a48d6..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/ClearLog.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.log.command;
-
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-/**
- * Clear the last log entries.
- */
-@Command(scope = "log", name = "clear", description = "Clear log entries.")
-@Service
-public class ClearLog implements Action {
-
- @Reference
- LogService logService;
-
- @Override
- public Object execute() throws Exception {
- logService.clearEvents();
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/DisplayException.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/DisplayException.java b/log/command/src/main/java/org/apache/karaf/log/command/DisplayException.java
deleted file mode 100644
index 52a2661..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/DisplayException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.log.command;
-
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-@Command(scope = "log", name = "exception-display", description = "Displays the last occurred exception from the log.")
-@Service
-public class DisplayException implements Action {
-
- @Argument(index = 0, name = "logger", description = "The name of the logger. This can be ROOT, ALL, or the name of a logger specified in the org.ops4j.pax.logger.cfg file.", required = false, multiValued = false)
- String logger;
-
- @Reference
- LogService logService;
-
- @Override
- public Object execute() throws Exception {
- PaxLoggingEvent throwableEvent = logService.getLastException(logger);
- if (throwableEvent != null) {
- for (String r : throwableEvent.getThrowableStrRep()) {
- System.out.println(r);
- }
- System.out.println();
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/DisplayLog.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/DisplayLog.java b/log/command/src/main/java/org/apache/karaf/log/command/DisplayLog.java
deleted file mode 100644
index 813eea5..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/DisplayLog.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.log.command;
-
-import java.io.PrintStream;
-
-import org.apache.karaf.log.core.LogEventFormatter;
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-/**
- * Displays the last log entries
- */
-@Command(scope = "log", name = "display", description = "Displays log entries.")
-@Service
-public class DisplayLog implements Action {
-
- @Option(name = "-n", aliases = {}, description="Number of entries to display", required = false, multiValued = false)
- int entries;
-
- @Option(name = "-p", aliases = {}, description="Pattern for formatting the output", required = false, multiValued = false)
- String overridenPattern;
-
- @Option(name = "--no-color", description="Disable syntax coloring of log events", required = false, multiValued = false)
- boolean noColor;
-
- @Argument(index = 0, name = "logger", description = "The name of the logger. This can be ROOT, ALL, or the name of a logger specified in the org.ops4j.pax.logger.cfg file.", required = false, multiValued = false)
- String logger;
-
- @Reference
- LogService logService;
-
- @Reference
- LogEventFormatter formatter;
-
- @Override
- public Object execute() throws Exception {
-
- final PrintStream out = System.out;
-
- Iterable<PaxLoggingEvent> le = logService.getEvents(entries == 0 ? Integer.MAX_VALUE : entries);
- for (PaxLoggingEvent event : le) {
- printEvent(out, event);
- }
- out.println();
- return null;
- }
-
- protected boolean checkIfFromRequestedLog(PaxLoggingEvent event) {
- return (event.getLoggerName().lastIndexOf(logger)>=0) ? true : false;
- }
-
- protected void printEvent(final PrintStream out, PaxLoggingEvent event) {
- if ((logger != null) &&
- (event != null)&&
- (checkIfFromRequestedLog(event))) {
- out.append(formatter.format(event, overridenPattern, noColor));
- }
- else if ((event != null)&&(logger == null)){
- out.append(formatter.format(event, overridenPattern, noColor));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/GetLogLevel.java b/log/command/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
deleted file mode 100644
index 83e5003..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/GetLogLevel.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.log.command;
-
-import java.util.Map;
-
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-/**
- * Get the log level
- */
-@Command(scope = "log", name = "get", description = "Shows the currently set log level.")
-@Service
-public class GetLogLevel implements Action {
-
- @Argument(index = 0, name = "logger", description = "The name of the logger, ALL or ROOT (default)", required = false, multiValued = false)
- String logger;
-
- @Option(name = "--no-format", description = "Disable table rendered output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- LogService logService;
-
- @Override
- public Object execute() throws Exception {
- Map<String, String> loggers = logService.getLevel(logger);
-
- ShellTable table = new ShellTable();
- table.column("Logger");
- table.column("Level");
-
- for (String logger : loggers.keySet()) {
- table.addRow().addContent(logger, loggers.get(logger));
- }
-
- table.print(System.out, !noFormat);
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/LogEntry.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/LogEntry.java b/log/command/src/main/java/org/apache/karaf/log/command/LogEntry.java
deleted file mode 100644
index d7c17a9..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/LogEntry.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.log.command;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-import org.osgi.service.log.LogService;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Command(scope = "log", name = "log", description = "Log a message.")
-@Service
-public class LogEntry implements Action {
-
- @Argument(index = 0, name = "message", description = "The message to log", required = true, multiValued = false)
- private String message;
-
- @Option(name = "--level", aliases = {"-l"}, description = "The level the message will be logged at", required = false, multiValued = false)
- @Completion(value = StringsCompleter.class, values = { "DEBUG", "INFO", "WARNING", "ERROR" })
- private String level = "INFO";
-
- @Reference
- LogService logService;
-
- private final Map<String,Integer> mappings = new HashMap<String,Integer>();
-
- public LogEntry() {
- mappings.put("ERROR", 1);
- mappings.put("WARNING", 2);
- mappings.put("INFO", 3);
- mappings.put("DEBUG", 4);
- }
-
- @Override
- public Object execute() throws Exception {
- logService.log(toLevel(level.toUpperCase()), message);
- return null;
- }
-
- private int toLevel(String logLevel) {
- Integer level = mappings.get(logLevel);
- if(level == null) {
- level = 3;
- }
- return level;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/LogTail.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/LogTail.java b/log/command/src/main/java/org/apache/karaf/log/command/LogTail.java
deleted file mode 100644
index bf2801e..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/LogTail.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.log.command;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.Session;
-import org.ops4j.pax.logging.spi.PaxAppender;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-@Command(scope = "log", name = "tail", description = "Continuously display log entries. Use ctrl-c to quit this command")
-@Service
-public class LogTail extends DisplayLog {
-
- @Reference
- Session session;
-
- @Reference
- LogService logService;
-
- private ExecutorService executorService = Executors.newSingleThreadExecutor();
-
- @Override
- public Object execute() throws Exception {
- PrintEventThread printThread = new PrintEventThread();
- executorService.execute(printThread);
- new Thread(new ReadKeyBoardThread(this, Thread.currentThread())).start();
- while (!Thread.currentThread().isInterrupted()) {
- try {
- Thread.sleep(200);
- } catch (java.lang.InterruptedException e) {
- break;
- }
- }
- printThread.abort();
- executorService.shutdownNow();
- return null;
- }
-
- class ReadKeyBoardThread implements Runnable {
- private LogTail logTail;
- private Thread sessionThread;
- public ReadKeyBoardThread(LogTail logtail, Thread thread) {
- this.logTail = logtail;
- this.sessionThread = thread;
- }
- public void run() {
- for (;;) {
- try {
- int c = this.logTail.session.getKeyboard().read();
- if (c < 0) {
- this.sessionThread.interrupt();
- break;
- }
- } catch (IOException e) {
- break;
- }
-
- }
- }
- }
-
- class PrintEventThread implements Runnable {
-
- PrintStream out = System.out;
- boolean doDisplay = true;
-
- public void run() {
- Iterable<PaxLoggingEvent> le = logService.getEvents(entries == 0 ? Integer.MAX_VALUE : entries);
- for (PaxLoggingEvent event : le) {
- if (event != null) {
- printEvent(out, event);
- }
- }
- // Tail
- final BlockingQueue<PaxLoggingEvent> queue = new LinkedBlockingQueue<PaxLoggingEvent>();
- PaxAppender appender = new PaxAppender() {
- public void doAppend(PaxLoggingEvent event) {
- queue.add(event);
- }
- };
- try {
- logService.addAppender(appender);
-
- while (doDisplay) {
- PaxLoggingEvent event = queue.take();
- if (event != null) {
- printEvent(out, event);
- }
- }
- } catch (InterruptedException e) {
- // Ignore
- } finally {
- logService.removeAppender(appender);
- }
- out.println();
-
- }
-
- public void abort() {
- doDisplay = false;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
----------------------------------------------------------------------
diff --git a/log/command/src/main/java/org/apache/karaf/log/command/SetLogLevel.java b/log/command/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
deleted file mode 100644
index b1145b4..0000000
--- a/log/command/src/main/java/org/apache/karaf/log/command/SetLogLevel.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.log.command;
-
-
-import org.apache.karaf.log.core.LogService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-/**
- * Set the log level for a given logger
- */
-@Command(scope = "log", name = "set", description = "Sets the log level.")
-@Service
-public class SetLogLevel implements Action {
-
- @Argument(index = 0, name = "level", description = "The log level to set (TRACE, DEBUG, INFO, WARN, ERROR) or DEFAULT to unset", required = true, multiValued = false)
- @Completion(value = StringsCompleter.class, values = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "DEFAULT" })
- String level;
-
- @Argument(index = 1, name = "logger", description = "Logger name or ROOT (default)", required = false, multiValued = false)
- String logger;
-
- @Reference
- LogService logService;
-
- @Override
- public Object execute() throws Exception {
- logService.setLevel(logger, level);
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/log/command/src/main/resources/OSGI-INF/bundle.info b/log/command/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index b7aa758..0000000
--- a/log/command/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,24 +0,0 @@
-h1. Synopsis
-
-${project.name}
-
-${project.description}
-
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-This bundle provides Karaf shell commands to manipulate the Log service.
-
-The following commands are available:
-* log:clear - Clear log entries.
-* log:display-exception - Displays the last occurred exception from the log.
-* log:display - Displays log entries.
-* log:get - Shows the currently set log level.
-* log:tail - Continuously display log entries.
-* log:set - Sets the log level.
-
-h1. See also
-
-Commands - and Logging system - sections of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/resources/OSGI-INF/metatype/metatype.properties
----------------------------------------------------------------------
diff --git a/log/command/src/main/resources/OSGI-INF/metatype/metatype.properties b/log/command/src/main/resources/OSGI-INF/metatype/metatype.properties
deleted file mode 100644
index 713283f..0000000
--- a/log/command/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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.
-#
-
-#
-# This file contains localization strings for configuration labels and
-# descriptions as used in the metatype.xml descriptor
-
-log.name = Apache Karaf Log
-log.description = Configuration of Apache Karaf Log
-
-size.name = Size
-size.description = size of the log to keep in memory
-
-pattern.name = Pattern
-pattern.description = Pattern used to display log entries
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/command/src/main/resources/OSGI-INF/metatype/metatype.xml
----------------------------------------------------------------------
diff --git a/log/command/src/main/resources/OSGI-INF/metatype/metatype.xml b/log/command/src/main/resources/OSGI-INF/metatype/metatype.xml
deleted file mode 100644
index 147cb82..0000000
--- a/log/command/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0" localization="OSGI-INF/metatype/metatype">
- <OCD id="org.apache.karaf.log" name="%log.name" description="%log.description">
- <AD id="size" type="Integer" default="500" name="%size.name"
- description="%size.description"/>
- <AD id="pattern" type="String" default="%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n" name="%pattern.name"
- description="%pattern.description"/>
- </OCD>
- <Designate pid="org.apache.karaf.log">
- <Object ocdref="org.apache.karaf.log"/>
- </Designate>
-</metatype:MetaData>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/NOTICE
----------------------------------------------------------------------
diff --git a/log/core/NOTICE b/log/core/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/log/core/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-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/7f1463c5/log/core/pom.xml
----------------------------------------------------------------------
diff --git a/log/core/pom.xml b/log/core/pom.xml
deleted file mode 100644
index 98f7637..0000000
--- a/log/core/pom.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?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.log</groupId>
- <artifactId>log</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>org.apache.karaf.log.core</artifactId>
- <packaging>bundle</packaging>
- <name>Apache Karaf :: Log :: Core</name>
- <description>Core Seervices and JMX MBean to manipulate the Karaf log layer</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.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-service</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf</groupId>
- <artifactId>org.apache.karaf.util</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <includes>
- <include>**/*</include>
- </includes>
- </resource>
- <resource>
- <directory>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>
- <Export-Package>
- org.apache.karaf.log.core
- </Export-Package>
- <Import-Package>
- *
- </Import-Package>
- <Private-Package>
- org.apache.karaf.log.core.internal,
- org.apache.karaf.log.core.internal.layout,
- org.apache.karaf.log.core.internal.osgi,
- org.apache.karaf.util.tracker
- </Private-Package>
- <Bundle-Activator>
- org.apache.karaf.log.core.internal.osgi.Activator
- </Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/Level.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/Level.java b/log/core/src/main/java/org/apache/karaf/log/core/Level.java
deleted file mode 100644
index a83396f..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/Level.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.log.core;
-
-/**
- * Enumeration of available log levels for the log:set command and
- * the command completer
- */
-public enum Level {
-
- TRACE,
- DEBUG,
- INFO,
- WARN,
- ERROR,
- DEFAULT;
-
- /**
- * Convert the list of values into a String array
- *
- * @return all the values as a String array
- */
- public static String[] strings() {
- String[] values = new String[values().length];
- for (int i = 0 ; i < values.length ; i++) {
- values[i] = values()[i].name();
- }
- return values;
- }
-
- /**
- * Check if the string value represents the default level
- *
- * @param level the level value
- * @return <code>true</code> if the value represents the {@link #DEFAULT} level
- */
- public static boolean isDefault(String level) {
- return valueOf(level).equals(DEFAULT);
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java b/log/core/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
deleted file mode 100644
index 71fe275..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/LogEventFormatter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.log.core;
-
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-public interface LogEventFormatter {
-
- public abstract String format(PaxLoggingEvent event, String overridenPattern, boolean noColor);
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/LogMBean.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/LogMBean.java b/log/core/src/main/java/org/apache/karaf/log/core/LogMBean.java
deleted file mode 100644
index ad5006f..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/LogMBean.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.log.core;
-
-import java.util.Map;
-
-/**
- * Log MBean.
- */
-public interface LogMBean {
-
- String getLevel();
- Map<String, String> getLevel(String logger);
-
- void setLevel(String level);
- void setLevel(String logger, String level);
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/LogService.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/LogService.java b/log/core/src/main/java/org/apache/karaf/log/core/LogService.java
deleted file mode 100644
index ae9f678..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/LogService.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.log.core;
-
-import org.ops4j.pax.logging.spi.PaxAppender;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-import java.util.Map;
-
-public interface LogService {
-
- String getLevel();
- void setLevel(String level);
-
- Map<String, String> getLevel(String logger);
- void setLevel(String logger, String level);
-
- void clearEvents();
- Iterable<PaxLoggingEvent> getEvents();
- Iterable<PaxLoggingEvent> getEvents(int maxNum);
- PaxLoggingEvent getLastException(String logger);
- void addAppender(PaxAppender appender);
- void removeAppender(PaxAppender appender);
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
deleted file mode 100644
index 0ba1f3e..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogEventFormatterImpl.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.log.core.internal;
-
-import org.apache.karaf.log.core.LogEventFormatter;
-import org.apache.karaf.log.core.internal.layout.PatternConverter;
-import org.apache.karaf.log.core.internal.layout.PatternParser;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-public class LogEventFormatterImpl implements LogEventFormatter {
-
- protected String pattern;
- protected String fatalColor;
- protected String errorColor;
- protected String warnColor;
- protected String infoColor;
- protected String debugColor;
- protected String traceColor;
-
- private static final String FATAL = "fatal";
- private static final String ERROR = "error";
- private static final String WARN = "warn";
- private static final String INFO = "info";
- private static final String DEBUG = "debug";
- private static final String TRACE = "trace";
-
- private static final char FIRST_ESC_CHAR = 27;
- private static final char SECOND_ESC_CHAR = '[';
- private static final char COMMAND_CHAR = 'm';
-
- public String getPattern() {
- return pattern;
- }
-
- public void setPattern(String pattern) {
- this.pattern = pattern;
- }
-
- public String getFatalColor() {
- return fatalColor;
- }
-
- public void setFatalColor(String fatalColor) {
- this.fatalColor = fatalColor;
- }
-
- public String getErrorColor() {
- return errorColor;
- }
-
- public void setErrorColor(String errorColor) {
- this.errorColor = errorColor;
- }
-
- public String getWarnColor() {
- return warnColor;
- }
-
- public void setWarnColor(String warnColor) {
- this.warnColor = warnColor;
- }
-
- public String getInfoColor() {
- return infoColor;
- }
-
- public void setInfoColor(String infoColor) {
- this.infoColor = infoColor;
- }
-
- public String getDebugColor() {
- return debugColor;
- }
-
- public void setDebugColor(String debugColor) {
- this.debugColor = debugColor;
- }
-
- public String getTraceColor() {
- return traceColor;
- }
-
- public void setTraceColor(String traceColor) {
- this.traceColor = traceColor;
- }
-
- /* (non-Javadoc)
- * @see org.apache.karaf.log.core.internal.LogEventFormatter#format(org.ops4j.pax.logging.spi.PaxLoggingEvent, java.lang.String, boolean)
- */
- @Override
- public String format(PaxLoggingEvent event, String overridenPattern, boolean noColor) {
- final PatternConverter cnv = new PatternParser(overridenPattern != null ? overridenPattern : pattern).parse();
- String color = getColor(event, noColor);
- StringBuffer sb = new StringBuffer();
- sb.setLength(0);
- if (color != null) {
- sb.append(FIRST_ESC_CHAR);
- sb.append(SECOND_ESC_CHAR);
- sb.append(color);
- sb.append(COMMAND_CHAR);
- }
- for (PatternConverter pc = cnv; pc != null; pc = pc.next) {
- pc.format(sb, event);
- }
- if (event.getThrowableStrRep() != null) {
- for (String r : event.getThrowableStrRep()) {
- sb.append(r).append('\n');
- }
- }
- if (color != null) {
- sb.append(FIRST_ESC_CHAR);
- sb.append(SECOND_ESC_CHAR);
- sb.append("0");
- sb.append(COMMAND_CHAR);
- }
- return sb.toString();
- }
-
- private String getColor(PaxLoggingEvent event, boolean noColor) {
- String color = null;
- if (!noColor && event != null && event.getLevel() != null && event.getLevel().toString() != null) {
- String lvl = event.getLevel().toString().toLowerCase();
- if (FATAL.equals(lvl)) {
- color = fatalColor;
- } else if (ERROR.equals(lvl)) {
- color = errorColor;
- } else if (WARN.equals(lvl)) {
- color = warnColor;
- } else if (INFO.equals(lvl)) {
- color = infoColor;
- } else if (DEBUG.equals(lvl)) {
- color = debugColor;
- } else if (TRACE.equals(lvl)) {
- color = traceColor;
- }
- if (color != null && color.length() == 0) {
- color = null;
- }
- }
- return color;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java
deleted file mode 100644
index 49ccbf6..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogMBeanImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.log.core.internal;
-
-import javax.management.NotCompliantMBeanException;
-import javax.management.StandardMBean;
-
-import org.apache.karaf.log.core.LogMBean;
-import org.apache.karaf.log.core.LogService;
-
-import java.util.Map;
-
-/**
- * Implementation of the LogMBean.
- */
-public class LogMBeanImpl extends StandardMBean implements LogMBean {
-
- private final LogService logService;
-
- public LogMBeanImpl(LogService logService) throws NotCompliantMBeanException {
- super(LogMBean.class);
- this.logService = logService;
- }
-
- @Override
- public String getLevel() {
- return logService.getLevel();
- }
-
- @Override
- public Map<String, String> getLevel(String logger) {
- return logService.getLevel(logger);
- }
-
- @Override
- public void setLevel(String level) {
- this.logService.setLevel(level);
- }
-
- @Override
- public void setLevel(String logger, String level) {
- this.logService.setLevel(logger, level);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
deleted file mode 100644
index 4751873..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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.log.core.internal;
-
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.karaf.log.core.Level;
-import org.apache.karaf.log.core.LogService;
-import org.ops4j.pax.logging.spi.PaxAppender;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-public class LogServiceImpl implements LogService {
-
- static final String CONFIGURATION_PID = "org.ops4j.pax.logging";
- static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger";
- static final String LOGGER_PREFIX = "log4j.logger.";
- static final String ALL_LOGGER = "ALL";
- static final String ROOT_LOGGER = "ROOT";
-
- private final ConfigurationAdmin configAdmin;
- private final LruList events;
-
- public LogServiceImpl(ConfigurationAdmin configAdmin, LruList events) {
- this.configAdmin = configAdmin;
- this.events = events;
- }
-
- public String getLevel() {
- return getLevel(null).get(ROOT_LOGGER);
- }
-
- public Map<String, String> getLevel(String logger) {
- Configuration cfg;
- try {
- cfg = configAdmin.getConfiguration(CONFIGURATION_PID, null);
- } catch (IOException e) {
- throw new RuntimeException("Error retrieving Log information from config admin", e);
- }
- @SuppressWarnings("rawtypes")
- Dictionary props = cfg.getProperties();
-
- if (ROOT_LOGGER.equalsIgnoreCase(logger)) {
- logger = null;
- }
-
- Map<String, String> loggers = new TreeMap<String, String>();
-
- if (ALL_LOGGER.equalsIgnoreCase(logger)) {
- String root = getLevelFromProperty((String) props.get(ROOT_LOGGER_PREFIX));
- loggers.put("ROOT", root);
- for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
- String prop = (String) e.nextElement();
- if (prop.startsWith(LOGGER_PREFIX)) {
- String val = getLevelFromProperty((String) props.get(prop));
- loggers.put(prop.substring(LOGGER_PREFIX.length()), val);
- }
- }
- return loggers;
- }
-
- String l = logger;
- String val;
- for (;;) {
- String prop;
- if (l == null) {
- prop = ROOT_LOGGER_PREFIX;
- } else {
- prop = LOGGER_PREFIX + l;
- }
- val = (String) props.get(prop);
- val = getLevelFromProperty(val);
- if (val != null || l == null) {
- break;
- }
- int idx = l.lastIndexOf('.');
- if (idx < 0) {
- l = null;
- } else {
- l = l.substring(0, idx);
- }
- }
-
- if (logger == null)
- logger = ROOT_LOGGER;
-
- loggers.put(logger, val);
-
- return loggers;
- }
-
- public void setLevel(String level) {
- setLevel(null, level);
- }
-
- @SuppressWarnings("unchecked")
- public void setLevel(String logger, String level) {
- if (ROOT_LOGGER.equalsIgnoreCase(logger)) {
- logger = null;
- }
-
- // make sure both uppercase and lowercase levels are supported
- level = level.toUpperCase();
-
- // check if the level is valid
- Level.valueOf(level);
-
- if (Level.isDefault(level) && logger == null) {
- throw new IllegalStateException("Can not unset the ROOT logger");
- }
-
- Configuration cfg = getConfiguration();
- Dictionary props = cfg.getProperties();
-
- String val;
- String prop;
- if (logger == null) {
- prop = ROOT_LOGGER_PREFIX;
- } else {
- prop = LOGGER_PREFIX + logger;
- }
-
- val = (String) props.get(prop);
- if (Level.isDefault(level)) {
- if (val != null) {
- val = val.trim();
- int idx = val.indexOf(",");
- if (idx < 0) {
- val = null;
- } else {
- val = val.substring(idx);
- }
- }
- } else {
- if (val == null) {
- val = level;
- } else {
- val = val.trim();
- int idx = val.indexOf(",");
- if (idx < 0) {
- val = level;
- } else {
- val = level + val.substring(idx);
- }
- }
- }
- if (val == null) {
- props.remove(prop);
- } else {
- props.put(prop, val);
- }
- try {
- cfg.update(props);
- } catch (IOException e) {
- throw new RuntimeException("Error writing log config to config admin", e);
- }
- }
-
- private boolean checkIfFromRequestedLog(PaxLoggingEvent event, String logger) {
- return (event.getLoggerName().lastIndexOf(logger) >= 0) ? true : false;
- }
-
- private String getLevelFromProperty(String prop) {
- if (prop == null) {
- return null;
- } else {
- String val = prop.trim();
- int idx = val.indexOf(",");
- if (idx == 0) {
- val = null;
- } else if (idx > 0) {
- val = val.substring(0, idx);
- }
- return val;
- }
- }
-
- private Configuration getConfiguration() {
- try {
- return configAdmin.getConfiguration(CONFIGURATION_PID, null);
- } catch (IOException e) {
- throw new RuntimeException("Error retrieving Log information from config admin", e);
- }
- }
-
- @Override
- public Iterable<PaxLoggingEvent> getEvents() {
- return events.getElements();
- }
-
- @Override
- public Iterable<PaxLoggingEvent> getEvents(int maxNum) {
- return events.getElements(maxNum);
- }
-
- @Override
- public void clearEvents() {
- events.clear();
- }
-
- @Override
- public PaxLoggingEvent getLastException(String logger) {
- PaxLoggingEvent throwableEvent = null;
- Iterable<PaxLoggingEvent> le = getEvents();
- for (PaxLoggingEvent event : le) {
- // if this is an exception, and the log is the same as the requested log,
- // then save this exception and continue iterating from oldest to newest
- if ((event.getThrowableStrRep() != null)
- &&(logger != null)
- &&(checkIfFromRequestedLog(event, logger))) {
- throwableEvent = event;
- // Do not break, as we iterate from the oldest to the newest event
- } else if ((event.getThrowableStrRep() != null)&&(logger == null)) {
- // now check if there has been no log passed in, and if this is an exception
- // then save this exception and continue iterating from oldest to newest
- throwableEvent = event;
- }
- }
-
- return throwableEvent;
- }
-
- @Override
- public void addAppender(PaxAppender appender) {
- events.addAppender(appender);
- }
-
- @Override
- public void removeAppender(PaxAppender appender) {
- events.removeAppender(appender);
- }
-
- public Level convertToLevel(String level) {
- level = level.toUpperCase();
- Level res = Level.valueOf(level);
- if (res == null) {
- throw new IllegalArgumentException("level must be set to TRACE, DEBUG, INFO, WARN or ERROR (or DEFAULT to unset it)");
- }
- return res;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/LruList.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/LruList.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/LruList.java
deleted file mode 100644
index ea51b34..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/LruList.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.log.core.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.ops4j.pax.logging.spi.PaxAppender;
-import org.ops4j.pax.logging.spi.PaxLoggingEvent;
-
-/**
- * A list that only keep the last N elements added
- */
-public class LruList implements PaxAppender {
-
- private PaxLoggingEvent[] elements;
- private transient int start = 0;
- private transient int end = 0;
- private transient boolean full = false;
- private final int maxElements;
- private final List<PaxAppender> appenders;
-
- public LruList(int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("The size must be greater than 0");
- }
- elements = new PaxLoggingEvent[size];
- maxElements = elements.length;
- appenders = new ArrayList<PaxAppender>();
- }
-
- public synchronized int size() {
- int size = 0;
- if (end < start) {
- size = maxElements - start + end;
- } else if (end == start) {
- size = (full ? maxElements : 0);
- } else {
- size = end - start;
- }
- return size;
- }
-
- public synchronized void clear() {
- start = 0;
- end = 0;
- elements = new PaxLoggingEvent[maxElements];
- }
-
- public synchronized void add(PaxLoggingEvent element) {
- if (null == element) {
- throw new NullPointerException("Attempted to add null object to buffer");
- }
- if (size() == maxElements) {
- Object e = elements[start];
- if (null != e) {
- elements[start++] = null;
- if (start >= maxElements) {
- start = 0;
- }
- full = false;
- }
- }
- elements[end++] = element;
- if (end >= maxElements) {
- end = 0;
- }
- if (end == start) {
- full = true;
- }
- for (PaxAppender appender : appenders) {
- try {
- appender.doAppend(element);
- } catch (Throwable t) {
- // Ignore
- }
- }
- }
-
- public synchronized Iterable<PaxLoggingEvent> getElements() {
- return getElements(size());
- }
-
- public synchronized Iterable<PaxLoggingEvent> getElements(int nb) {
- int s = size();
- nb = Math.min(Math.max(0, nb), s);
- PaxLoggingEvent[] e = new PaxLoggingEvent[nb];
- for (int i = 0; i < nb; i++) {
- e[i] = elements[(i + s - nb + start) % maxElements];
- }
- return Arrays.asList(e);
- }
-
- public synchronized void addAppender(PaxAppender appender) {
- this.appenders.add(appender);
- }
-
- public synchronized void removeAppender(PaxAppender appender) {
- this.appenders.remove(appender);
- }
-
- public void doAppend(PaxLoggingEvent event) {
- event.getProperties(); // ensure MDC properties are copied
- add(event);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
deleted file mode 100644
index 8bb3ff3..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/AbsoluteTimeDateFormat.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-import java.text.DateFormat;
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Copied from log4j
- */
-/**
- Formats a {@link Date} in the format "HH:mm:ss,SSS" for example,
- "15:49:37,459".
-
- @since 0.7.5
-*/
-public class AbsoluteTimeDateFormat extends DateFormat {
-
- /**
- String constant used to specify {@link
- org.apache.log4j.helpers.AbsoluteTimeDateFormat} in layouts. Current
- value is <b>ABSOLUTE</b>. */
- public final static String ABS_TIME_DATE_FORMAT = "ABSOLUTE";
-
- /**
- String constant used to specify {@link
- org.apache.log4j.helpers.DateTimeDateFormat} in layouts. Current
- value is <b>DATE</b>.
- */
- public final static String DATE_AND_TIME_DATE_FORMAT = "DATE";
-
- /**
- String constant used to specify {@link
- org.apache.log4j.helpers.ISO8601DateFormat} in layouts. Current
- value is <b>ISO8601</b>.
- */
- public final static String ISO8601_DATE_FORMAT = "ISO8601";
-
- public
- AbsoluteTimeDateFormat() {
- setCalendar(Calendar.getInstance());
- }
-
- public
- AbsoluteTimeDateFormat(TimeZone timeZone) {
- setCalendar(Calendar.getInstance(timeZone));
- }
-
- private static long previousTime;
- private static char[] previousTimeWithoutMillis = new char[9]; // "HH:mm:ss."
-
- /**
- Appends to <code>sbuf</code> the time in the format
- "HH:mm:ss,SSS" for example, "15:49:37,459"
-
- @param date the date to format
- @param sbuf the string buffer to write to
- @param fieldPosition remains untouched
- */
- public
- StringBuffer format(Date date, StringBuffer sbuf,
- FieldPosition fieldPosition) {
-
- long now = date.getTime();
- int millis = (int)(now % 1000);
-
- if ((now - millis) != previousTime) {
- // We reach this point at most once per second
- // across all threads instead of each time format()
- // is called. This saves considerable CPU time.
-
- calendar.setTime(date);
-
- int start = sbuf.length();
-
- int hour = calendar.get(Calendar.HOUR_OF_DAY);
- if(hour < 10) {
- sbuf.append('0');
- }
- sbuf.append(hour);
- sbuf.append(':');
-
- int mins = calendar.get(Calendar.MINUTE);
- if(mins < 10) {
- sbuf.append('0');
- }
- sbuf.append(mins);
- sbuf.append(':');
-
- int secs = calendar.get(Calendar.SECOND);
- if(secs < 10) {
- sbuf.append('0');
- }
- sbuf.append(secs);
- sbuf.append(',');
-
- // store the time string for next time to avoid recomputation
- sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0);
-
- previousTime = now - millis;
- }
- else {
- sbuf.append(previousTimeWithoutMillis);
- }
-
-
-
- if(millis < 100)
- sbuf.append('0');
- if(millis < 10)
- sbuf.append('0');
-
- sbuf.append(millis);
- return sbuf;
- }
-
- /**
- This method does not do anything but return <code>null</code>.
- */
- public
- Date parse(String s, ParsePosition pos) {
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
deleted file mode 100644
index 1aa884d..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/DateTimeDateFormat.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-import java.text.DateFormatSymbols;
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Copied from log4j
- */
-/**
- Formats a {@link Date} in the format "dd MMM yyyy HH:mm:ss,SSS" for example,
- "06 Nov 1994 15:49:37,459".
-
- @since 0.7.5
-*/
-public class DateTimeDateFormat extends AbsoluteTimeDateFormat {
-
- String[] shortMonths;
-
- public
- DateTimeDateFormat() {
- super();
- shortMonths = new DateFormatSymbols().getShortMonths();
- }
-
- public
- DateTimeDateFormat(TimeZone timeZone) {
- this();
- setCalendar(Calendar.getInstance(timeZone));
- }
-
- /**
- Appends to <code>sbuf</code> the date in the format "dd MMM yyyy
- HH:mm:ss,SSS" for example, "06 Nov 1994 08:49:37,459".
-
- @param sbuf the string buffer to write to
- */
- public
- StringBuffer format(Date date, StringBuffer sbuf,
- FieldPosition fieldPosition) {
-
- calendar.setTime(date);
-
- int day = calendar.get(Calendar.DAY_OF_MONTH);
- if(day < 10)
- sbuf.append('0');
- sbuf.append(day);
- sbuf.append(' ');
- sbuf.append(shortMonths[calendar.get(Calendar.MONTH)]);
- sbuf.append(' ');
-
- int year = calendar.get(Calendar.YEAR);
- sbuf.append(year);
- sbuf.append(' ');
-
- return super.format(date, sbuf, fieldPosition);
- }
-
- /**
- This method does not do anything but return <code>null</code>.
- */
- public
- Date parse(java.lang.String s, ParsePosition pos) {
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7f1463c5/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
----------------------------------------------------------------------
diff --git a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java b/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
deleted file mode 100644
index 6fd728f..0000000
--- a/log/core/src/main/java/org/apache/karaf/log/core/internal/layout/FormattingInfo.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.log.core.internal.layout;
-
-
-/**
- * Copied from log4j
- */
-/**
- FormattingInfo instances contain the information obtained when parsing
- formatting modifiers in conversion modifiers.
-
- @since 0.8.2
- */
-public class FormattingInfo {
- int min = -1;
- int max = 0x7FFFFFFF;
- boolean leftAlign = false;
-
- void reset() {
- min = -1;
- max = 0x7FFFFFFF;
- leftAlign = false;
- }
-
- void dump() {
- //LogLog.debug("min="+min+", max="+max+", leftAlign="+leftAlign);
- }
-}
-