Start searching of methods for references in the current source class and not in the class the reference is defined in. Start implementing method generation for references.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@570788 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
index e38859c..9d8be33 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
@@ -41,6 +41,8 @@
import org.apache.felix.scrplugin.tags.JavaClassDescriptorManager;
import org.apache.felix.scrplugin.tags.JavaField;
import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription;
+import org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription.Modification;
import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
import org.apache.felix.scrplugin.xml.MetaTypeIO;
import org.apache.maven.model.Resource;
@@ -240,7 +242,7 @@
// fields
do {
- JavaField[] fields = description.getFields();
+ final JavaField[] fields = description.getFields();
for (int i=0; fields != null && i < fields.length; i++) {
JavaTag tag = fields[i].getTagByName(Constants.REFERENCE);
if (tag != null) {
@@ -471,7 +473,8 @@
* @param defaultName
* @param component
*/
- protected void doReference(JavaTag reference, String defaultName, Component component) {
+ protected void doReference(JavaTag reference, String defaultName, Component component)
+ throws MojoExecutionException {
String name = reference.getNamedParameter(Constants.REFERENCE_NAME);
if (StringUtils.isEmpty(name)) {
name = defaultName;
@@ -486,20 +489,56 @@
}
if (!StringUtils.isEmpty(name)) {
- final Reference ref = new Reference(reference);
+ final Reference ref = new Reference(reference, component.getJavaClassDescription());
ref.setName(name);
ref.setInterfacename(type);
ref.setCardinality(reference.getNamedParameter(Constants.REFERENCE_CARDINALITY));
ref.setPolicy(reference.getNamedParameter(Constants.REFERENCE_POLICY));
ref.setTarget(reference.getNamedParameter(Constants.REFERENCE_TARGET));
- String value;
- value = reference.getNamedParameter(Constants.REFERENCE_BIND);
- if ( value != null ) {
- ref.setBind(value);
+ final String bindValue = reference.getNamedParameter(Constants.REFERENCE_BIND);
+ if ( bindValue != null ) {
+ ref.setBind(bindValue);
}
- value = reference.getNamedParameter(Constants.REFERENCE_UNDBIND);
- if ( value != null ) {
- ref.setUnbind(value);
+ final String unbindValue = reference.getNamedParameter(Constants.REFERENCE_UNDBIND);
+ if ( unbindValue != null ) {
+ ref.setUnbind(unbindValue);
+ }
+ // if this is a field we look for the bind/unbind methods
+ // and create them if they are not availabe
+ if ( false ) {
+ if ( reference.getField() != null && component.getJavaClassDescription() instanceof ModifiableJavaClassDescription ) {
+ String changed = null;
+ // Only create method if no bind name has been specified
+ if ( bindValue == null && ref.findMethod(ref.getBind()) == null ) {
+ // create bind method
+ final String realMethodName = "bind" + Character.toUpperCase(name.charAt(0))
+ + name.substring(1);
+ changed = ((ModifiableJavaClassDescription)component.getJavaClassDescription()).addProtectedMethod(
+ realMethodName,
+ type,
+ "{this." + reference.getField().getName() + "=param;}");
+ }
+ if ( unbindValue == null && ref.findMethod(ref.getUnbind()) == null ) {
+ // create unbind method
+ final String realMethodName = "unbind" + Character.toUpperCase(name.charAt(0))
+ + name.substring(1);
+ final String c = ((ModifiableJavaClassDescription)component.getJavaClassDescription()).addProtectedMethod(
+ realMethodName,
+ type,
+ "{this." + reference.getField().getName() + "=null;}");
+ if ( changed == null ) {
+ changed = c;
+ } else {
+ changed = changed + c;
+ }
+ }
+ if ( changed != null ) {
+ Modification mod = new Modification();
+ mod.lineNumber = 10;
+ mod.content = changed;
+ ((ModifiableJavaClassDescription)component.getJavaClassDescription()).writeClassFile(new Modification[] {mod});
+ }
+ }
}
component.addReference(ref);
}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Component.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Component.java
index 51c5e91..50d9d9c 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Component.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Component.java
@@ -79,6 +79,16 @@
}
/**
+ * Return the associated java class description
+ */
+ public JavaClassDescription getJavaClassDescription() {
+ if ( this.tag != null ) {
+ return this.tag.getJavaClassDescription();
+ }
+ return null;
+ }
+
+ /**
* @return
*/
public List getProperties() {
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Reference.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Reference.java
index 3ae5e26..fe151f1 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Reference.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/om/Reference.java
@@ -40,18 +40,21 @@
protected String bind;
protected String unbind;
+ protected final JavaClassDescription javaClassDescription;
+
/**
* Default constructor.
*/
public Reference() {
- this(null);
+ this(null, null);
}
/**
* Constructor from java source.
*/
- public Reference(JavaTag t) {
+ public Reference(JavaTag t, JavaClassDescription desc) {
super(t);
+ this.javaClassDescription = desc;
// set default values
this.setBind("bind");
this.setUnbind("unbind");
@@ -133,19 +136,14 @@
}
// validate bind and unbind methods
- JavaClassDescription javaClass = this.tag.getJavaClassDescription();
- if (javaClass != null) {
- this.bind = this.validateMethod(javaClass, this.bind, issues, warnings);
- this.unbind = this.validateMethod(javaClass, this.unbind, issues, warnings);
- } else {
- issues.add(this.getMessage("Cannot find Java class to which the reference belongs"));
- }
+ this.bind = this.validateMethod(this.bind, issues, warnings);
+ this.unbind = this.validateMethod(this.unbind, issues, warnings);
}
- protected String validateMethod(JavaClassDescription javaClass, String methodName, List issues, List warnings)
+ protected String validateMethod(String methodName, List issues, List warnings)
throws MojoExecutionException {
- JavaMethod method = this.findMethod(javaClass, methodName);
+ JavaMethod method = this.findMethod(methodName);
if (method == null) {
issues.add(this.getMessage("Missing method " + methodName + " for reference " + this.getName()));
@@ -162,17 +160,16 @@
return method.getName();
}
- protected JavaMethod findMethod(JavaClassDescription javaClass, String methodName)
+ public JavaMethod findMethod(String methodName)
throws MojoExecutionException {
-
String[] sig = new String[]{ this.getInterfacename() };
String[] sig2 = new String[]{ "org.osgi.framework.ServiceReference" };
// service interface or ServiceReference first
String realMethodName = methodName;
- JavaMethod method = javaClass.getMethodBySignature(realMethodName, sig);
+ JavaMethod method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
if (method == null) {
- method = javaClass.getMethodBySignature(realMethodName, sig2);
+ method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
}
// append reference name with service interface and ServiceReference
@@ -180,10 +177,10 @@
realMethodName = methodName + Character.toUpperCase(this.name.charAt(0))
+ this.name.substring(1);
- method = javaClass.getMethodBySignature(realMethodName, sig);
+ method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
}
if (method == null) {
- method = javaClass.getMethodBySignature(realMethodName, sig2);
+ method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
}
// append type name with service interface and ServiceReference
@@ -191,10 +188,10 @@
int lastDot = this.getInterfacename().lastIndexOf('.');
realMethodName = methodName
+ this.getInterfacename().substring(lastDot + 1);
- method = javaClass.getMethodBySignature(realMethodName, sig);
+ method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
}
if (method == null) {
- method = javaClass.getMethodBySignature(realMethodName, sig2);
+ method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
}
return method;
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java
new file mode 100644
index 0000000..28986f8
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scrplugin.tags;
+
+
+public interface ModifiableJavaClassDescription {
+
+ String addProtectedMethod(String name, String paramType, String contents);
+
+ void writeClassFile(Modification[] mods);
+
+ public static final class Modification {
+ public int lineNumber;
+ public String content;
+ }
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java
index cf569c9..bccf47d 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java
@@ -18,6 +18,9 @@
*/
package org.apache.felix.scrplugin.tags.qdox;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -27,10 +30,12 @@
import org.apache.felix.scrplugin.tags.JavaField;
import org.apache.felix.scrplugin.tags.JavaMethod;
import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription;
import org.apache.maven.plugin.MojoExecutionException;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.JavaSource;
import com.thoughtworks.qdox.model.Type;
@@ -38,15 +43,19 @@
* <code>QDoxJavaClassDescription.java</code>...
*
*/
-public class QDoxJavaClassDescription implements JavaClassDescription {
+public class QDoxJavaClassDescription
+ implements JavaClassDescription, ModifiableJavaClassDescription {
protected final JavaClass javaClass;
protected final JavaClassDescriptorManager manager;
+ protected final JavaSource source;
+
public QDoxJavaClassDescription(JavaSource source, JavaClassDescriptorManager m) {
this.javaClass = source.getClasses()[0];
this.manager = m;
+ this.source = source;
}
/**
@@ -216,4 +225,49 @@
public boolean isPublic() {
return this.javaClass.isPublic();
}
+
+ /**
+ * @see org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription#addProtectedMethod(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public String addProtectedMethod(String name, String paramType, String contents) {
+ final JavaParameter param = new JavaParameter(new Type(paramType), "param");
+ final JavaParameter[] params = new JavaParameter[] {param};
+ final com.thoughtworks.qdox.model.JavaMethod meth = new com.thoughtworks.qdox.model.JavaMethod();
+ meth.setName(name);
+ meth.setSourceCode(contents);
+ meth.setParameters(params);
+ meth.setModifiers(new String[] {"protected"});
+ this.javaClass.addMethod(meth);
+ return "protected void " + name + "(" + paramType + " param)" + contents + " ";
+ }
+
+ /**
+ * @see org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription#writeClassFile(org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription.Modification[])
+ */
+ public void writeClassFile(Modification[] mods) {
+ if ( mods != null && mods.length > 0 ) {
+ try {
+ final LineNumberReader reader = new LineNumberReader(new FileReader(this.source.getFile()));
+ for(int i=0; i<mods.length; i++) {
+ int lineNumber = mods[i].lineNumber;
+ while ( reader.getLineNumber() < lineNumber ) {
+ final String line = reader.readLine();
+ System.out.println(line);
+ }
+ final String line = reader.readLine();
+ System.out.print(line);
+ System.out.println(mods[i].content);
+ }
+ String line;
+ while ( (line = reader.readLine()) != null ) {
+ System.out.println(line);
+ }
+ reader.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
}