1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.kernel.util;
24  
25  import java.io.BufferedReader;
26  import java.io.File;
27  import java.io.FileReader;
28  import java.io.IOException;
29  import java.io.Reader;
30  import java.io.StreamTokenizer;
31  
32  import java.util.HashSet;
33  import java.util.Set;
34  
35  /**
36   * <a href="ClassUtil.java.html"><b><i>View Source</i></b></a>
37   *
38   * @author Brian Wing Shun Chan
39   * @author Sandeep Soni
40   *
41   */
42  public class ClassUtil {
43  
44      public static Set<String> getClasses(File file) throws IOException {
45          String fileName = file.getName();
46  
47          if (fileName.endsWith(".java")) {
48              fileName = fileName.substring(0, fileName.length() - 5);
49          }
50  
51          return getClasses(new FileReader(file), fileName);
52      }
53  
54      public static Set<String> getClasses(Reader reader, String className)
55          throws IOException {
56  
57          Set<String> classes = new HashSet<String>();
58  
59          StreamTokenizer st = new StreamTokenizer(new BufferedReader(reader));
60  
61          _setupParseTable(st);
62  
63          st.wordChars('@', '@');
64  
65          while (st.nextToken() != StreamTokenizer.TT_EOF) {
66              if (st.ttype == StreamTokenizer.TT_WORD) {
67                  if (st.sval.equals("class") || st.sval.equals("interface")) {
68                      break;
69                  }
70                  else if (st.sval.startsWith("@")) {
71                      String token = StringUtil.replace(st.sval, '@', "");
72  
73                      classes.add(token);
74                  }
75              }
76          }
77  
78          _setupParseTable(st);
79  
80          while (st.nextToken() != StreamTokenizer.TT_EOF) {
81              if (st.ttype == StreamTokenizer.TT_WORD) {
82                  if (st.sval.indexOf('.') >= 0) {
83                      classes.add(st.sval.substring(0, st.sval.indexOf('.')));
84                  }
85                  else {
86                      classes.add(st.sval);
87                  }
88              }
89              else if (st.ttype != StreamTokenizer.TT_NUMBER &&
90                       st.ttype != StreamTokenizer.TT_EOL) {
91  
92                  if (Character.isUpperCase((char)st.ttype)) {
93                      classes.add(String.valueOf((char)st.ttype));
94                  }
95              }
96          }
97  
98          classes.remove(className);
99  
100         return classes;
101     }
102 
103     public static boolean isSubclass(Class<?> a, Class<?> b) {
104         if (a == b) {
105             return true;
106         }
107 
108         if (a == null || b == null) {
109             return false;
110         }
111 
112         for (Class<?> x = a; x != null; x = x.getSuperclass()) {
113             if (x == b) {
114                 return true;
115             }
116 
117             if (b.isInterface()) {
118                 Class<?>[] interfaces = x.getInterfaces();
119 
120                 for (int i = 0; i < interfaces.length; i++) {
121                     if (isSubclass(interfaces[i], b)) {
122                         return true;
123                     }
124                 }
125             }
126         }
127 
128         return false;
129     }
130 
131     public static boolean isSubclass(Class<?> a, String s) {
132         if (a == null || s == null) {
133             return false;
134         }
135 
136         if (a.getName().equals(s)) {
137             return true;
138         }
139 
140         for (Class<?> x = a; x != null; x = x.getSuperclass()) {
141             if (x.getName().equals(s)) {
142                 return true;
143             }
144 
145             Class<?>[] interfaces = x.getInterfaces();
146 
147             for (int i = 0; i < interfaces.length; i++) {
148                 if (isSubclass(interfaces[i], s)) {
149                     return true;
150                 }
151             }
152         }
153 
154         return false;
155     }
156 
157     private static void _setupParseTable(StreamTokenizer st) {
158         st.resetSyntax();
159         st.slashSlashComments(true);
160         st.slashStarComments(true);
161         st.wordChars('a', 'z');
162         st.wordChars('A', 'Z');
163         st.wordChars('.', '.');
164         st.wordChars('0', '9');
165         st.wordChars('_', '_');
166         st.lowerCaseMode(false);
167         st.eolIsSignificant(false);
168         st.quoteChar('"');
169         st.quoteChar('\'');
170         st.parseNumbers();
171     }
172 
173 }