using the autoconfigured @COLLECTIONS@ imports.

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1087 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent 48d5c63aec
commit 6786a3fa35
  1. 44
      jode/configure.in
  2. 9
      jode/jode/bytecode/BinaryInfo.java.in
  3. 12
      jode/jode/bytecode/BytecodeInfo.java.in
  4. 785
      jode/jode/bytecode/ClassInfo.java
  5. 1
      jode/jode/decompiler/ClassAnalyzer.java
  6. 21
      jode/jode/decompiler/ImportHandler.java.in
  7. 6
      jode/jode/decompiler/MethodAnalyzer.java.in
  8. 6
      jode/jode/expr/CheckNullOperator.java.in
  9. 6
      jode/jode/expr/Expression.java.in
  10. 15
      jode/jode/expr/InvokeOperator.java.in
  11. 6
      jode/jode/expr/Operator.java.in
  12. 9
      jode/jode/flow/CatchBlock.java.in
  13. 22
      jode/jode/flow/FlowBlock.java.in
  14. 6
      jode/jode/flow/IfThenElseBlock.java.in
  15. 6
      jode/jode/flow/InstructionBlock.java.in
  16. 6
      jode/jode/flow/InstructionContainer.java.in
  17. 6
      jode/jode/flow/LoopBlock.java.in
  18. 9
      jode/jode/flow/RetBlock.java.in
  19. 6
      jode/jode/flow/SequentialBlock.java.in
  20. 12
      jode/jode/flow/SlotSet.java.in
  21. 12
      jode/jode/flow/StructuredBlock.java.in
  22. 6
      jode/jode/flow/SynchronizedBlock.java.in
  23. 17
      jode/jode/flow/TransformExceptionHandlers.java.in
  24. 12
      jode/jode/flow/VariableSet.java.in
  25. 23
      jode/jode/obfuscator/ClassBundle.java.in
  26. 34
      jode/jode/obfuscator/ClassIdentifier.java.in
  27. 24
      jode/jode/obfuscator/ConstantAnalyzer.java.in
  28. 18
      jode/jode/obfuscator/FieldIdentifier.java.in
  29. 9
      jode/jode/obfuscator/Identifier.java.in
  30. 9
      jode/jode/obfuscator/LocalIdentifier.java.in
  31. 12
      jode/jode/obfuscator/Main.java.in
  32. 12
      jode/jode/obfuscator/MethodIdentifier.java.in
  33. 15
      jode/jode/obfuscator/NameSwapper.java.in
  34. 12
      jode/jode/obfuscator/PackageIdentifier.java.in
  35. 15
      jode/jode/obfuscator/TranslationTable.java.in
  36. 23
      jode/jode/swingui/PackagesTreeModel.java.in
  37. 337
      jode/jode/util/AbstractCollection.java
  38. 560
      jode/jode/util/AbstractList.java
  39. 280
      jode/jode/util/AbstractMap.java
  40. 111
      jode/jode/util/AbstractSequentialList.java
  41. 78
      jode/jode/util/AbstractSet.java
  42. 489
      jode/jode/util/ArrayList.java
  43. 1685
      jode/jode/util/Arrays.java
  44. 138
      jode/jode/util/BasicMapEntry.java
  45. 198
      jode/jode/util/Bucket.java
  46. 234
      jode/jode/util/Collection.java
  47. 1413
      jode/jode/util/Collections.java
  48. 51
      jode/jode/util/Comparable.java
  49. 62
      jode/jode/util/Comparator.java
  50. 53
      jode/jode/util/ConcurrentModificationException.java
  51. 876
      jode/jode/util/HashMap.java
  52. 238
      jode/jode/util/HashSet.java
  53. 66
      jode/jode/util/Iterator.java
  54. 581
      jode/jode/util/LinkedList.java
  55. 331
      jode/jode/util/List.java
  56. 145
      jode/jode/util/ListIterator.java
  57. 29
      jode/jode/util/Makefile.am
  58. 55
      jode/jode/util/Map.java
  59. 46
      jode/jode/util/Set.java
  60. 48
      jode/jode/util/SimpleMap.java.in
  61. 6
      jode/jode/util/SimpleSet.java.in
  62. 38
      jode/jode/util/SortedMap.java
  63. 38
      jode/jode/util/SortedSet.java
  64. 1380
      jode/jode/util/TreeMap.java
  65. 331
      jode/jode/util/TreeSet.java
  66. 54
      jode/jode/util/UnsupportedOperationException.java

@ -89,15 +89,18 @@ JODE_CHECK_CLASS(java.lang.Object, $CLASSLIB,
AC_MSG_CHECKING(for collection classes)
JODE_CHECK_CLASS(java.util.Set, $CLASSPATH:$CLASSLIB,
[ COLLECTIONS="java.util" ],
[ COLLECTIONS="java.util"
COLLECTIONEXTRA="java.lang" ],
[ JODE_CHECK_CLASS(com.sun.java.util.collections.Set, $CLASSPATH:$CLASSLIB,
[ COLLECTIONS="com.sun.java.util.collections" ],
[ COLLECTIONS="com.sun.java.util.collections"
COLLECTIONEXTRA="com.sun.java.util.collections" ],
[ AC_MSG_RESULT(no)
AC_MSG_ERROR(You need the Java 1.2 collection classes in your classpath)
])
] )
AC_MSG_RESULT($COLLECTIONS)
AC_SUBST(COLLECTIONS)
AC_SUBST(COLLECTIONEXTRA)
AC_MSG_CHECKING(for gnu.getopt)
JODE_CHECK_CLASS(gnu.getopt.Getopt, $CLASSPATH:$CLASSLIB,
@ -136,9 +139,44 @@ jode/obfuscator/Makefile
jode/swingui/Makefile
jode/type/Makefile
jode/util/Makefile
jode/GlobalOptions.java
jode/bytecode/BinaryInfo.java
jode/bytecode/BytecodeInfo.java
jode/bytecode/ClassInfo.java
jode/decompiler/ImportHandler.java
jode/decompiler/MethodAnalyzer.java
jode/expr/Expression.java
jode/expr/InvokeOperator.java
jode/expr/Operator.java
jode/expr/CheckNullOperator.java
jode/flow/RetBlock.java
jode/flow/InstructionContainer.java
jode/flow/LoopBlock.java
jode/flow/SequentialBlock.java
jode/flow/SlotSet.java
jode/flow/StructuredBlock.java
jode/flow/SynchronizedBlock.java
jode/flow/VariableSet.java
jode/flow/CatchBlock.java
jode/flow/IfThenElseBlock.java
jode/flow/InstructionBlock.java
jode/flow/FlowBlock.java
jode/flow/TransformExceptionHandlers.java
jode/obfuscator/TranslationTable.java
jode/obfuscator/Main.java
jode/obfuscator/FieldIdentifier.java
jode/obfuscator/Identifier.java
jode/obfuscator/NameSwapper.java
jode/obfuscator/PackageIdentifier.java
jode/obfuscator/ClassBundle.java
jode/obfuscator/ConstantAnalyzer.java
jode/obfuscator/LocalIdentifier.java
jode/obfuscator/MethodIdentifier.java
jode/obfuscator/ClassIdentifier.java
jode/swingui/Main.java
jode/swingui/PackagesTreeModel.java
jode/util/SimpleSet.java
jode/util/SimpleMap.java
jode/GlobalOptions.java
bin/Makefile
bin/jode
doc/Makefile

@ -26,13 +26,8 @@ import java.io.IOException;
import java.io.InputStream;
import jode.util.SimpleMap;
///#ifdef JDK12
///import java.util.Map;
///import java.util.Iterator;
///#else
import jode.util.Map;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
/**

@ -29,15 +29,9 @@ import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.AbstractCollectoin;
///import java.util.Iterator;
///#else
import jode.util.Collection;
import jode.util.AbstractCollection;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.AbstractCollection;
import @COLLECTIONS@.Iterator;
/**

@ -1,785 +0,0 @@
/* ClassInfo Copyright (C) 1998-1999 Jochen Hoenicke.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package jode.bytecode;
import jode.GlobalOptions;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Enumeration;
///#ifdef JDK12
///import java.util.Map;
///import java.util.HashMap;
///import java.lang.ref.WeakReference;
///import java.lang.ref.ReferenceQueue;
///#else
import java.util.Hashtable;
///#endif
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* This class does represent a class similar to java.lang.Class. You
* can get the super class and the interfaces.
*
* The main difference to java.lang.Class is, that the objects are builded
* from a stream containing the .class file, and that it uses the
* <code>Type</code> to represent types instead of Class itself.
*
* @author Jochen Hoenicke
*/
public class ClassInfo extends BinaryInfo {
private static SearchPath classpath;
///#ifdef JDK12
/// private static final Map classes = new HashMap();
/// private static final ReferenceQueue queue = new ReferenceQueue();
///#else
private static final Hashtable classes = new Hashtable();
///#endif
private int status = 0;
private boolean modified = false;
private int modifiers = -1;
private String name;
private ClassInfo superclass;
private ClassInfo[] interfaces;
private FieldInfo[] fields;
private MethodInfo[] methods;
private InnerClassInfo[] outerClasses;
private InnerClassInfo[] innerClasses;
private InnerClassInfo[] extraClasses;
private String sourceFile;
public final static ClassInfo javaLangObject = forName("java.lang.Object");
public static void setClassPath(String path) {
classpath = new SearchPath(path);
///#ifdef JDK12
/// java.lang.ref.Reference died;
/// while ((died = queue.poll()) != null) {
/// classes.values().remove(died);
/// }
/// Iterator i = classes.values().iterator();
/// while (i.hasNext()) {
/// ClassInfo ci = (ClassInfo) ((WeakReference)i.next()).get();
/// if (ci == null) {
/// i.remove();
/// continue;
/// }
///#else
Enumeration enum = classes.elements();
while (enum.hasMoreElements()) {
ClassInfo ci = (ClassInfo) enum.nextElement();
///#endif
ci.status = 0;
ci.superclass = null;
ci.fields = null;
ci.interfaces = null;
ci.methods = null;
ci.removeAllAttributes();
}
}
public static boolean exists(String name) {
return classpath.exists(name.replace('.', '/') + ".class");
}
public static boolean isPackage(String name) {
return classpath.isDirectory(name.replace('.', '/'));
}
public static Enumeration getClassesAndPackages(final String packageName) {
final Enumeration enum =
classpath.listFiles(packageName.replace('.','/'));
return new Enumeration() {
public boolean hasMoreElements() {
return enum.hasMoreElements();
}
public Object nextElement() {
String name = (String) enum.nextElement();
if (!name.endsWith(".class"))
// This is a package
return name;
return name.substring(0, name.length()-6);
}
};
}
public static ClassInfo forName(String name) {
if (name == null
|| name.indexOf(';') != -1
|| name.indexOf('[') != -1
|| name.indexOf('/') != -1)
throw new IllegalArgumentException("Illegal class name: "+name);
///#ifdef JDK12
/// java.lang.ref.Reference died;
/// while ((died = queue.poll()) != null) {
/// classes.values().remove(died);
/// }
/// WeakReference ref = (WeakReference) classes.get(name);
/// ClassInfo clazz = (ref == null) ? null : (ClassInfo) ref.get();
///#else
ClassInfo clazz = (ClassInfo) classes.get(name);
///#endif
if (clazz == null) {
clazz = new ClassInfo(name);
///#ifdef JDK12
/// classes.put(name, new WeakReference(clazz, queue));
///#else
classes.put(name, clazz);
///#endif
}
return clazz;
}
private ClassInfo(String name) {
this.name = name;
}
protected void readAttribute(String name, int length,
ConstantPool cp,
DataInputStream input,
int howMuch) throws IOException {
if ((howMuch & ALL_ATTRIBUTES) != 0 && name.equals("SourceFile")) {
if (length != 2)
throw new ClassFormatException("SourceFile attribute"
+ " has wrong length");
sourceFile = cp.getUTF8(input.readUnsignedShort());
} else if ((howMuch & (OUTERCLASSES | INNERCLASSES)) != 0
&& name.equals("InnerClasses")) {
int count = input.readUnsignedShort();
int innerCount = 0, outerCount = 0, extraCount = 0;
InnerClassInfo[] innerClassInfo = new InnerClassInfo[count];
for (int i=0; i< count; i++) {
int innerIndex = input.readUnsignedShort();
int outerIndex = input.readUnsignedShort();
int nameIndex = input.readUnsignedShort();
String inner = cp.getClassName(innerIndex);
String outer =
outerIndex != 0 ? cp.getClassName(outerIndex) : null;
String innername =
nameIndex != 0 ? cp.getUTF8(nameIndex) : null;
int access = input.readUnsignedShort();
if (innername != null && innername.length() == 0)
innername = null;
InnerClassInfo ici = new InnerClassInfo
(inner, outer, innername, access);
if (outer != null && outer.equals(getName())
&& innername != null)
innerClassInfo[innerCount++] = ici;
else
innerClassInfo[count - (++extraCount)] = ici;
}
{
String lastOuterName = getName();
for (int i = count - extraCount; i < count; i++) {
InnerClassInfo ici = innerClassInfo[i];
if (ici.inner.equals(lastOuterName)) {
for (int j = i; j > count - extraCount; j--)
innerClassInfo[j] = innerClassInfo[j-1];
innerClassInfo[count-extraCount] = ici;
extraCount--;
outerCount++;
lastOuterName = ici.outer;
}
}
}
if (innerCount > 0) {
innerClasses = new InnerClassInfo[innerCount];
System.arraycopy(innerClassInfo, 0,
innerClasses, 0, innerCount);
} else
innerClasses = null;
if (outerCount > 0) {
outerClasses = new InnerClassInfo[outerCount];
System.arraycopy(innerClassInfo, innerCount,
outerClasses, 0, outerCount);
} else
outerClasses = null;
if (extraCount > 0) {
extraClasses = new InnerClassInfo[extraCount];
System.arraycopy(innerClassInfo, innerCount + outerCount,
extraClasses, 0, extraCount);
} else
extraClasses = null;
if (length != 2 + 8 * count)
throw new ClassFormatException
("InnerClasses attribute has wrong length");
} else
super.readAttribute(name, length, cp, input, howMuch);
}
public void read(DataInputStream input, int howMuch) throws IOException {
/* Since we have to read the whole class anyway, we load all
* info, that we may need later and that does not take much memory.
*/
howMuch |= FIELDS | METHODS | HIERARCHY | INNERCLASSES | OUTERCLASSES;
howMuch &= ~status;
/* header */
if (input.readInt() != 0xcafebabe)
throw new ClassFormatException("Wrong magic");
if (input.readUnsignedShort() > 3)
throw new ClassFormatException("Wrong minor");
if (input.readUnsignedShort() != 45)
throw new ClassFormatException("Wrong major");
/* constant pool */
ConstantPool cpool = new ConstantPool();
cpool.read(input);
/* always read modifiers, name, super, ifaces */
{
modifiers = input.readUnsignedShort();
String className = cpool.getClassName(input.readUnsignedShort());
if (!name.equals(className))
throw new ClassFormatException("wrong name " + className);
String superName = cpool.getClassName(input.readUnsignedShort());
superclass = superName != null ? ClassInfo.forName(superName) : null;
int count = input.readUnsignedShort();
interfaces = new ClassInfo[count];
for (int i=0; i< count; i++) {
interfaces[i] = ClassInfo.forName
(cpool.getClassName(input.readUnsignedShort()));
}
status |= HIERARCHY;
}
/* fields */
if ((howMuch & (FIELDS | ALL_ATTRIBUTES)) != 0) {
int count = input.readUnsignedShort();
if ((howMuch & FIELDS) != 0)
fields = new FieldInfo[count];
for (int i=0; i< count; i++) {
if ((howMuch & FIELDS) != 0)
fields[i] = new FieldInfo(this);
fields[i].read(cpool, input, howMuch);
}
} else {
byte[] skipBuf = new byte[6];
int count = input.readUnsignedShort();
for (int i=0; i< count; i++) {
input.readFully(skipBuf); // modifier, name, type
skipAttributes(input);
}
}
/* methods */
if ((howMuch & (METHODS | ALL_ATTRIBUTES)) != 0) {
int count = input.readUnsignedShort();
if ((howMuch & METHODS) != 0)
methods = new MethodInfo[count];
for (int i=0; i< count; i++) {
if ((howMuch & METHODS) != 0)
methods[i] = new MethodInfo(this);
methods[i].read(cpool, input, howMuch);
}
} else {
byte[] skipBuf = new byte[6];
int count = input.readUnsignedShort();
for (int i=0; i< count; i++) {
input.readFully(skipBuf); // modifier, name, type
skipAttributes(input);
}
}
/* attributes */
readAttributes(cpool, input, howMuch);
status |= howMuch;
}
public void reserveSmallConstants(GrowableConstantPool gcp) {
for (int i=0; i < fields.length; i++)
fields[i].reserveSmallConstants(gcp);
for (int i=0; i < methods.length; i++)
methods[i].reserveSmallConstants(gcp);
}
public void prepareWriting(GrowableConstantPool gcp) {
gcp.putClassName(name);
gcp.putClassName(superclass.getName());
for (int i=0; i < interfaces.length; i++)
gcp.putClassName(interfaces[i].getName());
for (int i=0; i < fields.length; i++)
fields[i].prepareWriting(gcp);
for (int i=0; i < methods.length; i++)
methods[i].prepareWriting(gcp);
if (sourceFile != null) {
gcp.putUTF8("SourceFile");
gcp.putUTF8(sourceFile);
}
if (outerClasses != null || innerClasses != null
|| extraClasses != null) {
gcp.putUTF8("InnerClasses");
int outerCount = outerClasses != null ? outerClasses.length : 0;
for (int i=outerCount; i-- > 0;) {
gcp.putClassName(outerClasses[i].inner);
if (outerClasses[i].outer != null)
gcp.putClassName(outerClasses[i].outer);
if (outerClasses[i].name != null)
gcp.putUTF8(outerClasses[i].name);
}
int innerCount = innerClasses != null ? innerClasses.length : 0;
for (int i=0; i< innerCount; i++) {
gcp.putClassName(innerClasses[i].inner);
if (innerClasses[i].outer != null)
gcp.putClassName(innerClasses[i].outer);
if (innerClasses[i].name != null)
gcp.putUTF8(innerClasses[i].name);
}
int extraCount = extraClasses != null ? extraClasses.length : 0;
for (int i=0; i< extraCount; i++) {
gcp.putClassName(extraClasses[i].inner);
if (extraClasses[i].outer != null)
gcp.putClassName(extraClasses[i].outer);
if (extraClasses[i].name != null)
gcp.putUTF8(extraClasses[i].name);
}
}
prepareAttributes(gcp);
}
protected int getKnownAttributeCount() {
int count = 0;
if (sourceFile != null)
count++;
if (innerClasses != null || outerClasses != null
|| extraClasses != null)
count++;
return count;
}
public void writeKnownAttributes(GrowableConstantPool gcp,
DataOutputStream output)
throws IOException {
if (sourceFile != null) {
output.writeShort(gcp.putUTF8("SourceFile"));
output.writeInt(2);
output.writeShort(gcp.putUTF8(sourceFile));
}
if (outerClasses != null || innerClasses != null
|| extraClasses != null) {
output.writeShort(gcp.putUTF8("InnerClasses"));
int outerCount = (outerClasses != null) ? outerClasses.length : 0;
int innerCount = (innerClasses != null) ? innerClasses.length : 0;
int extraCount = (extraClasses != null) ? extraClasses.length : 0;
int count = outerCount + innerCount + extraCount;
output.writeInt(2 + count * 8);
output.writeShort(count);
for (int i=outerCount; i-- > 0; ) {
output.writeShort(gcp.putClassName(outerClasses[i].inner));
output.writeShort(outerClasses[i].outer != null ?
gcp.putClassName(outerClasses[i].outer) : 0);
output.writeShort(outerClasses[i].name != null ?
gcp.putUTF8(outerClasses[i].name) : 0);
output.writeShort(outerClasses[i].modifiers);
}
for (int i=0; i< innerCount; i++) {
output.writeShort(gcp.putClassName(innerClasses[i].inner));
output.writeShort(innerClasses[i].outer != null ?
gcp.putClassName(innerClasses[i].outer) : 0);
output.writeShort(innerClasses[i].name != null ?
gcp.putUTF8(innerClasses[i].name) : 0);
output.writeShort(innerClasses[i].modifiers);
}
for (int i=0; i< extraCount; i++) {
output.writeShort(gcp.putClassName(extraClasses[i].inner));
output.writeShort(extraClasses[i].outer != null ?
gcp.putClassName(extraClasses[i].outer) : 0);
output.writeShort(extraClasses[i].name != null ?
gcp.putUTF8(extraClasses[i].name) : 0);
output.writeShort(extraClasses[i].modifiers);
}
}
}
public void write(DataOutputStream out) throws IOException {
GrowableConstantPool gcp = new GrowableConstantPool();
reserveSmallConstants(gcp);
prepareWriting(gcp);
out.writeInt(0xcafebabe);
out.writeShort(3);
out.writeShort(45);
gcp.write(out);
out.writeShort(modifiers);
out.writeShort(gcp.putClassName(name));
out.writeShort(gcp.putClassName(superclass.getName()));
out.writeShort(interfaces.length);
for (int i=0; i < interfaces.length; i++)
out.writeShort(gcp.putClassName(interfaces[i].getName()));
out.writeShort(fields.length);
for (int i=0; i < fields.length; i++)
fields[i].write(gcp, out);
out.writeShort(methods.length);
for (int i=0; i < methods.length; i++)
methods[i].write(gcp, out);
writeAttributes(gcp, out);
}
public void loadInfoReflection(Class clazz, int howMuch)
throws SecurityException {
if ((howMuch & HIERARCHY) != 0) {
modifiers = clazz.getModifiers();
if (clazz.getSuperclass() == null)
superclass = null;
else
superclass = ClassInfo.forName
(clazz.getSuperclass().getName());
Class[] ifaces = clazz.getInterfaces();
interfaces = new ClassInfo[ifaces.length];
for (int i=0; i<ifaces.length; i++)
interfaces[i] = ClassInfo.forName(ifaces[i].getName());
status |= HIERARCHY;
}
if ((howMuch & FIELDS) != 0 && fields == null) {
Field[] fs;
try {
fs = clazz.getDeclaredFields();
} catch (SecurityException ex) {
fs = clazz.getFields();
GlobalOptions.err.println
("Could only get public fields of class "
+ name + ".");
}
fields = new FieldInfo[fs.length];
for (int i = fs.length; --i >= 0; ) {
String type = TypeSignature.getSignature(fs[i].getType());
fields[i] = new FieldInfo
(this, fs[i].getName(), type, fs[i].getModifiers());
}
}
if ((howMuch & METHODS) != 0 && methods == null) {
Method[] ms;
try {
ms = clazz.getDeclaredMethods();
} catch (SecurityException ex) {
ms = clazz.getMethods();
GlobalOptions.err.println
("Could only get public methods of class "
+ name + ".");
}
methods = new MethodInfo[ms.length];
for (int i = ms.length; --i >= 0; ) {
String type = TypeSignature.getSignature
(ms[i].getParameterTypes(), ms[i].getReturnType());
methods[i] = new MethodInfo
(this, ms[i].getName(), type, ms[i].getModifiers());
}
}
if ((howMuch & INNERCLASSES) != 0 && innerClasses == null) {
Class[] is;
try {
is = clazz.getDeclaredClasses();
} catch (SecurityException ex) {
is = clazz.getClasses();
GlobalOptions.err.println
("Could only get public methods of class "
+ name + ".");
}
if (is.length > 0) {
innerClasses = new InnerClassInfo[is.length];
for (int i = is.length; --i >= 0; ) {
String inner = is[i].getName();
int dollar = inner.lastIndexOf('$');
String name = inner.substring(dollar+1);
innerClasses[i] = new InnerClassInfo
(inner, getName(), name, is[i].getModifiers());
}
}
}
if ((howMuch & OUTERCLASSES) != 0 && outerClasses == null) {
int count = 0;
Class declarer = clazz.getDeclaringClass();
while (declarer != null) {
count++;
declarer = declarer.getDeclaringClass();
}
if (count > 0) {
outerClasses = new InnerClassInfo[count];
Class current = clazz;
for (int i = 0; i < count; i++) {
declarer = current.getDeclaringClass();
String name = current.getName();
int dollar = name.lastIndexOf('$');
outerClasses[i] = new InnerClassInfo
(name, declarer.getName(),
name.substring(dollar+1), current.getModifiers());
current = declarer;
}
}
}
status |= howMuch;
}
public void loadInfo(int howMuch) {
if ((status & howMuch) == howMuch)
return;
if (modified) {
System.err.println("Allocating info 0x"
+ Integer.toHexString(howMuch)
+ " (status 0x" + Integer.toHexString(status)
+ ") in class " + this);
Thread.dumpStack();
return;
}
try {
DataInputStream input =
new DataInputStream(classpath.getFile(name.replace('.', '/')
+ ".class"));
read(input, howMuch);
} catch (IOException ex) {
String message = ex.getMessage();
if ((howMuch & ~(FIELDS|METHODS|HIERARCHY
|INNERCLASSES|OUTERCLASSES)) != 0) {
GlobalOptions.err.println
("Can't read class " + name + ".");
ex.printStackTrace(GlobalOptions.err);
throw new NoClassDefFoundError(name);
}
// Try getting the info through the reflection interface
// instead.
Class clazz = null;
try {
clazz = Class.forName(name);
} catch (ClassNotFoundException ex2) {
} catch (NoClassDefFoundError ex2) {
}
try {
if (clazz != null) {
loadInfoReflection(clazz, howMuch);
return;
}
} catch (SecurityException ex2) {
GlobalOptions.err.println
(ex2+" while collecting info about class " + name + ".");
}
// Give a warning and ``guess'' the hierarchie, methods etc.
GlobalOptions.err.println
("Can't read class " + name + ", types may be incorrect. ("
+ ex.getClass().getName()
+ (message != null ? ": " + message : "") + ")");
if ((howMuch & HIERARCHY) != 0) {
modifiers = Modifier.PUBLIC;
if (name.equals("java.lang.Object"))
superclass = null;
else
superclass = javaLangObject;
interfaces = new ClassInfo[0];
}
if ((howMuch & METHODS) != 0)
methods = new MethodInfo[0];
if ((howMuch & FIELDS) != 0)
fields = new FieldInfo[0];
status |= howMuch;
}
}
public String getName() {
return name;
}
public String getJavaName() {
/* Don't load attributes for class names not containing a
* dollar sign.
*/
if (name.indexOf('$') == -1)
return getName();
if (getOuterClasses() != null) {
int last = outerClasses.length-1;
StringBuffer sb =
new StringBuffer(outerClasses[last].outer != null
? outerClasses[last].outer : "METHOD");
for (int i=last; i >= 0; i--)
sb.append(".").append(outerClasses[i].name != null
? outerClasses[i].name : "ANONYMOUS");
return sb.toString();
}
return getName();
}
public ClassInfo getSuperclass() {
if ((status & HIERARCHY) == 0)
loadInfo(HIERARCHY);
return superclass;
}
public ClassInfo[] getInterfaces() {
if ((status & HIERARCHY) == 0)
loadInfo(HIERARCHY);
return interfaces;
}
public int getModifiers() {
if ((status & HIERARCHY) == 0)
loadInfo(HIERARCHY);
return modifiers;
}
public boolean isInterface() {
return Modifier.isInterface(getModifiers());
}
public FieldInfo findField(String name, String typeSig) {
if ((status & FIELDS) == 0)
loadInfo(FIELDS);
for (int i=0; i< fields.length; i++)
if (fields[i].getName().equals(name)
&& fields[i].getType().equals(typeSig))
return fields[i];
return null;
}
public MethodInfo findMethod(String name, String typeSig) {
if ((status & METHODS) == 0)
loadInfo(METHODS);
for (int i=0; i< methods.length; i++)
if (methods[i].getName().equals(name)
&& methods[i].getType().equals(typeSig))
return methods[i];
return null;
}
public MethodInfo[] getMethods() {
if ((status & METHODS) == 0)
loadInfo(METHODS);
return methods;
}
public FieldInfo[] getFields() {
if ((status & FIELDS) == 0)
loadInfo(FIELDS);
return fields;
}
public InnerClassInfo[] getOuterClasses() {
if ((status & OUTERCLASSES) == 0)
loadInfo(OUTERCLASSES);
return outerClasses;
}
public InnerClassInfo[] getInnerClasses() {
if ((status & INNERCLASSES) == 0)
loadInfo(INNERCLASSES);
return innerClasses;
}
public InnerClassInfo[] getExtraClasses() {
if ((status & INNERCLASSES) == 0)
loadInfo(INNERCLASSES);
return extraClasses;
}
public String getSourceFile() {
return sourceFile;
}
public void setName(String newName) {
name = newName;
modified = true;
}
public void setSuperclass(ClassInfo newSuper) {
superclass = newSuper;
modified = true;
}
public void setInterfaces(ClassInfo[] newIfaces) {
interfaces = newIfaces;
modified = true;
}
public void setModifiers(int newModifiers) {
modifiers = newModifiers;
modified = true;
}
public void setMethods(MethodInfo[] mi) {
methods = mi;
modified = true;
}
public void setFields(FieldInfo[] fi) {
fields = fi;
modified = true;
}
public void setOuterClasses(InnerClassInfo[] oc) {
outerClasses = oc;
modified = true;
}
public void setInnerClasses(InnerClassInfo[] ic) {
innerClasses = ic;
modified = true;
}
public void setExtraClasses(InnerClassInfo[] ec) {
extraClasses = ec;
modified = true;
}
public void setSourceFile(String newSource) {
sourceFile = newSource;
modified = true;
}
public boolean superClassOf(ClassInfo son) {
while (son != this && son != null) {
son = son.getSuperclass();
}
return son == this;
}
public boolean implementedBy(ClassInfo clazz) {
while (clazz != this && clazz != null) {
ClassInfo[] ifaces = clazz.getInterfaces();
for (int i=0; i< ifaces.length; i++) {
if (implementedBy(ifaces[i]))
return true;
}
clazz = clazz.getSuperclass();
}
return clazz == this;
}
public String toString() {
return name;
}
}

@ -29,7 +29,6 @@ import jode.bytecode.InnerClassInfo;
import jode.bytecode.ConstantPool;
import jode.expr.Expression;
import jode.expr.ThisOperator;
import jode.expr.ConstructorOperator;
import jode.flow.TransformConstructors;
import jode.flow.StructuredBlock;

@ -26,21 +26,12 @@ import jode.type.ArrayType;
import jode.type.ClassInterfacesType;
import jode.type.NullType;
///#ifdef JDK12
///import java.util.SortedMap;
///import java.util.TreeMap;
///import java.util.List;
///import java.util.LinkedList;
///import java.util.Comparator;
///import java.util.Iterator;
///#else
import jode.util.SortedMap;
import jode.util.TreeMap;
import jode.util.List;
import jode.util.LinkedList;
import jode.util.Comparator;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.SortedMap;
import @COLLECTIONS@.TreeMap;
import @COLLECTIONS@.List;
import @COLLECTIONS@.LinkedList;
import @COLLECTIONS@.Comparator;
import @COLLECTIONS@.Iterator;
import java.io.IOException;
import java.util.Hashtable;

@ -53,11 +53,7 @@ import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
///#ifdef JDK12
///import java.util.Map;
///#else
import jode.util.Map;
///#endif
import @COLLECTIONS@.Map;
public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
ImportHandler imports;

@ -22,11 +22,7 @@ import jode.type.Type;
import jode.decompiler.LocalInfo;
import jode.decompiler.TabbedPrintWriter;
///#ifdef JDK12
///import java.util.Collection;
///#else
import jode.util.Collection;
///#endif
import @COLLECTIONS@.Collection;
/**
* This is a pseudo operator, which represents the check against null

@ -22,11 +22,7 @@ import jode.type.Type;
import jode.GlobalOptions;
import jode.decompiler.TabbedPrintWriter;
///#ifdef JDK12
///import java.util.Collection;
///#else
import jode.util.Collection;
///#endif
import @COLLECTIONS@.Collection;
public abstract class Expression {
protected Type type;

@ -34,17 +34,10 @@ import jode.util.SimpleMap;
import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Collection;
///import java.util.Map;
///import java.util.Iterator;
///#else
import jode.util.Collections;
import jode.util.Collection;
import jode.util.Map;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
public final class InvokeOperator extends Operator
implements MatchableOperator {

@ -22,11 +22,7 @@ import jode.type.Type;
import jode.GlobalOptions;
import jode.decompiler.TabbedPrintWriter;
///#ifdef JDK12
///import java.util.Collection;
///#else
import jode.util.Collection;
///#endif
import @COLLECTIONS@.Collection;
public abstract class Operator extends Expression {
/* Don't reorder these constants unless you know what you are doing! */

@ -26,13 +26,8 @@ import jode.expr.LocalStoreOperator;
import jode.expr.StoreInstruction;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Set;
///#else
import jode.util.Collections;
import jode.util.Set;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Set;
/**

@ -18,7 +18,6 @@
*/
package jode.flow;
import java.util.*;
import jode.GlobalOptions;
import jode.AssertError;
import jode.decompiler.TabbedPrintWriter;
@ -29,22 +28,11 @@ import jode.expr.CombineableOperator;
import jode.util.SimpleMap;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Map;
///import java.util.Iterator;
///import java.util.Set;
///import java.util.SimpleSet;
///import java.util.ArrayList;
///import java.util.List;
///#else
import jode.util.Map;
import jode.util.Iterator;
import jode.util.Set;
import jode.util.ArrayList;
import jode.util.List;
import jode.util.SimpleSet;
///#endif
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.Set;
import @COLLECTIONS@.ArrayList;
import @COLLECTIONS@.List;
/**
* A flow block is the structure of which the flow graph consists. A

@ -24,11 +24,7 @@ import jode.expr.Expression;
import jode.type.Type;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* An IfThenElseBlock is the structured block representing an if

@ -26,11 +26,7 @@ import jode.expr.StoreInstruction;
import jode.expr.LocalStoreOperator;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* This is the structured block for atomic instructions.

@ -24,11 +24,7 @@ import jode.expr.InvokeOperator;
import jode.expr.LocalVarOperator;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* This is a method for block containing a single instruction.

@ -28,11 +28,7 @@ import jode.expr.LocalStoreOperator;
import jode.expr.CombineableOperator;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* This is the structured block for an Loop block.

@ -20,13 +20,8 @@
package jode.flow;
import jode.decompiler.LocalInfo;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Set;
///#else
import jode.util.Collections;
import jode.util.Set;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Set;
/**
* This block represents a ret instruction. A ret instruction is

@ -24,11 +24,7 @@ import jode.expr.LocalStoreOperator;
import jode.expr.StoreInstruction;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* A sequential block combines exactly two structured blocks to a new

@ -21,15 +21,9 @@ package jode.flow;
import jode.decompiler.LocalInfo;
import jode.util.ArrayEnum;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.AbstractSet;
///import java.util.Iterator;
///#else
import jode.util.Collection;
import jode.util.AbstractSet;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.AbstractSet;
import @COLLECTIONS@.Iterator;
/**
* This class represents a set of local info, all having different

@ -25,15 +25,9 @@ import jode.decompiler.LocalInfo;
import jode.decompiler.Declarable;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Iterator;
///import java.util.Set;
///#else
import jode.util.Collections;
import jode.util.Iterator;
import jode.util.Set;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.Set;
/**
* A structured block is the building block of the source programm.

@ -23,11 +23,7 @@ import jode.decompiler.TabbedPrintWriter;
import jode.expr.Expression;
import jode.util.SimpleSet;
///#ifdef JDK12
///import java.util.Set;
///#else
import jode.util.Set;
///#endif
import @COLLECTIONS@.Set;
/**
* This class represents a synchronized structured block.

@ -24,18 +24,11 @@ import jode.type.Type;
import jode.decompiler.LocalInfo;
import jode.expr.*;
///#ifdef JDK12
///import java.util.TreeSet;
///import java.util.SortedSetSet;
///import java.util.Map;
///import java.util.Iterator;
///#else
import jode.util.TreeSet;
import jode.util.SortedSet;
import jode.util.Map;
import jode.util.Iterator;
import jode.util.Comparable;
///#endif
import @COLLECTIONS@.TreeSet;
import @COLLECTIONS@.SortedSet;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
import @COLLECTIONEXTRA@.Comparable;
/**
*

@ -21,15 +21,9 @@ package jode.flow;
import jode.decompiler.LocalInfo;
import jode.util.ArrayEnum;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.AbstractSet;
///import java.util.Iterator;
///#else
import jode.util.Collection;
import jode.util.AbstractSet;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.AbstractSet;
import @COLLECTIONS@.Iterator;
/**
* This class represents a set of Variables, which are mainly used in

@ -24,22 +24,17 @@ import jode.bytecode.Reference;
import java.io.*;
import java.util.zip.ZipOutputStream;
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.Set;
import @COLLECTIONS@.HashSet;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.TreeMap;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.Iterator;
///import java.util.Set;
///import java.util.HashSet;
///import java.util.Map;
///import java.util.TreeMap;
///import java.util.WeakHashMap;
///import @COLLECTIONS@.WeakHashMap;
///#else
import jode.util.Collection;
import jode.util.Iterator;
import jode.util.Set;
import jode.util.HashSet;
import jode.util.Map;
import jode.util.TreeMap;
import jode.util.HashMap;
import @COLLECTIONS@.HashMap;
///#endif
public class ClassBundle {

@ -20,28 +20,17 @@
package jode.obfuscator;
import jode.GlobalOptions;
import jode.bytecode.*;
///#ifdef JDK12
///import java.util.Comparator;
///import java.util.Collection;
///import java.util.Collections;
///import java.util.ArrayList;
///import java.util.Arrays;
///import java.util.Iterator;
///import java.util.List;
///import java.util.LinkedList;
///import java.util.Map;
///#else
import jode.util.Comparator;
import jode.util.Collection;
import jode.util.Collections;
import jode.util.ArrayList;
import jode.util.Arrays;
import jode.util.Iterator;
import jode.util.List;
import jode.util.LinkedList;
import jode.util.Map;
import jode.util.UnsupportedOperationException;
///#endif
import @COLLECTIONS@.Comparator;
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.ArrayList;
import @COLLECTIONS@.Arrays;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.List;
import @COLLECTIONS@.LinkedList;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Random;
import @COLLECTIONEXTRA@.UnsupportedOperationException;
import java.lang.reflect.Modifier;
import java.security.MessageDigest;
@ -49,7 +38,6 @@ import java.security.NoSuchAlgorithmException;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;
public class ClassIdentifier extends Identifier {
PackageIdentifier pack;

@ -31,23 +31,13 @@ import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
import java.util.BitSet;
///#ifdef JDK12
///import java.util.Arrays;
///import java.util.Collection;
///import java.util.HashSet;
///import java.util.Set;
///import java.util.HashMap;
///import java.util.Map;
///import java.util.Iterator;
///#else
import jode.util.Arrays;
import jode.util.Collection;
import jode.util.HashSet;
import jode.util.Set;
import jode.util.HashMap;
import jode.util.Map;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Arrays;
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.HashSet;
import @COLLECTIONS@.Set;
import @COLLECTIONS@.HashMap;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
/**
* Analyze the code, assuming every field that is not yet written to

@ -20,19 +20,11 @@
package jode.obfuscator;
import java.lang.reflect.Modifier;
import jode.bytecode.*;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.Collections;
///import java.util.Iterator;
///import java.util.HashSet;
///import java.util.Map;
///#else
import jode.util.Collection;
import jode.util.Collections;
import jode.util.Iterator;
import jode.util.HashSet;
import jode.util.Map;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.HashSet;
import @COLLECTIONS@.Map;
public class FieldIdentifier extends Identifier{

@ -20,13 +20,8 @@
package jode.obfuscator;
import jode.GlobalOptions;
import java.io.*;
///#ifdef JDK12
///import java.util.Map;
///import java.util.Iterator;
///#else
import jode.util.Map;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
public abstract class Identifier {
/**

@ -19,13 +19,8 @@
package jode.obfuscator;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Iterator;
///#else
import jode.util.Collections;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Iterator;
public class LocalIdentifier extends Identifier {
String name;

@ -26,15 +26,9 @@ import java.util.StringTokenizer;
import java.lang.reflect.Modifier;
import java.io.PrintWriter;
import java.io.File;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.Arrays;
///import java.util.HashSet;
///#else
import jode.util.Collection;
import jode.util.Arrays;
import jode.util.HashSet;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Arrays;
import @COLLECTIONS@.HashSet;
public class Main {
public static boolean swapOrder = false;

@ -23,15 +23,9 @@ import jode.GlobalOptions;
import jode.bytecode.*;
import jode.type.Type;
///#ifdef JDK12
///import java.util.Collections;
///import java.util.Iterator;
///import java.util.Map;
///#else
import jode.util.Collections;
import jode.util.Iterator;
import jode.util.Map;
///#endif
import @COLLECTIONS@.Collections;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.Map;
///#ifdef JDK12
///import java.lang.ref.SoftReference;

@ -20,17 +20,10 @@
package jode.obfuscator;
import java.util.Random;
///#ifdef JDK12
///import java.util.Collection;
///import java.util.Set;
///import java.util.HashSet;
///import java.util.Iterator;
///#else
import jode.util.Collection;
import jode.util.Set;
import jode.util.HashSet;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Collection;
import @COLLECTIONS@.Set;
import @COLLECTIONS@.HashSet;
import @COLLECTIONS@.Iterator;
public class NameSwapper implements Renamer {

@ -29,15 +29,9 @@ import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
///#ifdef JDK12
///import java.util.Map;
///import java.util.HashMap;
///import java.util.Iterator;
///#else
import jode.util.Map;
import jode.util.HashMap;
import jode.util.Iterator;
///#endif
import @COLLECTIONS@.Map;
import @COLLECTIONS@.HashMap;
import @COLLECTIONS@.Iterator;
public class PackageIdentifier extends Identifier {
ClassBundle bundle;

@ -19,15 +19,12 @@
package jode.obfuscator;
///#ifdef JDK12
///import java.util.Map;
///import java.util.TreeMap;
///import java.util.Iterator;
///#else
import jode.util.Comparator;
import jode.util.Map;
import jode.util.TreeMap;
import jode.util.Iterator;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.TreeMap;
import @COLLECTIONS@.Iterator;
///#ifndef JDK12
import @COLLECTIONS@.Comparator;
///#endif
import java.io.InputStream;

@ -26,22 +26,13 @@ import @JAVAX_SWING@.tree.TreePath;
import @JAVAX_SWING@.event.TreeModelListener;
import @JAVAX_SWING@.event.TreeModelEvent;
///#ifndef JDK12
///import java.util.Arrays;
///import java.util.TreeSet;
///import java.util.HashSet;
///import java.util.Set;
///import java.util.HashMap;
///import java.util.Map;
///#else
import jode.util.Comparable;
import jode.util.Arrays;
import jode.util.TreeSet;
import jode.util.HashSet;
import jode.util.Set;
import jode.util.HashMap;
import jode.util.Map;
///#endif
import @COLLECTIONEXTRA@.Comparable;
import @COLLECTIONS@.Arrays;
import @COLLECTIONS@.TreeSet;
import @COLLECTIONS@.HashSet;
import @COLLECTIONS@.Set;
import @COLLECTIONS@.HashMap;
import @COLLECTIONS@.Map;
import java.util.Enumeration;

@ -1,337 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// AbstractCollection.java -- Abstract implementation of most of Collection
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.lang.reflect.Array;
/**
* A basic implementation of most of the methods in the Collection interface to
* make it easier to create a collection. To create an unmodifiable Collection,
* just subclass AbstractCollection and provide implementations of the
* iterator() and size() methods. The Iterator returned by iterator() need only
* provide implementations of hasNext() and next() (that is, it may throw an
* UnsupportedOperationException if remove() is called). To create a modifiable
* Collection, you must in addition provide an implementation of the
* add(Object) method and the Iterator returned by iterator() must provide an
* implementation of remove(). Other methods should be overridden if the
* backing data structure allows for a more efficient implementation. The
* precise implementation used by AbstractCollection is documented, so that
* subclasses can tell which methods could be implemented more efficiently.
*/
public abstract class AbstractCollection implements Collection {
/**
* Return an Iterator over this collection. The iterator must provide the
* hasNext and next methods and should in addition provide remove if the
* collection is modifiable.
*/
public abstract Iterator iterator();
/**
* Return the number of elements in this collection.
*/
public abstract int size();
/**
* Add an object to the collection. This implementation always throws an
* UnsupportedOperationException - it should be overridden if the collection
* is to be modifiable.
*
* @param o the object to add
* @return true if the add operation caused the Collection to change
* @exception UnsupportedOperationException if the add operation is not
* supported on this collection
*/
public boolean add(Object o) {
throw new UnsupportedOperationException();
}
/**
* Add all the elements of a given collection to this collection. This
* implementation obtains an Iterator over the given collection and iterates
* over it, adding each element with the add(Object) method (thus this method
* will fail with an UnsupportedOperationException if the add method does).
*
* @param c the collection to add the elements of to this collection
* @return true if the add operation caused the Collection to change
* @exception UnsupportedOperationException if the add operation is not
* supported on this collection
*/
public boolean addAll(Collection c) {
Iterator i = c.iterator();
boolean modified = false;
while (i.hasNext()) {
modified |= add(i.next());
}
return modified;
}
/**
* Remove all elements from the collection. This implementation obtains an
* iterator over the collection and calls next and remove on it repeatedly
* (thus this method will fail with an UnsupportedOperationException if the
* Iterator's remove method does) until there are no more elements to remove.
* Many implementations will have a faster way of doing this.
*
* @exception UnsupportedOperationException if the Iterator returned by
* iterator does not provide an implementation of remove
*/
public void clear() {
Iterator i = iterator();
while (i.hasNext()) {
i.next();
i.remove();
}
}
/**
* Test whether this collection contains a given object. That is, if the
* collection has an element e such that (o == null ? e == null :
* o.equals(e)). This implementation obtains an iterator over the collection
* and iterates over it, testing each element for equality with the given
* object. If it is equal, true is returned. Otherwise false is returned when
* the end of the collection is reached.
*
* @param o the object to remove from this collection
* @return true if this collection contains an object equal to o
*/
public boolean contains(Object o) {
Iterator i = iterator();
// This looks crazily inefficient, but it takes the test o==null outside
// the loop, saving time, and also saves needing to store the result of
// i.next() each time.
if (o == null) {
while (i.hasNext()) {
if (i.next() == null) {
return true;
}
}
} else {
while (i.hasNext()) {
if (o.equals(i.next())) {
return true;
}
}
}
return false;
}
/**
* Tests whether this collection contains all the elements in a given
* collection. This implementation iterates over the given collection,
* testing whether each element is contained in this collection. If any one
* is not, false is returned. Otherwise true is returned.
*
* @param c the collection to test against
* @return true if this collection contains all the elements in the given
* collection
*/
public boolean containsAll(Collection c) {
Iterator i = c.iterator();
while (i.hasNext()) {
if (!contains(i.next())) {
return false;
}
}
return true;
}
/**
* Test whether this collection is empty. This implementation returns
* size() == 0.
*
* @return true if this collection is empty.
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Remove a single instance of an object from this collection. That is,
* remove one element e such that (o == null ? e == null : o.equals(e)), if
* such an element exists. This implementation obtains an iterator over the
* collection and iterates over it, testing each element for equality with
* the given object. If it is equal, it is removed by the iterator's remove
* method (thus this method will fail with an UnsupportedOperationException
* if the Iterator's remove method does). After the first element has been
* removed, true is returned; if the end of the collection is reached, false
* is returned.
*
* @param o the object to remove from this collection
* @return true if the remove operation caused the Collection to change, or
* equivalently if the collection did contain o.
* @exception UnsupportedOperationException if this collection's Iterator
* does not support the remove method
*/
public boolean remove(Object o) {
Iterator i = iterator();
// This looks crazily inefficient, but it takes the test o==null outside
// the loop, saving time, and also saves needing to store the result of
// i.next() each time.
if (o == null) {
while (i.hasNext()) {
if (i.next() == null) {
i.remove();
return true;
}
}
} else {
while (i.hasNext()) {
if (o.equals(i.next())) {
i.remove();
return true;
}
}
}
return false;
}
/**
* Remove from this collection all its elements that are contained in a given
* collection. This implementation iterates over this collection, and for
* each element tests if it is contained in the given collection. If so, it
* is removed by the Iterator's remove method (thus this method will fail
* with an UnsupportedOperationException if the Iterator's remove method
* does).
*
* @param c the collection to remove the elements of
* @return true if the remove operation caused the Collection to change
* @exception UnsupportedOperationException if this collection's Iterator
* does not support the remove method
*/
public boolean removeAll(Collection c) {
Iterator i = iterator();
boolean changed = false;
while (i.hasNext()) {
if (c.contains(i.next())) {
i.remove();
changed = true;
}
}
return changed;
}
/**
* Remove from this collection all its elements that are not contained in a
* given collection. This implementation iterates over this collection, and
* for each element tests if it is contained in the given collection. If not,
* it is removed by the Iterator's remove method (thus this method will fail
* with an UnsupportedOperationException if the Iterator's remove method
* does).
*
* @param c the collection to retain the elements of
* @return true if the remove operation caused the Collection to change
* @exception UnsupportedOperationException if this collection's Iterator
* does not support the remove method
*/
public boolean retainAll(Collection c) {
Iterator i = iterator();
boolean changed = false;
while (i.hasNext()) {
if (!c.contains(i.next())) {
i.remove();
changed = true;
}
}
return changed;
}
/**
* Return an array containing the elements of this collection. This
* implementation creates an Object array of size size() and then iterates
* over the collection, setting each element of the array from the value
* returned by the iterator.
*
* @return an array containing the elements of this collection
*/
public Object[] toArray() {
Object[] a = new Object[size()];
Iterator i = iterator();
for (int pos = 0; pos < a.length; pos++) {
a[pos] = i.next();
}
return a;
}
/**
* Copy the collection into a given array if it will fit, or into a
* dynamically created array of the same run-time type as the given array if
* not. If there is space remaining in the array, the first element after the
* end of the collection is set to null (this is only useful if the
* collection is known to contain no null elements, however). This
* implementation first tests whether the given array is large enough to hold
* all the elements of the collection. If not, the reflection API is used to
* allocate a new array of the same run-time type. Next an iterator is
* obtained over the collection and the elements are placed in the array as
* they are returned by the iterator. Finally the first spare element, if
* any, of the array is set to null, and the created array is returned.
*
* @param a the array to copy into, or of the correct run-time type
* @return the array that was produced
* @exception ClassCastException if the type of the array precludes holding
* one of the elements of the Collection
*/
public Object[] toArray(Object[] a) {
final int n = size();
if (a.length < n) {
a = (Object[])Array.newInstance(a.getClass().getComponentType(), n);
}
Iterator i = iterator();
for (int pos = 0; pos < n; pos++) {
a[pos] = i.next();
}
if (a.length > n) {
a[n] = null;
}
return a;
}
/**
* Creates a String representation of the Collection. The string returned is
* of the form "[a, b, ...]" where a and b etc are the results of calling
* toString on the elements of the collection. This implementation obtains an
* Iterator over the Collection and adds each element to a StringBuffer as it
* is returned by the iterator.
*
* @return a String representation of the Collection
*/
public String toString() {
StringBuffer s = new StringBuffer();
s.append('[');
Iterator i = iterator();
boolean more = i.hasNext();
while(more) {
s.append(i.next());
if (more = i.hasNext()) {
s.append(", ");
}
}
s.append(']');
return s.toString();
}
}

@ -1,560 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// AbstractList.java -- Abstract implementation of most of List
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comments for almost everything.
// ~ Better general commenting
package jode.util;
import java.util.NoSuchElementException;
/**
* A basic implementation of most of the methods in the List interface to make
* it easier to create a List based on a random-access data structure. To
* create an unmodifiable list, it is only necessary to override the size() and
* get(int) methods (this contrasts with all other abstract collection classes
* which require an iterator to be provided). To make the list modifiable, the
* set(int, Object) method should also be overridden, and to make the list
* resizable, the add(int, Object) and remove(int) methods should be overridden
* too. Other methods should be overridden if the backing data structure allows
* for a more efficient implementation. The precise implementation used by
* AbstractList is documented, so that subclasses can tell which methods could
* be implemented more efficiently.
*/
public abstract class AbstractList extends AbstractCollection implements List {
/**
* A count of the number of structural modifications that have been made to
* the list (that is, insertions and removals).
*/
protected transient int modCount = 0;
public abstract Object get(int index);
public void add(int index, Object o) {
throw new UnsupportedOperationException();
}
public boolean add(Object o) {
add(size(), o);
return true;
}
public boolean addAll(int index, Collection c) {
Iterator i = c.iterator();
if (i.hasNext()) {
do {
add(index++, i.next());
} while (i.hasNext());
return true;
} else {
return false;
}
}
public void clear() {
removeRange(0, size());
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof List)) {
return false;
} else {
Iterator i1 = iterator();
Iterator i2 = ((List)o).iterator();
while (i1.hasNext()) {
if (!i2.hasNext()) {
return false;
} else {
Object e = i1.next();
if (e == null ? i2.next() != null : !e.equals(i2.next())) {
return false;
}
}
}
if (i2.hasNext()) {
return false;
} else {
return true;
}
}
}
public int hashCode() {
int hashCode = 1;
Iterator i = iterator();
while (i.hasNext()) {
Object obj = i.next();
hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
}
return hashCode;
}
public int indexOf(Object o) {
int index = 0;
ListIterator i = listIterator();
if (o == null) {
while (i.hasNext()) {
if (i.next() == null) {
return index;
}
index++;
}
} else {
while (i.hasNext()) {
if (o.equals(i.next())) {
return index;
}
index++;
}
}
return -1;
}
public Iterator iterator() {
return new Iterator() {
private int knownMod = modCount;
private int position = 0;
boolean removed = true;
private void checkMod() {
if (knownMod != modCount) {
throw new ConcurrentModificationException();
}
}
public boolean hasNext() {
checkMod();
return position < size();
}
public Object next() {
checkMod();
removed = false;
try {
return get(position++);
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public void remove() {
checkMod();
if (removed) {
throw new IllegalStateException();
}
AbstractList.this.remove(--position);
knownMod = modCount;
removed = true;
}
};
}
public int lastIndexOf(Object o) {
int index = size();
ListIterator i = listIterator(index);
if (o == null) {
while (i.hasPrevious()) {
if (i.previous() == null) {
return index;
}
index--;
}
} else {
while (i.hasPrevious()) {
if (o.equals(i.previous())) {
return index;
}
index--;
}
}
return -1;
}
public ListIterator listIterator() {
return listIterator(0);
}
public ListIterator listIterator(final int index) {
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException();
}
return new ListIterator() {
private int knownMod = modCount;
private int position = index;
private int lastReturned = -1;
private void checkMod() {
if (knownMod != modCount) {
throw new ConcurrentModificationException();
}
}
public boolean hasNext() {
checkMod();
return position < size();
}
public boolean hasPrevious() {
checkMod();
return position > 0;
}
public Object next() {
checkMod();
if (hasNext()) {
lastReturned = position++;
return get(lastReturned);
} else {
throw new NoSuchElementException();
}
}
public Object previous() {
checkMod();
if (hasPrevious()) {
lastReturned = --position;
return get(lastReturned);
} else {
throw new NoSuchElementException();
}
}
public int nextIndex() {
checkMod();
return position;
}
public int previousIndex() {
checkMod();
return position - 1;
}
public void remove() {
checkMod();
if (lastReturned < 0) {
throw new IllegalStateException();
}
AbstractList.this.remove(lastReturned);
knownMod = modCount;
position = lastReturned;
lastReturned = -1;
}
public void set(Object o) {
checkMod();
if (lastReturned < 0) {
throw new IllegalStateException();
}
AbstractList.this.set(lastReturned, o);
}
public void add(Object o) {
checkMod();
AbstractList.this.add(position++, o);
lastReturned = -1;
knownMod = modCount;
}
};
}
public Object remove(int index) {
throw new UnsupportedOperationException();
}
/**
* Remove a subsection of the list. This is called by the clear and
* removeRange methods of the class which implements subList, which are
* difficult for subclasses to override directly. Therefore, this method
* should be overridden instead by the more efficient implementation, if one
* exists.
* <p>
* This implementation first checks for illegal or out of range arguments. It
* then obtains a ListIterator over the list using listIterator(fromIndex).
* It then calls next() and remove() on this iterator repeatedly, toIndex -
* fromIndex times.
*
* @param fromIndex the index, inclusive, to remove from.
* @param toIndex the index, exclusive, to remove to.
* @exception UnsupportedOperationException if this list does not support
* the removeRange operation.
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex <
* 0 || toIndex > size().
*/
protected void removeRange(int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException();
} else if (fromIndex < 0 || toIndex > size()) {
throw new IndexOutOfBoundsException();
} else {
ListIterator i = listIterator(fromIndex);
for (int index = fromIndex; index < toIndex; index++) {
i.next();
i.remove();
}
}
}
public Object set(int index, Object o) {
throw new UnsupportedOperationException();
}
private static class SubList extends AbstractList {
// Note that within this class two fields called modCount are inherited -
// one from the superclass, and one from the backing class. These are
// explicitly disambiguated in the code by referring to "this.modCount"
// and "backing.modCount".
// The code uses both these two fields and *no other* to provide fail-fast
// behaviour. For correct operation, the two fields should contain equal
// values. Therefore, if this.modCount != backing.modCount, there
// has been a concurrent modification. This is all achieved purely by using
// the modCount field, precisely according to the docs of AbstractList.
// See the methods upMod and checkMod.
// Jikes doesn't want to access outer instance with AbstractList.this,
// since this is an AbstractList, too. I therefor changed class to static
// and do it by hand. This makes it a lot clearer by the way.
private AbstractList backing;
private final int offset;
private int size;
SubList(AbstractList backing, int fromIndex, int toIndex) {
this.backing = backing;
this.offset = fromIndex;
this.size = toIndex - fromIndex;
upMod();
}
/**
* This method checks the two modCount fields to ensure that there has
* not been a concurrent modification. It throws an exception if there
* has been, and otherwise returns normally.
* Note that since this method is private, it will be inlined.
*
* @exception ConcurrentModificationException if there has been a
* concurrent modification.
*/
private void checkMod() {
if (modCount != backing.modCount) {
throw new ConcurrentModificationException();
}
}
/**
* This method is called after every method that causes a structural
* modification to the backing list. It updates the local modCount field
* to match that of the backing list.
* Note that since this method is private, it will be inlined.
*/
private void upMod() {
modCount = backing.modCount;
}
/**
* This method checks that a value is between 0 and size (inclusive). If
* it is not, an exception is thrown.
* Note that since this method is private, it will be inlined.
*
* @exception IndexOutOfBoundsException if the value is out of range.
*/
private void checkBoundsInclusive(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
}
/**
* This method checks that a value is between 0 (inclusive) and size
* (exclusive). If it is not, an exception is thrown.
* Note that since this method is private, it will be inlined.
*
* @exception IndexOutOfBoundsException if the value is out of range.
*/
private void checkBoundsExclusive(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
}
public int size() {
checkMod();
return size;
}
public Iterator iterator() {
return listIterator();
}
public ListIterator listIterator(final int index) {
checkMod();
checkBoundsInclusive(index);
return new ListIterator() {
ListIterator i = backing.listIterator(index + offset);
int position = index;
public boolean hasNext() {
checkMod();
return position < size;
}
public boolean hasPrevious() {
checkMod();
return position > 0;
}
public Object next() {
if (position < size) {
Object o = i.next();
position++;
return o;
} else {
throw new NoSuchElementException();
}
}
public Object previous() {
if (position > 0) {
Object o = i.previous();
position--;
return o;
} else {
throw new NoSuchElementException();
}
}
public int nextIndex() {
return offset + i.nextIndex();
}
public int previousIndex() {
return offset + i.previousIndex();
}
public void remove() {
i.remove();
upMod();
size--;
position = nextIndex();
}
public void set(Object o) {
i.set(o);
}
public void add(Object o) {
i.add(o);
upMod();
size++;
position++;
}
// Here is the reason why the various modCount fields are mostly
// ignored in this wrapper listIterator.
// IF the backing listIterator is failfast, then the following holds:
// Using any other method on this list will call a corresponding
// method on the backing list *after* the backing listIterator
// is created, which will in turn cause a ConcurrentModException
// when this listIterator comes to use the backing one. So it is
// implicitly failfast.
// If the backing listIterator is NOT failfast, then the whole of
// this list isn't failfast, because the modCount field of the
// backing list is not valid. It would still be *possible* to
// make the iterator failfast wrt modifications of the sublist
// only, but somewhat pointless when the list can be changed under
// us.
// Either way, no explicit handling of modCount is needed.
// However upMod() must be called in add and remove, and size
// must also be updated in these two methods, since they do not go
// through the corresponding methods of the subList.
};
}
public Object set(int index, Object o) {
checkMod();
checkBoundsExclusive(index);
o = backing.set(index + offset, o);
upMod();
return o;
}
public Object get(int index) {
checkMod();
checkBoundsExclusive(index);
return backing.get(index + offset);
}
public void add(int index, Object o) {
checkMod();
checkBoundsInclusive(index);
backing.add(index + offset, o);
upMod();
size++;
}
public Object remove(int index) {
checkMod();
checkBoundsExclusive(index);
Object o = backing.remove(index + offset);
upMod();
size--;
return o;
}
public void removeRange(int fromIndex2, int toIndex2) {
checkMod();
checkBoundsExclusive(fromIndex2);
checkBoundsInclusive(toIndex2);
// this call will catch the toIndex2 < fromIndex2 condition
backing.removeRange(offset + fromIndex2, offset + toIndex2);
upMod();
size -= toIndex2 - fromIndex2;
}
public boolean addAll(int index, Collection c) {
checkMod();
checkBoundsInclusive(index);
int s = backing.size();
boolean result = backing.addAll(offset + index, c);
upMod();
size += backing.size() - s;
return result;
}
}
public List subList(final int fromIndex, final int toIndex) {
return new SubList(this, fromIndex, toIndex);
}
}

@ -1,280 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// AbstractMap.java -- Abstract implementation of most of Map
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com),
// Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// comments
// test suite
package jode.util;
public abstract class AbstractMap implements Map {
public void clear()
{
entrySet().clear();
}
public boolean containsKey( Object key )
{
Object k;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
k = ((Map.Entry)entries.next()).getKey();
if( key == null ? k == null : key.equals( k ) )
return true;
}
return false;
}
public boolean containsValue( Object value )
{
Object v;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
v = ((Map.Entry)entries.next()).getValue();
if( value == null ? v == null : value.equals( v ) )
return true;
}
return false;
}
public abstract Set entrySet();
public boolean equals( Object o )
{
if( this == o )
return true;
if( o == null || !( o instanceof Map ) )
return false;
Map m = (Map)o;
if( m.size() != size() )
return false;
Object key, value1, value2;
Map.Entry entry;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
entry = (Map.Entry)entries.next();
key = entry.getKey();
value1 = entry.getValue();
value2 = m.get( key );
if( !( ( value1 == null && value2 == null )
|| value1.equals( value2 ) ) )
return false;
}
return true;
}
public Object get( Object key )
{
Object k;
Map.Entry entry;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
entry = (Map.Entry)entries.next();
k = entry.getKey();
if( key == null ? k == null : key.equals( k ) )
return entry.getValue();
}
return null;
}
public int hashCode()
{
int hashcode = 0;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
hashcode += entries.next().hashCode();
return hashcode;
}
public boolean isEmpty()
{
return size() == 0;
}
public Set keySet()
{
if( this.keySet == null )
{
this.keySet =
new AbstractSet()
{
public int size()
{
return AbstractMap.this.size();
}
public boolean contains(Object key)
{
return AbstractMap.this.containsKey(key);
}
public Iterator iterator()
{
return new Iterator()
{
Iterator map_iterator = AbstractMap.this.entrySet().iterator();
public boolean hasNext()
{
return map_iterator.hasNext();
}
public Object next()
{
return ((Map.Entry)map_iterator.next()).getKey();
}
public void remove()
{
map_iterator.remove();
}
};
}
};
}
return this.keySet;
}
public Object put( Object key, Object value )
{
throw new UnsupportedOperationException();
}
public void putAll( Map m )
{
Map.Entry entry;
Iterator entries = m.entrySet().iterator();
while( entries.hasNext() )
{
entry = (Map.Entry)entries.next();
put( entry.getKey(), entry.getValue() );
}
}
public Object remove( Object key )
{
Object k, value;
Map.Entry entry;
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
entry = (Map.Entry)entries.next();
k = entry.getKey();
if( key == null ? k == null : key.equals( k ) )
{
value = entry.getValue();
entries.remove();
return value;
}
}
return null;
}
public int size()
{
return entrySet().size();
}
public String toString()
{
Map.Entry entry;
String rep = "AbstractMap< ";
Iterator entries = entrySet().iterator();
while( entries.hasNext() )
{
entry = (Map.Entry)entries.next();
rep += entry.getKey() + " -> " + entry.getValue() + ", ";
}
return rep.substring( 0, rep.length() - 2 ) + " >";
}
public Collection values()
{
if( this.valueCollection == null )
{
this.valueCollection =
new AbstractCollection()
{
public int size()
{
return AbstractMap.this.size();
}
public Iterator iterator()
{
return new Iterator()
{
Iterator map_iterator = AbstractMap.this.entrySet().iterator();
public boolean hasNext()
{
return map_iterator.hasNext();
}
public Object next()
{
return ((Map.Entry)map_iterator.next()).getValue();
}
public void remove()
{
map_iterator.remove();
}
};
}
};
}
return this.valueCollection;
}
private Collection valueCollection = null;
private Set keySet = null;
}

@ -1,111 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// AbstractSequentialList.java -- List implementation for sequential access
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Lots of doc comments still missing.
// ~ The class comment should include a description of what should be overridden
// to provide what features, as should the listIterator comment.
package jode.util;
/**
* Abstract superclass to make it easier to implement the List interface when
* backed by a sequential-access store, such as a linked list.
*/
public abstract class AbstractSequentialList extends AbstractList {
/**
* Returns a ListIterator over the list, starting from position index.
* Subclasses must provide an implementation of this method.
*
* @exception IndexOutOfBoundsException if index < 0 || index > size()
*/
public abstract ListIterator listIterator(int index);
/**
* Add an element to the list at a given index. This implementation obtains a
* ListIterator positioned at the specified index, and then adds the element
* using the ListIterator's add method.
*
* @param index the position to add the element
* @param o the element to insert
* @exception IndexOutOfBoundsException if index < 0 || index > size()
* @exception UnsupportedOperationException if the iterator returned by
* listIterator(index) does not support the add method.
*/
public void add(int index, Object o) {
ListIterator i = listIterator(index);
i.add(o);
}
public boolean addAll(int index, Collection c) {
boolean changed = false;
Iterator ci = c.iterator();
ListIterator i = listIterator(index);
while (ci.hasNext()) {
i.add(ci.next());
changed = true;
}
return changed;
}
public Object get(int index) {
ListIterator i = listIterator(index);
if (!i.hasNext()) {
throw new IndexOutOfBoundsException();
}
return i.next();
}
/**
* Return an Iterator over this List. This implementation returns
* listIterator().
*
* @return an Iterator over this List
*/
public Iterator iterator() {
return listIterator();
}
public Object remove(int index) {
ListIterator i = listIterator(index);
if (!i.hasNext()) {
throw new IndexOutOfBoundsException();
}
Object removed = i.next();
i.remove();
return removed;
}
public Object set(int index, Object o) {
ListIterator i = listIterator(index);
if (!i.hasNext()) {
throw new IndexOutOfBoundsException();
}
Object old = i.next();
i.set(o);
return old;
}
}

@ -1,78 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// AbstractSet.java -- Abstract implementation of most of Set
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* An abstract implementation of Set to make it easier to create your own
* implementations. In order to create a Set, subclass AbstractSet and
* implement the same methods that are required for AbstractCollection
* (although these methods must of course meet the requirements that Set puts
* on them - specifically, no element may be in the set more than once). This
* class simply provides implementations of equals() and hashCode() to fulfil
* the requirements placed on them by the Set interface.
*/
public abstract class AbstractSet extends AbstractCollection implements Set {
/**
* Tests whether the given object is equal to this Set. This implementation
* first checks whether this set <em>is</em> the given object, and returns
* true if so. Otherwise, if o is a Set and is the same size as this one, it
* returns the result of calling containsAll on the given Set. Otherwise, it
* returns false.
*
* @param o the Object to be tested for equality with this Set
* @return true if the given object is equal to this Set
*/
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (o instanceof Set && ((Set)o).size() == size()) {
return containsAll((Collection)o);
} else {
return false;
}
}
/**
* Returns a hash code for this Set. The hash code of a Set is the sum of the
* hash codes of all its elements, except that the hash code of null is
* defined to be zero. This implementation obtains an Iterator over the Set,
* and sums the results.
*
* @return a hash code for this Set
*/
public int hashCode() {
int hash = 0;
Iterator i = iterator();
while (i.hasNext()) {
try {
hash += i.next().hashCode();
} catch (NullPointerException e) {
}
}
return hash;
}
}

@ -1,489 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// ArrayList.java -- JDK1.2's answer to Vector; this is an array-backed
// implementation of the List interface
//
// This is a JDK 1.2 compliant version of ArrayList.java
//
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com),
// Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.lang.reflect.Array;
import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* An array-backed implementation of the List interface. ArrayList
* performs well on simple tasks: random access into a list, appending
* to or removing from the end of a list, checking the size, &c.
*
* @author Jon A. Zeppieri
* @version $Id$
* @see java.util.AbstractList
* @see java.util.List
*/
public class ArrayList extends AbstractList
implements List, Cloneable, Serializable
{
/** the default capacity for new ArrayLists */
private static final int DEFAULT_CAPACITY = 16;
/** the number of elements in this list */
int size;
/** where the data is stored */
transient Object[] _arData;
/**
* Construct a new ArrayList with the supplied initial capacity.
*
* @param iCapacity
*/
public ArrayList(int iCapacity)
{
_arData = new Object[iCapacity];
}
/**
* Construct a new ArrayList with the default capcity
*/
public ArrayList()
{
this(DEFAULT_CAPACITY);
}
/**
* Construct a new ArrayList, and initialize it with the elements
* in the supplied Collection; Sun specs say that the initial
* capacity is 110% of the Collection's size.
*
* @param oCollection the collection whose elements will
* initialize this list
*/
public ArrayList(Collection oCollection)
{
this((int) (oCollection.size() * 1.1));
addAll(oCollection);
}
/**
* Guarantees that this list will have at least enough capacity to
* hold iMinCapacity elements.
*
* @param iMinCapacity the minimum guaranteed capacity
*/
public void ensureCapacity(int iMinCapacity)
{
Object[] arNewData;
int iCapacity = _arData.length;
if (iMinCapacity > iCapacity)
{
arNewData = new Object[Math.max((iCapacity * 2), iMinCapacity)];
System.arraycopy(_arData, 0, arNewData, 0, iCapacity);
_arData = arNewData;
}
}
/**
* Appends the supplied element to the end of this list.
*
* @param oElement the element to be appended to this list
*/
public boolean add(Object oElement)
{
ensureCapacity(size + 1);
_arData[size++] = oElement;
modCount++;
return true;
}
/**
* Retrieves the element at the user-supplied index.
*
* @param iIndex the index of the element we are fetching
* @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size())
*/
public Object get(int iIndex)
{
if (iIndex >= size)
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"index=" + String.valueOf(iIndex));
return _arData[iIndex];
}
/**
* Returns the number of elements in this list
*/
public int size()
{
return size;
}
/**
* Removes the element at the user-supplied index
*
* @param iIndex the index of the element to be removed
* @return the removed Object
* @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size())
*/
public Object remove(int iIndex)
{
Object oResult;
if (iIndex >= size)
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"index=" + String.valueOf(iIndex));
oResult = _arData[iIndex];
if (iIndex != --size)
System.arraycopy(_arData, (iIndex + 1), _arData, iIndex,
(size - iIndex));
modCount++;
_arData[size] = null;
return oResult;
}
/**
* Removes all elements in the half-open interval [iFromIndex, iToIndex).
*
* @param iFromIndex the first index which will be removed
* @param iToIndex one greater than the last index which will be
* removed
*/
public void removeRange(int iFromIndex, int iToIndex)
{
int iReduction;
int i;
if ((iFromIndex >= size) || (iToIndex >= size))
{
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"indices=" +
String.valueOf(iFromIndex) + "," +
String.valueOf(iToIndex));
}
else if (iFromIndex > iToIndex)
{
throw new IllegalArgumentException("fromIndex(" +
String.valueOf(iFromIndex) +
") > toIndex(" +
String.valueOf(iToIndex) + ")");
}
else if (iFromIndex != iToIndex)
{
iReduction = iToIndex - iFromIndex;
System.arraycopy(_arData, (iFromIndex + iReduction), _arData,
iFromIndex, (size - iFromIndex - iReduction));
modCount++;
for (i = (iFromIndex + iReduction); i < size; i++)
_arData[i] = null;
size -= iReduction;
}
}
/**
* Adds the supplied element at the specified index, shifting all
* elements currently at that index or higher one to the right.
*
* @param iIndex the index at which the element is being added
* @param oElement the element being added
*/
public void add(int iIndex, Object oElement)
{
if (iIndex > size)
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"index=" + String.valueOf(iIndex));
ensureCapacity(size + 1);
System.arraycopy(_arData, iIndex, _arData,
(iIndex + 1), (size - iIndex));
_arData[iIndex] = oElement;
size++;
modCount++;
}
/**
* Add each element in the supplied Collection to this List.
*
* @param oCollection a Collection containing elements to be
* added to this List
*/
public boolean addAll(Collection oCollection)
{
Iterator itElements;
int iLen = oCollection.size();
if (iLen > 0)
{
ensureCapacity(size + iLen);
modCount++;
itElements = oCollection.iterator();
while (itElements.hasNext())
_arData[size++] = itElements.next();
return true;
}
return false;
}
/**
* Add all elements in the supplied collection, inserting them beginning
* at the specified index.
*
* @param iIndex the index at which the elements will be inserted
* @param oCollection the Collection containing the elements to be
* inserted
*/
public boolean addAll(int iIndex, Collection oCollection)
{
Iterator itElements;
int iLen;
if (iIndex > size)
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"index=" + String.valueOf(iIndex));
iLen = oCollection.size();
if (iLen > 0)
{
ensureCapacity(size + iLen);
System.arraycopy(_arData, iIndex, _arData,
(iIndex + iLen), (size - iIndex));
modCount++;
size += iLen;
itElements = oCollection.iterator();
while (itElements.hasNext())
_arData[iIndex++] = itElements.next();
return true;
}
return false;
}
/**
* Creates a shallow copy of this ArrayList
*/
public Object clone()
{
ArrayList oClone;
try
{
oClone = (ArrayList) super.clone();
oClone._arData = _arData;
oClone.size = size;
}
catch(CloneNotSupportedException e)
{
oClone = null;
}
return oClone;
}
/**
* Returns true iff oElement is in this ArrayList.
*
* @param oElement the element whose inclusion in the List is being
* tested
*/
public boolean contains(Object oElement)
{
return (indexOf(oElement) != -1);
}
/**
* Returns the lowest index at which oElement appears in this List, or
* -1 if it does not appear.
*
* @param oElement the element whose inclusion in the List is being
* tested
*/
public int indexOf(Object oElement)
{
int i;
for (i = 0; i < size; i++)
{
if (doesEqual(oElement, _arData[i]))
return i;
}
return -1;
}
/**
* Returns the highest index at which oElement appears in this List, or
* -1 if it does not appear.
*
* @param oElement the element whose inclusion in the List is being
* tested
*/
public int lastIndexOf(Object oElement)
{
int i;
for (i = size - 1; i >= 0; i--)
{
if (doesEqual(oElement, _arData[i]))
return i;
}
return -1;
}
/**
* Removes all elements from this List
*/
public void clear()
{
int i;
if (size > 0)
{
modCount++;
size = 0;
for (i = 0; i < size; i++)
_arData[i] = null;
}
}
/**
* Sets the element at the specified index.
*
* @param iIndex the index at which the element is being set
* @param oElement the element to be set
* @return the element previously at the specified index, or null if
* none was there
*/
public Object set(int iIndex, Object oElement)
{
Object oResult;
if (iIndex >= size)
throw new IndexOutOfBoundsException("ArrayList size=" +
String.valueOf(size) + "; " +
"index=" + String.valueOf(iIndex));
oResult = _arData[iIndex];
modCount++;
_arData[iIndex] = oElement;
return oResult;
}
/**
* Returns an Object Array containing all of the elements in this ArrayList
*/
public Object[] toArray()
{
Object[] arObjects = new Object[size];
System.arraycopy(_arData, 0, arObjects, 0, size);
return arObjects;
}
/**
* Returns an Array whse component type is the runtime component type of
* the passes-in Array. The returned Array is populated with all of the
* elements in this ArrayList. If the passed-in Array is not large enough
* to store all of the elements in this List, a new Array will be created
* and returned; if the passed-in Array is <i>larger</i> than the size
* of this List, then size() + 1 index will be set to null.
*
* @param arObjects the passed-in Array
*/
public Object[] toArray(Object[] arObjects)
{
Object[] arReturn = (arObjects.length >= size)
? arObjects
: (Object[])
Array.newInstance(arObjects.getClass().getComponentType(), size);
System.arraycopy(_arData, 0, arReturn, 0, size);
if (arReturn.length > size)
arReturn[size] = null;
return arReturn;
}
/**
* Trims the capacity of tjis List to be equal to its size;
* a memory saver.
*/
public void trimToSize()
{
Object[] arNewData = new Object[size];
System.arraycopy(_arData, 0, arNewData, 0, size);
modCount++;
_arData = arNewData;
}
private void writeObject(ObjectOutputStream oOut)
throws IOException
{
int i;
oOut.defaultWriteObject();
oOut.writeInt(_arData.length);
for (i = 0; i < _arData.length; i++)
oOut.writeObject(_arData[i]);
}
private void readObject(ObjectInputStream oIn)
throws IOException, ClassNotFoundException
{
int i;
int iCapacity;
oIn.defaultReadObject();
iCapacity = oIn.readInt();
_arData = new Object[iCapacity];
for (i = 0; i < iCapacity; i++)
_arData[i] = oIn.readObject();
}
private static final boolean doesEqual(Object oOne, Object oTwo)
{
return ((oOne == null) ? (oTwo == null) : oOne.equals(oTwo));
}
}

File diff suppressed because it is too large Load Diff

@ -1,138 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// BasicMapEntry.java -- a class providing a plain-vanilla implementation of
// the Map.Entry interface; could be used anywhere in
// java.util
//
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
///#ifdef JDK12
///import java.lang.UnsupportedOperationException;
///import java.util.Map;
///#endif
/**
* a class which implements Map.Entry
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
class BasicMapEntry implements Map.Entry
{
/** the key */
Object key;
/** the value */
Object value;
/**
* construct a new BasicMapEntry with the given key and value
*
* @param newKey the key of this Entry
* @param newValue the value of this Entry
*/
BasicMapEntry(Object newKey, Object newValue)
{
key = newKey;
value = newValue;
}
/**
* returns true if <pre>o</pre> is a Map.Entry and
* <pre>
* (((o.getKey == null) ? (key == null) :
* o.getKey().equals(key)) &&
* ((o.getValue() == null) ? (value == null) :
* o.getValue().equals(value)))
* </pre>
*
* NOTE: the calls to getKey() and getValue() in this implementation
* are <i>NOT</i> superfluous and should not be removed. They insure
* that subclasses such as HashMapEntry work correctly
*
* @param o the Object being tested for equality
*/
public boolean equals(Object o)
{
Map.Entry tester;
Object oTestingKey, oTestingValue;
Object oKey, oValue;
if (o instanceof Map.Entry)
{
tester = (Map.Entry) o;
oKey = getKey();
oValue = getValue();
oTestingKey = tester.getKey();
oTestingValue = tester.getValue();
return (((oTestingKey == null) ? (oKey == null) :
oTestingKey.equals(oKey)) &&
((oTestingValue == null) ? (oValue == null) :
oTestingValue.equals(oValue)));
}
return false;
}
/** returns the key */
public Object getKey()
{
return key;
}
/** returns the value */
public Object getValue()
{
return value;
}
/** the hashCode() for a Map.Entry is
* <pre>
* ((getKey() == null) ? 0 : getKey().hashCode()) ^
* ((getValue() == null) ? 0 : getValue().hashCode());
* </pre>
*
* NOTE: the calls to getKey() and getValue() in this implementation
* are <i>NOT</i> superfluous and should not be removed. They insure
* that subclasses such as HashMapEntry work correctly
*/
public int hashCode()
{
Object oKey = getKey();
Object oValue = getValue();
return ((oKey == null) ? 0 : oKey.hashCode()) ^
((oValue == null) ? 0 : oValue.hashCode());
}
/**
* sets the value of this Map.Entry
*
* @param newValue the new value of this Map.Entry
*/
public Object setValue(Object newValue)
throws UnsupportedOperationException, ClassCastException,
IllegalArgumentException, NullPointerException
{
Object oVal = value;
value = newValue;
return oVal;
}
}

@ -1,198 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Bucket.java -- a class providing a hash-bucket data structure (a lightweight
// linked list)
//
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* a class representing a simple, lightweight linked-list, using Node
* objects as its linked nodes; this is used by Hashtable and HashMap
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
class Bucket
{
/** the first node of the lined list, originally null */
Node first;
/** trivial constructor for a Bucket */
Bucket()
{
}
/** add this key / value pair to the list
*
* @param entry a Map.Entry object to be added to this list
*/
Map.Entry add(Node newNode)
{
Object oKey;
Object oTestKey = newNode.getKey();
Node it = first;
Node prev = null;
if (it == null) // if the list is empty (the ideal case), we make a new single-node list
{
first = newNode;
return null;
}
else // otherwise try to find where this key already exists in the list,
{// and if it does, replace the value with the new one (and return the old one)
while (it != null)
{
oKey = it.getKey();
if ((oKey == null) ? (oTestKey == null) :
oKey.equals(oTestKey))
{
if (prev != null)
prev.next = newNode;
else
first = newNode;
newNode.next = it.next;
return it;
}
prev = it;
it = it.next;
}
prev.next = newNode; // otherwise, just stick this at the
return null; // end of the list
}
}
/**
* remove a Map.Entry in this list with the supplied key and return its value,
* if it exists, else return null
*
* @param key the key we are looking for in this list
*/
Object removeByKey(Object key)
{
Object oEntryKey;
Node prev = null;
Node it = first;
while (it != null)
{
oEntryKey = it.getKey();
if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key))
{
if (prev == null) // we are removing the first element
first = it.next;
else
prev.next = it.next;
return it.getValue();
}
else
{
prev = it;
it = it.next;
}
}
return null;
}
/**
* return the value which the supplied key maps to, if it maps to anything in this list,
* otherwise, return null
*
* @param key the key mapping to a value that we are looking for
*/
Object getValueByKey(Object key)
{
Node entry = getEntryByKey(key);
return (entry == null) ? null : entry.getValue();
}
/**
* return the Map.Entry which the supplied key is a part of, if such a Map.Entry exists,
* null otherwise
*
* this method is important for HashMap, which can hold null values and the null key
*
* @param key the key for which we are finding the corresponding Map.Entry
*/
Node getEntryByKey(Object key)
{
Object oEntryKey;
Node it = first;
while (it != null)
{
oEntryKey = it.getKey();
if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key))
return it;
it = it.next;
}
return null;
}
/**
* return true if this list has a Map.Entry whose value equals() the supplied value
*
* @param value the value we are looking to match in this list
*/
boolean containsValue(Object value)
{
Object oEntryValue;
Node it = first;
while (it != null)
{
oEntryValue = it.getValue();
if ((oEntryValue == null) ? (value == null) : oEntryValue.equals(value))
return true;
it = it.next;
}
return false;
}
// INNSER CLASSES ----------------------------------------------------------
/**
* a class represnting a node in our lightweight linked-list
* that we use for hash buckets; a Node object contains a Map.Entry as its
* <pre>value</pre> property and a reference (possibly, even hopefully, null)
* to another Node as its <pre>next</pre> property.
*
* There <i>is</i> a reason for not using a highly generic "LinkedNode" type
* class: we want to eliminate runtime typechecks.
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
static class Node extends BasicMapEntry implements Map.Entry
{
/** a reference to the next node in the linked list */
Node next;
/** non-trivial contructor -- sets the <pre>value</pre> of the Bucket upon instantiation */
Node(Object key, Object value)
{
super(key, value);
}
}
// EOF ------------------------------------------------------------------------
}

@ -1,234 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Collection.java -- Interface that represents a collection of objects
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Maybe some more @see clauses would be helpful.
package jode.util;
/**
* Interface that represents a collection of objects. This interface is the
* root of the collection hierarchy, and does not provide any guarantees about
* the order of its elements or whether or not duplicate elements are
* permitted.
* <p>
* All methods of this interface that are defined to modify the collection are
* defined as <dfn>optional</dfn>. An optional operation may throw an
* UnsupportedOperationException if the data backing this collection does not
* support such a modification. This may mean that the data structure is
* immutable, or that it is read-only but may change ("unmodifiable"), or
* that it is modifiable but of fixed size (such as an array), or any number
* of other combinations.
* <p>
* A class that wishes to implement this interface should consider subclassing
* AbstractCollection, which provides basic implementations of most of the
* methods of this interface. Classes that are prepared to make guarantees
* about ordering or about absence of duplicate elements should consider
* implementing List or Set respectively, both of which are subinterfaces of
* Collection.
* <p>
* A general-purpose implementation of the Collection interface should in most
* cases provide at least two constructors: One which takes no arguments and
* creates an empty collection, and one which takes a Collection as an argument
* and returns a collection containing the same elements (that is, creates a
* copy of the argument using its own implementation).
*
* @see java.util.List
* @see java.util.Set
* @see java.util.AbstractCollection
*/
public interface Collection {
/**
* Add an element to this collection.
*
* @param o the object to add.
* @returns true if the collection was modified as a result of this action.
* @exception UnsupportedOperationException if this collection does not
* support the add operation.
* @exception ClassCastException if o cannot be added to this collection due
* to its type.
* @exception IllegalArgumentException if o cannot be added to this
* collection for some other reason.
*/
boolean add(Object o);
/**
* Add the contents of a given collection to this collection.
*
* @param c the collection to add.
* @returns true if the collection was modified as a result of this action.
* @exception UnsupportedOperationException if this collection does not
* support the addAll operation.
* @exception ClassCastException if some element of c cannot be added to this
* collection due to its type.
* @exception IllegalArgumentException if some element of c cannot be added
* to this collection for some other reason.
*/
boolean addAll(Collection c);
/**
* Clear the collection, such that a subsequent call to isEmpty() would
* return true.
*
* @exception UnsupportedOperationException if this collection does not
* support the clear operation.
*/
void clear();
/**
* Test whether this collection contains a given object as one of its
* elements.
*
* @param o the element to look for.
* @returns true if this collection contains at least one element e such that
* <code>o == null ? e == null : o.equals(e)</code>.
*/
boolean contains(Object o);
/**
* Test whether this collection contains every element in a given collection.
*
* @param c the collection to test for.
* @returns true if for every element o in c, contains(o) would return true.
*/
boolean containsAll(Collection c);
/**
* Test whether this collection is equal to some object. The Collection
* interface does not explicitly require any behaviour from this method, and
* it may be left to the default implementation provided by Object. The Set
* and List interfaces do, however, require specific behaviour from this
* method.
* <p>
* If an implementation of Collection, which is not also an implementation of
* Set or List, should choose to implement this method, it should take care
* to obey the contract of the equals method of Object. In particular, care
* should be taken to return false when o is a Set or a List, in order to
* preserve the symmetry of the relation.
*
* @param o the object to compare to this collection.
* @returns true if the o is equal to this collection.
*/
boolean equals(Object o);
/**
* Obtain a hash code for this collection. The Collection interface does not
* explicitly require any behaviour from this method, and it may be left to
* the default implementation provided by Object. The Set and List interfaces
* do, however, require specific behaviour from this method.
* <p>
* If an implementation of Collection, which is not also an implementation of
* Set or List, should choose to implement this method, it should take care
* to obey the contract of the hashCode method of Object. Note that this
* method renders it impossible to correctly implement both Set and List, as
* the required implementations are mutually exclusive.
*
* @returns a hash code for this collection.
*/
int hashCode();
/**
* Test whether this collection is empty, that is, if size() == 0.
*
* @returns true if this collection contains no elements.
*/
boolean isEmpty();
/**
* Obtain an Iterator over this collection.
*
* @returns an Iterator over the elements of this collection, in any order.
*/
Iterator iterator();
/**
* Remove a single occurrence of an object from this collection. That is,
* remove an element e, if one exists, such that <code>o == null ? e == null
* : o.equals(e)</code>.
*
* @param o the object to remove.
* @returns true if the collection changed as a result of this call, that is,
* if the collection contained at least one occurrence of o.
* @exception UnsupportedOperationException if this collection does not
* support the remove operation.
*/
boolean remove(Object o);
/**
* Remove all elements of a given collection from this collection. That is,
* remove every element e such that c.contains(e).
*
* @returns true if this collection was modified as a result of this call.
* @exception UnsupportedOperationException if this collection does not
* support the removeAll operation.
*/
boolean removeAll(Collection c);
/**
* Remove all elements of this collection that are not contained in a given
* collection. That is, remove every element e such that !c.contains(e).
*
* @returns true if this collection was modified as a result of this call.
* @exception UnsupportedOperationException if this collection does not
* support the retainAll operation.
*/
boolean retainAll(Collection c);
/**
* Get the number of elements in this collection.
*
* @returns the number of elements in the collection.
*/
int size();
/**
* Copy the current contents of this collection into an array.
*
* @returns an array of type Object[] and length equal to the size of this
* collection, containing the elements currently in this collection, in
* any order.
*/
Object[] toArray();
/**
* Copy the current contents of this collection into an array. If the array
* passed as an argument has length less than the size of this collection, an
* array of the same run-time type as a, and length equal to the size of this
* collection, is allocated using Reflection. Otherwise, a itself is used.
* The elements of this collection are copied into it, and if there is space
* in the array, the following element is set to null. The resultant array is
* returned.
* Note: The fact that the following element is set to null is only useful
* if it is known that this collection does not contain any null elements.
*
* @param a the array to copy this collection into.
* @returns an array containing the elements currently in this collection, in
* any order.
* @exception ArrayStoreException if the type of any element of the
* collection is not a subtype of the element type of a.
*/
Object[] toArray(Object[] a);
}

File diff suppressed because it is too large Load Diff

@ -1,51 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/*************************************************************************
/* Comparable.java -- Interface for comparaing objects to obtain an ordering
/*
/* Copyright (c) 1998 by Free Software Foundation, Inc.
/*
/* This program is free software; you can redistribute it and/or modify
/* it under the terms of the GNU Library General Public License as published
/* by the Free Software Foundation, version 2. (see COPYING.LIB)
/*
/* This program is distributed in the hope that it will be useful, but
/* WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* GNU General Public License for more details.
/*
/* You should have received a copy of the GNU General Public License
/* along with this program; if not, write to the Free Software Foundation
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/*************************************************************************/
package jode.util;
/**
** Interface for objects that can be ordering among other
** objects. The ordering can be <EM>total</EM>, such that two objects
** only compare equal if they are equal by the equals method, or
** <EM>partial</EM> such that this is not necessarily true. For
** example, a case-sensitive dictionary order comparison of Strings
** is total, but if it is case-insensitive it is partial, because
** "abc" and "ABC" compare as equal even though "abc".equals("ABC")
** returns false.
**
** @author Geoff Berry
**
** @since JDK1.2
** @see java.util.Comparator
**/
public interface Comparable
{
/**
** @return a negative integer if this object is less than
** <code>o<code>, zero if this object is equal to <code>o</code>, or
** a positive integer if this object is greater than <code>o</code>
**/
public int compareTo( Object o );
}

@ -1,62 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Comparator.java -- Interface for objects that specify an ordering
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* Interface for objects that specify an ordering between objects. The ordering
* can be <EM>total</EM>, such that two objects only compare equal if they are
* equal by the equals method, or <EM>partial</EM> such that this is not
* necessarily true. For example, a case-sensitive dictionary order comparison
* of Strings is total, but if it is case-insensitive it is partial, because
* "abc" and "ABC" compare as equal even though "abc".equals("ABC") returns
* false.
* <P>
* In general, Comparators should be Serializable, because when they are passed
* to Serializable data structures such as SortedMap or SortedSet, the entire
* data structure will only serialize correctly if the comparator is
* Serializable.
*/
public interface Comparator {
/**
* Return an integer that is negative, zero or positive depending on whether
* the first argument is less than, equal to or greater than the second
* according to this ordering. This method should obey the following contract:
* <UL>
* <LI>if compare(a, b) &lt; 0 then compare(b, a) &gt; 0</LI>
* <LI>if compare(a, b) throws an exception, so does compare(b, a)</LI>
* <LI>if compare(a, b) &lt; 0 and compare(b, c) &lt; 0 then compare(a, c)
* &lt; 0</LI>
* <LI>if a.equals(b) or both a and b are null, then compare(a, b) == 0.
* The converse need not be true, but if it is, this Comparator
* specifies a <EM>total</EM> ordering.</LI>
* </UL>
*
* @throws ClassCastException if the elements are not of types that can be
* compared by this ordering.
*/
int compare(Object o1, Object o2);
}

@ -1,53 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// ConcurrentModificationException.java -- Data structure concurrently modified
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* Exception that is thrown by the collections classes when it is detected that
* a modification has been made to a data structure when this is not allowed,
* such as when a collection is structurally modified while an Iterator is
* operating over it. In cases where this can be detected, a
* ConcurrentModificationException will be thrown. An Iterator that detects this
* condition is referred to as fail-fast.
*/
public class ConcurrentModificationException extends RuntimeException {
/**
* Constructs a ConcurrentModificationException with no detail message.
*/
public ConcurrentModificationException() {
super();
}
/**
* Constructs a ConcurrentModificationException with a detail message.
*
* @param detail the detail message for the exception
*/
public ConcurrentModificationException(String detail) {
super(detail);
}
}

@ -1,876 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// HashMap.java -- a class providing a basic hashtable data structure,
// mapping Object --> Object; part of the JDK1.2 collections
// API
//
// This is a JDK 1.2 compliant version of HashMap.java
//
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com),
// Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.util.NoSuchElementException;
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* This class provides a hashtable-backed implementation of the
* Map interface.
*
* It uses a hash-bucket approach; that is, hash
* collisions are handled by linking the new node off of the
* pre-existing node (or list of nodes). In this manner, techniques
* such as linear probing (which can casue primary clustering) and
* rehashing (which does not fit very well with Java's method of
* precomputing hash codes) are avoided.
*
* Under ideal circumstances (no collisions, HashMap offers O(1)
* performance on most operations (<pre>containsValue()</pre> is,
* of course, O(n)). In the worst case (all keys map to the same
* hash code -- very unlikely), most operations are O(n).
*
* HashMap is part of the JDK1.2 Collections API. It differs from
* Hashtable in that it accepts the null key and null values, and it
* does not support "Enumeration views."
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable
{
// STATIC (CLASS) VARIABLES ------------------------------------------
/**
* the default capacity for an instance of HashMap -- I think this
* is low, and perhaps it shoudl be raised; Sun's documentation mildly
* suggests that this (11) is the correct value, though
*/
private static final int DEFAULT_CAPACITY = 11;
/** the default load factor of a HashMap */
private static final float DEFAULT_LOAD_FACTOR = 0.75F;
/** used internally to represent the null key */
private static final HashMap.Null NULL_KEY = new HashMap.Null();
/** used internally to parameterize the creation of set/collection views */
private static final int KEYS = 0;
/** used internally to parameterize the creation of set/collection views */
private static final int VALUES = 1;
/** used internally to parameterize the creation of set/collection views */
private static final int ENTRIES = 2;
private static final long serialVersionUID = 362498820763181265L;
// INSTANCE VARIABLES -------------------------------------------------
/** the capacity of this HashMap: denotes the size of the bucket array */
transient int capacity;
/** the size of this HashMap: denotes the number of key-value pairs */
private transient int size;
/** the load factor of this HashMap: used in computing the threshold
* @serial
*/
float loadFactor;
/* the rounded product of the capacity and the load factor; when the number of
* elements exceeds the threshold, the HashMap calls <pre>rehash()</pre>
* @serial
*/
private int threshold;
/**
* this data structure contains the actual key-value mappings; a
* <pre>BucketList</pre> is a lightweight linked list of "Buckets",
* which, in turn, are linked nodes containing a key-value mapping
* and a reference to the "next" Bucket in the list
*/
private transient Bucket[] buckets;
/**
* counts the number of modifications this HashMap has undergone; used by Iterators
* to know when to throw ConcurrentModificationExceptions (idea ripped-off from
* Stuart Ballard's AbstractList implementation)
*/
private transient int modCount;
// CONSTRUCTORS ---------------------------------------------------------
/**
* construct a new HashMap with the default capacity and the default
* load factor
*/
public HashMap()
{
init(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
}
/**
* construct a new HashMap with a specific inital capacity and load factor
*
* @param initialCapacity the initial capacity of this HashMap (>=0)
* @param initialLoadFactor the load factor of this HashMap
* (a misnomer, really, since the load factor of
* a HashMap does not change)
*
* @throws IllegalArgumentException if (initialCapacity < 0) ||
* (initialLoadFactor > 1.0) ||
* (initialLoadFactor <= 0.0)
*/
public HashMap(int initialCapacity, float initialLoadFactor)
throws IllegalArgumentException
{
if (initialCapacity < 0 || initialLoadFactor <= 0 || initialLoadFactor > 1)
throw new IllegalArgumentException();
else
init(initialCapacity, initialLoadFactor);
}
/**
* construct a new HashMap with a specific inital capacity
*
* @param initialCapacity the initial capacity of this HashMap (>=0)
*
* @throws IllegalArgumentException if (initialCapacity < 0)
*/
public HashMap(int initialCapacity)
throws IllegalArgumentException
{
if (initialCapacity < 0)
throw new IllegalArgumentException();
else
init(initialCapacity, DEFAULT_LOAD_FACTOR);
}
/**
* construct a new HashMap from the given Map
*
* every element in Map t will be put into this new HashMap
*
* @param t a Map whose key / value pairs will be put into
* the new HashMap. <b>NOTE: key / value pairs
* are not cloned in this constructor</b>
*/
public HashMap(Map t)
{
int mapSize = t.size() * 2;
init(((mapSize > DEFAULT_CAPACITY) ? mapSize : DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
putAll(t);
}
// PUBLIC METHODS ---------------------------------------------------------
/** returns the number of kay-value mappings currently in this Map */
public int size()
{
return size;
}
/** returns true if there are no key-value mappings currently in this Map */
public boolean isEmpty()
{
return size == 0;
}
/** empties this HashMap of all elements */
public void clear()
{
size = 0;
modCount++;
buckets = new Bucket[capacity];
}
/**
* returns a shallow clone of this HashMap (i.e. the Map itself is cloned, but
* its contents are not)
*/
public Object clone()
{
Map.Entry entry;
Iterator it = entrySet().iterator();
HashMap clone = new HashMap(capacity, loadFactor);
while (it.hasNext())
{
entry = (Map.Entry) it.next();
clone.internalPut(entry.getKey(), entry.getValue());
}
return clone;
}
/** returns a "set view" of this HashMap's keys */
public Set keySet()
{
return new HashMapSet(KEYS);
}
/** returns a "set view" of this HashMap's entries */
public Set entrySet()
{
return new HashMapSet(ENTRIES);
}
/** returns a "collection view" (or "bag view") of this HashMap's values */
public Collection values()
{
return new HashMapCollection();
}
/**
* returns true if the supplied object equals (<pre>equals()</pre>) a key
* in this HashMap
*
* @param key the key to search for in this HashMap
*/
public boolean containsKey(Object key)
{
return (internalGet(key) != null);
}
/**
* returns true if this HashMap contains a value <pre>o</pre>, such that
* <pre>o.equals(value)</pre>.
*
* @param value the value to search for in this Hashtable
*/
public boolean containsValue(Object value)
{
int i;
Bucket list;
for (i = 0; i < capacity; i++)
{
list = buckets[i];
if (list != null && list.containsValue(value))
return true;
}
return false;
}
/*
* return the value in this Hashtable associated with the supplied key, or <pre>null</pre>
* if the key maps to nothing
*
* @param key the key for which to fetch an associated value
*/
public Object get(Object key)
{
Map.Entry oResult = internalGet(key);
return (oResult == null) ? null : oResult.getValue();
}
/**
* puts the supplied value into the Map, mapped by the supplied key
*
* @param key the HashMap key used to locate the value
* @param value the value to be stored in the HashMap
*/
public Object put(Object key, Object value)
{
return internalPut(key, value);
}
/**
* part of the Map interface; for each Map.Entry in t, the key / value pair is
* added to this Map, <b>using the <pre>put()</pre> method -- this may not be
* you want, so be warned (if you override the put() method, this could lead to
* off behavior)</b>
*
* @param t a Map whose key / value pairs will be added to this Hashtable
*/
public void putAll(Map t)
{
Map.Entry entry;
Iterator it = t.entrySet().iterator();
while (it.hasNext())
{
entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
/**
* removes from the HashMap and returns the value which is mapped by the
* supplied key; if the key maps to nothing, then the HashMap remains unchanged,
* and <pre>null</pre> is returned
*
* @param key the key used to locate the value to remove from the HashMap
*/
public Object remove(Object key)
{
Bucket list;
int index;
Object result = null;
if (size > 0)
{
index = hash(((key == null) ? NULL_KEY : key));
list = buckets[index];
if (list != null)
{
result = list.removeByKey(key);
if (result != null)
{
size--;
modCount++;
if (list.first == null)
buckets[index] = null;
}
}
}
return result;
}
// PRIVATE METHODS -----------------------------------------------------------
/**
* puts the given key-value pair into this HashMap; a private method is used
* because it is called by the rehash() method as well as the put() method,
* and if a subclass overrides put(), then rehash would do funky things
* if it called put()
*
* @param key the HashMap key used to locate the value
* @param value the value to be stored in the HashMap
*/
private Object internalPut(Object key, Object value)
{
HashMapEntry entry;
Bucket list;
int hashIndex;
Object oResult;
Object oRealKey = ((key == null) ? NULL_KEY : key);
modCount++;
if (size == threshold)
rehash();
entry = new HashMapEntry(oRealKey, value);
hashIndex = hash(oRealKey);
list = buckets[hashIndex];
if (list == null)
{
list = new Bucket();
buckets[hashIndex] = list;
}
oResult = list.add(entry);
if (oResult == null)
{
size++;
return null;
}
else
{
return ((Map.Entry) oResult).getValue();
}
}
/**
* a private method, called by all of the constructors to initialize a new HashMap
*
* @param initialCapacity the initial capacity of this HashMap (>=0)
* @param initialLoadFactor the load factor of this HashMap
* (a misnomer, really, since the load factor of
* a HashMap does not change)
*/
private void init(int initialCapacity, float initialLoadFactor)
{
size = 0;
modCount = 0;
capacity = initialCapacity;
loadFactor = initialLoadFactor;
threshold = (int) ((float) capacity * loadFactor);
buckets = new Bucket[capacity];
}
/** private -- simply hashes a non-null Object to its array index */
private int hash(Object key)
{
return Math.abs(key.hashCode() % capacity);
}
/**
* increases the size of the HashMap and rehashes all keys to new array indices;
* this is called when the addition of a new value would cause size() > threshold
*/
private void rehash()
{
int i;
Bucket[] data = buckets;
Bucket.Node node;
modCount++;
capacity = (capacity * 2) + 1;
size = 0;
threshold = (int) ((float) capacity * loadFactor);
buckets = new Bucket[capacity];
for (i = 0; i < data.length; i++)
{
if (data[i] != null)
{
node = data[i].first;
while (node != null)
{
internalPut(node.getKey(), node.getValue());
node = node.next;
}
}
}
}
/**
* a private method which does the "dirty work" (or some of it anyway) of fetching a value
* with a key
*
* @param key the key for which to fetch an associated value
*/
private Map.Entry internalGet(Object key)
{
Bucket list;
if (size == 0)
{
return null;
}
else
{
list = buckets[hash(((key == null) ? NULL_KEY : key))];
return (list == null) ? null : list.getEntryByKey(key);
}
}
/**
* a private method used by inner class HashMapSet to implement its own
* <pre>contains(Map.Entry)</pre> method; returns true if the supplied
* key / value pair is found in this HashMap (again, using <pre>equals()</pre>,
* rather than <pre>==</pre>)
*
* @param entry a Map.Entry to match against key / value pairs in
* this HashMap
*/
private boolean containsEntry(Map.Entry entry)
{
Map.Entry oInternalEntry;
if (entry == null)
{
return false;
}
else
{
oInternalEntry = internalGet(entry.getKey());
return (oInternalEntry != null && oInternalEntry.equals(entry));
}
}
/**
* Serializes this object to the given stream.
* @serialdata the <i>capacity</i>(int) that is the length of the
* bucket array, the <i>size</i>(int) of the hash map are emitted
* first. They are followed by size entries, each consisting of
* a key (Object) and a value (Object).
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
// the fields
s.defaultWriteObject();
s.writeInt(capacity);
s.writeInt(size);
Iterator it = entrySet().iterator();
while (it.hasNext())
{
Map.Entry oEntry = (Map.Entry) it.next();
s.writeObject(oEntry.getKey());
s.writeObject(oEntry.getValue());
}
}
/**
* Deserializes this object from the given stream.
* @serialdata the <i>capacity</i>(int) that is the length of the
* bucket array, the <i>size</i>(int) of the hash map are emitted
* first. They are followed by size entries, each consisting of
* a key (Object) and a value (Object).
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
// the fields
s.defaultReadObject();
capacity = s.readInt();
int iLen = s.readInt();
size = 0;
modCount = 0;
buckets = new Bucket[capacity];
for (int i = 0; i < iLen; i++)
{
Object oKey = s.readObject();
Object oValue = s.readObject();
internalPut(oKey, oValue);
}
}
// INNER CLASSES -------------------------------------------------------------
// ---------------------------------------------------------------------------
/**
* an inner class providing a Set view of a HashMap; this implementation is
* parameterized to view either a Set of keys or a Set of Map.Entry objects
*
* Note: a lot of these methods are implemented by AbstractSet, and would work
* just fine without any meddling, but far greater efficiency can be gained by
* overriding a number of them. And so I did.
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
private class HashMapSet extends AbstractSet
implements Set
{
/** the type of this Set view: KEYS or ENTRIES */
private int setType;
/** construct a new HashtableSet with the supplied view type */
HashMapSet(int type)
{
setType = type;
}
/**
* adding an element is unsupported; this method simply throws an exception
*
* @throws UnsupportedOperationException
*/
public boolean add(Object o) throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
/**
* adding an element is unsupported; this method simply throws an exception
*
* @throws UnsupportedOperationException
*/
public boolean addAll(Collection c) throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
/**
* clears the backing HashMap; this is a prime example of an overridden implementation
* which is far more efficient than its superclass implementation (which uses an iterator
* and is O(n) -- this is an O(1) call)
*/
public void clear()
{
HashMap.this.clear();
}
/**
* returns true if the supplied object is contained by this Set
*
* @param o an Object being testing to see if it is in this Set
*/
public boolean contains(Object o)
{
if (setType == KEYS)
return HashMap.this.containsKey(o);
else
return (o instanceof Map.Entry) ? HashMap.this.containsEntry((Map.Entry) o) : false;
}
/**
* returns true if the backing HashMap is empty (which is the only case either a KEYS
* Set or an ENTRIES Set would be empty)
*/
public boolean isEmpty()
{
return HashMap.this.isEmpty();
}
/**
* removes the supplied Object from the Set
*
* @param o the Object to be removed
*/
public boolean remove(Object o)
{
if (setType == KEYS)
return (HashMap.this.remove(o) != null);
else
return (o instanceof Map.Entry) ?
(HashMap.this.remove(((Map.Entry) o).getKey()) != null) : false;
}
/** returns the size of this Set (always equal to the size of the backing Hashtable) */
public int size()
{
return HashMap.this.size();
}
/** returns an Iterator over the elements of this Set */
public Iterator iterator()
{
return new HashMapIterator(setType);
}
}
/**
* Like the above Set view, except this one if for values, which are not
* guaranteed to be unique in a Map; this prvides a Bag of values
* in the HashMap
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
private class HashMapCollection extends AbstractCollection
implements Collection
{
/** a trivial contructor for HashMapCollection */
HashMapCollection()
{
}
/**
* adding elements is not supported by this Collection;
* this method merely throws an exception
*
* @throws UnsupportedOperationException
*/
public boolean add(Object o) throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
/**
* adding elements is not supported by this Collection;
* this method merely throws an exception
*
* @throws UnsupportedOperationException
*/
public boolean addAll(Collection c) throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
/** removes all elements from this Collection (and from the backing HashMap) */
public void clear()
{
HashMap.this.clear();
}
/**
* returns true if this Collection contains at least one Object which equals() the
* supplied Object
*
* @param o the Object to compare against those in the Set
*/
public boolean contains(Object o)
{
return HashMap.this.containsValue(o);
}
/** returns true IFF the Collection has no elements */
public boolean isEmpty()
{
return HashMap.this.isEmpty();
}
/** returns the size of this Collection */
public int size()
{
return HashMap.this.size();
}
/** returns an Iterator over the elements in this Collection */
public Iterator iterator()
{
return new HashMapIterator(VALUES);
}
}
/**
* a class which implements the Iterator interface and is used for
* iterating over HashMaps;
* this implementation is parameterized to give a sequential view of
* keys, values, or entries; it also allows the removal of elements,
* as per the Javasoft spec.
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
class HashMapIterator implements Iterator
{
/** the type of this Iterator: KEYS, VALUES, or ENTRIES */
private int myType;
/**
* the number of modifications to the backing Hashtable for which
* this Iterator can account (idea ripped off from Stuart Ballard)
*/
private int knownMods;
/** the location of our sequential "cursor" */
private int position;
/** the current index of the BucketList array */
private int bucketIndex;
/** a reference, originally null, to the specific Bucket our "cursor" is pointing to */
private Bucket.Node currentNode;
/** a reference to the current key -- used fro removing elements via the Iterator */
private Object currentKey;
/** construct a new HashtableIterator with the supllied type: KEYS, VALUES, or ENTRIES */
HashMapIterator(int type)
{
myType = type;
knownMods = HashMap.this.modCount;
position = 0;
bucketIndex = -1;
currentNode = null;
currentKey = null;
}
/**
* Stuart Ballard's code: if the backing HashMap has been altered through anything
* but <i>this</i> Iterator's <pre>remove()</pre> method, we will give up right here,
* rather than risking undefined behavior
*
* @throws ConcurrentModificationException
*/
private void checkMod()
{
if (knownMods != HashMap.this.modCount)
throw new ConcurrentModificationException();
}
/** returns true if the Iterator has more elements */
public boolean hasNext()
{
checkMod();
return position < HashMap.this.size();
}
/** returns the next element in the Iterator's sequential view */
public Object next()
{
Bucket list = null;
Object result;
checkMod();
try
{
while (currentNode == null)
{
while (list == null)
list = HashMap.this.buckets[++bucketIndex];
currentNode = list.first;
}
currentKey = currentNode.getKey();
result = (myType == KEYS) ? currentKey :
((myType == VALUES) ? currentNode.getValue() : currentNode);
currentNode = currentNode.next;
}
catch(Exception e)
{
throw new NoSuchElementException();
}
position++;
return result;
}
/**
* removes from the backing HashMap the last element which was fetched with the
* <pre>next()</pre> method
*/
public void remove()
{
checkMod();
if (currentKey == null)
{
throw new IllegalStateException();
}
else
{
HashMap.this.remove(currentKey);
knownMods++;
currentKey = null;
}
}
}
/**
* a singleton instance of this class (HashMap.NULL_KEY)
* is used to represent the null key in HashMap objects
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
private static class Null
{
/** trivial constructor */
Null()
{
}
}
/**
* a HashMap version of Map.Entry -- one thing in this implementation is
* HashMap-specific: if the key is HashMap.NULL_KEY, getKey() will return
* null
*
* Simply, a key / value pair
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
private static class HashMapEntry extends Bucket.Node implements Map.Entry
{
/** construct a new HashMapEntry with the given key and value */
public HashMapEntry(Object key, Object value)
{
super(key, value);
}
/**
* if the key == HashMap.NULL_KEY, null is returned, otherwise the actual
* key is returned
*/
public Object getKey()
{
Object oResult = super.getKey();
return (oResult == HashMap.NULL_KEY) ? null : oResult;
}
}
// EOF -----------------------------------------------------------------------
}

@ -1,238 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// HashSet.java -- a class providing a HashMap-backet Set
//
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* This class provides a HashMap-backed implementation of the
* Set interface.
*
* Each element in the Set is a key in the backing HashMap; each key
* maps to a static token, denoting that the key does, in fact, exist.
*
* Most operations are O(1), assuming no hash collisions. In the worst
* case (where all hases collide), operations are O(n).
*
* HashSet is a part of the JDK1.2 Collections API.
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
public class HashSet extends AbstractSet
implements Set, Cloneable, Serializable
{
// INSTANCE VARIABLES -------------------------------------------------
/** the HashMap which backs this Set */
private transient HashMap map;
static final long serialVersionUID = -5024744406713321676L;
// CONSTRUCTORS ---------------------------------------------------------
/**
* construct a new, empty HashSet whose backing HashMap has the default
* capacity and loadFacor
*/
public HashSet()
{
map = new HashMap();
}
/**
* construct a new, empty HashSet whose backing HashMap has the supplied
* capacity and the default load factor
*
* @param initialCapacity the initial capacity of the backing
* HashMap
*/
public HashSet(int initialCapacity)
{
map = new HashMap(initialCapacity);
}
/**
* construct a new, empty HashSet whose backing HashMap has the supplied
* capacity and load factor
*
* @param initialCapacity the initial capacity of the backing
* HashMap
* @param loadFactor the load factor of the backing HashMap
*/
public HashSet(int initialCapacity, float loadFactor)
{
map = new HashMap(initialCapacity, loadFactor);
}
/**
* construct a new HashSet with the same elements as are in the supplied
* collection (eliminating any duplicates, of course; the backing HashMap
* will have the default capacity and load factor
*
* @param c a collection containing the elements with
* which this set will be initialized
*/
public HashSet(Collection c)
{
map = new HashMap();
addAll(c);
}
// PUBLIC METHODS ---------------------------------------------------------
/**
* adds the given Object to the set if it is not already in the Set,
* returns true if teh element was added, false otherwise
*
* @param o the Object to add to this Set
*/
public boolean add(Object o)
{
if (map.containsKey(o))
{
return false;
}
else
{
internalAdd(o);
return true;
}
}
/**
* empties this Set of all elements; this is a fast operation [O(1)]
*/
public void clear()
{
map.clear();
}
/**
* returns a shallow copy of this Set (the Set itself is cloned; its
* elements are not)
*/
public Object clone()
{
Iterator it = iterator();
HashSet clone = new HashSet(map.capacity, map.loadFactor);
while (it.hasNext())
clone.internalAdd(it.next());
return clone;
}
/**
* returns true if the supplied element is in this Set, false otherwise
*
* @param o the Object whose presence in this Set we are testing for
*/
public boolean contains(Object o)
{
return map.containsKey(o);
}
/**
* returns true if this set has no elements in it (size() == 0)
*/
public boolean isEmpty()
{
return map.isEmpty();
}
/**
* returns an Iterator over the elements of this Set; the Iterator allows
* removal of elements
*/
public Iterator iterator()
{
return map.keySet().iterator();
}
/**
* removes the supplied Object from this Set if it is in the Set; returns
* true if an element was removed, false otherwise
*/
public boolean remove(Object o)
{
return (map.remove(o) != null);
}
/**
* returns the number of elements in this Set
*/
public int size()
{
return map.size();
}
// PRIVATE METHODS -----------------------------------------------------------
/**
* adds the supplied element to this Set; this private method is used
* internally [clone()] instead of add(), because add() can be overridden
* to do unexpected things
*
* @param o the Object to add to this Set
*/
private void internalAdd(Object o)
{
map.put(o, Boolean.TRUE);
}
/** Serialize this Object in a manner which is binary-compatible with the JDK */
private void writeObject(ObjectOutputStream s) throws IOException
{
Iterator it = iterator();
s.writeInt(map.capacity);
s.writeFloat(map.loadFactor);
s.writeInt(size());
while (it.hasNext())
s.writeObject(it.next());
}
/** Deserialize this Object in a manner which is binary-compatible with the JDK */
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
{
int i, iSize, iCapacity;
float fLoadFactor;
Object oElement;
iCapacity = s.readInt();
fLoadFactor = s.readFloat();
iSize = s.readInt();
map = new HashMap(iCapacity, fLoadFactor);
for (i = 0; i < iSize; i++)
{
oElement = s.readObject();
internalAdd(oElement);
}
}
}

@ -1,66 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Iterator.java -- Interface for iterating over collections
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* An object which iterates over a collection. An Iterator is used to return the
* items once only, in sequence, by successive calls to the next method. It is
* also possible to remove elements from the underlying collection by using the
* optional remove method. Iterator is intended as a replacement for the
* Enumeration interface of previous versions of Java, which did not have the
* remove method and had less conveniently named methods.
*/
public interface Iterator {
/**
* Tests whether there are elements remaining in the collection.
*
* @return true if there is at least one more element in the collection,
* that is, if the next call to next will not throw NoSuchElementException.
*/
boolean hasNext();
/**
* Obtain the next element in the collection.
*
* @return the next element in the collection
* @exception NoSuchElementException if there are no more elements
*/
Object next();
/**
* Remove from the underlying collection the last element returned by next.
* This method can be called only once after each call to next. It does not
* affect what will be returned by subsequent calls to next. This operation is
* optional, it may throw an UnsupportedOperationException.
*
* @exception IllegalStateException if next has not yet been called or remove
* has already been called since the last call to next.
* @exception UnsupportedOperationException if this Iterator does not support
* the remove operation.
*/
void remove();
}

@ -1,581 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// LinkedList.java -- Linked list implementation of the List interface
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.util.NoSuchElementException;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
// TO DO:
// ~ Doc comment for the class.
// ~ Doc comments for the non-list methods.
// ~ Some commenting on the Backing API and other general implementation notes.
/**
* Linked list implementation of the List interface.
*/
public class LinkedList extends AbstractSequentialList
implements Serializable, Cloneable
{
static final long serialVersionUID = 876323262645176354L;
/**
* An Entry containing the head (in the next field) and the tail (in the
* previous field) of the list. The data field is null. If the list is empty,
* both the head and the tail point to ends itself.
*/
transient Entry ends = new Entry();
/**
* The current length of the list.
*/
transient int size = 0;
/**
* Class to represent an entry in the list. Holds a single element.
*/
private static class Entry {
/**
* The list element.
*/
Object data = null;
/**
* The next entry in the list. If this is the last entry in the list, the
* ends field of the list is held here.
*/
Entry next;
/**
* The previous entry in the list. If this is the first entry in the list,
* the ends field of the list is held here.
*/
Entry previous;
/**
* Create an entry with given data and linkage.
*/
Entry(Object d, Entry n, Entry p) {
data = d;
next = n;
previous = p;
}
/**
* Create an entry with no data and linking to itself, for use as the ends
* field of the list.
*/
Entry() {
next = previous = this;
}
/**
* Remove this entry.
*/
Object remove() {
previous.next = next;
next.previous = previous;
return data;
}
}
private static interface Backing {
void checkMod(int known);
void upMod();
void incSize(int by);
void decSize(int by);
}
private final Backing back = new Backing() {
public void checkMod(int known) {
if (known != modCount) {
throw new ConcurrentModificationException();
}
}
public void upMod() {
modCount++;
}
public void incSize(int by) {
size += by;
}
public void decSize(int by) {
size -= by;
}
};
/** A ListIterator over the list. This class keeps track of its
* position in the list, the size of the list, and the two list
* entries it is between. This enables it to be used identically
* for both the list itself and a sublist of the list.
*/
private static class Iter implements ListIterator {
/**
* The index of the element that will be returned by next().
*/
int pos;
/**
* The size of the backing list.
*/
int size;
/**
* The entry containing the element that will be returned by next().
*/
Entry next;
/**
* The entry containing the element that will be returned by previous().
*/
Entry previous;
/**
* The entry that will be affected by remove() or set().
*/
Entry recent;
/**
* The known value of the modCount of the backing list.
*/
int knownMod;
private final Backing b;
/**
* Create a new Iter starting at a given Entry within the list, at a given
* position, in a list of given size.
*
* @param index the index to begin iteration.
* @exception IndexOutOfBoundsException if index < 0 || index > size.
*/
Iter(Backing backing, Entry n, int index, int s, int mc) {
b = backing;
pos = index;
size = s;
next = n;
previous = n.previous;
knownMod = mc;
}
public int nextIndex() {
b.checkMod(knownMod);
return pos;
}
public int previousIndex() {
b.checkMod(knownMod);
return pos - 1;
}
public boolean hasNext() {
b.checkMod(knownMod);
return pos < size;
}
public boolean hasPrevious() {
b.checkMod(knownMod);
return pos > 0;
}
public Object next() {
b.checkMod(knownMod);
if (pos >= size) {
throw new NoSuchElementException();
} else {
pos++;
recent = previous = next;
next = recent.next;
return recent.data;
}
}
public Object previous() {
b.checkMod(knownMod);
if (pos <= 0) {
throw new NoSuchElementException();
} else {
pos--;
recent = next = previous;
previous = recent.previous;
return recent.data;
}
}
public void remove() {
b.checkMod(knownMod);
if (recent == null) {
throw new IllegalStateException();
}
// Adjust the position to before the removed element
if (recent == previous) pos--;
// Could use recent.remove() but this way is quicker, and also correctly
// fixes next and previous.
next = recent.previous.next = recent.next;
previous = recent.next.previous = recent.previous;
size--;
b.decSize(1);
knownMod++;
b.upMod();
recent = null;
}
public void add(Object o) {
b.checkMod(knownMod);
previous.next = next.previous = new Entry(o, next, previous);
// New for 1.2RC1 - the semantics changed so that the iterator is
// positioned *after* the new element.
previous = next;
next = previous.next;
pos++;
size++;
b.incSize(1);
knownMod++;
b.upMod();
recent = null;
}
public void set(Object o) {
b.checkMod(knownMod);
if (recent == null) {
throw new IllegalStateException();
}
recent.data = o;
}
}
/**
* Obtain the Entry at a given position in a list. This method of course
* takes linear time, but it is intelligent enough to take the shorter of the
* paths to get to the Entry required. This implies that the first or last
* entry in the list is obtained in constant time, which is a very desirable
* property.
* For speed and flexibility in which ranges are valid, range checking is not
* done in this method, and if n is outside the range -1 <= n <= size, the
* result will be wrong (but no exception will be thrown).
* Note that you *can* obtain entries at position -1 and size, which are
* equal to prehead and posttail respectively.
* This method is static so that it can also be used in subList.
*
* @param n the number of the entry to get.
* @param size the size of the list to get the entry in.
* @param head the entry before the first element of the list (usually ends).
* @param tail the entry after the last element of the list (usually ends).
*/
static Entry getEntry(int n, int size, Entry head, Entry tail) {
// n less than size/2, iterate from start
if (n < size >> 1) {
while (n-- >= 0) {
head = head.next;
}
return head;
// n greater than size/2, iterate from end
} else {
while (++n <= size) {
tail = tail.previous;
}
return tail;
}
}
/**
* Create an empty linked list.
*/
public LinkedList() {
super();
}
/**
* Create a linked list containing the elements, in order, of a given
* collection.
*
* @param c the collection to populate this list from.
*/
public LinkedList(Collection c) {
super();
// Note: addAll could be made slightly faster, but not enough so to justify
// re-implementing it from scratch. It is just a matter of a relatively
// small constant factor.
addAll(c);
}
public Object getFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
return ends.next.data;
}
public Object getLast() {
if (size == 0) {
throw new NoSuchElementException();
}
return ends.previous.data;
}
public Object removeFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
size--;
modCount++;
return ends.next.remove();
}
public Object removeLast() {
if (size == 0) {
throw new NoSuchElementException();
}
size--;
modCount++;
return ends.previous.remove();
}
public void addFirst(Object o) {
ends.next.previous = ends.next = new Entry(o, ends.next, ends);
size++;
modCount++;
}
public void addLast(Object o) {
ends.previous.next = ends.previous = new Entry(o, ends, ends.previous);
size++;
modCount++;
}
/**
* Obtain the number of elements currently in this list.
*
* @returns the number of elements currently in this list.
*/
public int size() {
return size;
}
/**
* Remove a range of elements from this list.
*
* @param fromIndex the index, inclusive, to remove from.
* @param toIndex the index, exclusive, to remove to.
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex <
* 0 || toIndex > size().
*/
// Note: normally removeRange is provided to allow efficient ways to
// implement clear() on subLists. However, in this case clear on subLists
// works anyway, so this implementation is included just for completeness
// and because subclasses might try to use it.
protected void removeRange(int fromIndex, int toIndex) {
subList(fromIndex, toIndex).clear();
}
/**
* Clear the list.
*/
public void clear() {
ends.next = ends.previous = ends;
modCount++;
size = 0;
}
/**
* Obtain a ListIterator over this list, starting at a given index. The
* ListIterator returned by this method supports the add, remove and set
* methods.
*
* @param index the index of the element to be returned by the first call to
* next(), or size() to be initially positioned at the end of the list.
* @exception IndexOutOfBoundsException if index < 0 || index > size().
*/
public ListIterator listIterator(int index) {
// Check bounds
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
return new Iter(back, getEntry(index, size, ends, ends),
index, size, modCount);
}
/**
* Obtain a List view of a subsection of this list, from fromIndex
* (inclusive) to toIndex (exclusive). The returned list is modifiable in
* every respect. Changes to the returned list are reflected in this list. If
* this list is structurally modified is any way other than through the
* returned list, any subsequent operations on the returned list will result
* in a ConcurrentModificationException (that is, the returned list is
* fail-fast).
*
* @param fromIndex the index that the returned list should start from
* (inclusive).
* @param toIndex the index that the returned list should go to (exclusive).
* @returns a List backed by a subsection of this list.
* @exception IndexOutOfBoundsException if fromIndex < 0 || toIndex > size()
* || fromIndex > toIndex.
*/
public List subList(int fromIndex, int toIndex) {
// Check bounds
if (fromIndex > toIndex || fromIndex < 0 || toIndex > size) {
throw new IndexOutOfBoundsException();
}
return new SubLinkedList(back, getEntry(fromIndex - 1, size, ends, ends),
getEntry(toIndex, size, ends, ends),
toIndex - fromIndex);
}
private static class SubLinkedList extends AbstractSequentialList {
Entry head; // entry before the beginning
Entry tail; // entry after the end
int size;
private final Backing b;
private final Backing back = new Backing() {
public void checkMod(int known) {
if (known != modCount) {
throw new ConcurrentModificationException();
}
}
public void upMod() {
modCount++;
}
public void incSize(int by) {
size += by;
}
public void decSize(int by) {
size -= by;
}
};
SubLinkedList(Backing backing, Entry h, Entry t, int s) {
b = backing;
head = h;
tail = t;
size = s;
}
public int size() {
b.checkMod(this.modCount);
return size;
}
public ListIterator listIterator(int index) {
b.checkMod(this.modCount);
// Check bounds
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
return new Iter(back, getEntry(index, size, head, tail),
index, size, modCount);
}
public void clear() {
b.checkMod(this.modCount);
head.next = tail;
tail.previous = head;
size = 0;
b.decSize(size);
modCount++;
b.upMod();
}
// No removeRange because this class cannot be publically subclassed.
public List subList(int fromIndex, int toIndex) {
b.checkMod(this.modCount);
// Check bounds
if (fromIndex > toIndex || fromIndex < 0 || toIndex > size) {
throw new IndexOutOfBoundsException();
}
return new SubLinkedList(back, getEntry(fromIndex - 1, size, head, tail),
getEntry(toIndex, size, head, tail),
toIndex - fromIndex);
}
}
/**
* Create a shallow copy of this LinkedList.
* @return an object of the same class as this object, containing the
* same elements in the same order.
*/
public Object clone()
{
LinkedList copy;
try
{
copy = (LinkedList) super.clone();
}
catch (CloneNotSupportedException ex)
{
throw new InternalError(ex.getMessage());
}
copy.size = 0;
copy.ends = new Entry();
copy.addAll(this);
return copy;
}
/**
* Serialize an object to a stream.
* @serialdata the size of the list (int), followed by all the elements
* (Object) in proper order.
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
s.writeInt(size);
for (Iterator i = iterator(); i.hasNext(); )
s.writeObject(i.next());
}
/**
* Deserialize an object from a stream.
* @serialdata the size of the list (int), followed by all the elements
* (Object) in proper order.
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
int serialSize = s.readInt();
ends = new Entry();
for (int i=0; i< serialSize; i++)
addLast(s.readObject());
}
}

@ -1,331 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// List.java -- An ordered collection which allows indexed access
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comment for the interface itself needs to be put into english.
// ~ Some more @see clauses might be nice.
package jode.util;
/**
* [This is what this doc comment will mention:
* ~ Additional restrictions on some methods. Others included for completeness.
* ~ ListIterator and what it can do
* ~ Positional and iterated access
* ~ search (but linear time)
* ~ be careful when containing self as an element, because equals and hashCode
* loop.]
*/
public interface List extends Collection {
/**
* Insert an element into the list at a given position.
*
* @param index the location to insert the item.
* @param o the object to insert.
* @exception UnsupportedOperationException if this list does not support the
* add operation.
* @exception IndexOutOfBoundsException if index < 0 || index > size()
* @exception ClassCastException if o cannot be added to this list due to its
* type.
* @exception IllegalArgumentException if o cannot be added to this list for
* some other reason.
*/
void add(int index, Object o);
/**
* Add an element to the end of the list.
*
* @param o the object to add.
* @returns true, as Collection defines this method as returning true if the
* list was modified as a result of this action, and it always is for a
* list.
* @exception UnsupportedOperationException if this list does not support the
* add operation.
* @exception ClassCastException if o cannot be added to this list due to its
* type.
* @exception IllegalArgumentException if o cannot be added to this list for
* some other reason.
*/
boolean add(Object o);
/**
* Insert the contents of a collection into the list at a given position.
*
* @param index the location to insert the collection.
* @param c the collection to insert.
* @returns true if the list was modified by this action, that is, if c is
* non-empty.
* @exception UnsupportedOperationException if this list does not support the
* addAll operation.
* @exception IndexOutOfBoundsException if index < 0 || index > size()
* @exception ClassCastException if some element of c cannot be added to this
* list due to its type.
* @exception IllegalArgumentException if some element of c cannot be added
* to this list for some other reason.
*/
boolean addAll(int index, Collection c);
/**
* Add the contents of a collection to the end of the list.
*
* @param c the collection to add.
* @returns true if the list was modified by this action, that is, if c is
* non-empty.
* @exception UnsupportedOperationException if this list does not support the
* addAll operation.
* @exception ClassCastException if some element of c cannot be added to this
* list due to its type.
* @exception IllegalArgumentException if some element of c cannot be added
* to this list for some other reason.
*/
boolean addAll(Collection c);
/**
* Clear the list, such that a subsequent call to isEmpty() would return
* true.
*
* @exception UnsupportedOperationException if this list does not support the
* clear operation.
*/
void clear();
/**
* Test whether this list contains a given object as one of its elements.
*
* @param o the element to look for.
* @returns true if this list contains an element e such that <code>o ==
* null ? e == null : o.equals(e)</code>.
*/
boolean contains(Object o);
/**
* Test whether this list contains every element in a given collection.
*
* @param c the collection to test for.
* @returns true if for every element o in c, contains(o) would return true.
*/
boolean containsAll(Collection c);
/**
* Test whether this list is equal to another object. A List is defined to be
* equal to an object if and only if that object is also a List, and the two
* lists are equal. Two lists l1 and l2 are defined to be equal if and only
* if <code>l1.size() == l2.size()</code>, and for every integer n between 0
* and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ?
* l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>.
*
* @param o the object to test for equality with this list.
* @returns true if o is equal to this list.
*/
boolean equals(Object o);
/**
* Get the element at a given index in this list.
*
* @param index the index of the element to be returned.
* @returns the element at index index in this list.
* @exception IndexOutOfBoundsException if index < 0 || index >= size()
*/
Object get(int index);
/**
* Obtain a hash code for this list. In order to obey the general contract of
* the hashCode method of class Object, this value is calculated as follows:
* <pre>
* hashCode = 1;
* Iterator i = list.iterator();
* while (i.hasNext()) {
* Object obj = i.next();
* hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
* }
* </pre>
* This ensures that the general contract of Object.hashCode() is adhered to.
*
* @returns the hash code of this list.
*/
int hashCode();
/**
* Obtain the first index at which a given object is to be found in this
* list.
*
* @returns the least integer n such that <code>o == null ? get(n) == null :
* o.equals(get(n))</code>, or -1 if there is no such index.
*/
int indexOf(Object o);
/**
* Test whether this list is empty, that is, if size() == 0.
*
* @returns true if this list contains no elements.
*/
boolean isEmpty();
/**
* Obtain an Iterator over this list.
*
* @returns an Iterator over the elements of this list, in order.
*/
Iterator iterator();
/**
* Obtain the last index at which a given object is to be found in this
* list.
*
* @returns the greatest integer n such that <code>o == null ? get(n) == null
* : o.equals(get(n))</code>.
*/
int lastIndexOf(Object o);
/**
* Obtain a ListIterator over this list, starting at the beginning.
*
* @returns a ListIterator over the elements of this list, in order, starting
* at the beginning.
*/
ListIterator listIterator();
/**
* Obtain a ListIterator over this list, starting at a given position.
*
* @param index the position, between 0 and size() inclusive, to begin the
* iteration from.
* @returns a ListIterator over the elements of this list, in order, starting
* at index.
* @exception IndexOutOfBoundsException if index < 0 || index > size()
*/
ListIterator listIterator(int index);
/**
* Remove the element at a given position in this list.
*
* @param index the position within the list of the object to remove.
* @returns the object that was removed.
* @exception UnsupportedOperationException if this list does not support the
* remove operation.
* @exception IndexOutOfBoundsException if index < 0 || index > size()
*/
Object remove(int index);
/**
* Remove the first occurence of an object from this list. That is, remove
* the first element e such that <code>o == null ? e == null :
* o.equals(e)</code>.
*
* @param o the object to remove.
* @returns true if the list changed as a result of this call, that is, if
* the list contained at least one occurrence of o.
* @exception UnsupportedOperationException if this list does not support the
* remove operation.
*/
boolean remove(Object o);
/**
* Remove all elements of a given collection from this list. That is, remove
* every element e such that c.contains(e).
*
* @returns true if this list was modified as a result of this call.
* @exception UnsupportedOperationException if this list does not support the
* removeAll operation.
*/
boolean removeAll(Collection c);
/**
* Remove all elements of this list that are not contained in a given
* collection. That is, remove every element e such that !c.contains(e).
*
* @returns true if this list was modified as a result of this call.
* @exception UnsupportedOperationException if this list does not support the
* retainAll operation.
*/
boolean retainAll(Collection c);
/**
* Replace an element of this list with another object.
*
* @param index the position within this list of the element to be replaced.
* @param o the object to replace it with.
* @returns the object that was replaced.
* @exception UnsupportedOperationException if this list does not support the
* set operation.
* @exception IndexOutOfBoundsException if index < 0 || index >= size()
* @exception ClassCastException if o cannot be added to this list due to its
* type.
* @exception IllegalArgumentException if o cannot be added to this list for
* some other reason.
*/
Object set(int index, Object o);
/**
* Get the number of elements in this list.
*
* @returns the number of elements in the list.
*/
int size();
/**
* Obtain a List view of a subsection of this list, from fromIndex
* (inclusive) to toIndex (exclusive). The returned list should be modifiable
* if and only if this list is modifiable. Changes to the returned list
* should be reflected in this list. If this list is structurally modified in
* any way other than through the returned list, the result of any subsequent
* operations on the returned list is undefined.
*
* @param fromIndex the index that the returned list should start from
* (inclusive).
* @param toIndex the index that the returned list should go to (exclusive).
* @returns a List backed by a subsection of this list.
* @exception IndexOutOfBoundsException if fromIndex < 0 || toIndex > size()
* || fromIndex > toIndex.
*/
List subList(int fromIndex, int toIndex);
/**
* Copy the current contents of this list into an array.
*
* @returns an array of type Object[] and length equal to the length of this
* list, containing the elements currently in this list, in order.
*/
Object[] toArray();
/**
* Copy the current contents of this list into an array. If the array passed
* as an argument has length less than that of this list, an array of the
* same run-time type as a, and length equal to the length of this list, is
* allocated using Reflection. Otherwise, a itself is used. The elements of
* this list are copied into it, and if there is space in the array, the
* following element is set to null. The resultant array is returned.
* Note: The fact that the following element is set to null is only useful
* if it is known that this list does not contain any null elements.
*
* @param a the array to copy this list into.
* @returns an array containing the elements currently in this list, in
* order.
* @exception ArrayStoreException if the type of any element of the
* collection is not a subtype of the element type of a.
*/
Object[] toArray(Object[] a);
}

@ -1,145 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// ListIterator.java -- Extended Iterator for iterating over ordered lists
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
/**
* An extended version of Iterator to support the extra features of Lists. The
* elements may be accessed in forward or reverse order, elements may be
* replaced as well as removed, and new elements may be inserted, during the
* traversal of the list.
*/
public interface ListIterator extends Iterator {
/**
* Tests whether there are elements remaining in the list in the forward
* direction.
*
* @return true if there is at least one more element in the list in the
* forward direction, that is, if the next call to next will not throw
* NoSuchElementException.
*/
boolean hasNext();
/**
* Tests whether there are elements remaining in the list in the reverse
* direction.
*
* @return true if there is at least one more element in the list in the
* reverse direction, that is, if the next call to previous will not throw
* NoSuchElementException.
*/
boolean hasPrevious();
/**
* Obtain the next element in the list in the forward direction. Repeated
* calls to next may be used to iterate over the entire list, or calls to next
* and previous may be used together to go forwards and backwards. Alternating
* calls to next and previous will return the same element.
*
* @return the next element in the list in the forward direction
* @exception NoSuchElementException if there are no more elements
*/
Object next();
/**
* Obtain the next element in the list in the reverse direction. Repeated
* calls to previous may be used to iterate backwards over the entire list, or
* calls to next and previous may be used together to go forwards and
* backwards. Alternating calls to next and previous will return the same
* element.
*
* @return the next element in the list in the reverse direction
* @exception NoSuchElementException if there are no more elements
*/
Object previous();
/**
* Find the index of the element that would be returned by a call to next.
*
* @return the index of the element that would be returned by a call to next,
* or list.size() if the iterator is at the end of the list.
*/
int nextIndex();
/**
* Find the index of the element that would be returned by a call to previous.
*
* @return the index of the element that would be returned by a call to
* previous, or -1 if the iterator is at the beginning of the list.
*/
int previousIndex();
/**
* Insert an element into the list at the current position of the iterator.
* The element is inserted in between the element that would be returned by
* previous and the element that would be returned by next. After the
* insertion, a subsequent call to next is unaffected, but a call to
* previous returns the item that was added. This operation is optional, it
* may throw an UnsupportedOperationException.
*
* @param o the object to insert into the list
* @exception ClassCastException the object is of a type which cannot be added
* to this list
* @exception IllegalArgumentException some other aspect of the object stops
* it being added to this list
* @exception UnsupportedOperationException if this ListIterator does not
* support the add operation
*/
void add(Object o);
/**
* Remove from the list the element last returned by a call to next or
* previous. This method may only be called if neither add nor remove have
* been called since the last call to next or previous. This operation is
* optional, it may throw an UnsupportedOperationException.
*
* @exception IllegalStateException if neither next or previous have been
* called, or if add or remove has been called since the last call to next
* or previous.
* @exception UnsupportedOperationException if this ListIterator does not
* support the remove operation.
*/
void remove();
/**
* Replace the element last returned by a call to next or previous with a
* given object. This method may only be called if neither add nor remove have
* been called since the last call to next or previous. This operation is
* optional, it may throw an UnsupportedOperationException.
*
* @param o the object to replace the element with
* @exception ClassCastException the object is of a type which cannot be added
* to this list
* @exception IllegalArgumentException some other aspect of the object stops
* it being added to this list
* @exception IllegalStateException if neither next or previous have been
* called, or if add or remove has been called since the last call to next
* or previous.
* @exception UnsupportedOperationException if this ListIterator does not
* support the set operation.
*/
void set(Object o);
}

@ -11,34 +11,7 @@ BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB)
MY_JAVA_FILES = \
SimpleMap.java \
SimpleSet.java \
ArrayEnum.java \
AbstractCollection.java \
AbstractList.java \
AbstractMap.java \
AbstractSequentialList.java \
AbstractSet.java \
ArrayList.java \
Arrays.java \
BasicMapEntry.java \
Bucket.java \
Collection.java \
Collections.java \
Comparable.java \
Comparator.java \
ConcurrentModificationException.java \
HashMap.java \
HashSet.java \
Iterator.java \
LinkedList.java \
List.java \
ListIterator.java \
Map.java \
Set.java \
SortedMap.java \
SortedSet.java \
TreeMap.java \
TreeSet.java \
UnsupportedOperationException.java
ArrayEnum.java
noinst_DATA = $(MY_JAVA_FILES:.java=.class)
EXTRA_DIST = $(MY_JAVA_FILES)

@ -1,55 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Map.java -- An object that maps keys to values
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comments for everything.
package jode.util;
public interface Map
{
public void clear();
public boolean containsKey(Object key);
public boolean containsValue(Object value);
public Set entrySet();
public boolean equals(Object o);
public Object get(Object key);
public Object put(Object key, Object value);
public int hashCode();
public boolean isEmpty();
public Set keySet();
public void putAll(Map m);
public Object remove(Object o);
public int size();
public Collection values();
public static interface Entry {
public Object getKey();
public Object getValue();
public Object setValue(Object value);
public int hashCode();
public boolean equals(Object o);
}
}

@ -1,46 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// Set.java -- A collection that prohibits duplicates
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comments for everything.
package jode.util;
public interface Set extends Collection {
boolean add(Object o);
boolean addAll(Collection c);
void clear();
boolean contains(Object o);
boolean containsAll(Collection c);
boolean equals(Object o);
int hashCode();
boolean isEmpty();
Iterator iterator();
boolean remove(Object o);
boolean removeAll(Collection c);
boolean retainAll(Collection c);
int size();
Object[] toArray();
}

@ -18,12 +18,10 @@
*/
package jode.util;
///#ifdef JDK12
///import java.util.AbstractMap;
///import java.util.Map;
///import java.util.Iterator;
///import java.util.Set;
///#endif
import @COLLECTIONS@.AbstractMap;
import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
import @COLLECTIONS@.Set;
/**
* This is a very simple map, using a set as backing.
@ -49,11 +47,41 @@ public class SimpleMap extends AbstractMap {
return backing;
}
public static class SimpleEntry extends BasicMapEntry {
public static class SimpleEntry implements Map.Entry {
Object key;
Object value;
public SimpleEntry(Object key, Object value) {
super(key, value);
}
}
this.key = key;
this.value = value;
}
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
public Object setValue(Object newValue) {
Object old = value;
value = newValue;
return old;
}
public int hashCode() {
return key.hashCode() ^ value.hashCode();
}
public boolean equals(Object o) {
if (o instanceof Map.Entry) {
Map.Entry e = (Map.Entry) o;
return key.equals(e.getKey()) && value.equals(e.getValue());
}
return false;
}
}
public Object put(Object key, Object value) {
for (Iterator i = backing.iterator();

@ -18,10 +18,8 @@
*/
package jode.util;
///#ifdef JDK12
///import java.util.AbstractSet;
///import java.util.Iterator;
///#endif
import @COLLECTIONS@.AbstractSet;
import @COLLECTIONS@.Iterator;
public class SimpleSet extends AbstractSet implements Cloneable
{

@ -1,38 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// SortedMap.java -- A map that makes guarantees about the order of its keys
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comments for everything.
package jode.util;
public interface SortedMap extends Map {
Comparator comparator();
Object firstKey();
SortedMap headMap(Object toKey);
Object lastKey();
SortedMap subMap(Object fromKey, Object toKey);
SortedMap tailMap(Object fromKey);
}

@ -1,38 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// SortedSet.java -- A set that makes guarantees about the order of its elements
//
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
// TO DO:
// ~ Doc comments for everything.
package jode.util;
public interface SortedSet extends Set {
Comparator comparator();
Object first();
SortedSet headSet(Object toElement);
Object last();
SortedSet subSet(Object fromElement, Object toElement);
SortedSet tailSet(Object fromElement);
}

File diff suppressed because it is too large Load Diff

@ -1,331 +0,0 @@
// This class is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/////////////////////////////////////////////////////////////////////////////
// TreeSet.java -- a class providing a TreeMap-backet SortedSet
//
// Copyright (c) 1999 by Jon A. Zeppieri (jon@eease.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation, version 2. (see COPYING.LIB)
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with this program; if not, write to the Free Software Foundation
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////////
package jode.util;
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* This class provides a TreeMap-backed implementation of the
* SortedSet interface.
*
* Each element in the Set is a key in the backing TreeMap; each key
* maps to a static token, denoting that the key does, in fact, exist.
*
* Most operations are O(log n).
*
* TreeSet is a part of the JDK1.2 Collections API.
*
* @author Jon Zeppieri
* @version $Revision$
* @modified $Id$
*/
public class TreeSet extends AbstractSet
implements SortedSet, Cloneable, Serializable
{
// INSTANCE VARIABLES -------------------------------------------------
/** The TreeMap which backs this Set */
transient SortedMap _oMap;
static final long serialVersionUID = -2479143000061671589L;
// CONSTRUCTORS -------------------------------------------------------
/**
* Construct a new TreeSet whose backing TreeMap using the "natural" ordering
* of keys.
*/
public TreeSet()
{
this((Comparator) null);
}
/**
* Construct a new TreeSet whose backing TreeMap uses the supplied
* Comparator.
*
* @param oComparator the Comparator this Set will use
*/
public TreeSet(Comparator oComparator)
{
_oMap = new TreeMap(oComparator);
}
/**
* Construct a new TreeSet whose backing TreeMap uses the "natural"
* orering of the keys and which contains all of the elements in the
* supplied Collection.
*
* @param oCollection the new Set will be initialized with all
* of the elements in this Collection
*/
public TreeSet(Collection oCollection)
{
this((Comparator) null);
addAll(oCollection);
}
/**
* Construct a new TreeSet, using the same key ordering as the supplied
* SortedSet and containing all of the elements in the supplied SortedSet.
* This constructor runs in linear time.
*
* @param oSortedSet the new TreeSet will use this SortedSet's
* comparator and will initialize itself
* with all of the elements in this SortedSet
*/
public TreeSet(SortedSet oSortedSet)
{
this(oSortedSet.comparator());
TreeMap oMap = (TreeMap) _oMap;
int i = 0;
Map.Entry[] arEntries = new Map.Entry[oSortedSet.size()];
Iterator itEntries = oSortedSet.iterator();
while (itEntries.hasNext())
arEntries[i++] = new BasicMapEntry(itEntries.next(), Boolean.TRUE);
oMap._iSize = i;
oMap.putAllLinear(arEntries);
}
TreeSet(SortedMap oMap)
{
_oMap = oMap;
}
// METHODS -----------------------------------------------------------
/**
* Adds the spplied Object to the Set if it is not already in the Set;
* returns true if the element is added, false otherwise
*
* @param oObject the Object to be added to this Set
*/
public boolean add(Object oObject)
{
if (_oMap.containsKey(oObject))
{
return false;
}
else
{
internalAdd(_oMap, oObject);
return true;
}
}
/**
* Adds all of the elements in the supplied Collection to this TreeSet.
*
* @param oCollection All of the elements in this Collection
* will be added to the Set.
*
* @return true if the Set is altered, false otherwise
*/
public boolean addAll(Collection oCollection)
{
boolean boResult = false;
Iterator itElements = oCollection.iterator();
while (itElements.hasNext())
boResult = (boResult || add(itElements.next()));
return boResult;
}
/**
* Removes all elements in this Set.
*/
public void clear()
{
_oMap.clear();
}
/** Returns a shallow copy of this Set. */
public Object clone()
{
TreeSet oClone;
try
{
oClone = (TreeSet) super.clone();
oClone._oMap = _oMap;
}
catch(CloneNotSupportedException e)
{
oClone = null;
}
return oClone;
}
/** Returns this Set's comparator */
public Comparator comparator()
{
return _oMap.comparator();
}
/**
* Returns true if this Set contains the supplied Object,
* false otherwise
*
* @param oObject the Object whose existence in the Set is
* being tested
*/
public boolean contains(Object oObject)
{
return _oMap.containsKey(oObject);
}
/** Returns true if this Set has size 0, false otherwise */
public boolean isEmpty()
{
return _oMap.isEmpty();
}
/** Returns the number of elements in this Set */
public int size()
{
return _oMap.size();
}
/**
* If the supplied Object is in this Set, it is removed, and true is
* returned; otherwise, false is returned.
*
* @param oObject the Object we are attempting to remove
* from this Set
*/
public boolean remove(Object oObject)
{
return (_oMap.remove(oObject) != null);
}
/** Returns the first (by order) element in this Set */
public Object first()
{
return _oMap.firstKey();
}
/** Returns the last (by order) element in this Set */
public Object last()
{
return _oMap.lastKey();
}
/**
* Returns a view of this Set including all elements in the interval
* [oFromElement, oToElement).
*
* @param oFromElement the resultant view will contain all
* elements greater than or equal to this
* element
* @param oToElement the resultant view will contain all
* elements less than this element
*/
public SortedSet subSet(Object oFromElement, Object oToElement)
{
return new TreeSet(_oMap.subMap(oFromElement, oToElement));
}
/**
* Returns a view of this Set including all elements less than oToElement
*
* @param oToElement the resultant view will contain all
* elements less than this element
*/
public SortedSet headSet(Object oToElement)
{
return new TreeSet(_oMap.headMap(oToElement));
}
/**
* Returns a view of this Set including all elements greater than or
* equal to oFromElement.
*
* @param oFromElement the resultant view will contain all
* elements greater than or equal to this
* element
*/
public SortedSet tailSet(Object oFromElement)
{
return new TreeSet(_oMap.tailMap(oFromElement));
}
/** Returns in Iterator over the elements in this TreeSet */
public Iterator iterator()
{
return _oMap.keySet().iterator();
}
private void writeObject(ObjectOutputStream oOut) throws IOException
{
Iterator itElements = iterator();
oOut.writeObject(comparator());
oOut.writeInt(size());
while (itElements.hasNext())
oOut.writeObject(itElements.next());
}
private void readObject(ObjectInputStream oIn)
throws IOException, ClassNotFoundException
{
int i;
Map.Entry[] arEntries;
TreeMap oMap;
Comparator oComparator = (Comparator) oIn.readObject();
int iSize = oIn.readInt();
arEntries = new Map.Entry[iSize];
for (i = 0; i < iSize; i++)
arEntries[iSize] = new BasicMapEntry(oIn.readObject(), Boolean.TRUE);
oMap = new TreeMap(oComparator);
oMap._iSize = iSize;
oMap.putAllLinear(arEntries);
_oMap = oMap;
}
/**
* adds the supplied element to this Set; this private method is used
* internally instead of add(), because add() can be overridden
* to do unexpected things
*
* @param o the Object to add to this Set
*/
private static final void internalAdd(Map oMap, Object oObject)
{
oMap.put(oObject, Boolean.TRUE);
}
}

@ -1,54 +0,0 @@
// This interface is taken from the Classpath project.
// Please note the different copyright holder!
// The changes I did is this comment, the package line, some
// imports from java.util and some minor jdk12 -> jdk11 fixes.
// -- Jochen Hoenicke <jochen@gnu.org>
/*************************************************************************
/* UnsupportedOperationException.java -- Exception thrown when an
/* unsupported operation is attempted on an object
/*
/* Copyright (c) 1998 by Free Software Foundation, Inc.
/*
/* This program is free software; you can redistribute it and/or modify
/* it under the terms of the GNU Library General Public License as published
/* by the Free Software Foundation, version 2. (see COPYING.LIB)
/*
/* This program is distributed in the hope that it will be useful, but
/* WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* GNU General Public License for more details.
/*
/* You should have received a copy of the GNU General Public License
/* along with this program; if not, write to the Free Software Foundation
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
/*************************************************************************/
package jode.util;
/**
* This exception is thrown by an object when an operation is
* requested of it that it does not support.
*
* @since JDK 1.2
*/
public class UnsupportedOperationException extends RuntimeException
{
static final long serialVersionUID = -1242599979055084673L;
/**
* Create an exception without a message.
*/
public UnsupportedOperationException()
{
super();
}
/**
* Create an exception with a message.
*/
public UnsupportedOperationException( String s )
{
super(s);
}
}
Loading…
Cancel
Save