Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / iapi / services / classfile / ClassEnumeration.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/services/classfile/ClassEnumeration.java
new file mode 100644 (file)
index 0000000..6cc2258
--- /dev/null
@@ -0,0 +1,201 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.services.classfile.ClassEnumeration\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.services.classfile;\r
+\r
+import java.util.Enumeration;\r
+import java.util.HashSet;\r
+import java.util.StringTokenizer;\r
+import org.apache.derby.iapi.services.classfile.VMDescriptor;\r
+\r
+/**\r
+       An enumeration that filters only classes\r
+       from the enumeration of the class pool.\r
+\r
+       Code has been added to also include classes referenced in method and\r
+       field signatures.\r
+*/\r
+\r
+\r
+class ClassEnumeration implements Enumeration {\r
+       ClassHolder     cpt;\r
+       Enumeration                     inner;\r
+       CONSTANT_Index_info     position;\r
+       HashSet           foundClasses;\r
+    Enumeration         classList;\r
+\r
+    ClassEnumeration(   ClassHolder cpt,\r
+                        Enumeration e,\r
+                        Enumeration methods,\r
+                        Enumeration fields)\r
+    {\r
+               this.cpt = cpt;\r
+               inner = e;\r
+               foundClasses = new HashSet(30, 0.8f);\r
+               findMethodReferences(methods, foundClasses);\r
+               findFieldReferences(fields, foundClasses);\r
+               findClassReferences(foundClasses);\r
+               classList = java.util.Collections.enumeration(foundClasses);\r
+\r
+       }\r
+\r
+       public boolean hasMoreElements() {\r
+           return classList.hasMoreElements();\r
+       }\r
+\r
+       // uses cpt and inner\r
+       private void findClassReferences(HashSet foundClasses)\r
+       {\r
+\r
+               ConstantPoolEntry       item;\r
+               CONSTANT_Index_info     ref;\r
+\r
+\r
+               while (inner.hasMoreElements())\r
+               {\r
+                       item = (ConstantPoolEntry) inner.nextElement();\r
+                       if (item == null)\r
+                               continue;\r
+                       if (item.getTag() == VMDescriptor.CONSTANT_Class)\r
+                       {\r
+                               ref = (CONSTANT_Index_info) item;\r
+\r
+                               String className = cpt.className(ref.getIndex());\r
+\r
+                               // if this is an array type, distillClasses can\r
+                               // handle it\r
+                if (className.startsWith("["))\r
+                {\r
+                   distillClasses(className, foundClasses);\r
+                   continue;\r
+                }\r
+\r
+                // now we've got either a primitive type or a classname\r
+                // primitive types are all a single char\r
+\r
+                if (className.length() > 1)\r
+                {\r
+                    //we've got a class\r
+                    if (className.startsWith("java"))\r
+                    {\r
+                        //skip it\r
+                        continue;\r
+                    }\r
+\r
+                    foundClasses.add(className);\r
+                }\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       private void findMethodReferences(  Enumeration methods,\r
+                                           HashSet foundClasses)\r
+       {\r
+           while (methods.hasMoreElements())\r
+           {\r
+               ClassMember member = (ClassMember) methods.nextElement();\r
+               String description = member.getDescriptor();\r
+               distillClasses(description, foundClasses);\r
+           }\r
+       }\r
+\r
+       private void findFieldReferences(   Enumeration fields,\r
+                                           HashSet foundClasses)\r
+       {\r
+           while (fields.hasMoreElements())\r
+           {\r
+               ClassMember member = (ClassMember) fields.nextElement();\r
+               String description = member.getDescriptor();\r
+               distillClasses(description, foundClasses);\r
+           }\r
+       }\r
+\r
+       void distillClasses(String fieldOrMethodSig, HashSet foundClasses)\r
+       {\r
+           if (fieldOrMethodSig == null || fieldOrMethodSig.length() < 1)\r
+           {\r
+               //empty string\r
+               return;\r
+           }\r
+\r
+           if (fieldOrMethodSig.charAt(0) != '(')\r
+           {\r
+           // first time through, we're dealing with a field here\r
+           // otherwise, it is a token from a method signature\r
+\r
+            int classNameStart = fieldOrMethodSig.indexOf('L');\r
+\r
+            if (classNameStart == -1)\r
+            {\r
+                // no class in the type, so stop\r
+                return;\r
+            }\r
+\r
+            // chop off any leading ['s or other Java-primitive type\r
+            // signifiers (like I or L) *AND* substitute the dots\r
+               String fieldType =\r
+                   fieldOrMethodSig.substring(classNameStart + 1).replace('/', '.');\r
+\r
+            // we have to check for the semi-colon in case we are\r
+            // actually looking at a token from a method signature\r
+               if (fieldType.endsWith(";"))\r
+               {\r
+               fieldType = fieldType.substring(0,fieldType.length()-1);\r
+            }\r
+\r
+               if (fieldType.startsWith("java"))\r
+               {\r
+                   return;     // it's a java base class and we don't care about\r
+                               // that either\r
+               }\r
+\r
+            foundClasses.add(fieldType);\r
+            return;\r
+         }\r
+         else\r
+         {\r
+            // it's a method signature\r
+            StringTokenizer tokens = new StringTokenizer(fieldOrMethodSig, "();[");\r
+            while (tokens.hasMoreElements())\r
+            {\r
+                String aToken = (String) tokens.nextToken();\r
+                // because of the semi-colon delimiter in the tokenizer, we\r
+                // can have only one class name per token and it must be the\r
+                // last item in the token\r
+                int classNameStart = aToken.indexOf('L');\r
+                if (classNameStart != -1)\r
+                {\r
+                    distillClasses(aToken, foundClasses);\r
+                }\r
+                else\r
+                {\r
+                    continue;\r
+                }\r
+            }\r
+         }\r
+     }\r
+\r
+       public Object nextElement() {\r
+        return classList.nextElement();\r
+       }\r
+\r
+}\r