You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2013/07/06 10:35:30 UTC

svn commit: r1500228 - in /felix/trunk/scrplugin/bnd-scr-plugin: ./ src/ src/main/ src/main/appended-resources/ src/main/appended-resources/META-INF/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/j...

Author: pderop
Date: Sat Jul  6 08:35:29 2013
New Revision: 1500228

URL: http://svn.apache.org/r1500228
Log:
FELIX-4135: Committed initial version for the Bnd ScrPlugin.

Added:
    felix/trunk/scrplugin/bnd-scr-plugin/
    felix/trunk/scrplugin/bnd-scr-plugin/pom.xml
    felix/trunk/scrplugin/bnd-scr-plugin/src/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/DEPENDENCIES
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/LICENSE
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/NOTICE
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/BndLog.java
    felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java

Added: felix/trunk/scrplugin/bnd-scr-plugin/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/pom.xml?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/pom.xml (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/pom.xml Sat Jul  6 08:35:29 2013
@@ -0,0 +1,144 @@
+<!-- 
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+    http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License. 
+-->
+<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/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.felix</groupId>
+		<artifactId>felix-parent</artifactId>
+		<version>2.1</version>
+		<relativePath>../../pom/pom.xml</relativePath>
+	</parent>
+
+	<groupId>org.apache.felix</groupId>
+	<artifactId>org.apache.felix.scr.bnd</artifactId>
+
+	<version>1.0.0-SNAPSHOT</version>
+	<packaging>jar</packaging>
+
+	<name>Bnd SCR Plugin</name>
+	<description>
+		Implements a Bnd scrplugin to generate Declarative Services
+		and Metatype Service descriptors from Java 5 annotations 
+		and/or JavaDoc tags.
+	</description>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.scr.generator</artifactId>
+			<version>1.7.1-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.scr.annotations</artifactId>
+			<version>1.9.5-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.scr.ds-annotations</artifactId>
+			<version>1.2.2</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.ow2.asm</groupId>
+			<artifactId>asm-all</artifactId>
+			<version>4.0</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<version>4.3.0</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.compendium</artifactId>
+			<version>4.3.0</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>biz.aQute.bnd</groupId>
+			<artifactId>bndlib</artifactId>
+			<version>2.1.0</version>
+			<scope>compile</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<!-- Use a shade plugin in order to append META-INF/service SPI resources into target artifact -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-shade-plugin</artifactId>
+				<version>2.1</version>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<goals>
+							<goal>shade</goal>
+						</goals>
+						<configuration>
+							<transformers>
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+							</transformers>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<!-- unpack cmpdm,asm,scr generator and annotations in target artifact -->
+			<plugin>
+				<artifactId>maven-dependency-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>unpack-dependencies</goal>
+						</goals>
+						<configuration>
+							<includeArtifactIds>
+								org.osgi.compendium,asm-all,org.apache.felix.scr.generator,org.apache.felix.scr.annotations,org.apache.felix.scr.ds-annotations
+							</includeArtifactIds>
+							<outputDirectory>
+								${project.build.outputDirectory}
+							</outputDirectory>
+							<excludes>
+								**/MANIFEST.MF
+							</excludes>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<!-- JDK 1.5 needed for annotation support -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.5</source>
+					<target>1.5</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>

Added: felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/DEPENDENCIES
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/DEPENDENCIES?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/DEPENDENCIES (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/DEPENDENCIES Sat Jul  6 08:35:29 2013
@@ -0,0 +1,27 @@
+I. Included Third-Party Software
+
+This product includes software developed at http://asm.objectweb.org
+Copyright (c) 2000-2011 INRIA, France Telecom
+Licensed under the BSD License.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0. 
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0. 
+
+This product uses software developed by Peter Kriens
+(http://www.aqute.biz/Code/Bnd)
+Copyright 2006-2013 aQute, All rights reserved
+Licensed under the Apache License 2.0.
+
+
+III. License Summary
+- Apache License 2.0
+- BSD License

Added: felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/LICENSE
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/LICENSE?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/LICENSE (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/LICENSE Sat Jul  6 08:35:29 2013
@@ -0,0 +1,31 @@
+For the asm component:
+
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

Added: felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/NOTICE
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/NOTICE?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/NOTICE (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/src/main/appended-resources/META-INF/NOTICE Sat Jul  6 08:35:29 2013
@@ -0,0 +1,7 @@
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at http://asm.objectweb.org
+Copyright (c) 2000-2011 INRIA, France Telecom
+Licensed under the BSD License.

Added: felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/BndLog.java
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/BndLog.java?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/BndLog.java (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/BndLog.java Sat Jul  6 08:35:29 2013
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scrplugin.bnd;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.felix.scrplugin.Log;
+
+import aQute.service.reporter.Reporter;
+
+/**
+ * Scrplugin Log implementation, which redirects log to both bnd "Reporter" and
+ * to /tmp/scrplugin/<BundleSymbolicName>.log
+ */
+public class BndLog implements Log {
+	/**
+	 * The BndLib logging reported.
+	 */
+	private final Reporter reporter;
+
+	/**
+	 * Enabled log level, which can be configured in bnd scrplugin declaration.
+	 */
+	private Level logEnabled = Level.Warn;
+
+	/**
+	 * Writer to log file, in tmp dir/scrplugin-BSN.log
+	 */
+	private final PrintWriter logWriter;
+
+	/**
+	 * DateFormat used when logging.
+	 */
+	private final static SimpleDateFormat dateFormat = new SimpleDateFormat(
+			"E yyyy.MM.dd hh:mm:ss.S");
+	
+	/**
+	 * Log Levels.
+	 */
+	enum Level {
+		Error, Warn, Info, Debug
+	}
+
+	/**
+	 * Creates a new bnd Log implementaiton
+	 * 
+	 * @param reporter
+	 *            the bnd logger
+	 * @param logLevel
+	 * @param bsn
+	 */
+	BndLog(Reporter reporter, String bsn) {
+		this.reporter = reporter;
+		File logFilePath = new File(System.getProperty("java.io.tmpdir")
+				+ File.separator + "scrplugin" + File.separator + bsn + ".log");
+		new File(logFilePath.getParent()).mkdirs();
+		
+		PrintWriter writer = null;
+		try {
+			writer = new PrintWriter(new FileWriter(logFilePath, false));
+		} catch (IOException e) {
+			reporter.exception(e, "Could not create scrplugin log file: %s",
+					logFilePath);
+			writer = null;
+		}
+		this.logWriter = writer;
+	}
+
+	/**
+	 * Close log file.
+	 */
+	public void close() {
+		if (logWriter != null) {
+			logWriter.close();
+		}
+	}
+
+	/**
+	 * Sets the enabled log level.
+	 * 
+	 * @param level
+	 *            the enabled level ("Error", "Warn", "Info", or "Debug")
+	 */
+	public void setLevel(String level) {
+		try {
+			level = Character.toUpperCase(level.charAt(0))
+					+ level.substring(1).toLowerCase();
+			this.logEnabled = Level.valueOf(level);
+		} catch (IllegalArgumentException e) {
+			this.logEnabled = Level.Warn;
+			warn("Bnd scrplugin logger initialized with invalid log level: "
+					+ level);
+		}
+	}
+
+	// Reporter
+
+	public boolean isDebugEnabled() {
+		return logEnabled.ordinal() >= Level.Debug.ordinal();
+	}
+
+	public boolean isInfoEnabled() {
+		return logEnabled.ordinal() >= Level.Info.ordinal();
+	}
+
+	public boolean isWarnEnabled() {
+		return logEnabled.ordinal() >= Level.Warn.ordinal();
+	}
+
+	public boolean isErrorEnabled() {
+		return logEnabled.ordinal() >= Level.Error.ordinal();
+	}
+
+	public void debug(String content) {
+		if (isDebugEnabled()) {
+			reporter.trace("%s", content);
+			logDebug(content, null);
+		}
+	}
+
+	public void debug(String content, Throwable error) {
+		if (isDebugEnabled()) {
+			reporter.trace("%s:%s", content, toString(error));
+			logDebug(content, error);
+		}
+	}
+
+	public void debug(Throwable error) {
+		if (isDebugEnabled()) {
+			reporter.trace("%s", toString(error));
+			logDebug("exception", error);
+		}
+	}
+
+	public void info(String content) {
+		if (isInfoEnabled()) {
+			reporter.trace("%s", content);
+			logInfo(content, null);
+		}
+	}
+
+	public void info(String content, Throwable error) {
+		if (isInfoEnabled()) {
+			reporter.trace("%s:%s", content, toString(error));
+			logInfo(content, error);
+		}
+	}
+
+	public void info(Throwable error) {
+		if (isInfoEnabled()) {
+			reporter.trace("%s", toString(error));
+			logInfo("exception:", error);
+		}
+	}
+
+	public void warn(String content) {
+		if (isWarnEnabled()) {
+			reporter.warning("%s", content);
+			logWarn(content, null);
+		}
+	}
+
+	public void warn(String content, Throwable error) {
+		if (isWarnEnabled()) {
+			reporter.warning("%s:%s", content, toString(error));
+			logWarn(content, error);
+		}
+	}
+
+	public void warn(Throwable error) {
+		if (isWarnEnabled()) {
+			reporter.warning("%s", toString(error));
+			logWarn("exception:", error);
+		}
+	}
+
+	public void warn(String content, String location, int lineNumber) {
+		warn(String.format("%s [%s,%d]", content, location, lineNumber));
+	}
+
+	public void warn(String content, String location, int lineNumber,
+			int columNumber) {
+		warn(String.format("%s [%s,%d:%d]", content, location, lineNumber,
+				columNumber));
+	}
+
+	public void error(String content) {
+		reporter.error("%s", content);
+		logErr(content, null);
+	}
+
+	public void error(String content, Throwable error) {
+		reporter.error("%s:%s", content, toString(error));
+		logErr(content, error);
+	}
+
+	public void error(Throwable error) {
+		reporter.error("%s", toString(error));
+		logErr("exception:", error);
+	}
+
+	public void error(String content, String location, int lineNumber) {
+		error(String.format("%s [%s,%d]", content, location, lineNumber));
+	}
+
+	public void error(String content, String location, int lineNumber,
+			int columnNumber) {
+		error(String.format("%s [%s,%d:%d]", content, location, lineNumber,
+				columnNumber));
+	}
+
+	private void logErr(String msg, Throwable t) {
+		log(Level.Error, msg, t);
+	}
+
+	private void logWarn(String msg, Throwable t) {
+		log(Level.Warn, msg, t);
+	}
+
+	private void logInfo(String msg, Throwable t) {
+		log(Level.Info, msg, t);
+	}
+
+	private void logDebug(String msg, Throwable t) {
+		log(Level.Debug, msg, t);
+	}
+
+	private void log(Level level, String msg, Throwable t) {
+		if (logWriter != null) {
+			StringBuilder sb = new StringBuilder();
+			sb.append(dateFormat.format(new Date()));
+			sb.append(" - ");
+			sb.append(level);
+			sb.append(": ");
+			sb.append(msg);
+			if (t != null) {
+				sb.append(" - ").append(toString(t));
+			}
+			logWriter.println(sb.toString());
+		}
+	}
+
+	private static String toString(Throwable e) {
+		StringWriter buffer = new StringWriter();
+		PrintWriter pw = new PrintWriter(buffer);
+		e.printStackTrace(pw);
+		return (buffer.toString());
+	}
+}

Added: felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java?rev=1500228&view=auto
==============================================================================
--- felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java (added)
+++ felix/trunk/scrplugin/bnd-scr-plugin/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java Sat Jul  6 08:35:29 2013
@@ -0,0 +1,339 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scrplugin.bnd;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scrplugin.Options;
+import org.apache.felix.scrplugin.Result;
+import org.apache.felix.scrplugin.SCRDescriptorGenerator;
+import org.apache.felix.scrplugin.Source;
+import org.apache.felix.scrplugin.SpecVersion;
+
+import aQute.bnd.osgi.Analyzer;
+import aQute.bnd.osgi.Clazz;
+import aQute.bnd.osgi.Clazz.QUERY;
+import aQute.bnd.osgi.EmbeddedResource;
+import aQute.bnd.osgi.Jar;
+import aQute.bnd.service.AnalyzerPlugin;
+import aQute.bnd.service.Plugin;
+import aQute.service.reporter.Reporter;
+
+/**
+ * The <code>SCRDescriptorBndPlugin</code> class is a <code>bnd</code> analyzer
+ * plugin which generates a service descriptor file based on annotations found
+ * in the sources.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SCRDescriptorBndPlugin implements AnalyzerPlugin, Plugin {
+	/**
+	 * "destdir" parameter, optionally provided in the "-plugin" directive.
+	 */
+	private static final String DESTDIR = "destdir";
+
+	/**
+	 * "finalName" parameter, optionally provided in the "-plugin" directive.
+	 */
+	private static final String FINALNAME = "finalName";
+
+	/**
+	 * "metaTypeName" parameter, optionally provided in the "-plugin" directive.
+	 */
+	private static final String METATYPENAME = "metaTypeName";
+
+	/**
+	 * "generateAccessors" parameter, optionally provided in the "-plugin"
+	 * directive.
+	 */
+	private static final String GENERATE_ACCESSOR = "generateAccessors";
+
+	/**
+	 * "strictMode" parameter, optionally provided in the "-plugin" directive.
+	 */
+	private static final String STRICT_MODE = "strictMode";
+
+	/**
+	 * "specVersion" parameter, optionally provided in the "-plugin" directive.
+	 */
+	private static final String SPECVERSION = "specVersion";
+
+	/**
+	 * "genSeparateDescs" parameter, optionally provided in the "-plugin"
+	 * directive.
+	 */
+	private static final String GENSEPDESC = "genSeparateDescs";
+
+	/**
+	 * "log" parameter, which may be provided in the "-plugin" directive.
+	 */
+	private static final String LOGLEVEL = "log";
+
+	/**
+	 * The name of the directory where the descriptor files are generated into.
+	 */
+	private File destDir;
+
+	/**
+	 * Object allowing to log debug messages using bnd reporter object.
+	 */
+	private BndLog log;
+
+	/**
+	 * Name of the generated descriptor.
+	 */
+	private String finalName = "serviceComponents.xml";
+
+	/**
+	 * Name of the generated meta type file.
+	 */
+	private String metaTypeName = "metatype.xml";
+
+	/**
+	 * This flag controls the generation of the bind/unbind methods.
+	 */
+	private boolean generateAccessor = true;
+
+	/**
+	 * In strict mode the plugin even fails on warnings.
+	 */
+	private boolean strictMode = false;
+
+	/**
+	 * The version of the DS spec this plugin generates a descriptor for. By
+	 * default the version is detected by the used tags.
+	 */
+	private SpecVersion specVersion;
+
+	/**
+	 * Do we must generate descriptors in separate files
+	 */
+	private boolean generateSeparateDescriptors = true;
+
+	/**
+	 * Bnd plugin properties.
+	 */
+	private Map<String, String> properties;
+
+	/**
+	 * Object used to report logs to bnd.
+	 */
+	private Reporter reporter;
+
+	/**
+	 * Sets the reporter for logging into the bnd logger.
+	 */
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	/**
+	 * Sets properties which can be specified in the "-plugin" directive. For
+	 * example: -plugin
+	 * org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;destdir
+	 * =target/classes
+	 */
+	public void setProperties(Map<String, String> map) {
+		this.properties = map;
+	}
+
+	/**
+	 * Scan scr or ds annotation from the target jar.
+	 */
+	public boolean analyzeJar(Analyzer analyzer) throws Exception {
+		this.log = new BndLog(reporter, analyzer.getBsn());
+
+		try {
+			init(analyzer);
+
+			log.info("Analyzing " + analyzer.getBsn());
+			final org.apache.felix.scrplugin.Project project = new org.apache.felix.scrplugin.Project();
+			project.setClassLoader(new URLClassLoader(getClassPath(analyzer),
+					this.getClass().getClassLoader()));
+			project.setDependencies(getDependencies(analyzer));
+			project.setSources(getClassFiles(analyzer));
+			project.setClassesDirectory(destDir.getAbsolutePath());
+
+			// create options
+			final Options options = new Options();
+			options.setOutputDirectory(destDir);
+			options.setSCRName(finalName);
+			options.setMetaTypeName(metaTypeName);
+			options.setGenerateAccessors(generateAccessor);
+			options.setStrictMode(strictMode);
+			options.setProperties(new HashMap<String, String>());
+			options.setSpecVersion(specVersion);
+			options.setGenerateSeparateDescriptors(generateSeparateDescriptors);
+
+			final SCRDescriptorGenerator generator = new SCRDescriptorGenerator(
+					log);
+
+			// setup from plugin configuration
+			generator.setOptions(options);
+			generator.setProject(project);
+
+			Result r = generator.execute();
+
+			// Embed scr descriptors in target jar
+			List<String> scrFiles = r.getScrFiles();
+			if (scrFiles != null) {
+				StringBuilder sb = new StringBuilder();
+				for (String scrFile : scrFiles) {
+					log.info("SCR descriptor result file: " + scrFile);
+					sb.append(scrFile);
+					sb.append(",");
+					putResource(analyzer, scrFile);
+				}
+				sb.setLength(sb.length() - 1);
+				analyzer.setProperty("Service-Component", sb.toString());
+			}
+
+			// Embed metatype descriptors in target jar
+			List<String> metaTypeFiles = r.getMetatypeFiles();
+			if (metaTypeFiles != null) {
+				for (String metaTypeFile : metaTypeFiles) {
+					log.info("Meta Type result file: " + metaTypeFile);
+					putResource(analyzer, metaTypeFile);
+				}
+			}
+		} catch (Throwable t) {
+			log.error("Got unexpected exception while analyzing",
+					t);
+		} finally {
+			log.close();
+		}
+		return true;
+	}
+
+	private void init(Analyzer analyzer) {
+		this.log.setLevel(parseOption(properties, LOGLEVEL,
+				BndLog.Level.Warn.toString()));
+
+		String param = parseOption(properties, DESTDIR, new File(analyzer.getBase() + File.separator + "bin").getPath());
+		destDir = new File(param);
+		if (!destDir.exists() && !destDir.mkdirs()) {
+			throw new IllegalArgumentException("Could not create " + destDir
+					+ " directory.");
+		}
+
+		finalName = parseOption(properties, FINALNAME, finalName);
+		metaTypeName = parseOption(properties, METATYPENAME, metaTypeName);
+		generateAccessor = parseOption(properties, GENERATE_ACCESSOR,
+				generateAccessor);
+		strictMode = parseOption(properties, STRICT_MODE, strictMode);
+		String version = parseOption(properties, SPECVERSION, null);
+		specVersion = SpecVersion.fromName(version);
+		if (version != null && specVersion == null) {
+			throw new IllegalArgumentException(
+					"Unknown spec version specified: " + version);
+		}
+		generateSeparateDescriptors = parseOption(properties, GENSEPDESC,
+				generateSeparateDescriptors);
+
+		if (log.isInfoEnabled()) {
+			log.info("Initialized Bnd ScrPlugin: destDir=" + destDir
+					+ ", finalName=" + finalName + ", metaTypeName="
+					+ metaTypeName + ", strictMode=" + strictMode
+					+ ", specVersion=" + specVersion
+					+ ", generateSeparateDescriptors="
+					+ generateSeparateDescriptors);
+		}
+	}
+
+	private String parseOption(Map<String, String> opts, String name, String def) {
+		String value = opts.get(name);
+		return value == null ? def : value;
+	}
+
+	private boolean parseOption(Map<String, String> opts, String name,
+			boolean def) {
+		String value = opts.get(name);
+		return value == null ? def : Boolean.valueOf(value);
+	}
+
+	private Collection<Source> getClassFiles(Analyzer analyzer)
+			throws Exception {
+		ArrayList<Source> files = new ArrayList<Source>();
+		Collection<Clazz> expanded = analyzer.getClasses("",
+				QUERY.NAMED.toString(), "*");
+		for (final Clazz c : expanded) {
+			files.add(new Source() {
+				public File getFile() {
+					log.debug("Found class "
+							+ c.getAbsolutePath());
+					return new File(c.getAbsolutePath());
+				}
+
+				public String getClassName() {
+					return c.getFQN();
+				}
+			});
+		}
+		return files;
+	}
+
+	private URL[] getClassPath(Analyzer a) throws Exception {
+		final ArrayList<URL> path = new ArrayList<URL>();
+		for (final Jar j : a.getClasspath()) {
+			path.add(j.getSource().toURI().toURL());
+		}
+		log.info("Using claspath: " + path);
+		return path.toArray(new URL[path.size()]);
+	}
+
+	private void putResource(Analyzer analyzer, String path) throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		File f = new File(destDir, path);
+		InputStream in = new BufferedInputStream(new FileInputStream(f));
+		try {
+			int c;
+			while ((c = in.read()) != -1) {
+				out.write(c);
+			}
+		} finally {
+			in.close();
+		}
+		byte[] data = out.toByteArray();
+		analyzer.getJar().putResource(path, new EmbeddedResource(data, 0));
+	}
+
+	private List<File> getDependencies(Analyzer a) {
+		ArrayList<File> files = new ArrayList<File>();
+		for (final Jar j : a.getClasspath()) {
+			File file = j.getSource();
+			if (file.isFile()) {
+				files.add(file);
+			}
+		}
+		log.info("Using dependencies: " + files);
+		return files;
+	}
+}