1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package vogar;
18 
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import vogar.util.Strings;
24 
25 /**
26  * A {@code .java} file for execution as an action.
27  */
28 public final class DotJavaFile {
29     private static final Pattern PACKAGE_PATTERN = Pattern.compile(
30             "(?m)^\\s*package\\s+(\\S+)\\s*;");
31     private static final Pattern TYPE_DECLARATION_PATTERN = Pattern.compile(
32             "(?m)\\b(?:public|private\\s+)?(?:final\\s+)?(?:interface|class|enum)\\b");
33     private static final Pattern AT_TEST_PATTERN = Pattern.compile("\\W@test\\W");
34 
35     private final String simpleName;
36     private final String packageName;
37     private final String actionName;
38     private final boolean isJtreg;
39 
DotJavaFile(String simpleName, String packageName, String actionName, boolean isJtreg)40     private DotJavaFile(String simpleName, String packageName, String actionName, boolean isJtreg) {
41         this.simpleName = simpleName;
42         this.packageName = packageName;
43         this.actionName = actionName;
44         this.isJtreg = isJtreg;
45     }
46 
getActionName()47     public String getActionName() {
48         return actionName;
49     }
50 
51     /**
52      * Returns true if this file looks like a jtreg test. Jtreg tests usually
53      * require additional target setup; in particular they expect to be
54      * able to load files from their working directory.
55      */
isJtreg()56     public boolean isJtreg() {
57         return isJtreg;
58     }
59 
getClassName()60     public String getClassName() {
61         return packageName != null ? packageName + "." + simpleName : simpleName;
62     }
63 
parse(File javaFile)64     public static DotJavaFile parse(File javaFile) throws IOException {
65         // We can get the unqualified class name from the path.
66         // It's the last element minus the trailing ".java".
67         String filename = javaFile.getName();
68         String simpleName = filename.substring(0, filename.length() - ".java".length());
69 
70         // For the package, the only foolproof way is to look for the package
71         // declaration inside the file.
72         String content = Strings.readFile(javaFile);
73         boolean isjtreg = AT_TEST_PATTERN.matcher(content).find();
74 
75         String packageName;
76         String actionName;
77         Matcher packageMatcher = PACKAGE_PATTERN.matcher(content);
78         if (packageMatcher.find()) {
79             packageName = packageMatcher.group(1);
80             actionName = packageName + "." + simpleName;
81         } else {
82             packageName = null;
83             actionName = Action.nameForJavaFile(javaFile);
84         }
85 
86         if (!TYPE_DECLARATION_PATTERN.matcher(content).find()) {
87             throw new IllegalArgumentException("Malformed .java file: " + javaFile);
88         }
89 
90         return new DotJavaFile(simpleName, packageName, actionName, isjtreg);
91     }
92 }
93