Yes, you're right. At some point, it may makes sense to extract some classes from the gshell-features module and share them, but given the fact that the current features bundle requires gshell-core (hence a bunch of other bundles), it looks easier this way.
On Thu, Mar 12, 2009 at 09:52, Freeman Fang <[email protected]> wrote: > Hi Guillaume, > > Besides the felix preference service, to install gshell-features bundle, I > also need install bundles like > getBundle("com.google.code.sshd", "sshd"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.commons-vfs"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.commons-jexl"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.commons-httpclient"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.mina"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.oro"), > getBundle("org.apache.servicemix.bundles", > "org.apache.servicemix.bundles.jline"), > getBundle("org.apache.servicemix.kernel", > "org.apache.servicemix.kernel.filemonitor"), > getBundle("org.apache.servicemix.kernel.gshell", > "org.apache.servicemix.kernel.gshell.core"), > to overcome the "Unresolved constraint in bundle xx" exception. > But with more bundles involved, seems I aslo need set properties for > placeholders in the bundles spring dm configuration. > The gshell-features bundle import package > org.apache.geronimo.gshell.wisdom.command, which provided by gshell-core, > and so lots of other bundles gshell-core needed get involved. > For me, to install gshell-features bundle I almost need start the whole SMX > kernel. > Do I miss something? > Thanks > Freeman > > > Guillaume Nodet wrote: > >> What are the other bundles needed ? Maybe the felix preference service, >> is >> there any other needed ? >> >> On Thu, Mar 12, 2009 at 08:29, Freeman Fang <[email protected]> >> wrote: >> >> >> >>> Hi, >>> >>> I've tried your suggestion first, but it also means we need install >>> several >>> other bundles, which I though too heavy for the test framework. >>> It's kind of trade off, for me, I prefer to as least as possible bundles >>> needed for the test framework. >>> What dou you think? >>> >>> Freeman >>> >>> >>> Guillaume Nodet wrote: >>> >>> >>> >>>> I'm not very keen on having a lot of duplicated classes and logic. >>>> Wouldn't >>>> it be simpler to just install the gshell-features bundle and call the >>>> FeaturesService instead ? >>>> >>>> On Thu, Mar 12, 2009 at 08:30, <[email protected]> wrote: >>>> >>>> >>>> >>>> >>>> >>>>> Author: ffang >>>>> Date: Thu Mar 12 07:30:22 2009 >>>>> New Revision: 752790 >>>>> >>>>> URL: http://svn.apache.org/viewvc?rev=752790&view=rev >>>>> Log: >>>>> [SMX4KNL-213]Improve testing framework to support easily installation >>>>> of >>>>> features >>>>> >>>>> Added: >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/ >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> (with props) >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> (with props) >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> (with props) >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> (with props) >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> (with props) >>>>> Modified: >>>>> servicemix/smx4/kernel/trunk/gshell/itests/pom.xml >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/java/org/apache/servicemix/kernel/gshell/itests/CoreTest.java >>>>> servicemix/smx4/kernel/trunk/testing/support/pom.xml >>>>> >>>>> >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/AbstractIntegrationTest.java >>>>> >>>>> Modified: servicemix/smx4/kernel/trunk/gshell/itests/pom.xml >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/itests/pom.xml?rev=752790&r1=752789&r2=752790&view=diff >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- servicemix/smx4/kernel/trunk/gshell/itests/pom.xml (original) >>>>> +++ servicemix/smx4/kernel/trunk/gshell/itests/pom.xml Thu Mar 12 >>>>> 07:30:22 >>>>> 2009 >>>>> @@ -72,6 +72,27 @@ >>>>> >>>>> <build> >>>>> <plugins> >>>>> + <plugin> >>>>> + <artifactId>maven-resources-plugin</artifactId> >>>>> + <executions> >>>>> + <execution> >>>>> + <id>copy-resources</id> >>>>> + <phase>validate</phase> >>>>> + <goals> >>>>> + <goal>copy-resources</goal> >>>>> + </goals> >>>>> + <configuration> >>>>> + >>>>> <outputDirectory>${pom.basedir}/target/test-classes/</outputDirectory> >>>>> + <resources> >>>>> + <resource> >>>>> + >>>>> <directory>${pom.basedir}/src/test/filtered-resources</directory> >>>>> + <filtering>true</filtering> >>>>> + </resource> >>>>> + </resources> >>>>> + </configuration> >>>>> + </execution> >>>>> + </executions> >>>>> + </plugin> >>>>> <!-- generate dependencies versions --> >>>>> <plugin> >>>>> <groupId>org.apache.servicemix.tooling</groupId> >>>>> @@ -109,4 +130,4 @@ >>>>> </profile> >>>>> </profiles> >>>>> >>>>> -</project> >>>>> \ No newline at end of file >>>>> +</project> >>>>> >>>>> Added: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml?rev=752790&view=auto >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> (added) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -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> >>>>> + <feature name="wrapper" version="${version}"> >>>>> + >>>>> >>>>> >>>>> >>>>> <bundle>mvn:org.apache.servicemix.kernel.gshell/org.apache.servicemix.kernel.gshell.wrapper/${version}</bundle> >>>>> + </feature> >>>>> + <feature name="obr" version="${version}"> >>>>> + >>>>> >>>>> >>>>> >>>>> <bundle>mvn:org.apache.felix/org.apache.felix.bundlerepository/${felix.bundlerepository.version}</bundle> >>>>> + >>>>> >>>>> >>>>> >>>>> <bundle>mvn:org.apache.servicemix.kernel.gshell/org.apache.servicemix.kernel.gshell.obr/${version}</bundle> >>>>> + </feature> >>>>> +</features> >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:eol-style = native >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:keywords = Rev Date >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/filtered-resources/features.xml >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:mime-type = text/xml >>>>> >>>>> Modified: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/java/org/apache/servicemix/kernel/gshell/itests/CoreTest.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/itests/src/test/java/org/apache/servicemix/kernel/gshell/itests/CoreTest.java?rev=752790&r1=752789&r2=752790&view=diff >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/java/org/apache/servicemix/kernel/gshell/itests/CoreTest.java >>>>> (original) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/gshell/itests/src/test/java/org/apache/servicemix/kernel/gshell/itests/CoreTest.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -87,6 +87,31 @@ >>>>> shell.execute("help"); >>>>> shell.execute(".."); >>>>> } >>>>> + >>>>> + public void testInstallFeature() throws Exception { >>>>> + Shell shell = getOsgiService(Shell.class); >>>>> + >>>>> + try { >>>>> + shell.execute("obr"); >>>>> + fail("command should not exist"); >>>>> + } catch (CommandLineExecutionFailed e) { >>>>> + assertNotNull(e.getCause()); >>>>> + assertTrue(e.getCause() instanceof >>>>> NoSuchCommandException); >>>>> + } >>>>> + try { >>>>> + shell.execute("wrapper"); >>>>> + fail("command should not exist"); >>>>> + } catch (CommandLineExecutionFailed e) { >>>>> + assertNotNull(e.getCause()); >>>>> + assertTrue(e.getCause() instanceof >>>>> NoSuchCommandException); >>>>> + } >>>>> + String url = >>>>> getClass().getClassLoader().getResource("features.xml").toString(); >>>>> + addFeatureRepo(url); >>>>> + installFeature("obr"); >>>>> + installFeature("wrapper"); >>>>> + shell.execute("obr"); >>>>> + shell.execute("wrapper"); >>>>> + } >>>>> >>>>> /** >>>>> * TODO: This test seems to fail, there must be a timing issue >>>>> somewhere >>>>> >>>>> Modified: servicemix/smx4/kernel/trunk/testing/support/pom.xml >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/pom.xml?rev=752790&r1=752789&r2=752790&view=diff >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- servicemix/smx4/kernel/trunk/testing/support/pom.xml (original) >>>>> +++ servicemix/smx4/kernel/trunk/testing/support/pom.xml Thu Mar 12 >>>>> 07:30:22 2009 >>>>> @@ -94,6 +94,10 @@ >>>>> <groupId>org.apache.servicemix.bundles</groupId> >>>>> >>>>> <artifactId>org.apache.servicemix.bundles.jaxp-ri</artifactId> >>>>> </dependency> >>>>> + <dependency> >>>>> + <groupId>org.ops4j.pax.url</groupId> >>>>> + <artifactId>pax-url-mvn</artifactId> >>>>> + </dependency> >>>>> </dependencies> >>>>> >>>>> <build> >>>>> >>>>> Modified: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/AbstractIntegrationTest.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/AbstractIntegrationTest.java?rev=752790&r1=752789&r2=752790&view=diff >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/AbstractIntegrationTest.java >>>>> (original) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/AbstractIntegrationTest.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -19,6 +19,7 @@ >>>>> import java.io.File; >>>>> import java.io.FileInputStream; >>>>> import java.io.IOException; >>>>> +import java.net.URI; >>>>> import java.util.ArrayList; >>>>> import java.util.List; >>>>> import java.util.Properties; >>>>> @@ -36,6 +37,7 @@ >>>>> import org.springframework.util.Assert; >>>>> import org.springframework.util.StringUtils; >>>>> >>>>> + >>>>> public class AbstractIntegrationTest extends >>>>> AbstractConfigurableBundleCreatorTests { >>>>> >>>>> static { >>>>> @@ -55,6 +57,7 @@ >>>>> } >>>>> >>>>> private Properties dependencies; >>>>> + private FeatureInstaller featureInstaller; >>>>> >>>>> @Override >>>>> protected String getPlatformName() { >>>>> @@ -109,8 +112,9 @@ >>>>> getBundle("org.springframework.osgi", >>>>> "spring-osgi-extender"), >>>>> getBundle("org.springframework.osgi", "spring-osgi-test"), >>>>> getBundle("org.springframework.osgi", >>>>> "spring-osgi-annotation"), >>>>> + getBundle("org.ops4j.pax.url", "pax-url-mvn"), >>>>> getBundle("org.apache.servicemix.kernel.testing", >>>>> "org.apache.servicemix.kernel.testing.support"), >>>>> - }; >>>>> + }; >>>>> } >>>>> >>>>> protected Bundle installBundle(String groupId, String artifactId, >>>>> String classifier, String type) throws Exception { >>>>> @@ -120,7 +124,28 @@ >>>>> bundle.start(); >>>>> return bundle; >>>>> } >>>>> + >>>>> + protected void addFeatureRepo(String url) throws Exception { >>>>> + if (featureInstaller == null) { >>>>> + featureInstaller = new FeatureInstaller(); >>>>> + featureInstaller.setBundleContext(bundleContext); >>>>> + } >>>>> + featureInstaller.addRepository(new URI(url)); >>>>> + } >>>>> + >>>>> + protected void installFeature(String name) throws Exception { >>>>> + installFeature(name, FeatureImpl.DEFAULT_VERSION); >>>>> + } >>>>> >>>>> + protected void installFeature(String name, String version) throws >>>>> Exception { >>>>> + if (featureInstaller == null) { >>>>> + featureInstaller = new FeatureInstaller(); >>>>> + featureInstaller.setBundleContext(bundleContext); >>>>> + >>>>> + } >>>>> + featureInstaller.installFeature(name, version); >>>>> + } >>>>> + >>>>> protected Resource locateBundle(String bundleId) { >>>>> Assert.hasText(bundleId, "bundleId should not be empty"); >>>>> >>>>> >>>>> Added: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java?rev=752790&view=auto >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> (added) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -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.servicemix.kernel.testing.support; >>>>> + >>>>> +import java.util.List; >>>>> +import java.util.Map; >>>>> + >>>>> +/** >>>>> + * A feature is a list of bundles associated identified by its name. >>>>> + */ >>>>> +public interface Feature { >>>>> + >>>>> + String getId(); >>>>> + >>>>> + String getName(); >>>>> + >>>>> + String getVersion(); >>>>> + >>>>> + List<Feature> getDependencies(); >>>>> + >>>>> + List<String> getBundles(); >>>>> + >>>>> + Map<String, Map<String, String>> getConfigurations(); >>>>> + >>>>> + void addDependency(Feature dependency); >>>>> + >>>>> + void addBundle(String bundle); >>>>> + >>>>> + void addConfig(String name, Map<String,String> properties); >>>>> + >>>>> +} >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:eol-style = native >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/Feature.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:keywords = Rev Date >>>>> >>>>> Added: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java?rev=752790&view=auto >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> (added) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -0,0 +1,125 @@ >>>>> +/* >>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more >>>>> + * contributor license agreements. See the NOTICE file distributed >>>>> with >>>>> + * this work for additional information regarding copyright ownership. >>>>> + * The ASF licenses this file to You under the Apache License, Version >>>>> 2.0 >>>>> + * (the "License"); you may not use this file except in compliance >>>>> with >>>>> + * the License. You may obtain a copy of the License at >>>>> + * >>>>> + * http://www.apache.org/licenses/LICENSE-2.0 >>>>> + * >>>>> + * Unless required by applicable law or agreed to in writing, software >>>>> + * distributed under the License is distributed on an "AS IS" BASIS, >>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>>> implied. >>>>> + * See the License for the specific language governing permissions and >>>>> + * limitations under the License. >>>>> + */ >>>>> +package org.apache.servicemix.kernel.testing.support; >>>>> + >>>>> +import java.util.ArrayList; >>>>> +import java.util.HashMap; >>>>> +import java.util.List; >>>>> +import java.util.Map; >>>>> + >>>>> + >>>>> +public class FeatureImpl implements Feature { >>>>> + >>>>> + private String id; >>>>> + private String name; >>>>> + private String version; >>>>> + private List<Feature> dependencies = new ArrayList<Feature>(); >>>>> + private List<String> bundles = new ArrayList<String>(); >>>>> + private Map<String, Map<String,String>> configs = new >>>>> HashMap<String, >>>>> Map<String,String>>(); >>>>> + public static String SPLIT_FOR_NAME_AND_VERSION = >>>>> "_split_for_name_and_version_"; >>>>> + public static String DEFAULT_VERSION = "0.0.0"; >>>>> + >>>>> + public FeatureImpl(String name) { >>>>> + this(name, DEFAULT_VERSION); >>>>> + } >>>>> + >>>>> + public FeatureImpl(String name, String version) { >>>>> + this.name = name; >>>>> + this.version = version; >>>>> + this.id = name + "-" + version; >>>>> + } >>>>> + >>>>> + >>>>> + public String getId() { >>>>> + return id; >>>>> + } >>>>> + >>>>> + >>>>> + public String getName() { >>>>> + return name; >>>>> + } >>>>> + >>>>> + >>>>> + public String getVersion() { >>>>> + return version; >>>>> + } >>>>> + >>>>> + public void setVersion(String version) { >>>>> + this.version = version; >>>>> + } >>>>> + >>>>> + >>>>> + public List<Feature> getDependencies() { >>>>> + return dependencies; >>>>> + } >>>>> + >>>>> + public List<String> getBundles() { >>>>> + return bundles; >>>>> + } >>>>> + >>>>> + public Map<String, Map<String, String>> getConfigurations() { >>>>> + return configs; >>>>> + } >>>>> + >>>>> + public void addDependency(Feature dependency) { >>>>> + dependencies.add(dependency); >>>>> + } >>>>> + >>>>> + public void addBundle(String bundle) { >>>>> + bundles.add(bundle); >>>>> + } >>>>> + >>>>> + public void addConfig(String name, Map<String,String> properties) >>>>> { >>>>> + configs.put(name, properties); >>>>> + } >>>>> + >>>>> + public String toString() { >>>>> + String ret = getName() + SPLIT_FOR_NAME_AND_VERSION + >>>>> getVersion(); >>>>> + return ret; >>>>> + } >>>>> + >>>>> + public static Feature valueOf(String str) { >>>>> + if (str.indexOf(SPLIT_FOR_NAME_AND_VERSION) >= 0) { >>>>> + 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 FeatureImpl(strName, strVersion); >>>>> + } else { >>>>> + return new FeatureImpl(str); >>>>> + } >>>>> + >>>>> + >>>>> + } >>>>> + >>>>> + public boolean equals(Object o) { >>>>> + if (this == o) return true; >>>>> + if (o == null || getClass() != o.getClass()) return false; >>>>> + >>>>> + FeatureImpl feature = (FeatureImpl) o; >>>>> + >>>>> + if (!name.equals(feature.name)) return false; >>>>> + if (!version.equals(feature.version)) return false; >>>>> + >>>>> + return true; >>>>> + } >>>>> + >>>>> + public int hashCode() { >>>>> + int result = name.hashCode(); >>>>> + result = 31 * result + version.hashCode(); >>>>> + return result; >>>>> + } >>>>> +} >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:eol-style = native >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureImpl.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:keywords = Rev Date >>>>> >>>>> Added: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java?rev=752790&view=auto >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> (added) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -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.servicemix.kernel.testing.support; >>>>> + >>>>> +import java.io.BufferedInputStream; >>>>> +import java.io.IOException; >>>>> +import java.io.InputStream; >>>>> +import java.net.URI; >>>>> +import java.net.URL; >>>>> +import java.util.Collection; >>>>> +import java.util.HashMap; >>>>> +import java.util.HashSet; >>>>> +import java.util.Map; >>>>> +import java.util.Set; >>>>> +import java.util.jar.JarInputStream; >>>>> +import java.util.jar.Manifest; >>>>> +import java.util.regex.Matcher; >>>>> +import java.util.regex.Pattern; >>>>> + >>>>> + >>>>> + >>>>> +import org.osgi.framework.Bundle; >>>>> +import org.osgi.framework.BundleContext; >>>>> +import org.osgi.framework.BundleException; >>>>> +import org.osgi.framework.Constants; >>>>> +import org.osgi.framework.Version; >>>>> + >>>>> + >>>>> +public class FeatureInstaller { >>>>> + >>>>> + private Map<URI, FeatureRepositoryImpl> repositories = new >>>>> HashMap<URI, FeatureRepositoryImpl>(); >>>>> + private Map<String, Map<String, Feature>> features; >>>>> + private BundleContext bundleContext; >>>>> + >>>>> + public void addRepository(URI uri) throws Exception { >>>>> + if (!repositories.values().contains(uri)) { >>>>> + internalAddRepository(uri); >>>>> + } >>>>> + } >>>>> + >>>>> + protected FeatureRepositoryImpl internalAddRepository(URI uri) >>>>> throws >>>>> Exception { >>>>> + FeatureRepositoryImpl repo = new FeatureRepositoryImpl(uri); >>>>> + repositories.put(uri, repo); >>>>> + features = null; >>>>> + return repo; >>>>> + } >>>>> + >>>>> + public void setBundleContext(BundleContext bundleContext) { >>>>> + this.bundleContext = bundleContext; >>>>> + } >>>>> + >>>>> + >>>>> + public void installFeature(String name, String version) throws >>>>> Exception { >>>>> + Feature f = getFeature(name, version); >>>>> + if (f == null) { >>>>> + throw new Exception("No feature named '" + name >>>>> + + "' with version '" + version + "' available"); >>>>> + } >>>>> + for (Feature dependency : f.getDependencies()) { >>>>> + installFeature(dependency.getName(), >>>>> dependency.getVersion()); >>>>> + } >>>>> + >>>>> + Set<Long> bundles = new HashSet<Long>(); >>>>> + for (String bundleLocation : f.getBundles()) { >>>>> + Bundle b = installBundleIfNeeded(bundleLocation); >>>>> + bundles.add(b.getBundleId()); >>>>> + } >>>>> + for (long id : bundles) { >>>>> + bundleContext.getBundle(id).start(); >>>>> + } >>>>> + >>>>> + >>>>> + } >>>>> + >>>>> + protected Feature getFeature(String name, String version) throws >>>>> Exception { >>>>> + Map<String, Feature> versions = getFeatures().get(name); >>>>> + if (versions == null || versions.isEmpty()) { >>>>> + return null; >>>>> + } else { >>>>> + Feature feature = versions.get(version); >>>>> + if (feature == null && >>>>> FeatureImpl.DEFAULT_VERSION.equals(version)) { >>>>> + Version latest = new Version(cleanupVersion(version)); >>>>> + for (String available : versions.keySet()) { >>>>> + Version availableVersion = new >>>>> Version(cleanupVersion(available)); >>>>> + if (availableVersion.compareTo(latest) > 0) { >>>>> + feature = versions.get(available); >>>>> + latest = availableVersion; >>>>> + } >>>>> + } >>>>> + } >>>>> + return feature; >>>>> + } >>>>> + } >>>>> + >>>>> + protected Map<String, Map<String, Feature>> getFeatures() throws >>>>> Exception { >>>>> + if (features == null) { >>>>> + //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 >>>>> + for (;;) { >>>>> + boolean newRepo = false; >>>>> + for (FeatureRepositoryImpl repo : listRepositories()) >>>>> { >>>>> + for (URI uri : repo.getRepositories()) { >>>>> + if (!repositories.keySet().contains(uri)) { >>>>> + internalAddRepository(uri); >>>>> + newRepo = true; >>>>> + } >>>>> + } >>>>> + } >>>>> + if (!newRepo) { >>>>> + break; >>>>> + } >>>>> + } >>>>> + // * then load all features >>>>> + for (FeatureRepositoryImpl repo : repositories.values()) { >>>>> + 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); >>>>> + } >>>>> + } >>>>> + } >>>>> + features = map; >>>>> + } >>>>> + return features; >>>>> + } >>>>> + >>>>> + public FeatureRepositoryImpl[] listRepositories() { >>>>> + Collection<FeatureRepositoryImpl> repos = >>>>> repositories.values(); >>>>> + return repos.toArray(new FeatureRepositoryImpl[repos.size()]); >>>>> + } >>>>> + >>>>> + protected Bundle installBundleIfNeeded(String bundleLocation) >>>>> throws >>>>> IOException, BundleException { >>>>> + InputStream is = new BufferedInputStream(new >>>>> URL(bundleLocation).openStream()); >>>>> + try { >>>>> + is.mark(256 * 1024); >>>>> + JarInputStream jar = new JarInputStream(is); >>>>> + Manifest m = jar.getManifest(); >>>>> + String sn = >>>>> m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME); >>>>> + String vStr = >>>>> m.getMainAttributes().getValue(Constants.BUNDLE_VERSION); >>>>> + Version v = vStr == null ? Version.emptyVersion : >>>>> Version.parseVersion(vStr); >>>>> + for (Bundle b : bundleContext.getBundles()) { >>>>> + if (b.getSymbolicName() != null && >>>>> b.getSymbolicName().equals(sn)) { >>>>> + vStr = (String) >>>>> b.getHeaders().get(Constants.BUNDLE_VERSION); >>>>> + Version bv = vStr == null ? Version.emptyVersion : >>>>> Version.parseVersion(vStr); >>>>> + if (v.equals(bv)) { >>>>> + return b; >>>>> + } >>>>> + } >>>>> + } >>>>> + try { >>>>> + is.reset(); >>>>> + } catch (IOException e) { >>>>> + is.close(); >>>>> + is = new BufferedInputStream(new >>>>> URL(bundleLocation).openStream()); >>>>> + } >>>>> + return getBundleContext().installBundle(bundleLocation, >>>>> is); >>>>> + } finally { >>>>> + is.close(); >>>>> + } >>>>> + } >>>>> + >>>>> + private BundleContext getBundleContext() { >>>>> + return this.bundleContext; >>>>> + } >>>>> + >>>>> + /** >>>>> + * Clean up version parameters. Other builders use more fuzzy >>>>> definitions of >>>>> + * the version syntax. This method cleans up such a version to >>>>> match >>>>> an OSGi >>>>> + * version. >>>>> + * >>>>> + * @param version >>>>> + * @return >>>>> + */ >>>>> + static Pattern fuzzyVersion = >>>>> Pattern.compile("(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?", >>>>> + Pattern.DOTALL); >>>>> + static Pattern fuzzyModifier = Pattern.compile("(\\d+[.-])*(.*)", >>>>> + Pattern.DOTALL); >>>>> + static public String cleanupVersion(String version) { >>>>> + Matcher m = fuzzyVersion.matcher(version); >>>>> + if (m.matches()) { >>>>> + StringBuffer result = new StringBuffer(); >>>>> + String d1 = m.group(1); >>>>> + String d2 = m.group(3); >>>>> + String d3 = m.group(5); >>>>> + String qualifier = m.group(7); >>>>> + >>>>> + if (d1 != null) { >>>>> + result.append(d1); >>>>> + if (d2 != null) { >>>>> + result.append("."); >>>>> + result.append(d2); >>>>> + if (d3 != null) { >>>>> + result.append("."); >>>>> + result.append(d3); >>>>> + if (qualifier != null) { >>>>> + result.append("."); >>>>> + cleanupModifier(result, qualifier); >>>>> + } >>>>> + } else if (qualifier != null) { >>>>> + result.append(".0."); >>>>> + cleanupModifier(result, qualifier); >>>>> + } >>>>> + } else if (qualifier != null) { >>>>> + result.append(".0.0."); >>>>> + cleanupModifier(result, qualifier); >>>>> + } >>>>> + return result.toString(); >>>>> + } >>>>> + } >>>>> + return version; >>>>> + } >>>>> + >>>>> + static void cleanupModifier(StringBuffer result, String modifier) >>>>> { >>>>> + Matcher m = fuzzyModifier.matcher(modifier); >>>>> + if (m.matches()) >>>>> + modifier = m.group(2); >>>>> + >>>>> + for (int i = 0; i < modifier.length(); i++) { >>>>> + char c = modifier.charAt(i); >>>>> + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') >>>>> + || (c >= 'A' && c <= 'Z') || c == '_' || c == '-') >>>>> + result.append(c); >>>>> + } >>>>> + } >>>>> + >>>>> +} >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:eol-style = native >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureInstaller.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:keywords = Rev Date >>>>> >>>>> Added: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> URL: >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java?rev=752790&view=auto >>>>> >>>>> >>>>> >>>>> ============================================================================== >>>>> --- >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> (added) >>>>> +++ >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> Thu Mar 12 07:30:22 2009 >>>>> @@ -0,0 +1,139 @@ >>>>> +/* >>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more >>>>> + * contributor license agreements. See the NOTICE file distributed >>>>> with >>>>> + * this work for additional information regarding copyright ownership. >>>>> + * The ASF licenses this file to You under the Apache License, Version >>>>> 2.0 >>>>> + * (the "License"); you may not use this file except in compliance >>>>> with >>>>> + * the License. You may obtain a copy of the License at >>>>> + * >>>>> + * http://www.apache.org/licenses/LICENSE-2.0 >>>>> + * >>>>> + * Unless required by applicable law or agreed to in writing, software >>>>> + * distributed under the License is distributed on an "AS IS" BASIS, >>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>>> implied. >>>>> + * See the License for the specific language governing permissions and >>>>> + * limitations under the License. >>>>> + */ >>>>> +package org.apache.servicemix.kernel.testing.support; >>>>> +import java.io.ByteArrayInputStream; >>>>> +import java.io.IOException; >>>>> +import java.net.URI; >>>>> +import java.net.URISyntaxException; >>>>> +import java.util.ArrayList; >>>>> +import java.util.Hashtable; >>>>> +import java.util.List; >>>>> +import java.util.Map; >>>>> +import java.util.Properties; >>>>> + >>>>> +import javax.xml.parsers.DocumentBuilderFactory; >>>>> +import javax.xml.parsers.ParserConfigurationException; >>>>> + >>>>> +import org.w3c.dom.Document; >>>>> +import org.w3c.dom.Element; >>>>> +import org.w3c.dom.Node; >>>>> +import org.w3c.dom.NodeList; >>>>> +import org.xml.sax.SAXException; >>>>> + >>>>> + >>>>> + >>>>> +/** >>>>> + * The repository implementation. >>>>> + */ >>>>> + >>>>> +public class FeatureRepositoryImpl { >>>>> + >>>>> + private URI uri; >>>>> + private List<Feature> features; >>>>> + private List<URI> repositories; >>>>> + >>>>> + public FeatureRepositoryImpl(URI uri) { >>>>> + this.uri = uri; >>>>> + } >>>>> + >>>>> + >>>>> + public URI getURI() { >>>>> + return uri; >>>>> + } >>>>> + >>>>> + public URI[] getRepositories() throws Exception { >>>>> + if (repositories == null) { >>>>> + load(); >>>>> + } >>>>> + return repositories.toArray(new URI[repositories.size()]); >>>>> + } >>>>> + >>>>> + public Feature[] getFeatures() throws Exception { >>>>> + if (features == null) { >>>>> + load(); >>>>> + } >>>>> + return features.toArray(new Feature[features.size()]); >>>>> + } >>>>> + >>>>> + public void load() throws IOException { >>>>> + try { >>>>> + repositories = new ArrayList<URI>(); >>>>> + features = new ArrayList<Feature>(); >>>>> + DocumentBuilderFactory factory = >>>>> DocumentBuilderFactory.newInstance(); >>>>> + Document doc = >>>>> factory.newDocumentBuilder().parse(uri.toURL().openStream()); >>>>> + NodeList nodes = doc.getDocumentElement().getChildNodes(); >>>>> + for (int i = 0; i < nodes.getLength(); i++) { >>>>> + Node node = nodes.item(i); >>>>> + if (!(node instanceof Element)) { >>>>> + continue; >>>>> + } >>>>> + if ("repository".equals(node.getNodeName())) { >>>>> + Element e = (Element) nodes.item(i); >>>>> + repositories.add(new URI(e.getTextContent())); >>>>> + } else if ("feature".equals(node.getNodeName())) { >>>>> + Element e = (Element) nodes.item(i); >>>>> + String name = e.getAttribute("name"); >>>>> + String version = e.getAttribute("version"); >>>>> + Feature f; >>>>> + if (version != null && version.length() > 0) { >>>>> + f = new FeatureImpl(name, version); >>>>> + } else { >>>>> + f = new FeatureImpl(name); >>>>> + } >>>>> + >>>>> + NodeList featureNodes = >>>>> e.getElementsByTagName("feature"); >>>>> + for (int j = 0; j < featureNodes.getLength(); j++) >>>>> { >>>>> + Element b = (Element) featureNodes.item(j); >>>>> + String dependencyFeatureVersion = >>>>> b.getAttribute("version"); >>>>> + if (dependencyFeatureVersion != null && >>>>> dependencyFeatureVersion.length() > 0) { >>>>> + f.addDependency(new >>>>> FeatureImpl(b.getTextContent(), dependencyFeatureVersion)); >>>>> + } else { >>>>> + f.addDependency(new >>>>> FeatureImpl(b.getTextContent())); >>>>> + } >>>>> + } >>>>> + NodeList configNodes = >>>>> e.getElementsByTagName("config"); >>>>> + for (int j = 0; j < configNodes.getLength(); j++) >>>>> { >>>>> + Element c = (Element) configNodes.item(j); >>>>> + String cfgName = c.getAttribute("name"); >>>>> + String data = c.getTextContent(); >>>>> + Properties properties = new Properties(); >>>>> + properties.load(new >>>>> ByteArrayInputStream(data.getBytes())); >>>>> + Map<String, String> hashtable = new >>>>> Hashtable<String, String>(); >>>>> + for (Object key : properties.keySet()) { >>>>> + String n = key.toString(); >>>>> + hashtable.put(n, >>>>> properties.getProperty(n)); >>>>> + } >>>>> + f.addConfig(cfgName, hashtable); >>>>> + } >>>>> + NodeList bundleNodes = >>>>> e.getElementsByTagName("bundle"); >>>>> + for (int j = 0; j < bundleNodes.getLength(); j++) >>>>> { >>>>> + Element b = (Element) bundleNodes.item(j); >>>>> + f.addBundle(b.getTextContent()); >>>>> + } >>>>> + features.add(f); >>>>> + } >>>>> + } >>>>> + } catch (SAXException e) { >>>>> + throw (IOException) new IOException().initCause(e); >>>>> + } catch (ParserConfigurationException e) { >>>>> + throw (IOException) new IOException().initCause(e); >>>>> + } catch (URISyntaxException e) { >>>>> + throw (IOException) new IOException().initCause(e); >>>>> + } >>>>> + } >>>>> + >>>>> +} >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:eol-style = native >>>>> >>>>> Propchange: >>>>> >>>>> >>>>> servicemix/smx4/kernel/trunk/testing/support/src/main/java/org/apache/servicemix/kernel/testing/support/FeatureRepositoryImpl.java >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> svn:keywords = Rev Date >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>> >>>> >>> >>> >> >> >> >> > > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/ ------------------------ Open Source SOA http://fusesource.com
