Skip to content

Commit 40d94a1

Browse files
committed
extracting the R class package from the AndroidManifest.xml file. Added some tests for the extraction
1 parent 4964b05 commit 40d94a1

4 files changed

Lines changed: 155 additions & 21 deletions

File tree

‎AndroidAnnotations/pom.xml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<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">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
23

34
<modelVersion>4.0.0</modelVersion>
45
<groupId>com.googlecode.androidannotations</groupId>
@@ -82,6 +83,12 @@
8283
<artifactId>codemodel</artifactId>
8384
<version>2.5-SNAPSHOT</version>
8485
</dependency>
86+
<dependency>
87+
<groupId>junit</groupId>
88+
<artifactId>junit</artifactId>
89+
<version>4.8.1</version>
90+
<scope>test</scope>
91+
</dependency>
8592
</dependencies>
8693

8794
<distributionManagement>

‎AndroidAnnotations/src/main/java/com/googlecode/androidannotations/rclass/CompiledRClassFinder.java‎

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,21 @@
1515
*/
1616
package com.googlecode.androidannotations.rclass;
1717

18-
import java.util.Iterator;
19-
import java.util.Set;
18+
import java.io.BufferedReader;
19+
import java.io.File;
20+
import java.io.FileNotFoundException;
21+
import java.io.FileReader;
22+
import java.io.IOException;
2023

24+
import javax.annotation.processing.Filer;
25+
import javax.annotation.processing.Messager;
2126
import javax.annotation.processing.ProcessingEnvironment;
22-
import javax.lang.model.element.Element;
23-
import javax.lang.model.element.PackageElement;
2427
import javax.lang.model.element.TypeElement;
2528
import javax.lang.model.util.Elements;
29+
import javax.tools.Diagnostic.Kind;
30+
import javax.tools.FileObject;
31+
import javax.tools.StandardLocation;
2632

27-
import com.googlecode.androidannotations.annotations.Enhance;
2833
import com.googlecode.androidannotations.helper.AnnotationHelper;
2934
import com.googlecode.androidannotations.model.AnnotationElements;
3035

@@ -34,31 +39,55 @@ public CompiledRClassFinder(ProcessingEnvironment processingEnv) {
3439
super(processingEnv);
3540
}
3641

37-
public IRClass find(AnnotationElements extractedModel) {
42+
public IRClass find(AnnotationElements extractedModel) throws IOException {
43+
44+
File manifestFile = findManifestFile();
45+
46+
String rClassPackage = extractPackage(manifestFile);
47+
48+
if (rClassPackage == null) {
49+
Messager messager = processingEnv.getMessager();
50+
messager.printMessage(Kind.WARNING, "Could not find the AndroidManifest.xml file in " + manifestFile.getAbsolutePath());
51+
return IRClass.EMPTY_R_CLASS;
52+
}
3853

3954
Elements elementUtils = processingEnv.getElementUtils();
55+
String rClass = rClassPackage + ".R";
56+
TypeElement rType = elementUtils.getTypeElement(rClass);
4057

41-
Set<? extends Element> annotatedElements = extractedModel.getAnnotatedElements(Enhance.class);
58+
if (rType == null) {
59+
Messager messager = processingEnv.getMessager();
60+
messager.printMessage(Kind.WARNING, "The AndroidManifest.xml file was found, but not the compiled R class: " + rClass);
61+
return IRClass.EMPTY_R_CLASS;
62+
}
4263

43-
Iterator<? extends Element> iterator = annotatedElements.iterator();
64+
return new RClass(rType);
65+
}
4466

45-
if (iterator.hasNext()) {
46-
TypeElement firstLayoutAnnotatedElement = (TypeElement) iterator.next();
67+
private String extractPackage(File manifestFile) throws FileNotFoundException, IOException {
68+
FileReader reader = new FileReader(manifestFile);
69+
BufferedReader br = new BufferedReader(reader);
4770

48-
// TODO better handling at finding R class
49-
PackageElement firstActivityPackage = elementUtils.getPackageOf(firstLayoutAnnotatedElement);
71+
String line;
72+
while ((line = br.readLine()) != null) {
5073

51-
TypeElement rType = elementUtils.getTypeElement(firstActivityPackage.getQualifiedName() + "." + "R");
74+
ManifestPackageExtractor extractor = new ManifestPackageExtractor(line);
5275

53-
if (rType != null) {
54-
return new RClass(rType);
55-
} else {
56-
printAnnotationError(firstLayoutAnnotatedElement, Enhance.class, "In order to find the R class, all Activities annotated with @" + Enhance.class.getSimpleName() + " should belong to the same package as the R class, which is not the case for: " + firstLayoutAnnotatedElement);
57-
return IRClass.EMPTY_R_CLASS;
76+
if (extractor.matches()) {
77+
return extractor.extract();
5878
}
59-
} else {
60-
return IRClass.EMPTY_R_CLASS;
6179
}
80+
return null;
81+
}
82+
83+
private File findManifestFile() throws IOException {
84+
Filer filer = processingEnv.getFiler();
85+
86+
FileObject res = filer.getResource(StandardLocation.CLASS_OUTPUT, "", "");
87+
File projectRoot = new File(res.toUri()).getParentFile();
88+
89+
File androidManifestFile = new File(projectRoot, "AndroidManifest.xml");
90+
return androidManifestFile;
6291
}
6392

6493
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2010-2011 Pierre-Yves Ricau (py.ricau at gmail.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.googlecode.androidannotations.rclass;
17+
18+
import java.util.regex.Matcher;
19+
import java.util.regex.Pattern;
20+
21+
public class ManifestPackageExtractor {
22+
23+
private static final Pattern pattern = Pattern.compile("package\\s*=\\s*\"([^\"]+)\"");
24+
private Matcher matcher;
25+
private boolean matches;
26+
27+
public ManifestPackageExtractor(String manifestLine) {
28+
if (manifestLine != null) {
29+
matcher = pattern.matcher(manifestLine);
30+
matches = matcher.find();
31+
} else {
32+
matches = false;
33+
}
34+
}
35+
36+
public boolean matches() {
37+
return matches;
38+
}
39+
40+
public String extract() {
41+
return matches ? matcher.group(1) : null;
42+
}
43+
44+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.googlecode.androidannotations.rclass;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNull;
6+
import static org.junit.Assert.assertTrue;
7+
8+
import org.junit.Test;
9+
10+
public class ManifestPackageExtractorTest{
11+
12+
@Test
13+
public void simpleMatches() {
14+
ManifestPackageExtractor extractor = new ManifestPackageExtractor("package=\"com.toto\"");
15+
assertTrue(extractor.matches());
16+
}
17+
18+
@Test
19+
public void spacesMatches() {
20+
ManifestPackageExtractor extractor = new ManifestPackageExtractor(" package = \"com.toto\" ");
21+
assertTrue(extractor.matches());
22+
}
23+
24+
@Test
25+
public void fooDoesNotMatch() {
26+
ManifestPackageExtractor extractor = new ManifestPackageExtractor("Hello you");
27+
assertFalse(extractor.matches());
28+
}
29+
30+
@Test
31+
public void emptyPackageDoesNotMatch() {
32+
ManifestPackageExtractor extractor = new ManifestPackageExtractor("package=\"\"");
33+
assertFalse(extractor.matches());
34+
}
35+
36+
@Test
37+
public void simpleExtract() {
38+
ManifestPackageExtractor extractor = new ManifestPackageExtractor("package=\"com.toto\"");
39+
assertEquals("com.toto", extractor.extract());
40+
}
41+
42+
@Test
43+
public void fooExtractsNull() {
44+
ManifestPackageExtractor extractor = new ManifestPackageExtractor("Hello you");
45+
assertNull(extractor.extract());
46+
}
47+
48+
@Test
49+
public void inputIsNull() {
50+
new ManifestPackageExtractor(null).extract();
51+
}
52+
53+
54+
}

0 commit comments

Comments
 (0)