Latest pre-release bnd code

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1387568 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
index 09c5f25..f9c396e 100644
--- a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
+++ b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
@@ -29,18 +29,35 @@
 	final static Pattern		PROPERTY_PATTERN		= Pattern
 																.compile("\\s*([^=\\s:]+)\\s*(?::\\s*(Boolean|Byte|Character|Short|Integer|Long|Float|Double|String)\\s*)?=(.*)");
 
-	public static final Version	V1_0					= new Version("1.0.0");																												// "1.1.0"
+	public static final Version	V1_0					= new Version("1.0.0");																												// "1.0.0"
 	public static final Version	V1_1					= new Version("1.1.0");																												// "1.1.0"
-	public static final Version	V1_2					= new Version("1.2.0");																												// "1.1.0"
-	static Pattern				BINDNAME				= Pattern.compile("(set|add|bind)?(.*)");
-	static Pattern				BINDDESCRIPTOR			= Pattern
-																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)V");
+	public static final Version	V1_2					= new Version("1.2.0");																												// "1.2.0"
+//	public static final Version	V1_3					= new Version("1.3.0");																												// "1.3.0"
 
-	static Pattern				LIFECYCLEDESCRIPTOR		= Pattern
-																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
-	static Pattern				REFERENCEBINDDESCRIPTOR	= Pattern
+	public static final String FELIX_1_2				= "http://felix.apache.org/xmlns/scr/v1.2.0-felix";
+	
+	static Pattern				BINDNAME				= Pattern.compile("(set|add|bind)?(.*)");
+	
+	static Pattern				BINDDESCRIPTORDS10			= Pattern
+																.compile("\\(((L([^;]+);)|Lorg/osgi/framework/ServiceReference;)\\)V");
+	static Pattern				BINDDESCRIPTORDS11			= Pattern
+																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)V");
+	static Pattern				BINDDESCRIPTORDS13			= Pattern
+																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)Ljava/util/Map;");
+	static Pattern				REFERENCEBINDDESCRIPTOR		= Pattern
 																.compile("\\(Lorg/osgi/framework/ServiceReference;\\)V");
 
+	static Pattern				LIFECYCLEDESCRIPTORDS10		= Pattern
+																.compile("\\((Lorg/osgi/service/component/ComponentContext;)\\)V");
+	static Pattern				LIFECYCLEDESCRIPTORDS11		= Pattern
+																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
+	static Pattern				LIFECYCLEDESCRIPTORDS13		= Pattern
+																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)Ljava/util/Map;");
+	static Pattern				DEACTIVATEDESCRIPTORDS11	= Pattern
+																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;)|(Ljava/lang/Integer;)|(I))*\\)V");
+	static Pattern				DEACTIVATEDESCRIPTORDS13	= Pattern
+																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;)|(Ljava/lang/Integer;)|(I))*\\)Ljava/util/Map;");
+
 	ComponentDef				component				= new ComponentDef();
 
 	Clazz						clazz;
@@ -50,18 +67,22 @@
 	Analyzer					analyzer;
 	MultiMap<String,String>		methods					= new MultiMap<String,String>();
 	TypeRef						extendsClass;
-	boolean						inherit;
+	final boolean						inherit;
 	boolean						baseclass				= true;
+	
+	final boolean						felixExtensions;
 
-	AnnotationReader(Analyzer analyzer, Clazz clazz, boolean inherit) {
+	AnnotationReader(Analyzer analyzer, Clazz clazz, boolean inherit, boolean felixExtensions) {
 		this.analyzer = analyzer;
 		this.clazz = clazz;
 		this.inherit = inherit;
+		this.felixExtensions = felixExtensions;
 	}
 
 	public static ComponentDef getDefinition(Clazz c, Analyzer analyzer) throws Exception {
 		boolean inherit = Processor.isTrue(analyzer.getProperty("-dsannotations-inherit"));
-		AnnotationReader r = new AnnotationReader(analyzer, c, inherit);
+		boolean felixExtensions = Processor.isTrue(analyzer.getProperty("-ds-felix-extensions"));
+		AnnotationReader r = new AnnotationReader(analyzer, c, inherit, felixExtensions);
 		return r.getDef();
 	}
 
@@ -112,15 +133,36 @@
 
 		if (methods.containsKey(value)) {
 			for (String descriptor : methods.get(value)) {
-				Matcher matcher = BINDDESCRIPTOR.matcher(descriptor);
+				Matcher matcher = BINDDESCRIPTORDS10.matcher(descriptor);
 				if (matcher.matches()) {
 					String type = matcher.group(2);
-					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) || type.equals("Ljava/util/Map;")
+					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
 							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
 
 						return value;
 					}
 				}
+				matcher = BINDDESCRIPTORDS11.matcher(descriptor);
+				if (matcher.matches()) {
+					String type = matcher.group(2);
+					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
+							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
+						rdef.updateVersion(V1_1);
+						return value;
+					}
+				}
+				matcher = BINDDESCRIPTORDS13.matcher(descriptor);
+				if (felixExtensions && matcher.matches()) {
+					String type = matcher.group(2);
+					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
+							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
+						rdef.updateVersion(V1_2);
+						if (component.xmlns == null) {
+							component.xmlns = FELIX_1_2;
+						}
+						return value;
+					}
+				}
 			}
 			analyzer.error(
 					"A related method to %s from the reference %s has no proper prototype for class %s. Expected void %s(%s s [,Map m] | ServiceReference r)",
@@ -153,27 +195,66 @@
 	/**
 	 * 
 	 */
-	protected void doDeactivate() {
-		if (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+	protected void doActivate() {
+		String methodDescriptor = method.getDescriptor().toString();
+		if ("activate".equals(method.getName()) && LIFECYCLEDESCRIPTORDS10.matcher(methodDescriptor).matches()) {
+			component.activate = method.getName();			
+		} else if (LIFECYCLEDESCRIPTORDS11.matcher(methodDescriptor).matches()) {
+			component.activate = method.getName();	
+			component.updateVersion(V1_1);
+		} else if (felixExtensions && LIFECYCLEDESCRIPTORDS13.matcher(methodDescriptor).matches()) {
+			component.activate = method.getName();	
+			component.updateVersion(V1_2);
+			if (component.xmlns == null) {
+				component.xmlns = FELIX_1_2;
+			}
+		} else 
 			analyzer.error(
-					"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
 					clazz, method.getDescriptor());
-		else {
+		
+	}
+
+	/**
+	 * 
+	 */
+	protected void doDeactivate() {
+		String methodDescriptor = method.getDescriptor().toString();
+		if ( "deactivate".equals(method.getName()) && LIFECYCLEDESCRIPTORDS10.matcher(methodDescriptor).matches()) {
+			component.deactivate = method.getName();			
+		} else if (DEACTIVATEDESCRIPTORDS11.matcher(methodDescriptor).matches()) {
 			component.deactivate = method.getName();
-		}
+			component.updateVersion(V1_1);
+		} else if (felixExtensions && DEACTIVATEDESCRIPTORDS13.matcher(methodDescriptor).matches()) {
+			component.deactivate = method.getName();
+			component.updateVersion(V1_2);
+			if (component.xmlns == null) {
+				component.xmlns = FELIX_1_2;
+			}
+		} else
+			analyzer.error(
+					"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, BundleContext, int, or Integer is allowed. Found: %s",
+					clazz, method.getDescriptor());
 	}
 
 	/**
 	 * 
 	 */
 	protected void doModified() {
-		if (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+		if (LIFECYCLEDESCRIPTORDS11.matcher(method.getDescriptor().toString()).matches()) {
+			component.modified = method.getName();
+			component.updateVersion(V1_1);
+		} else if (felixExtensions && LIFECYCLEDESCRIPTORDS13.matcher(method.getDescriptor().toString()).matches()) {
+			component.modified = method.getName();
+			component.updateVersion(V1_2);
+			if (component.xmlns == null) {
+				component.xmlns = FELIX_1_2;
+			}
+		} else
+
 			analyzer.error(
 					"Modified method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
 					clazz, method.getDescriptor());
-		else {
-			component.modified = method.getName();
-		}
 	}
 
 	/**
@@ -202,13 +283,29 @@
 		} else {
 			// We have to find the type of the current method to
 			// link it to the referenced service.
-			Matcher m = BINDDESCRIPTOR.matcher(method.getDescriptor().toString());
+			String methodDescriptor = method.getDescriptor().toString();
+			Matcher m = BINDDESCRIPTORDS10.matcher(methodDescriptor);
 			if (m.matches()) {
 				def.service = Descriptors.binaryToFQN(m.group(3));
-			} else
-				throw new IllegalArgumentException(
-						"Cannot detect the type of a Component Reference from the descriptor: "
-								+ method.getDescriptor());
+			} else {
+				m = BINDDESCRIPTORDS11.matcher(methodDescriptor);
+				if (m.matches()) {
+					def.service = Descriptors.binaryToFQN(m.group(3));
+					def.updateVersion(V1_1);
+				} else {
+					m = BINDDESCRIPTORDS13.matcher(methodDescriptor);
+					if (felixExtensions && m.matches()) {
+						def.service = Descriptors.binaryToFQN(m.group(3));
+						def.updateVersion(V1_2);
+						if (component.xmlns == null) {
+							component.xmlns = FELIX_1_2;
+						}
+					} else 
+						throw new IllegalArgumentException(
+							"Cannot detect the type of a Component Reference from the descriptor: "
+									+ method.getDescriptor());
+				}
+			}
 		}
 
 		// Check if we have a target, this must be a filter
@@ -227,19 +324,6 @@
 	}
 
 	/**
-	 * 
-	 */
-	protected void doActivate() {
-		if (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
-			analyzer.error(
-					"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
-					clazz, method.getDescriptor());
-		else {
-			component.activate = method.getName();
-		}
-	}
-
-	/**
 	 * @param annotation
 	 * @throws Exception
 	 */
@@ -249,7 +333,6 @@
 		if (component.implementation != null)
 			return;
 
-		component.version = V1_0;
 		component.implementation = clazz.getClassName();
 		component.name = comp.name();
 		component.factory = comp.factory();
@@ -263,8 +346,10 @@
 		if (annotation.get("servicefactory") != null)
 			component.servicefactory = comp.servicefactory();
 
-		if (annotation.get("configurationPid") != null)
+		if (annotation.get("configurationPid") != null) {
 			component.configurationPid = comp.configurationPid();
+			component.updateVersion(V1_2);
+		}
 
 		if (annotation.get("xmlns") != null)
 			component.xmlns = comp.xmlns();