View Javadoc

1   /*
2    * Jour - bytecode instrumentation library
3    *
4    * Copyright (C) 2007 Vlad Skarzhevskyy
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Library General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Library General Public License for more details.
15   *
16   * You should have received a copy of the GNU Library General Public
17   * License along with this library; if not, write to the
18   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   * Boston, MA  02111-1307, USA.
20   */
21  package net.sf.jour.signature;
22  
23  import java.util.HashSet;
24  import java.util.Set;
25  import java.util.StringTokenizer;
26  
27  import javassist.CtClass;
28  import javassist.CtMember;
29  import javassist.Modifier;
30  
31  /**
32   * @author vlads
33   * 
34   */
35  public class APIFilter {
36  
37  	public static final String javaLangString = "java.lang.String";
38  
39  	public static final int PUBLIC = 1;
40  
41  	public static final int PROTECTED = 2;
42  
43  	public static final int PACKAGE = 3;
44  
45  	public static final int PRIVATE = 4;
46  
47  	public static final APIFilter ALL = new APIFilter(PRIVATE);
48  
49  	private int level;
50  
51  	private Set packageSet;
52  
53  	public APIFilter(int level) throws IllegalArgumentException {
54  		this.level = level;
55  		if (this.level > PRIVATE) {
56  			throw new IllegalArgumentException("level " + level);
57  		}
58  	}
59  
60  	public APIFilter(String level) throws IllegalArgumentException {
61  		this(getAPILevel(level));
62  	}
63  
64  	public APIFilter(String level, String packages) throws IllegalArgumentException {
65  		this(level);
66  		if ((packages != null) && (packages.length() > 0)) {
67  			packageSet = new HashSet();
68  			StringTokenizer st = new StringTokenizer(packages, ";");
69  			if (st.hasMoreTokens()) {
70  				while (st.hasMoreTokens()) {
71  					packageSet.add(st.nextToken());
72  				}
73  			} else {
74  				packageSet.add(packages);
75  			}
76  		}
77  	}
78  
79  	public static int getAPILevel(String level) throws IllegalArgumentException {
80  		if (level == null) {
81  			return PROTECTED;
82  		} else if (level.equalsIgnoreCase("public")) {
83  			return PUBLIC;
84  		} else if (level.equalsIgnoreCase("protected")) {
85  			return PROTECTED;
86  		} else if (level.equalsIgnoreCase("package")) {
87  			return PACKAGE;
88  		} else if (level.equalsIgnoreCase("private")) {
89  			return PRIVATE;
90  		} else {
91  			throw new IllegalArgumentException("level " + level);
92  		}
93  	}
94  
95  	public boolean isAPIModifier(int mod) {
96  		if (Modifier.isPublic(mod)) {
97  			return (level >= PUBLIC);
98  		} else if (Modifier.isProtected(mod)) {
99  			return (level >= PROTECTED);
100 		} else if (Modifier.isPackage(mod)) {
101 			return (level >= PACKAGE);
102 		} else if (Modifier.isPrivate(mod)) {
103 			return (level >= PRIVATE);
104 		}
105 		return true;
106 	}
107 
108 	public boolean isSelectedPackage(String className) {
109 		if (packageSet == null) {
110 			return true;
111 		}
112 		StringBuffer packageName = new StringBuffer();
113 		StringTokenizer st = new StringTokenizer(className, ".");
114 		while (st.hasMoreTokens()) {
115 			if (packageName.length() > 0) {
116 				packageName.append(".");
117 			}
118 			packageName.append(st.nextToken());
119 			if (packageSet.contains(packageName.toString())) {
120 				return true;
121 			}
122 		}
123 		return false;
124 	}
125 
126 	public boolean isAPIClass(CtClass klass) {
127 		if (!isAPIModifier(klass.getModifiers())) {
128 			return false;
129 		} else {
130 			return isSelectedPackage(klass.getName());
131 		}
132 	}
133 
134 	public boolean isAPIMember(CtMember member) {
135 		return isAPIModifier(member.getModifiers());
136 	}
137 
138 	public static boolean isExportableConstantType(CtClass klass) {
139 		if (klass.isPrimitive()) {
140 			return true;
141 		} else if (javaLangString.equals(klass.getName())) {
142 			return true;
143 		}
144 		return false;
145 	}
146 
147 	public APIFilter getLessRestrictiveFilter() throws IllegalArgumentException {
148 		return new APIFilter(this.level + 1);
149 	}
150 
151 	static int filterModifiers(int mod) {
152 		if (Modifier.isNative(mod)) {
153 			mod = mod - Modifier.NATIVE;
154 		}
155 		if (Modifier.isSynchronized(mod)) {
156 			mod = mod - Modifier.SYNCHRONIZED;
157 		}
158 		if (Modifier.isInterface(mod)) {
159 			mod = mod - Modifier.INTERFACE;
160 			mod = mod - Modifier.ABSTRACT;
161 		}
162 		return mod;
163 	}
164 }