Repository: karaf Updated Branches: refs/heads/master 17c95881d -> 291d564eb
[KARAF-2763] Provide SCR support for the annotations and use them Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/291d564e Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/291d564e Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/291d564e Branch: refs/heads/master Commit: 291d564eba4102a33ba79ff60a0777340ea07013 Parents: ee59ed7 Author: Guillaume Nodet <[email protected]> Authored: Tue Feb 18 23:22:57 2014 +0100 Committer: Guillaume Nodet <[email protected]> Committed: Tue Feb 18 23:24:07 2014 +0100 ---------------------------------------------------------------------- pom.xml | 5 + scr/command/pom.xml | 13 + .../org/apache/karaf/scr/command/Commands.java | 84 ------ .../scr/command/action/ActivateAction.java | 2 + .../scr/command/action/DeactivateAction.java | 4 + .../karaf/scr/command/action/DetailsAction.java | 2 + .../karaf/scr/command/action/ListAction.java | 2 + .../scr/command/action/ScrActionSupport.java | 2 + .../command/completer/ActivateCompleter.java | 2 + .../command/completer/DeactivateCompleter.java | 2 + .../scr/command/completer/DetailsCompleter.java | 2 + .../command/completer/ScrCompleterSupport.java | 2 + scr/pom.xml | 1 + scr/support/pom.xml | 113 ++++++++ .../karaf/scr/support/InjectAnnotations.java | 279 +++++++++++++++++++ .../karaf/scr/support/ScrCommandSupport.java | 112 ++++++++ 16 files changed, 543 insertions(+), 84 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8cbb326..62c4d7f 100644 --- a/pom.xml +++ b/pom.xml @@ -725,6 +725,11 @@ <dependency> <groupId>org.apache.karaf.scr</groupId> + <artifactId>org.apache.karaf.scr.support</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.karaf.scr</groupId> <artifactId>org.apache.karaf.scr.command</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/pom.xml ---------------------------------------------------------------------- diff --git a/scr/command/pom.xml b/scr/command/pom.xml index d702d05..4475bfc 100644 --- a/scr/command/pom.xml +++ b/scr/command/pom.xml @@ -69,6 +69,11 @@ <artifactId>bndlib</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.apache.karaf.scr</groupId> + <artifactId>org.apache.karaf.scr.support</artifactId> + <scope>provided</scope> + </dependency> </dependencies> <build> @@ -94,8 +99,16 @@ <configuration> <instructions> <Service-Component>*</Service-Component> + <_plugin>org.apache.karaf.scr.support.InjectAnnotations</_plugin> </instructions> </configuration> + <dependencies> + <dependency> + <groupId>org.apache.karaf.scr</groupId> + <artifactId>org.apache.karaf.scr.support</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> </plugin> </plugins> </build> http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java b/scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java deleted file mode 100644 index 70533e5..0000000 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.karaf.scr.command; - -import aQute.bnd.annotation.component.Activate; -import aQute.bnd.annotation.component.Component; -import aQute.bnd.annotation.component.Deactivate; -import aQute.bnd.annotation.component.Reference; -import org.apache.felix.scr.ScrService; -import org.apache.karaf.scr.command.action.ActivateAction; -import org.apache.karaf.scr.command.action.DeactivateAction; -import org.apache.karaf.scr.command.action.DetailsAction; -import org.apache.karaf.scr.command.action.ListAction; -import org.apache.karaf.scr.command.completer.ActivateCompleter; -import org.apache.karaf.scr.command.completer.DeactivateCompleter; -import org.apache.karaf.scr.command.completer.DetailsCompleter; -import org.apache.karaf.scr.command.completer.ScrCompleterSupport; -import org.apache.karaf.shell.commands.Action; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - */ -@Component -public class Commands extends org.apache.karaf.shell.commands.Commands { - - protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); - protected ScrService scrService; - - @Activate - public void activate() { - logger.info("Activating SCR commands"); - completer(ActivateCompleter.class); - completer(DeactivateCompleter.class); - completer(DetailsCompleter.class); - command(ActivateAction.class); - command(DeactivateAction.class); - command(DetailsAction.class); - command(ListAction.class); - register(); - } - - @Deactivate - public void deactivate() { - logger.info("Deactivating SCR commands"); - unregister(); - } - - @Reference - public void setScrService(ScrService scrService) { - this.scrService = scrService; - } - - public CompleterBuilder completer(Class<? extends ScrCompleterSupport> completerClass) { - try { - ScrCompleterSupport completer = completerClass.newInstance(); - completer.setScrService(scrService); - return completer(completer); - } catch (Exception e) { - throw new RuntimeException("Unable to create completer", e); - } - } - - public CommandBuilder command(Class<? extends Action> actionClass) { - return super.command(actionClass) - .properties(scrService) - .serviceProp(ScrCommandConstants.HIDDEN_COMPONENT_KEY, "true"); - } - -} http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/action/ActivateAction.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ActivateAction.java b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ActivateAction.java index 5e435d4..049488c 100755 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ActivateAction.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ActivateAction.java @@ -24,11 +24,13 @@ import org.apache.felix.scr.ScrService; import org.apache.karaf.scr.command.ScrCommandConstants; import org.apache.karaf.scr.command.ScrUtils; import org.apache.karaf.shell.commands.Completer; +import org.apache.karaf.shell.inject.Service; /** * Activates the given component by supplying its component name. */ @Command(scope = ScrCommandConstants.SCR_COMMAND, name = ScrCommandConstants.ACTIVATE_FUNCTION, description = "Activates a Component for the given name") +@Service public class ActivateAction extends ScrActionSupport { @Argument(index = 0, name = "name", description = "The name of the Component to activate ", required = true, multiValued = false) http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/action/DeactivateAction.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/action/DeactivateAction.java b/scr/command/src/main/java/org/apache/karaf/scr/command/action/DeactivateAction.java index e417459..31eeecc 100755 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/action/DeactivateAction.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/action/DeactivateAction.java @@ -23,11 +23,15 @@ import org.apache.felix.scr.Component; import org.apache.felix.scr.ScrService; import org.apache.karaf.scr.command.ScrCommandConstants; import org.apache.karaf.shell.commands.Completer; +import org.apache.karaf.shell.inject.Destroy; +import org.apache.karaf.shell.inject.Init; +import org.apache.karaf.shell.inject.Service; /** * Deactivates the given component by supplying its component name. */ @Command(scope = ScrCommandConstants.SCR_COMMAND, name = ScrCommandConstants.DEACTIVATE_FUNCTION, description = "Deactivates a Component for the given name") +@Service public class DeactivateAction extends ScrActionSupport { @Argument(index = 0, name = "name", description = "The name of the Component to deactivate ", required = true, multiValued = false) http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/action/DetailsAction.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/action/DetailsAction.java b/scr/command/src/main/java/org/apache/karaf/scr/command/action/DetailsAction.java index 39b462c..a93c722 100644 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/action/DetailsAction.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/action/DetailsAction.java @@ -25,6 +25,7 @@ import org.apache.karaf.scr.command.completer.DetailsCompleter; import org.apache.karaf.shell.commands.Argument; import org.apache.karaf.shell.commands.Command; import org.apache.karaf.shell.commands.Completer; +import org.apache.karaf.shell.inject.Service; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentConstants; @@ -35,6 +36,7 @@ import java.util.Hashtable; * Displays the details associated with a given component by supplying its component name. */ @Command(scope = ScrCommandConstants.SCR_COMMAND, name = ScrCommandConstants.DETAILS_FUNCTION, description = "Displays a list of available components") +@Service public class DetailsAction extends ScrActionSupport { @Argument(index = 0, name = "name", description = "The name of the Component to display the details of", required = true, multiValued = false) http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/action/ListAction.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ListAction.java b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ListAction.java index da6b16e..26e3ca9 100755 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ListAction.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ListAction.java @@ -22,6 +22,7 @@ import org.apache.karaf.scr.command.ScrCommandConstants; import org.apache.karaf.scr.command.ScrUtils; import org.apache.karaf.scr.command.support.IdComparator; import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.inject.Service; import java.util.Arrays; @@ -29,6 +30,7 @@ import java.util.Arrays; * Lists all the components currently installed. */ @Command(scope = ScrCommandConstants.SCR_COMMAND, name = ScrCommandConstants.LIST_FUNCTION, description = "Displays a list of available components") +@Service public class ListAction extends ScrActionSupport { private final IdComparator idComparator = new IdComparator(); http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/action/ScrActionSupport.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ScrActionSupport.java b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ScrActionSupport.java index 0580dae..24c8619 100755 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/action/ScrActionSupport.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/action/ScrActionSupport.java @@ -25,6 +25,7 @@ import org.apache.karaf.shell.console.AbstractAction; import org.apache.karaf.shell.console.CommandSessionHolder; import org.apache.karaf.shell.console.SubShellAction; import org.apache.karaf.shell.console.completer.ArgumentCompleter; +import org.apache.karaf.shell.inject.Reference; import org.fusesource.jansi.Ansi; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -45,6 +46,7 @@ public abstract class ScrActionSupport extends AbstractAction { protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); + @Reference private ScrService scrService; public ScrActionSupport() { http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ActivateCompleter.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ActivateCompleter.java b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ActivateCompleter.java index b2358dd..7cfe6e6 100644 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ActivateCompleter.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ActivateCompleter.java @@ -17,7 +17,9 @@ package org.apache.karaf.scr.command.completer; import org.apache.felix.scr.Component; +import org.apache.karaf.shell.inject.Service; +@Service public class ActivateCompleter extends ScrCompleterSupport { /** http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DeactivateCompleter.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DeactivateCompleter.java b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DeactivateCompleter.java index a44df15..60361d7 100644 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DeactivateCompleter.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DeactivateCompleter.java @@ -17,7 +17,9 @@ package org.apache.karaf.scr.command.completer; import org.apache.felix.scr.Component; +import org.apache.karaf.shell.inject.Service; +@Service public class DeactivateCompleter extends ScrCompleterSupport { /** http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DetailsCompleter.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DetailsCompleter.java b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DetailsCompleter.java index b332be9..49bc9ba 100644 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DetailsCompleter.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/DetailsCompleter.java @@ -17,7 +17,9 @@ package org.apache.karaf.scr.command.completer; import org.apache.felix.scr.Component; +import org.apache.karaf.shell.inject.Service; +@Service public class DetailsCompleter extends ScrCompleterSupport { /** http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ScrCompleterSupport.java ---------------------------------------------------------------------- diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ScrCompleterSupport.java b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ScrCompleterSupport.java index 5994639..3434f86 100755 --- a/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ScrCompleterSupport.java +++ b/scr/command/src/main/java/org/apache/karaf/scr/command/completer/ScrCompleterSupport.java @@ -23,6 +23,7 @@ import org.apache.felix.scr.ScrService; import org.apache.karaf.scr.command.action.ScrActionSupport; import org.apache.karaf.shell.console.Completer; import org.apache.karaf.shell.console.completer.StringsCompleter; +import org.apache.karaf.shell.inject.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +31,7 @@ public abstract class ScrCompleterSupport implements Completer { protected final transient Logger logger = LoggerFactory.getLogger(ScrCompleterSupport.class); + @Reference private ScrService scrService; /** http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/pom.xml ---------------------------------------------------------------------- diff --git a/scr/pom.xml b/scr/pom.xml index 162477a..4d7422c 100644 --- a/scr/pom.xml +++ b/scr/pom.xml @@ -34,6 +34,7 @@ <name>Apache Karaf :: Declarative Services (DS)</name> <modules> + <module>support</module> <module>command</module> <module>management</module> <module>examples</module> http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/support/pom.xml ---------------------------------------------------------------------- diff --git a/scr/support/pom.xml b/scr/support/pom.xml new file mode 100644 index 0000000..3ee6706 --- /dev/null +++ b/scr/support/pom.xml @@ -0,0 +1,113 @@ +<?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.scr</groupId> + <artifactId>scr</artifactId> + <version>3.0.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>org.apache.karaf.scr.support</artifactId> + <packaging>jar</packaging> + <name>Apache Karaf :: SCR :: Support</name> + <description>This bundle provides support for commands.</description> + + <properties> + <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>provided</scope> + </dependency> + <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.console</artifactId> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr</artifactId> + </dependency> + <dependency> + <groupId>biz.aQute.bnd</groupId> + <artifactId>bndlib</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.gogo.runtime</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> + org.apache.felix.gogo.commands, + org.apache.karaf.shell.commands.basic, + org.apache.karaf.shell.console, + org.apache.karaf.shell.inject, + org.osgi.framework, + org.osgi.service.component, + org.slf4j + </Import-Package> + <Export-Package> + org.apache.karaf.scr.support + </Export-Package> + <Private-Package> + org.apache.karaf.scr.support.plugin + </Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/support/src/main/java/org/apache/karaf/scr/support/InjectAnnotations.java ---------------------------------------------------------------------- diff --git a/scr/support/src/main/java/org/apache/karaf/scr/support/InjectAnnotations.java b/scr/support/src/main/java/org/apache/karaf/scr/support/InjectAnnotations.java new file mode 100644 index 0000000..92e56b1 --- /dev/null +++ b/scr/support/src/main/java/org/apache/karaf/scr/support/InjectAnnotations.java @@ -0,0 +1,279 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.karaf.scr.support; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import aQute.bnd.component.HeaderReader; +import aQute.bnd.component.TagResource; +import aQute.bnd.header.Parameters; +import aQute.bnd.osgi.Analyzer; +import aQute.bnd.osgi.Annotation; +import aQute.bnd.osgi.ClassDataCollector; +import aQute.bnd.osgi.Clazz; +import aQute.bnd.osgi.Constants; +import aQute.bnd.osgi.Descriptors; +import aQute.bnd.osgi.Instruction; +import aQute.bnd.osgi.Processor; +import aQute.bnd.osgi.URLResource; +import aQute.bnd.service.AnalyzerPlugin; +import aQute.lib.tag.Tag; +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.Function; +import org.apache.karaf.scr.support.ScrCommandSupport; +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.CommandWithAction; +import org.apache.karaf.shell.commands.basic.AbstractCommand; +import org.apache.karaf.shell.console.CompletableFunction; +import org.apache.karaf.shell.inject.Destroy; +import org.apache.karaf.shell.inject.Init; +import org.apache.karaf.shell.inject.Reference; +import org.apache.karaf.shell.inject.Service; + +import static aQute.bnd.osgi.Constants.COMPONENT_ACTIVATE; +import static aQute.bnd.osgi.Constants.COMPONENT_DEACTIVATE; +import static aQute.bnd.osgi.Constants.COMPONENT_PROPERTIES; +import static aQute.bnd.osgi.Constants.COMPONENT_PROVIDE; + +/** + * + */ +public class InjectAnnotations implements AnalyzerPlugin { + + private Analyzer analyzer; + + @Override + public boolean analyzeJar(Analyzer analyzer) throws Exception { + try { + return doAnalyzeJar(analyzer); + } catch (Exception t) { + t.printStackTrace(System.out); + throw t; + } + } + + protected boolean doAnalyzeJar(Analyzer analyzer) throws Exception { + this.analyzer = analyzer; + + System.out.println("\nLooking for @Service annotated classes\n"); + + Collection<Clazz> annotatedComponents = analyzer.getClasses("", Clazz.QUERY.ANNOTATED.toString(), Service.class.getName()); + + List<String> components = new ArrayList<String>(); + + + for (Clazz clazz : annotatedComponents) { + System.out.println("\nFound @Service annotated class: " + clazz); + + if (clazz.is(Clazz.QUERY.ANNOTATED, new Instruction(Command.class.getName()), analyzer)) { + System.out.println("\tCommand"); + Collector collector = new Collector(); + clazz.parseClassFileWithCollector(collector); + + Map<String, String> info = new LinkedHashMap<String, String>(); + info.put(COMPONENT_ACTIVATE, "activate"); + info.put(COMPONENT_DEACTIVATE, "deactivate"); + for (String key : collector.references.keySet()) { + info.put(key, collector.references.get(key)); + } + info.put(COMPONENT_PROVIDE, Processor.join(Arrays.asList(new String[] { + Function.class.getName(), + CompletableFunction.class.getName(), + CommandWithAction.class.getName(), +// AbstractCommand.class.getName() + }))); + + List<String> properties = new ArrayList<String>(); + properties.add(CommandProcessor.COMMAND_SCOPE + "=" + collector.command.get("scope")); + properties.add(CommandProcessor.COMMAND_FUNCTION + "=" + collector.command.get("name")); + properties.add("hidden.component=true"); + info.put(COMPONENT_PROPERTIES, Processor.join(properties)); + + TagResource resource = createComponentResource(clazz.getFQN(), ScrCommandSupport.class.getName(), info); + analyzer.getJar().putResource("OSGI-INF/" + clazz.getFQN() + ".xml", resource); + components.add("OSGI-INF/" + clazz.getFQN() + ".xml"); + resource.write(System.out); + System.out.println(); + + } else { + System.out.println("\tNot a command"); + Collector collector = new Collector(); + clazz.parseClassFileWithCollector(collector); + + Map<String, String> info = new LinkedHashMap<String, String>(); + if (collector.init != null) { + info.put(COMPONENT_ACTIVATE, collector.init); + } + if (collector.destroy != null) { + info.put(COMPONENT_DEACTIVATE, collector.destroy); + } + for (String key : collector.references.keySet()) { + info.put(key, collector.references.get(key)); + } + info.put(COMPONENT_PROVIDE, Processor.join(collector.allClasses)); + List<String> properties = new ArrayList<String>(); + properties.add("hidden.component=true"); + info.put(COMPONENT_PROPERTIES, Processor.join(properties)); + + TagResource resource = createComponentResource(clazz.getFQN(), clazz.getFQN(), info); + analyzer.getJar().putResource("OSGI-INF/" + clazz.getFQN() + ".xml", resource); + components.add("OSGI-INF/" + clazz.getFQN() + ".xml"); + resource.write(System.out); + System.out.println(); + } + + } + + String name = ScrCommandSupport.class.getName().replace('.', '/') + ".class"; + analyzer.getJar().putResource(name, new URLResource(ScrCommandSupport.class.getClassLoader().getResource(name))); + String pkg = ScrCommandSupport.class.getName(); + pkg = pkg.substring( 0, pkg.lastIndexOf( '.' ) ); + Descriptors.PackageRef pkgRef = analyzer.getPackageRef( pkg ); + if ( !analyzer.getContained().containsKey( pkgRef ) ) { + analyzer.getContained().put(pkgRef); + } + String[] imports = new String[] { + "org.apache.felix.gogo.commands", + "org.apache.karaf.shell.commands.basic", + "org.apache.karaf.shell.console", + "org.apache.karaf.shell.inject", + "org.osgi.framework", + "org.osgi.service.component", + "org.slf4j" + }; + for (String importPkg : imports) { + pkgRef = analyzer.getPackageRef( importPkg ); + if ( !analyzer.getReferred().containsKey( pkgRef ) ) { + analyzer.getReferred().put( pkgRef ); + } + } + + String prop = analyzer.getProperty(Constants.SERVICE_COMPONENT); + for (String comp : components) { + if (prop == null || prop.length() == 0) { + prop = comp; + } else { + prop = prop + "," + comp; + } + } + analyzer.setProperty(Constants.SERVICE_COMPONENT, prop); + + return false; + } + + TagResource createComponentResource(String name, String impl, Map<String, String> info) + throws Exception { + Tag tag = new HeaderReader(analyzer).createComponentTag(name, impl, info); + return new TagResource(tag); + } + + class Collector extends ClassDataCollector { + Descriptors.TypeRef zuper; + Clazz.MethodDef method; + Clazz.FieldDef field; + + String init; + String destroy; + Annotation command; + Map<String, String> references = new LinkedHashMap<String, String>(); + List<String> allClasses = new ArrayList<String>(); + + @Override + public void classBegin(int access, Descriptors.TypeRef name) { + if (!name.getFQN().equals(Object.class.getName())) { + allClasses.add(name.getFQN()); + } + } + + public void implementsInterfaces(Descriptors.TypeRef[] interfaces) throws Exception { + if (interfaces != null) { + for (Descriptors.TypeRef ref : interfaces) { + allClasses.add(ref.getFQN()); + } + } + } + + @Override + public void extendsClass(Descriptors.TypeRef zuper) throws Exception { + this.zuper = zuper; + } + + @Override + public void field(Clazz.FieldDef defined) { + field = defined; + } + + @Override + public void method(Clazz.MethodDef defined) { + method = defined; + } + + @Override + public void annotation(Annotation annotation) { + String name = annotation.getName().getFQN(); + if (Command.class.getName().equals(name)) { + System.out.println("\tCommand: " + annotation.get("scope") + ":" + annotation.get("name")); + command = annotation; + } + if (Reference.class.getName().equals(name)) { + System.out.println("\tReference: field=" + field.getName() + ", type=" + field.getType().getFQN()); + references.put(field.getName(), field.getType().getFQN()); + } + if (Init.class.getName().equals(name)) { + if (init == null) { + System.out.println("\tInit method: " + method.getName()); + init = method.getName(); + } + } + if (Destroy.class.getName().equals(name)) { + if (destroy == null) { + System.out.println("\tDestroy method: " + method.getName()); + destroy = method.getName(); + } + } + } + + @Override + public void classEnd() throws Exception { + if (zuper != null) { + Clazz clazz = analyzer.findClass(zuper); + zuper = null; + if (clazz != null) { + clazz.parseClassFileWithCollector(this); + } + } + } + } + + static boolean isAnnotated(Clazz.Def def, Class annotation) { + Collection<Descriptors.TypeRef> anns = def.getAnnotations(); + if (anns != null) { + for (Descriptors.TypeRef ann : anns) { + if (annotation.getName().equals(ann.getFQN())) { + return true; + } + } + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/291d564e/scr/support/src/main/java/org/apache/karaf/scr/support/ScrCommandSupport.java ---------------------------------------------------------------------- diff --git a/scr/support/src/main/java/org/apache/karaf/scr/support/ScrCommandSupport.java b/scr/support/src/main/java/org/apache/karaf/scr/support/ScrCommandSupport.java new file mode 100644 index 0000000..18eadb0 --- /dev/null +++ b/scr/support/src/main/java/org/apache/karaf/scr/support/ScrCommandSupport.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.karaf.scr.support; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +import org.apache.felix.gogo.commands.Action; +import org.apache.karaf.shell.commands.basic.AbstractCommand; +import org.apache.karaf.shell.console.BundleContextAware; +import org.apache.karaf.shell.console.CompletableFunction; +import org.apache.karaf.shell.console.Completer; +import org.apache.karaf.shell.inject.Init; +import org.apache.karaf.shell.inject.Reference; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + */ +public class ScrCommandSupport extends AbstractCommand implements CompletableFunction { + + private static final Logger LOGGER = LoggerFactory.getLogger(ScrCommandSupport.class); + + private ComponentContext componentContext; + + public ScrCommandSupport() { + } + + public void activate(ComponentContext componentContext) { + LOGGER.info("Activating SCR command for " + componentContext.getProperties().get("component.name")); + this.componentContext = componentContext; + } + + public void deactivate(ComponentContext componentContext) { + } + + public Class<? extends Action> getActionClass() { + try { + String className = (String) componentContext.getProperties().get("component.name"); + return (Class<? extends Action>) componentContext.getBundleContext().getBundle().loadClass(className); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + } + + @Override + public Action createNewAction() { + Class actionClass = getActionClass(); + try { + Action action = (Action) actionClass.newInstance(); + // Inject services + for (Class<?> cl = actionClass; cl != Object.class; cl = cl.getSuperclass()) { + for (Field field : cl.getDeclaredFields()) { + if (field.getAnnotation(Reference.class) != null) { + Object value; + if (field.getType() == BundleContext.class) { + value = componentContext.getBundleContext(); + } else { + value = componentContext.locateService(field.getName()); + } + if (value == null) { + throw new RuntimeException("No OSGi service matching " + field.getType().getName()); + } + field.setAccessible(true); + field.set(action, value); + } + } + } + if (action instanceof BundleContextAware) { + ((BundleContextAware) action).setBundleContext(componentContext.getBundleContext()); + } + for (Method method : actionClass.getDeclaredMethods()) { + Init ann = method.getAnnotation(Init.class); + if (ann != null && method.getParameterTypes().length == 0 && method.getReturnType() == void.class) { + method.setAccessible(true); + method.invoke(action); + } + } + return action; + } catch (Exception e) { + throw new RuntimeException("Unable to creation command action " + actionClass.getName(), e); + } + } + + @Override + public List<Completer> getCompleters() { + return null; + } + + @Override + public Map<String, Completer> getOptionalCompleters() { + return null; + } +}
