diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility')
213 files changed, 0 insertions, 46821 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/.classpath b/jpa/plugins/org.eclipse.jpt.utility/.classpath deleted file mode 100644 index 304e86186a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/.classpath +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" path="src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> - <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/jpa/plugins/org.eclipse.jpt.utility/.cvsignore b/jpa/plugins/org.eclipse.jpt.utility/.cvsignore deleted file mode 100644 index a128605b1f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -bin -@dot -temp.folder -build.xml
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.utility/.project b/jpa/plugins/org.eclipse.jpt.utility/.project deleted file mode 100644 index 99b389b9c5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/.project +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>org.eclipse.jpt.utility</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.pde.ManifestBuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.pde.SchemaBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.pde.PluginNature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.core.resources.prefs b/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 8e5b2c2b65..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Jan 15 11:12:22 EST 2008 -eclipse.preferences.version=1 -encoding/<project>=ISO-8859-1 diff --git a/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.jdt.core.prefs b/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 443826069d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,7 +0,0 @@ -#Sun May 27 14:55:37 EDT 2007 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF deleted file mode 100644 index 9f1f09d92a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF +++ /dev/null @@ -1,67 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName -Bundle-SymbolicName: org.eclipse.jpt.utility -Bundle-Version: 1.3.0.qualifier -Bundle-Localization: plugin -Export-Package: org.eclipse.jpt.utility, - org.eclipse.jpt.utility.internal; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.iterators; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.model; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.model.listener.awt; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.model.value; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.model.value.prefs; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.model.value.swing; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.node; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.internal.swing; - x-friends:="org.eclipse.jpt.core, - org.eclipse.jpt.db, - org.eclipse.jpt.db.ui, - org.eclipse.jpt.gen, - org.eclipse.jpt.ui", - org.eclipse.jpt.utility.model, - org.eclipse.jpt.utility.model.event, - org.eclipse.jpt.utility.model.listener, - org.eclipse.jpt.utility.model.value -Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/jpa/plugins/org.eclipse.jpt.utility/about.html b/jpa/plugins/org.eclipse.jpt.utility/about.html deleted file mode 100644 index be534ba44f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/about.html +++ /dev/null @@ -1,34 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> -<HTML> - -<head> -<title>About</title> -<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1"> -</head> - -<BODY lang="EN-US"> - -<H3>About This Content</H3> - -<P>May 02, 2008</P> - -<H3>License</H3> - -<P>The Eclipse Foundation makes available all content in this plug-in -("Content"). Unless otherwise indicated below, the Content is provided to you -under the terms and conditions of the Eclipse Public License Version 1.0 -("EPL"). A copy of the EPL is available at -<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. -For purposes of the EPL, "Program" will mean the Content.</P> - -<P>If you did not receive this Content directly from the Eclipse Foundation, the -Content is being redistributed by another party ("Redistributor") and different -terms and conditions may apply to your use of any object code in the Content. -Check the Redistributor's license that was provided with the Content. If no such -license exists, contact the Redistributor. Unless otherwise indicated below, the -terms and conditions of the EPL still apply to any source code in the Content -and such source code may be obtained at -<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P> - -</BODY> -</HTML> diff --git a/jpa/plugins/org.eclipse.jpt.utility/build.properties b/jpa/plugins/org.eclipse.jpt.utility/build.properties deleted file mode 100644 index 11ab8d42f6..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/build.properties +++ /dev/null @@ -1,17 +0,0 @@ -################################################################################ -# Copyright (c) 2006, 2007 Oracle. All rights reserved. -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License v1.0, which accompanies this distribution -# and is available at http://www.eclipse.org/legal/epl-v10.html. -# -# Contributors: -# Oracle - initial API and implementation -################################################################################ -javacSource=1.5 -javacTarget=1.5 -source.. = src/ -output.. = bin/ -bin.includes = .,\ - META-INF/,\ - about.html,\ - plugin.properties diff --git a/jpa/plugins/org.eclipse.jpt.utility/component.xml b/jpa/plugins/org.eclipse.jpt.utility/component.xml deleted file mode 100644 index b210b281dd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/component.xml +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><component xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt.utility"><description url=""></description><component-depends unrestricted="true"></component-depends><plugin id="org.eclipse.jpt.utility" fragment="false"/></component>
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.utility/plugin.properties b/jpa/plugins/org.eclipse.jpt.utility/plugin.properties deleted file mode 100644 index 95c029d5d8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/plugin.properties +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# Copyright (c) 2006, 2007 Oracle. All rights reserved. -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License v1.0, which accompanies this distribution -# and is available at http://www.eclipse.org/legal/epl-v10.html. -# -# Contributors: -# Oracle - initial API and implementation -################################################################################ -# ==================================================================== -# To code developer: -# Do NOT change the properties between this line and the -# "%%% END OF TRANSLATED PROPERTIES %%%" line. -# Make a new property name, append to the end of the file and change -# the code to use the new property. -# ==================================================================== - -# ==================================================================== -# %%% END OF TRANSLATED PROPERTIES %%% -# ==================================================================== - -pluginName = Java Persistence API Tools - Utility -providerName = Eclipse.org - diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Command.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Command.java deleted file mode 100644 index 60fbfaf6b6..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Command.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility; - -/** - * Simple interface for implementing the GOF Command design pattern, - * and it doesn't carry the baggage of java.lang.Runnable. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface Command { - - /** - * Execute the command. The semantics of the command - * is determined by the contract between the client and server. - */ - void execute(); - - /** - * Singleton implementation of the command interface that will do nothing - * when executed. - */ - final class Null implements Command { - public static final Command INSTANCE = new Null(); - public static Command instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - public void execute() { - // do nothing - } - @Override - public String toString() { - return "Command.Null"; //$NON-NLS-1$ - } - } - - /** - * Singleton implementation of the command interface that will throw an - * exception when executed. - */ - final class Disabled implements Command { - public static final Command INSTANCE = new Disabled(); - public static Command instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public void execute() { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "Command.Disabled"; //$NON-NLS-1$ - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutor.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutor.java deleted file mode 100644 index dde714a27e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutor.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility; - -/** - * This interface allows clients to control how a command is executed. - * This is useful when the server provides the command but the client provides - * the context (e.g. the client would like to dispatch the command to the UI - * thread). - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface CommandExecutor { - - /** - * Execute the specified command. - */ - void execute(Command command); - - - /** - * Singleton implementation of the command executor interface - * that simply executes the command without any sort of enhancement. - */ - final class Default implements CommandExecutor { - public static final CommandExecutor INSTANCE = new Default(); - public static CommandExecutor instance() { - return INSTANCE; - } - // ensure single instance - private Default() { - super(); - } - public void execute(Command command) { - command.execute(); - } - @Override - public String toString() { - return "CommandExecutor.Default"; //$NON-NLS-1$ - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Filter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Filter.java deleted file mode 100644 index a1285a5847..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/Filter.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility; - -/** - * Used by various "pluggable" classes to filter objects. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface Filter<T> { - - /** - * Return whether the specified object is "accepted" by the - * filter. The semantics of "accept" is determined by the - * contract between the client and the server. - */ - boolean accept(T o); - - - /** - * Singleton implemetation of the filter interface that accepts all the - * objects (i.e. it does no filtering). - */ - final class Null<S> implements Filter<S> { - @SuppressWarnings("unchecked") - public static final Filter INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R> Filter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // nothing is filtered - everything is accepted - public boolean accept(S o) { - return true; - } - @Override - public String toString() { - return "Filter.Null"; //$NON-NLS-1$ - } - } - - /** - * Singleton implemetation of the filter interface that accepts none of the - * objects (i.e. it filters out all the objects). - */ - final class Opaque<S> implements Filter<S> { - @SuppressWarnings("unchecked") - public static final Filter INSTANCE = new Opaque(); - @SuppressWarnings("unchecked") - public static <R> Filter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Opaque() { - super(); - } - // everything is filtered - nothing is accepted - public boolean accept(S o) { - return false; - } - @Override - public String toString() { - return "Filter.Opaque"; //$NON-NLS-1$ - } - } - - /** - * Singleton implemetation of the filter interface that throws an exception - * if called. - */ - final class Disabled<S> implements Filter<S> { - @SuppressWarnings("unchecked") - public static final Filter INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> Filter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public boolean accept(S o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "Filter.Disabled"; //$NON-NLS-1$ - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/JavaType.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/JavaType.java deleted file mode 100644 index cfba58e7a9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/JavaType.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility; - -import java.io.PrintWriter; - -/** - * This interface describes a Java type; i.e. its "element type" - * and its "array depth". The element type is referenced by name, - * allowing us to reference classes that are not (or cannot be) loaded. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - * - * This interface is not intended to be implemented by clients. - */ -public interface JavaType - extends Comparable<JavaType> -{ - - /** - * Return the name of the type's "element type". - * A member type will have one or more '$' characters in its name. - */ - String getElementTypeName(); - - /** - * Return the type's "array depth". - */ - int getArrayDepth(); - - /** - * Return whether the type is an array (i.e. its "array depth" is greater - * than zero). - */ - boolean isArray(); - - /** - * Return whether the type is a "primitive" (e.g. 'int', 'float'). - * NB: void.class.isPrimitive() == true - */ - boolean isPrimitive(); - - /** - * Return whether the type is a "primitive" (e.g. 'java.lang.Integer', - * 'java.lang.Float'). - * NB: void.class.isPrimitive() == true - */ - boolean isPrimitiveWrapper(); - - /** - * Return whether the type is a "variable primitive" (e.g. 'int', 'float', - * but not 'void'). - * NB: variables cannot be declared 'void' - */ - boolean isVariablePrimitive(); - - /** - * Return whether the type is a "variable primitive" (e.g. - * 'java.lang.Integer', 'java.lang.Float', but not 'java.lang.Void'). - * NB: variables cannot be declared 'void' - */ - boolean isVariablePrimitiveWrapper(); - - /** - * Return the class corresponding to the type's element type and array depth. - */ - Class<?> getJavaClass() throws ClassNotFoundException; - - /** - * Return the version of the type's name that matches that - * returned by java.lang.Class#getName() - * (e.g. "[[J", "[Ljava.lang.Object;", "java.util.Map$Entry"). - */ - String getJavaClassName(); - - /** - * Return whether the type is equal to the specified type. - */ - boolean equals(String otherElementTypeName, int otherArrayDepth); - - /** - * Return whether the type describes to the specified type. - */ - boolean describes(String className); - - /** - * Return whether the type describes to the specified type. - */ - boolean describes(Class<?> javaClass); - - /** - * Return whether the type is equal to the specified type. - */ - boolean equals(JavaType other); - - /** - * Return the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - String declaration(); - - /** - * Append the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - void appendDeclarationTo(StringBuilder sb); - - /** - * Print the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - void printDeclarationOn(PrintWriter pw); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java deleted file mode 100644 index 00adfd998e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility; - -import java.io.PrintWriter; -import java.lang.reflect.Method; - -/** - * This interface describes a Java method signature; i.e. its "name" - * and its "parameter types". The parameter types are referenced by name, - * allowing us to reference classes that are not (or cannot be) loaded. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - * - * This interface is not intended to be implemented by clients. - */ -public interface MethodSignature - extends Comparable<MethodSignature> -{ - - /** - * Return the method's name. - */ - String getName(); - - /** - * Return the method's parameter types. - */ - JavaType[] getParameterTypes(); - - /** - * Return whether the method signature describes the specified method. - */ - boolean describes(Method method); - - /** - * Return whether the method signature equals the specified signature. - */ - boolean equals(String otherName, JavaType[] otherParameterTypes); - - /** - * Return whether the method signature equals the specified signature. - */ - boolean equals(MethodSignature other); - - /** - * Return a string representation of the method's signature: - * "foo(int, java.lang.String)" - */ - String getSignature(); - - /** - * Append a string representation of the method's signature: - * "foo(int, java.lang.String)" - */ - void appendSignatureTo(StringBuilder sb); - - /** - * Print a string representation of the method's signature: - * "foo(int, java.lang.String)" - */ - void printSignatureOn(PrintWriter pw); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/AbstractAssociation.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/AbstractAssociation.java deleted file mode 100644 index 8ffa61d1d2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/AbstractAssociation.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Implement some of the methods in Association that can - * be defined in terms of the other methods. - */ -public abstract class AbstractAssociation<K, V> - implements Association<K, V> -{ - - /** - * Default constructor. - */ - protected AbstractAssociation() { - super(); - } - - @Override - public synchronized boolean equals(Object o) { - if ( ! (o instanceof Association)) { - return false; - } - Association<?, ?> other = (Association<?, ?>) o; - return (this.key() == null ? - other.key() == null : this.key().equals(other.key())) - && (this.value() == null ? - other.value() == null : this.value().equals(other.value())); - } - - @Override - public synchronized int hashCode() { - return (this.key() == null ? 0 : this.key().hashCode()) - ^ (this.value() == null ? 0 : this.value().hashCode()); - } - - @Override - public synchronized String toString() { - return this.key() + " => " + this.value(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Association.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Association.java deleted file mode 100644 index 03130e89be..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Association.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Straightforward definition of an object pairing. - * The key is immutable. - */ -public interface Association<K, V> { - - /** - * Return the association's key. - */ - K key(); - - /** - * Return the association's value. - */ - V value(); - - /** - * Set the association's value. - * Return the previous value. - */ - V setValue(V value); - - /** - * Return true if both the associations' keys and values - * are equal. - */ - boolean equals(Object o); - - /** - * Return a hash code based on the association's - * key and value. - */ - int hashCode(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java deleted file mode 100644 index b2c7223a40..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; - -/** - * A collection that allows duplicate elements. - * <p> - * The <code>Bag</code> interface places additional stipulations, - * beyond those inherited from the <code>java.util.Collection</code> interface, - * on the contracts of the <code>equals</code> and <code>hashCode</code> methods. - * - * @see HashBag - */ - -public interface Bag<E> extends java.util.Collection<E> { - - /** - * Compares the specified object with this bag for equality. Returns - * <code>true</code> if the specified object is also a bag, the two bags - * have the same size, and every member of the specified bag is - * contained in this bag with the same number of occurrences (or equivalently, - * every member of this bag is contained in the specified bag with the same - * number of occurrences). This definition ensures that the - * equals method works properly across different implementations of the - * bag interface. - */ - boolean equals(Object o); - - /** - * Returns the hash code value for this bag. The hash code of a bag is - * defined to be the sum of the hash codes of the elements in the bag, - * where the hashcode of a <code>null</code> element is defined to be zero. - * This ensures that <code>b1.equals(b2)</code> implies that - * <code>b1.hashCode() == b2.hashCode()</code> for any two bags - * <code>b1</code> and <code>b2</code>, as required by the general - * contract of the <code>Object.hashCode</code> method. - */ - int hashCode(); - - /** - * Return the number of times the specified object occurs in the bag. - */ - int count(Object o); - - /** - * Add the specified object the specified number of times to the bag. - */ - boolean add(E o, int count); - - /** - * Remove the specified number of occurrences of the specified object - * from the bag. Return whether the bag changed. - */ - boolean remove(Object o, int count); - - /** - * Return an iterator that returns each item in the bag - * once and only once, irrespective of how many times - * the item was added to the bag. - */ - java.util.Iterator<E> uniqueIterator(); - - /** - * Return an iterator that returns an entry for each item in the bag - * once and only once, irrespective of how many times - * the item was added to the bag. The entry will indicate the item's - * count. - */ - java.util.Iterator<Entry<E>> entries(); - - - /** - * A bag entry (element-count pair). - * The <code>Bag.entries</code> method returns an iterator whose - * elements are of this class. The <i>only</i> way to obtain a reference - * to a bag entry is from the iterator returned by this method. These - * <code>Bag.Entry</code> objects are valid <i>only</i> for the duration - * of the iteration; more formally, the behavior of a bag entry is - * undefined if the backing bag has been modified after the entry was - * returned by the iterator, except through the <code>setCount</code> - * operation on the bag entry. - */ - interface Entry<E> { - - /** - * Return the entry's element. - */ - E getElement(); - - /** - * Return entry's count; i.e. the number of times the entry's element - * occurs in the bag. - * @see Bag#count(Object) - */ - int getCount(); - - /** - * Set the entry's count; i.e. the number of times the entry's element - * occurs in the bag. The new count must be a positive number. - * Return the previous count of the entry's element. - * NB: Use the iterator's <code>remove</code> method to set the - * count to zero. - */ - int setCount(int count); - - /** - * Return whether the entry is equal to the specified object; - * i.e. the specified object is a <code>Bag.Entry</code> and its - * element and count are the same as the entry's. - */ - boolean equals(Object obj); - - /** - * Return the entry's hash code. - */ - int hashCode(); - - } - - - final class Empty<E> extends AbstractCollection<E> implements Bag<E>, Serializable { - @SuppressWarnings("unchecked") - public static final Bag INSTANCE = new Empty(); - @SuppressWarnings("unchecked") - public static <T> Bag<T> instance() { - return INSTANCE; - } - // ensure single instance - private Empty() { - super(); - } - @Override - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - @Override - public int size() { - return 0; - } - public Iterator<E> uniqueIterator() { - return EmptyIterator.instance(); - } - public int count(Object o) { - return 0; - } - public Iterator<Bag.Entry<E>> entries() { - return EmptyIterator.instance(); - } - public boolean remove(Object o, int count) { - return false; - } - public boolean add(E o, int count) { - throw new UnsupportedOperationException(); - } - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ( ! (o instanceof Bag)) { - return false; - } - return ((Bag<?>) o).size() == 0; - } - @Override - public int hashCode() { - return 0; - } - private static final long serialVersionUID = 1L; - private Object readResolve() { - return INSTANCE; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiFilter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiFilter.java deleted file mode 100644 index e7bdf8c663..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiFilter.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import org.eclipse.jpt.utility.Filter; - -/** - * Used by various "pluggable" classes to filter objects - * in both directions. - * - * If anyone can come up with a better class name - * and/or method name, I would love to hear it. ~bjv - */ -public interface BidiFilter<T> extends Filter<T> { - - /** - * Return whether the specified object is "accepted" by the - * "reverse" filter. What that means is determined by the client. - */ - boolean reverseAccept(T o); - - - final class Null<S> implements BidiFilter<S> { - @SuppressWarnings("unchecked") - public static final BidiFilter INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R> BidiFilter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // nothing is filtered - everything is accepted - public boolean accept(S o) { - return true; - } - // nothing is "reverse-filtered" - everything is accepted - public boolean reverseAccept(S o) { - return true; - } - @Override - public String toString() { - return "BidiFilter.Null"; //$NON-NLS-1$ - } - } - - final class Opaque<S> implements BidiFilter<S> { - @SuppressWarnings("unchecked") - public static final BidiFilter INSTANCE = new Opaque(); - @SuppressWarnings("unchecked") - public static <R> BidiFilter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Opaque() { - super(); - } - // everything is filtered - nothing is accepted - public boolean accept(S o) { - return false; - } - // everything is "reverse-filtered" - nothing is accepted - public boolean reverseAccept(S o) { - return false; - } - @Override - public String toString() { - return "BidiFilter.Opaque"; //$NON-NLS-1$ - } - } - - final class Disabled<S> implements BidiFilter<S> { - @SuppressWarnings("unchecked") - public static final BidiFilter INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> BidiFilter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public boolean accept(S o) { - throw new UnsupportedOperationException(); - } - // throw an exception - public boolean reverseAccept(S o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "BidiFilter.Disabled"; //$NON-NLS-1$ - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java deleted file mode 100644 index fcd8f4a311..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Used by various "pluggable" classes to transform objects - * into strings and vice versa. - * - * If anyone can come up with a better class name - * and/or method name, I would love to hear it. ~bjv - */ -public interface BidiStringConverter<T> extends StringConverter<T> { - - /** - * Convert the specified string into an object. - * The semantics of "convert to object" is determined by the - * contract between the client and the server. - * Typically, if the string is null, null is returned. - */ - T convertToObject(String s); - - - final class Default<S> implements BidiStringConverter<S> { - @SuppressWarnings("unchecked") - public static final BidiStringConverter INSTANCE = new Default(); - @SuppressWarnings("unchecked") - public static <R> BidiStringConverter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Default() { - super(); - } - // simply return the object's #toString() result - public String convertToString(S o) { - return (o == null) ? null : o.toString(); - } - // simply return the string - @SuppressWarnings("unchecked") - public S convertToObject(String s) { - return (S) s; - } - @Override - public String toString() { - return "BidiStringConverter.Default"; - } - } - - final class Disabled<S> implements BidiStringConverter<S> { - @SuppressWarnings("unchecked") - public static final BidiStringConverter INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> BidiStringConverter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public String convertToString(S o) { - throw new UnsupportedOperationException(); - } - // throw an exception - public S convertToObject(String s) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "BidiStringConverter.Disabled"; - } - } - - final class BooleanConverter implements BidiStringConverter<Boolean> { - public static final BidiStringConverter<Boolean> INSTANCE = new BooleanConverter(); - public static BidiStringConverter<Boolean> instance() { - return INSTANCE; - } - // ensure single instance - private BooleanConverter() { - super(); - } - /** Return "true" if the Boolean is true, otherwise return "false". */ - public String convertToString(Boolean b) { - return (b == null) ? null : b.toString(); - } - /** Return Boolean.TRUE if the string is "true" (case-insensitive), otherwise return Boolean.FALSE. */ - public Boolean convertToObject(String s) { - return (s == null) ? null : Boolean.valueOf(s); - } - @Override - public String toString() { - return "BidiStringConverter.BooleanConverter"; - } - } - - final class IntegerConverter implements BidiStringConverter<Integer> { - public static final BidiStringConverter<Integer> INSTANCE = new IntegerConverter(); - public static BidiStringConverter<Integer> instance() { - return INSTANCE; - } - // ensure single instance - private IntegerConverter() { - super(); - } - /** Integer's #toString() works well. */ - public String convertToString(Integer integer) { - return (integer == null) ? null : integer.toString(); - } - /** Convert the string to an Integer, if possible. */ - public Integer convertToObject(String s) { - return (s == null) ? null : Integer.valueOf(s); - } - @Override - public String toString() { - return "BidiStringConverter.IntegerConverter"; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiTransformer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiTransformer.java deleted file mode 100644 index 5f6d3d221b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiTransformer.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Used by various "pluggable" classes to transform objects - * in both directions. - * - * If anyone can come up with a better class name - * and/or method name, I would love to hear it. ~bjv - */ -public interface BidiTransformer<T1, T2> extends Transformer<T1, T2> { - - /** - * Return the "reverse-transformed" object. - * The semantics of "reverse-transform" is determined by the - * contract between the client and the server. - */ - T1 reverseTransform(T2 o); - - - final class Null<S1, S2> implements BidiTransformer<S1, S2> { - @SuppressWarnings("unchecked") - public static final BidiTransformer INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R1, R2> BidiTransformer<R1, R2> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // simply return the object, unchanged - @SuppressWarnings("unchecked") - public S2 transform(S1 o) { - return (S2) o; - } - // simply return the object, unchanged - @SuppressWarnings("unchecked") - public S1 reverseTransform(S2 o) { - return (S1) o; - } - @Override - public String toString() { - return "BidiTransformer.Null"; - } - } - - final class Disabled<S1, S2> implements BidiTransformer<S1, S2> { - @SuppressWarnings("unchecked") - public static final BidiTransformer INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R1, R2> BidiTransformer<R1, R2> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public S2 transform(S1 o) { - throw new UnsupportedOperationException(); - } - // throw an exception - public S1 reverseTransform(S2 o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "BidiTransformer.Disabled"; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java deleted file mode 100644 index 544f5bba82..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Assorted bit tools - */ -public class BitTools { - - /** - * Return whether the specified 'flags' has the specified - * 'flagToCheck' set. - */ - public static boolean flagIsSet(int flags, int flagToCheck) { - return allFlagsAreSet(flags, flagToCheck); - } - - /** - * Return whether the specified 'flags' has the specified - * 'flagToCheck' turned off. - */ - public static boolean flagIsOff(int flags, int flagToCheck) { - return allFlagsAreOff(flags, flagToCheck); - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagToCheck' set. - */ - public static boolean onlyFlagIsSet(int flags, int flagToCheck) { - return onlyFlagsAreSet(flags, flagToCheck); - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagToCheck' turned off. - */ - public static boolean onlyFlagIsOff(int flags, int flagToCheck) { - return onlyFlagsAreOff(flags, flagToCheck); - } - - /** - * Return whether the specified 'flags' has all the specified - * 'flagsToCheck' set. - */ - public static boolean allFlagsAreSet(int flags, int flagsToCheck) { - return (flags & flagsToCheck) == flagsToCheck; - } - - /** - * Return whether the specified 'flags' has all the specified - * 'flagsToCheck' turned off. - */ - public static boolean allFlagsAreOff(int flags, int flagsToCheck) { - return (flags & flagsToCheck) == 0; - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagsToCheck' set. - */ - public static boolean onlyFlagsAreSet(int flags, int flagsToCheck) { - return allFlagsAreSet(flags, flagsToCheck) && allFlagsAreOff(flags, ~flagsToCheck); - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagsToCheck' turned off. - */ - public static boolean onlyFlagsAreOff(int flags, int flagsToCheck) { - return allFlagsAreOff(flags, flagsToCheck) && allFlagsAreSet(flags, ~flagsToCheck); - } - - /** - * Return whether the specified 'flags' has any one of the specified - * 'flagsToCheck' set. - */ - public static boolean anyFlagsAreSet(int flags, int flagsToCheck) { - return (flags & flagsToCheck) != 0; - } - - /** - * Return whether the specified 'flags' has any one of the specified - * 'flagsToCheck' turned off. - */ - public static boolean anyFlagsAreOff(int flags, int flagsToCheck) { - return (flags & flagsToCheck) != flagsToCheck; - } - - /** - * Return whether the specified 'flags' has all the specified - * 'flagsToCheck' set. - */ - public static boolean allFlagsAreSet(int flags, int[] flagsToCheck) { - for (int i = flagsToCheck.length; i-- > 0; ) { - if ( ! allFlagsAreSet(flags, flagsToCheck[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified 'flags' has all the specified - * 'flagsToCheck' turned off. - */ - public static boolean allFlagsAreOff(int flags, int[] flagsToCheck) { - for (int i = flagsToCheck.length; i-- > 0; ) { - if ( ! allFlagsAreOff(flags, flagsToCheck[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagsToCheck' set. - */ - public static boolean onlyFlagsAreSet(int flags, int[] flagsToCheck) { - int combinedFlags = orFlags(flagsToCheck); - return allFlagsAreSet(flags, combinedFlags) && allFlagsAreOff(flags, ~combinedFlags); - } - - /** - * Return whether the specified 'flags' has ONLY the specified - * 'flagsToCheck' turned off. - */ - public static boolean onlyFlagsAreOff(int flags, int[] flagsToCheck) { - int combinedFlags = orFlags(flagsToCheck); - return allFlagsAreOff(flags, combinedFlags) && allFlagsAreSet(flags, ~combinedFlags); - } - - /** - * Return whether the specified 'flags' has any one of the specified - * 'flagsToCheck' set. - */ - public static boolean anyFlagsAreSet(int flags, int[] flagsToCheck) { - for (int i = flagsToCheck.length; i-- > 0; ) { - if (anyFlagsAreSet(flags, flagsToCheck[i])) { - return true; - } - } - return false; - } - - /** - * Return whether the specified 'flags' has any one of the specified - * 'flagsToCheck' turned off. - */ - public static boolean anyFlagsAreOff(int flags, int[] flagsToCheck) { - for (int i = flagsToCheck.length; i-- > 0; ) { - if (anyFlagsAreOff(flags, flagsToCheck[i])) { - return true; - } - } - return false; - } - - /** - * OR all the specified 'flags' together and return the result. - */ - public static int orFlags(int[] flags) { - int last = flags.length - 1; - int result = flags[last]; - for (int i = last; i-- > 0; ) { - result |= flags[i]; - } - return result; - } - - /** - * AND all the specified 'flags' together and return the result. - */ - public static int andFlags(int[] flags) { - int last = flags.length - 1; - int result = flags[last]; - for (int i = last; i-- > 0; ) { - result &= flags[i]; - } - return result; - } - - /** - * XOR all the specified 'flags' together and return the result. - */ - public static int xorFlags(int[] flags) { - int last = flags.length - 1; - int result = flags[last]; - for (int i = last; i-- > 0; ) { - result ^= flags[i]; - } - return result; - } - - - // ********** constructor ********** - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private BitTools() { - super(); - throw new UnsupportedOperationException(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BooleanHolder.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BooleanHolder.java deleted file mode 100644 index e014e4eea1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BooleanHolder.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; - -/** - * Provide a container for passing a flag that can be changed by the recipient. - * @see SynchronizedBoolean - */ -public class BooleanHolder - implements Cloneable, Serializable -{ - /** Backing boolean. */ - private boolean value; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Create a boolean holder with the specified initial value. - */ - public BooleanHolder(boolean value) { - super(); - this.value = value; - } - - /** - * Create a boolean holder with an initial value of false. - */ - public BooleanHolder() { - this(false); - } - - - // ********** accessors ********** - - /** - * Return the current boolean value. - */ - public boolean getValue() { - return this.value; - } - - /** - * Return whether the current boolean value is true. - */ - public boolean isTrue() { - return this.value; - } - - /** - * Return whether the current boolean value is false. - */ - public boolean isFalse() { - return ! this.value; - } - - /** - * Return whether the current boolean value is the specified value. - */ - public boolean is(boolean v) { - return this.value == v; - } - - /** - * Set the boolean value. - */ - public void setValue(boolean value) { - this.value = value; - } - - /** - * Set the boolean value to true. - */ - public void setTrue() { - this.value = true; - } - - /** - * Set the boolean value to false. - */ - public void setFalse() { - this.value = false; - } - - - // ********** standard methods ********** - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public boolean equals(Object o) { - if (o instanceof BooleanHolder) { - return this.value == ((BooleanHolder) o).value; - } - return false; - } - - @Override - public int hashCode() { - return this.value ? 1 : 0; - } - - @Override - public String toString() { - return '[' + String.valueOf(this.value) + ']'; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java deleted file mode 100644 index a09dc39b06..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java +++ /dev/null @@ -1,1678 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Collections; -import java.util.Stack; - -/** - * Convenience methods related to the java.lang.reflect package. - * These methods provide shortcuts for manipulating objects via - * reflection; particularly when dealing with fields and/or methods that - * are not publicly accessible or are inherited. - * - * In most cases, all the exceptions are handled and - * wrapped in java.lang.RuntimeExceptions; so these methods should - * be used when you are confident that you will not having any problems - * using reflection. - * - * There are also a number of methods whose names - * begin with "attempt". These methods will throw a NoSuchMethodException - * or NoSuchFieldException when appropriate, allowing you to probe - * for methods that should be present but might not. - */ -public final class ClassTools { - - public static final Class<?>[] ZERO_PARAMETER_TYPES = new Class[0]; - public static final Object[] ZERO_PARAMETERS = new Object[0]; - private static final String CR = StringTools.CR; - - public static final char NESTED_CLASS_NAME_SEPARATOR = '$'; - - public static final char ARRAY_INDICATOR = '['; - public static final char TYPE_DECLARATION_ARRAY_OPEN = '['; - public static final char TYPE_DECLARATION_ARRAY_CLOSE = ']'; - - public static final char REFERENCE_CLASS_CODE = 'L'; - public static final char REFERENCE_CLASS_NAME_DELIMITER = ';'; - - private static Primitive[] PRIMITIVES; // pseudo-'final' - lazy-initialized - public static final char BYTE_CODE = 'B'; - public static final char CHAR_CODE = 'C'; - public static final char DOUBLE_CODE = 'D'; - public static final char FLOAT_CODE = 'F'; - public static final char INT_CODE = 'I'; - public static final char LONG_CODE = 'J'; - public static final char SHORT_CODE = 'S'; - public static final char BOOLEAN_CODE = 'Z'; - public static final char VOID_CODE = 'V'; - private static int MAX_PRIMITIVE_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized - private static int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized - - public static final String VOID_CLASS_NAME = void.class.getName(); - public static final String VOID_WRAPPER_CLASS_NAME = java.lang.Void.class.getName(); - - - /** - * Return all the fields for the - * specified class, including inherited fields. - * Class#allFields() - */ - public static Field[] allFields(Class<?> javaClass) { - Stack<Field> stack = new Stack<Field>(); - for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) { - pushDeclaredFields(tempClass, stack); - } - Collections.reverse(stack); - return stack.toArray(new Field[stack.size()]); - } - - /** - * Return all the methods for the - * specified class, including inherited methods. - * Class#allMethods() - */ - public static Method[] allMethods(Class<?> javaClass) { - Stack<Method> stack = new Stack<Method>(); - for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) { - pushDeclaredMethods(tempClass, stack); - } - Collections.reverse(stack); - return stack.toArray(new Method[stack.size()]); - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * using the class's default (zero-argument) constructor. - * Throw an exception if the default constructor is not defined. - * Class#newInstance() throws NoSuchMethodException - */ - public static <T> T attemptNewInstance(Class<T> javaClass) throws NoSuchMethodException { - return attemptNewInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter types and parameters. - * Throw an exception if the constructor is not defined. - * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException - */ - public static <T> T attemptNewInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException { - try { - return constructor(javaClass, parameterTypes).newInstance(parameters); - } catch (InstantiationException ie) { - throw new RuntimeException(ie + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), ie); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), iae); - } catch (InvocationTargetException ite) { - throw new RuntimeException(fullyQualifiedConstructorSignature(javaClass, parameterTypes) + CR + ite.getTargetException(), ite); - } - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * given the constructor parameter type and parameter. - * Throw an exception if the constructor is not defined. - * Class#newInstance(Class<?> parameterType, Object parameter) throws NoSuchMethodException - */ - public static <T> T attemptNewInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) throws NoSuchMethodException { - return attemptNewInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Attempt to get a field value, given the containing object and field name. - * Return its result. - * Useful for accessing private, package, or protected fields. - * Throw an exception if the field is not defined. - * Object#getFieldValue(String fieldName) throws NoSuchFieldException - */ - public static Object attemptToGetFieldValue(Object object, String fieldName) throws NoSuchFieldException { - try { - return field(object, fieldName).get(object); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae); - } - } - - /** - * Attempt to get a static field value, given the containing object and field name. - * Return its result. - * Useful for accessing private, package, or protected fields. - * Throw an exception if the field is not defined. - * Class#getStaticFieldValue(String fieldName) throws NoSuchFieldException - */ - public static Object attemptToGetStaticFieldValue(Class<?> javaClass, String fieldName) throws NoSuchFieldException { - try { - return field(javaClass, fieldName).get(null); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae); - } - } - - /** - * Convenience method. - * Attempt to execute a zero-argument method, - * given the receiver and method name. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName) throws NoSuchMethodException - */ - public static Object attemptToExecuteMethod(Object receiver, String methodName) throws NoSuchMethodException { - return attemptToExecuteMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Convenience method. - * Attempt to execute a method, given the receiver, - * method name, parameter type, and parameter. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException - */ - public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException { - return attemptToExecuteMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Attempt to execute a method, given the receiver, - * method name, parameter types, and parameters. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException - */ - public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException { - return executeMethod(method(receiver, methodName, parameterTypes), receiver, parameters); - } - - /** - * Attempt to execute a method, given the receiver, - * method name, parameter types, and parameters. - * Return its result. - * Throw an exception if the method is not found. - * If the executed method throws an exception, rethrow that exception. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException - */ - public static Object attemptToExecuteMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) - throws Throwable, NoSuchMethodException - { - return executeMethodWithException(method(receiver, methodName, parameterTypes), receiver, parameters); - } - - /** - * Convenience method. - * Attempt to execute a zero-argument static method, - * given the class and method name. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName) throws NoSuchMethodException - */ - public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException { - return attemptToExecuteStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Attempt to execute a static method, given the class, - * method name, parameter types, and parameters. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException - */ - public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException { - return executeStaticMethod(staticMethod(javaClass, methodName, parameterTypes), parameters); - } - - /** - * Convenience method. - * Attempt to execute a static method, given the class, - * method name, parameter type, and parameter. - * Return its result. - * Throw an exception if the method is not found. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException - */ - public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException { - return attemptToExecuteStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Attempt to set a field value, given the - * containing object, field name, and new field value. - * Useful for accessing private, package, or protected fields. - * Throw an exception if the field is not defined. - * Object#setFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException - */ - public static void attemptToSetFieldValue(Object object, String fieldName, Object fieldValue) throws NoSuchFieldException { - try { - field(object, fieldName).set(object, fieldValue); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae); - } - } - - /** - * Attempt to set a static field value, given the - * containing class, field name, and new field value. - * Useful for accessing private, package, or protected fields. - * Throw an exception if the field is not defined. - * Class#setStaticFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException - */ - public static void attemptToSetStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) throws NoSuchFieldException { - try { - field(javaClass, fieldName).set(null, fieldValue); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae); - } - } - - /** - * Convenience method. - * Return the default (zero-argument) constructor - * for the specified class. - * Set accessible to true, so we can access - * private/package/protected constructors. - * Class#constructor() throws NoSuchMethodException - */ - public static <T> Constructor<T> constructor(Class<T> javaClass) throws NoSuchMethodException { - return constructor(javaClass, ZERO_PARAMETER_TYPES); - } - - /** - * Return the constructor for the specified class - * and formal parameter types. - * Set accessible to true, so we can access - * private/package/protected constructors. - * Class#constructor(Class<?>[] parameterTypes) throws NoSuchMethodException - */ - public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?>[] parameterTypes) throws NoSuchMethodException { - Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes); - constructor.setAccessible(true); - return constructor; - } - - /** - * Convenience method. - * Return the constructor for the specified class - * and formal parameter type. - * Set accessible to true, so we can access - * private/package/protected constructors. - * Class#constructor(Class<?> parameterType) throws NoSuchMethodException - */ - public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?> parameterType) throws NoSuchMethodException { - return constructor(javaClass, new Class[] {parameterType}); - } - - /** - * Return the declared fields for the specified class. - * Set accessible to true, so we can access - * private/package/protected fields. - * Class#accessibleDeclaredFields() - */ - public static Field[] declaredFields(Class<?> javaClass) { - Field[] fields = javaClass.getDeclaredFields(); - for (Field field : fields) { - field.setAccessible(true); - } - return fields; - } - - /** - * Return the declared methods for the - * specified class. - * Set accessible to true, so we can access - * private/package/protected methods. - * Class#accessibleDeclaredMethods() - */ - public static Method[] declaredMethods(Class<?> javaClass) { - Method[] methods = javaClass.getDeclaredMethods(); - for (Method method : methods) { - method.setAccessible(true); - } - return methods; - } - - /** - * Return the default (zero-argument) constructor - * for the specified class. - * Set accessible to true, so we can access - * private/package/protected constructors. - * Class#defaultConstructor() - */ - public static <T> Constructor<T> defaultConstructor(Class<T> javaClass) throws NoSuchMethodException { - return constructor(javaClass); - } - - /** - * Return a field for the specified class and field name. - * If the class does not directly - * define the field, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected fields. - */ - public static Field field(Class<?> javaClass, String fieldName) throws NoSuchFieldException { - Field field = null; - try { - field = javaClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException ex) { - Class<?> superclass = javaClass.getSuperclass(); - if (superclass == null) { - throw ex; - } - // recurse - return field(superclass, fieldName); - } - field.setAccessible(true); - return field; - } - - /** - * Convenience method. - * Return a field for the specified object and field name. - * If the object's class does not directly - * define the field, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected fields. - */ - public static Field field(Object object, String fieldName) throws NoSuchFieldException { - return field(object.getClass(), fieldName); - } - - /* - * Return a string representation of the specified constructor. - */ - private static String fullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) { - return fullyQualifiedMethodSignature(javaClass, null, parameterTypes); - } - - /* - * Return a string representation of the specified field. - */ - private static String fullyQualifiedFieldName(Class<?> javaClass, String fieldName) { - StringBuilder sb = new StringBuilder(200); - sb.append(javaClass.getName()); - sb.append('.'); - sb.append(fieldName); - return sb.toString(); - } - - /* - * Return a string representation of the specified field. - */ - private static String fullyQualifiedFieldName(Object object, String fieldName) { - return fullyQualifiedFieldName(object.getClass(), fieldName); - } - - /* - * Return a string representation of the specified method. - */ - private static String fullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) { - StringBuilder sb = new StringBuilder(200); - sb.append(javaClass.getName()); - // this check allows us to use this code for constructors, where the methodName is null - if (methodName != null) { - sb.append('.'); - sb.append(methodName); - } - sb.append('('); - int max = parameterTypes.length - 1; - if (max != -1) { - // stop one short of the end of the array - for (int i = 0; i < max; i++) { - sb.append(parameterTypes[i].getName()); - sb.append(", "); //$NON-NLS-1$ - } - sb.append(parameterTypes[max].getName()); - } - sb.append(')'); - return sb.toString(); - } - - /* - * Return a string representation of the specified method. - */ - private static String fullyQualifiedMethodSignature(Object receiver, String methodName, Class<?>[] parameterTypes) { - return fullyQualifiedMethodSignature(receiver.getClass(), methodName, parameterTypes); - } - - /** - * Get a field value, given the containing object and field name. - * Return its result. - * Useful for accessing private, package, or protected fields. - * Object#getFieldValue(String fieldName) - */ - public static Object fieldValue(Object object, String fieldName) { - try { - return attemptToGetFieldValue(object, fieldName); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe); - } - } - - /** - * Get a static field value, given the containing class and field name. - * Return its result. - * Useful for accessing private, package, or protected fields. - * Class#getStaticFieldValue(String fieldName) - */ - public static Object staticFieldValue(Class<?> javaClass, String fieldName) { - try { - return attemptToGetStaticFieldValue(javaClass, fieldName); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe); - } - } - - /** - * Convenience method. - * Execute a zero-argument method, given the receiver and method name. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName) - */ - public static Object executeMethod(Object receiver, String methodName) { - return executeMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Execute a method, given the receiver, - * method name, parameter types, and parameters. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) - */ - public static Object executeMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) { - try { - return attemptToExecuteMethod(receiver, methodName, parameterTypes, parameters); - } catch (NoSuchMethodException nsme) { - throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme); - } - } - - /** - * Convenience method. - * Execute a one-argument method, given the receiver, - * method name, parameter type, and parameter. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?> parameterType, Object parameter) - */ - public static Object executeMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) { - return executeMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Convenience method. - * Execute a zero-argument method, given the receiver and method name. - * Return its result. - * If the method throws an exception, rethrow that exception. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName) - */ - public static Object executeMethodWithException(Object receiver, String methodName) - throws Throwable - { - return executeMethodWithException(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Convenience method. - * Execute a one-argument method, given the receiver, - * method name, parameter type, and parameter. - * Return its result. - * If the method throws an exception, rethrow that exception. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?> parameterType, Object parameter) - */ - public static Object executeMethodWithException(Object receiver, String methodName, Class<?> parameterType, Object parameter) - throws Throwable - { - return executeMethodWithException(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Execute a method, given the receiver, - * method name, parameter types, and parameters. - * Return its result. - * If the method throws an exception, rethrow that exception. - * Useful for invoking private, package, or protected methods. - * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) - */ - public static Object executeMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) - throws Throwable - { - try { - return attemptToExecuteMethodWithException(receiver, methodName, parameterTypes, parameters); - } catch (NoSuchMethodException nsme) { - throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme); - } - } - - /** - * Execute the specified method with the specified parameters. - * Return its result. - * Convert exceptions to RuntimeExceptions. - */ - public static Object executeMethod(Method method, Object receiver, Object[] parameters) { - try { - return method.invoke(receiver, parameters); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + method, iae); - } catch (InvocationTargetException ite) { - throw new RuntimeException(method + CR + ite.getTargetException(), ite); - } - } - - /** - * Execute the specified method with the specified parameters. - * Return its result. - * If the method throws an exception, rethrow that exception. - * Convert all other exceptions to RuntimeExceptions. - */ - public static Object executeMethodWithException(Method method, Object receiver, Object[] parameters) - throws Throwable - { - try { - return method.invoke(receiver, parameters); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae + CR + method, iae); - } catch (InvocationTargetException ite) { - Throwable cause = ite.getCause(); - if (cause == null) { - throw new RuntimeException(method.toString(), ite); - } - throw cause; - } - } - - /** - * Convenience method. - * Execute a zero-argument static method, - * given the class and method name. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName) - */ - public static Object executeStaticMethod(Class<?> javaClass, String methodName) { - return executeStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Execute a static method, given the class, - * method name, parameter types, and parameters. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters) - */ - public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) { - try { - return attemptToExecuteStaticMethod(javaClass, methodName, parameterTypes, parameters); - } catch (NoSuchMethodException nsme) { - throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), nsme); - } - } - - /** - * Convenience method. - * Execute a static method, given the class, - * method name, parameter type, and parameter. - * Return its result. - * Useful for invoking private, package, or protected methods. - * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter) - */ - public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) { - return executeStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Execute the specified static method with the specified parameters. - * Return its result. - * Convert exceptions to RuntimeExceptions. - */ - public static Object executeStaticMethod(Method method, Object[] parameters) { - return executeMethod(method, null, parameters); - } - - /** - * Convenience method. - * Return a zero-argument method for the specified class - * and method name. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Class<?> javaClass, String methodName) throws NoSuchMethodException { - return method(javaClass, methodName, ZERO_PARAMETER_TYPES); - } - - /** - * Return a method for the specified class, method name, - * and formal parameter types. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException { - Method method = null; - try { - method = javaClass.getDeclaredMethod(methodName, parameterTypes); - } catch (NoSuchMethodException ex) { - Class<?> superclass = javaClass.getSuperclass(); - if (superclass == null) { - throw ex; - } - // recurse - return method(superclass, methodName, parameterTypes); - } - method.setAccessible(true); - return method; - } - - /** - * Convenience method. - * Return a method for the specified class, method name, - * and formal parameter type. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Class<?> javaClass, String methodName, Class<?> parameterType) throws NoSuchMethodException { - return method(javaClass, methodName, new Class[] {parameterType}); - } - - /** - * Convenience method. - * Return a zero-argument method for the specified object - * and method name. If the object's class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Object object, String methodName) throws NoSuchMethodException { - return method(object.getClass(), methodName); - } - - /** - * Convenience method. - * Return a method for the specified object, method name, - * and formal parameter types. If the object's class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Object object, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException { - return method(object.getClass(), methodName, parameterTypes); - } - - /** - * Convenience method. - * Return a method for the specified object, method name, - * and formal parameter type. If the object's class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method method(Object object, String methodName, Class<?> parameterType) throws NoSuchMethodException { - return method(object.getClass(), methodName, parameterType); - } - - /** - * Convenience method. - * Return the specified class (without the checked exception). - */ - public static Class<?> classForName(String className) { - try { - return Class.forName(className); - } catch (ClassNotFoundException ex) { - throw new RuntimeException(className, ex); - } - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * using the class's default (zero-argument) constructor. - * Class#newInstance() - */ - public static <T> T newInstance(Class<T> javaClass) { - return newInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS); - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * using the class's default (zero-argument) constructor. - * Class#newInstance() - */ - public static Object newInstance(String className) throws ClassNotFoundException { - return newInstance(className, null); - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * using the class's default (zero-argument) constructor. - * Class#newInstance() - */ - public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException { - return newInstance(Class.forName(className, true, classLoader)); - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter types and parameters. - * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) - */ - public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) { - try { - return attemptNewInstance(javaClass, parameterTypes, parameters); - } catch (NoSuchMethodException nsme) { - throw new RuntimeException(nsme + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), nsme); - } - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter types and parameters. - * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) - */ - public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters) throws ClassNotFoundException { - return newInstance(className, parameterTypes, parameters, null); - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter types and parameters. - * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) - */ - public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters, ClassLoader classLoader) throws ClassNotFoundException { - return newInstance(Class.forName(className, true, classLoader), parameterTypes, parameters); - } - - /** - * Convenience method. - * Return a new instance of the specified class, - * given the constructor parameter type and parameter. - * Class#newInstance(Class<?> parameterType, Object parameter) - */ - public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) { - return newInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter}); - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter type and parameter. - * Class#newInstance(Class<?> parameterType, Object parameter) - */ - public static Object newInstance(String className, Class<?> parameterType, Object parameter) throws ClassNotFoundException { - return newInstance(className, parameterType, parameter, null); - } - - /** - * Return a new instance of the specified class, - * given the constructor parameter type and parameter. - * Class#newInstance(Class<?> parameterType, Object parameter) - */ - public static Object newInstance(String className, Class<?> parameterType, Object parameter, ClassLoader classLoader) throws ClassNotFoundException { - return newInstance(Class.forName(className, false, classLoader), parameterType, parameter); - } - - /* - * Push the declared fields for the specified class - * onto the top of the stack. - */ - private static void pushDeclaredFields(Class<?> javaClass, Stack<Field> stack) { - Field[] fields = declaredFields(javaClass); - for (int i = fields.length; i-- > 0; ) { - stack.push(fields[i]); - } - } - - /* - * Push the declared methods for the specified class - * onto the top of the stack. - */ - private static void pushDeclaredMethods(Class<?> javaClass, Stack<Method> stack) { - Method[] methods = declaredMethods(javaClass); - for (int i = methods.length; i-- > 0; ) { - stack.push(methods[i]); - } - } - - /** - * Set a field value, given the containing object, field name, and new field value. - * Useful for accessing private, package, or protected fields. - * Object#setFieldValue(String fieldName, Object fieldValue) - */ - public static void setFieldValue(Object object, String fieldName, Object fieldValue) { - try { - attemptToSetFieldValue(object, fieldName, fieldValue); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe); - } - } - - /** - * Set a static field value, given the containing class, field name, and new field value. - * Useful for accessing private, package, or protected fields. - * Class#setStaticFieldValue(String fieldName, Object fieldValue) - */ - public static void setStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) { - try { - attemptToSetStaticFieldValue(javaClass, fieldName, fieldValue); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe); - } - } - - /** - * Return the short name of the object's class. - * Class#getShortName() - */ - public static String shortClassNameForObject(Object object) { - return shortNameFor(object.getClass()); - } - - /** - * Return the short name of the class (e.g. "Object"). - * Class#getShortName() - */ - public static String shortNameForClassNamed(String className) { - return className.substring(className.lastIndexOf('.') + 1); - } - - /** - * Return the short name of the class (e.g. "Object"). - * Class#getShortName() - */ - public static String shortNameFor(Class<?> javaClass) { - return shortNameForClassNamed(javaClass.getName()); - } - - /** - * Return the nested name of the object's class. - * Class#getNestedName() - */ - public static String nestedClassNameForObject(Object object) { - return nestedNameFor(object.getClass()); - } - - /** - * Return the nested name of the class (e.g. "Entry"). - * Class#getNestedName() - */ - public static String nestedNameForClassNamed(String className) { - return className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1); - } - - /** - * Return the nested name of the class (e.g. "Entry"). - * Class#getNestedName() - */ - public static String nestedNameFor(Class<?> javaClass) { - return nestedNameForClassNamed(javaClass.getName()); - } - - /** - * Return the "toString()" name of the object's class. - */ - public static String toStringClassNameForObject(Object object) { - return toStringNameFor(object.getClass()); - } - - /** - * Return the "toString()" name of the class. - * "Member" classes will return only the final name: - * "com.foo.bar.TopLevelClass$MemberClass$NestedMemberClass" - * => "NestedMemberClass" - * "Local" and "anonymous" classes will still return the embedded '$'s: - * "com.foo.bar.TopLevelClass$1LocalClass" - * => "TopLevelClass$1LocalClass" - * "com.foo.bar.TopLevelClass$1" - * => "TopLevelClass$1" - */ - public static String toStringNameForClassNamed(String className) { - return classNamedIsMember(className) ? - className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1) - : - className.substring(className.lastIndexOf('.') + 1); - } - - /** - * Return the "toString()" name of the class. - */ - public static String toStringNameFor(Class<?> javaClass) { - return toStringNameForClassNamed(javaClass.getName()); - } - - /** - * Return the package name of the class (e.g. "java.lang"). - * Class#getPackageName() - */ - public static String packageNameFor(Class<?> javaClass) { - return packageNameForClassNamed(javaClass.getName()); - } - - /** - * Return the package name of the class (e.g. "java.lang"). - * Class#getPackageName() - */ - public static String packageNameForClassNamed(String className) { - int lastPeriod = className.lastIndexOf('.'); - if (lastPeriod == -1) { - return ""; //$NON-NLS-1$ - } - return className.substring(0, lastPeriod); - } - - /** - * Return the short name of the class, - * followed by its package name (e.g. "Object (java.lang)"). - * Class#getShortNameWithPackage() - */ - public static String shortNameWithPackage(Class<?> javaClass) { - StringBuilder sb = new StringBuilder(200); - sb.append(shortNameFor(javaClass)); - if ( ! javaClass.isPrimitive()) { - sb.append(" ("); //$NON-NLS-1$ - sb.append(packageNameFor(javaClass)); - sb.append(')'); - } - return sb.toString(); - } - - /** - * Convenience method. - * Return a zero-argument, static method for the specified class - * and method name. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method staticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException { - return staticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES); - } - - /** - * Return a static method for the specified class, method name, - * and formal parameter types. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method staticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException { - Method method = method(javaClass, methodName, parameterTypes); - if (Modifier.isStatic(method.getModifiers())) { - return method; - } - throw new NoSuchMethodException(fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes)); - } - - /** - * Convenience method. - * Return a static method for the specified class, method name, - * and formal parameter type. If the class does not directly - * implement the method, look for it in the class's superclasses. - * Set accessible to true, so we can access - * private/package/protected methods. - */ - public static Method staticMethod(Class<?> javaClass, String methodName, Class<?> parameterTypes) throws NoSuchMethodException { - return staticMethod(javaClass, methodName, new Class[] {parameterTypes}); - } - - /** - * Return whether the specified class can be "declared" in code; - * i.e. it is either a "top-level" class or a "member" class, but it - * is not an "array" class. This method rolls together all the checks - * from the other methods for a bit of a performance tweak. - * Class#isDeclarable() - */ - public static boolean classNamedIsDeclarable(String className) { - if (className.charAt(0) == ARRAY_INDICATOR) { - return false; // it is an "array" class - } - int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR); - if (index == -1) { - return true; // it is a "top-level" class - } - do { - // the character immediately after each dollar sign cannot be a digit - index++; - if (Character.isDigit(className.charAt(index))) { - return false; - } - index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index); - } while (index != -1); - return true; - } - - /** - * Return whether the specified class is a "top-level" class, - * as opposed to a "member", "local", or "anonymous" class, - * using the standard jdk naming conventions (i.e. the class - * name does NOT contain a '$': "TopLevelClass"). - * Class#isTopLevel() - */ - public static boolean classNamedIsTopLevel(String className) { - if (classNamedIsArray(className)) { - return false; - } - return className.indexOf(NESTED_CLASS_NAME_SEPARATOR) == -1; - } - - /** - * Return whether the specified class is a "member" class, - * as opposed to a "top-level", "local", or "anonymous" class, - * using the standard jdk naming conventions (i.e. the class - * name contains at least one '$' and all the names between - * each '$' are legal class names: - * "TopLevelClass$MemberClass$NestedMemberClass"). - * Class#isMember() - */ - public static boolean classNamedIsMember(String className) { - if (classNamedIsArray(className)) { - return false; - } - int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR); - if (index == -1) { - return false; // it is a "top-level" class - } - do { - // the character immediately after each dollar sign cannot be a digit - index++; - if (Character.isDigit(className.charAt(index))) { - return false; - } - index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index); - } while (index != -1); - return true; - } - - /** - * Return whether the specified class is a "local" class, - * as opposed to a "top-level", "member", or "anonymous" class, - * using the standard jdk (or Eclipse) naming conventions. - * In the jdk, the class name ends with '$nnnXXX' where the '$' is - * followed by a series of numeric digits which are followed by the - * local class name: "TopLevelClass$1LocalClass". - * In Eclipse, the class name ends with '$nnn$XXX' where the '$' is - * followed by a series of numeric digits which are separated from - * the local class name by another '$': "TopLevelClass$1$LocalClass". - * Class#isLocal() - */ - public static boolean classNamedIsLocal(String className) { - if (classNamedIsArray(className)) { - return false; - } - int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR); - if (dollar == -1) { - return false; - } - if ( ! Character.isDigit(className.charAt(dollar + 1))) { - return false; - } - int len = className.length(); - for (int i = dollar + 2; i < len; i++) { - if (Character.isJavaIdentifierStart(className.charAt(i))) { - return true; - } - } - // all the characters past the $ are digits (anonymous) - return false; - } - - /** - * Return whether the specified class is an "anonymous" class, - * as opposed to a "top-level", "member", or "local" class, - * using the standard jdk naming conventions (i.e. the class - * name ends with '$nnn' where all the characters past the - * last '$' are numeric digits: "TopLevelClass$1"). - * Class#isAnonymous() - */ - public static boolean classNamedIsAnonymous(String className) { - if (classNamedIsArray(className)) { - return false; - } - int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR); - if (dollar == -1) { - return false; - } - int start = dollar + 1; - for (int i = className.length(); i-- > start; ) { - if ( ! Character.isDigit(className.charAt(i))) { - return false; - } - } - // all the characters past the $ are digits - return true; - } - - /** - * Return the "array depth" of the specified class. - * The depth is the number of dimensions for an array type. - * Non-array types have a depth of zero. - * Class#getArrayDepth() - */ - public static int arrayDepthFor(Class<?> javaClass) { - int depth = 0; - while (javaClass.isArray()) { - depth++; - javaClass = javaClass.getComponentType(); - } - return depth; - } - - /** - * Return the "array depth" of the specified object. - * The depth is the number of dimensions for an array. - * Non-arrays have a depth of zero. - */ - public static int arrayDepthForObject(Object object) { - return arrayDepthFor(object.getClass()); - } - - /** - * Return the "array depth" of the specified class. - * The depth is the number of dimensions for an array type. - * Non-array types have a depth of zero. - * @see java.lang.Class#getName() - * Class#getArrayDepth() - */ - public static int arrayDepthForClassNamed(String className) { - int depth = 0; - while (className.charAt(depth) == ARRAY_INDICATOR) { - depth++; - } - return depth; - } - - /** - * Return whether the specified class is an array type. - * @see java.lang.Class#getName() - */ - public static boolean classNamedIsArray(String className) { - return className.charAt(0) == ARRAY_INDICATOR; - } - - /** - * Return the "element type" of the specified class. - * The element type is the base type held by an array type. - * A non-array type simply returns itself. - * Class#getElementType() - */ - public static Class<?> elementTypeFor(Class<?> javaClass) { - while (javaClass.isArray()) { - javaClass = javaClass.getComponentType(); - } - return javaClass; - } - - /** - * Return the "element type" of the specified object. - * The element type is the base type held by an array. - * A non-array simply returns its class. - */ - public static Class<?> elementTypeForObject(Object object) { - return elementTypeFor(object.getClass()); - } - - /** - * Return the "element type" of the specified class. - * The element type is the base type held by an array type. - * Non-array types simply return themselves. - * Class#getElementType() - */ - public static String elementTypeNameFor(Class<?> javaClass) { - return elementTypeFor(javaClass).getName(); - } - - /** - * Return the "element type" of the specified class. - * The element type is the base type held by an array type. - * Non-array types simply return themselves. - * @see java.lang.Class#getName() - * Class#getElementType() - */ - public static String elementTypeNameForClassNamed(String className) { - int depth = arrayDepthForClassNamed(className); - if (depth == 0) { - // the name is in the form: "java.lang.Object" or "int" - return className; - } - int last = className.length() - 1; - if (className.charAt(depth) == REFERENCE_CLASS_CODE) { - // the name is in the form: "[[[Ljava.lang.Object;" - return className.substring(depth + 1, last); // drop the trailing ';' - } - // the name is in the form: "[[[I" - return classNameForCode(className.charAt(last)); - } - - /** - * Return whether the specified class is a "reference" - * class (i.e. neither 'void' nor one of the primitive variable classes, - * ['boolean', 'int', 'float', etc.]). - * NB: void.class.isPrimitive() == true - */ - public static boolean classNamedIsReference(String className) { - return ! classNamedIsPrimitive(className); - } - - /** - * Return whether the specified class is a primitive - * class (i.e. 'void' or one of the primitive variable classes, - * ['boolean', 'int', 'float', etc.]). - * NB: void.class.isPrimitive() == true - */ - public static boolean classNamedIsPrimitive(String className) { - if (classNamedIsArray(className) || (className.length() > maxPrimitiveClassNameLength())) { - return false; // performance tweak - } - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].javaClass.getName().equals(className)) { - return true; - } - } - return false; - } - - /** - * Return whether the specified class is a "variable" primitive - * class (i.e. 'boolean', 'int', 'float', etc., but not 'void'). - * NB: void.class.isPrimitive() == true - */ - public static boolean classNamedIsVariablePrimitive(String className) { - return classNamedIsPrimitive(className) - && ( ! className.equals(VOID_CLASS_NAME)); - } - - /** - * Return whether the specified class is a primitive wrapper - * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes, - * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]). - * NB: void.class.isPrimitive() == true - */ - public static boolean classNamedIsPrimitiveWrapperClass(String className) { - if (classNamedIsArray(className) || (className.length() > maxPrimitiveWrapperClassNameLength())) { - return false; // performance tweak - } - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].wrapperClass.getName().equals(className)) { - return true; - } - } - return false; - } - - /** - * Return whether the specified class is a "variable" primitive - * class (i.e. 'boolean', 'int', 'float', etc., but not 'void'). - * NB: void.class.isPrimitive() == true - */ - public static boolean classNamedIsVariablePrimitiveWrapperClass(String className) { - return classNamedIsPrimitiveWrapperClass(className) - && ( ! className.equals(VOID_WRAPPER_CLASS_NAME)); - } - - /** - * Return whether the specified class is a primitive wrapper - * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes, - * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]). - * NB: void.class.isPrimitive() == true - */ - public static boolean classIsPrimitiveWrapperClass(Class<?> javaClass) { - if (javaClass.isArray() || (javaClass.getName().length() > maxPrimitiveWrapperClassNameLength())) { - return false; // performance tweak - } - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].wrapperClass == javaClass) { - return true; - } - } - return false; - } - - /** - * Return whether the specified class is a "variable" primitive - * class (i.e. 'boolean', 'int', 'float', etc., but not 'void'). - * NB: void.class.isPrimitive() == true - */ - public static boolean classIsVariablePrimitiveWrapperClass(Class<?> javaClass) { - return classIsPrimitiveWrapperClass(javaClass) - && (javaClass != java.lang.Void.class); - } - - /** - * Return the class name for the specified class code. - * @see java.lang.Class#getName() - */ - public static String classNameForCode(char classCode) { - return classForCode(classCode).getName(); - } - - /** - * Return the class name for the specified class code. - * @see java.lang.Class#getName() - */ - public static String classNameForCode(int classCode) { - return classNameForCode((char) classCode); - } - - /** - * Return the class for the specified class code. - * @see java.lang.Class#getName() - */ - public static Class<?> classForCode(char classCode) { - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].code == classCode) { - return codes[i].javaClass; - } - } - throw new IllegalArgumentException(String.valueOf(classCode)); - } - - /** - * Return the class for the specified class code. - * @see java.lang.Class#getName() - */ - public static Class<?> classForCode(int classCode) { - return classForCode((char) classCode); - } - - /** - * Return the class code for the specified class. - * @see java.lang.Class#getName() - */ - public static char codeForClass(Class<?> javaClass) { - if (( ! javaClass.isArray()) && (javaClass.getName().length() <= maxPrimitiveClassNameLength())) { - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].javaClass == javaClass) { - return codes[i].code; - } - } - } - throw new IllegalArgumentException(javaClass.getName()); - } - - /** - * Return the class code for the specified class. - * @see java.lang.Class#getName() - */ - public static char codeForClassNamed(String className) { - if (( ! classNamedIsArray(className)) && (className.length() <= maxPrimitiveClassNameLength())) { - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].javaClass.getName().equals(className)) { - return codes[i].code; - } - } - } - throw new IllegalArgumentException(className); - } - - /** - * Return the class for the specified "type declaration". - */ - public static Class<?> classForTypeDeclaration(String typeDeclaration) throws ClassNotFoundException { - return classForTypeDeclaration(typeDeclaration, null); - } - - /** - * Return the class for the specified "type declaration", - * using the specified class loader. - */ - public static Class<?> classForTypeDeclaration(String typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException { - TypeDeclaration td = typeDeclaration(typeDeclaration); - return classForTypeDeclaration(td.elementTypeName, td.arrayDepth, classLoader); - } - - private static TypeDeclaration typeDeclaration(String typeDeclaration) { - typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration); - int arrayDepth = arrayDepthForTypeDeclaration_(typeDeclaration); - String elementTypeName = typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2)); - return new TypeDeclaration(elementTypeName, arrayDepth); - } - - /** - * Return the class for the specified "type declaration". - */ - public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth) throws ClassNotFoundException { - return classForTypeDeclaration(elementTypeName, arrayDepth, null); - } - - /** - * Return the class for the specified "type declaration", - * using the specified class loader. - */ - // see the "Evaluation" of jdk bug 6446627 for a discussion of loading classes - public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) throws ClassNotFoundException { - // primitives cannot be loaded via Class#forName(), - // so check for a primitive class name first - Primitive pcc = null; - if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].javaClass.getName().equals(elementTypeName)) { - pcc = codes[i]; - break; - } - } - } - - // non-array - if (arrayDepth == 0) { - return (pcc == null) ? Class.forName(elementTypeName, false, classLoader) : pcc.javaClass; - } - - // array - StringBuilder sb = new StringBuilder(100); - for (int i = arrayDepth; i-- > 0; ) { - sb.append(ARRAY_INDICATOR); - } - if (pcc == null) { - sb.append(REFERENCE_CLASS_CODE); - sb.append(elementTypeName); - sb.append(REFERENCE_CLASS_NAME_DELIMITER); - } else { - sb.append(pcc.code); - } - return Class.forName(sb.toString(), false, classLoader); - } - - /** - * Return the class name for the specified "type declaration"; e.g. - * "int[]" -> "[I" - * @see java.lang.Class#getName() - */ - public static String classNameForTypeDeclaration(String typeDeclaration) { - TypeDeclaration td = typeDeclaration(typeDeclaration); - return classNameForTypeDeclaration(td.elementTypeName, td.arrayDepth); - } - - /** - * Return the array depth for the specified "type declaration"; e.g. - * "int[]" -> 1 - */ - public static int arrayDepthForTypeDeclaration(String typeDeclaration) { - return arrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration)); - } - - /* - * Assume no whitespace in the type declaration. - */ - private static int arrayDepthForTypeDeclaration_(String typeDeclaration) { - int last = typeDeclaration.length() - 1; - int depth = 0; - int close = last; - while (typeDeclaration.charAt(close) == TYPE_DECLARATION_ARRAY_CLOSE) { - if (typeDeclaration.charAt(close - 1) == TYPE_DECLARATION_ARRAY_OPEN) { - depth++; - } else { - throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration); //$NON-NLS-1$ - } - close = last - (depth * 2); - } - return depth; - } - - /** - * Return the class name for the specified "type declaration". - * @see java.lang.Class#getName() - */ - public static String classNameForTypeDeclaration(String elementTypeName, int arrayDepth) { - // non-array - if (arrayDepth == 0) { - return elementTypeName; - } - - if (elementTypeName.equals(VOID_CLASS_NAME)) { - throw new IllegalArgumentException('\'' + VOID_CLASS_NAME + "' must have an array depth of zero: " + arrayDepth + '.'); //$NON-NLS-1$ - } - // array - StringBuilder sb = new StringBuilder(100); - for (int i = arrayDepth; i-- > 0; ) { - sb.append(ARRAY_INDICATOR); - } - - // look for a primitive first - Primitive pcc = null; - if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - if (codes[i].javaClass.getName().equals(elementTypeName)) { - pcc = codes[i]; - break; - } - } - } - - if (pcc == null) { - sb.append(REFERENCE_CLASS_CODE); - sb.append(elementTypeName); - sb.append(REFERENCE_CLASS_NAME_DELIMITER); - } else { - sb.append(pcc.code); - } - - return sb.toString(); - } - - private static int maxPrimitiveClassNameLength() { - if (MAX_PRIMITIVE_CLASS_NAME_LENGTH == -1) { - MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength(); - } - return MAX_PRIMITIVE_CLASS_NAME_LENGTH; - } - - private static int calculateMaxPrimitiveClassNameLength() { - int max = -1; - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - int len = codes[i].javaClass.getName().length(); - if (len > max) { - max = len; - } - } - return max; - } - - private static int maxPrimitiveWrapperClassNameLength() { - if (MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH == -1) { - MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength(); - } - return MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH; - } - - private static int calculateMaxPrimitiveWrapperClassNameLength() { - int max = -1; - Primitive[] codes = primitives(); - for (int i = codes.length; i-- > 0; ) { - int len = codes[i].wrapperClass.getName().length(); - if (len > max) { - max = len; - } - } - return max; - } - - private static Primitive[] primitives() { - if (PRIMITIVES == null) { - PRIMITIVES = buildPrimitives(); - } - return PRIMITIVES; - } - - /** - * NB: void.class.isPrimitive() == true - */ - private static Primitive[] buildPrimitives() { - Primitive[] result = new Primitive[9]; - result[0] = new Primitive(BYTE_CODE, java.lang.Byte.class); - result[1] = new Primitive(CHAR_CODE, java.lang.Character.class); - result[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class); - result[3] = new Primitive(FLOAT_CODE, java.lang.Float.class); - result[4] = new Primitive(INT_CODE, java.lang.Integer.class); - result[5] = new Primitive(LONG_CODE, java.lang.Long.class); - result[6] = new Primitive(SHORT_CODE, java.lang.Short.class); - result[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class); - result[8] = new Primitive(VOID_CODE, java.lang.Void.class); - return result; - } - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private ClassTools() { - super(); - throw new UnsupportedOperationException(); - } - - - // ********** member classes ********** - - private static class Primitive { - final char code; - final Class<?> javaClass; - final Class<?> wrapperClass; - private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE"; //$NON-NLS-1$ - // e.g. java.lang.Boolean.TYPE => boolean.class - Primitive(char code, Class<?> wrapperClass) { - this.code = code; - this.wrapperClass = wrapperClass; - this.javaClass = (Class<?>) staticFieldValue(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME); - } - } - - private static class TypeDeclaration { - final String elementTypeName; - final int arrayDepth; - TypeDeclaration(String elementTypeName, int arrayDepth) { - this.elementTypeName = elementTypeName; - this.arrayDepth = arrayDepth; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java deleted file mode 100644 index 1d21184745..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java +++ /dev/null @@ -1,911 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.io.Serializable; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; - -/** - * TODO - */ -public class Classpath - implements Serializable -{ - /** The entries in the classpath */ - private final Entry[] entries; - - private static final long serialVersionUID = 1L; - - - // ********** static methods ********** - - // ***** factory methods for "standard" classpaths ***** - - /** - * Return the Java "boot" classpath. This includes rt.jar. - */ - public static Classpath bootClasspath() { - return new Classpath(System.getProperty("sun.boot.class.path")); //$NON-NLS-1$ - } - - /** - * Return a "virtual classpath" that contains all the jars - * that would be used by the Java Extension Mechanism. - */ - public static Classpath javaExtensionClasspath() { - File[] dirs = javaExtensionDirectories(); - List<String> jarFileNames = new ArrayList<String>(); - for (File dir : dirs) { - if (dir.isDirectory()) { - addJarFileNamesTo(dir, jarFileNames); - } - } - return new Classpath(jarFileNames); - } - - /** - * Return the Java "system" classpath. - */ - public static Classpath javaClasspath() { - return new Classpath(System.getProperty("java.class.path")); //$NON-NLS-1$ - } - - /** - * Return the unretouched "complete" classpath. - * This includes the boot classpath, the Java Extension - * Mechanism classpath, and the normal "system" classpath. - */ - public static Classpath completeClasspath() { - return new Classpath(new Classpath[] { - bootClasspath(), - javaExtensionClasspath(), - javaClasspath() - }); - } - - /** - * Return a classpath that contains the location of the specified class. - */ - public static Classpath classpathFor(Class<?> javaClass) { - return new Classpath(locationFor(javaClass)); - } - - - // ***** file => class ***** - - /** - * Convert a relative file name to a class name; this will work for - * any file that has a single extension beyond the base - * class name. - * e.g. "java/lang/String.class" is converted to "java.lang.String" - * e.g. "java/lang/String.java" is converted to "java.lang.String" - */ - public static String convertToClassName(String classFileName) { - String className = FileTools.stripExtension(classFileName); - // do this for archive entry names - className = className.replace('/', '.'); - // do this for O/S-specific file names - if (File.separatorChar != '/') { - className = className.replace(File.separatorChar, '.'); - } - return className; - } - - /** - * Convert a file to a class name; - * e.g. File(java/lang/String.class) is converted to "java.lang.String" - */ - public static String convertToClassName(File classFile) { - return convertToClassName(classFile.getPath()); - } - - /** - * Convert a relative file name to a class; - * e.g. "java/lang/String.class" is converted to java.lang.String.class - */ - public static Class<?> convertToClass(String classFileName) throws ClassNotFoundException { - return Class.forName(convertToClassName(classFileName)); - } - - /** - * Convert a relative file to a class; - * e.g. File(java/lang/String.class) is converted to java.lang.String.class - */ - public static Class<?> convertToClass(File classFile) throws ClassNotFoundException { - return convertToClass(classFile.getPath()); - } - - - // ***** class => JAR entry ***** - - /** - * Convert a class name to an archive entry name base; - * e.g. "java.lang.String" is converted to "java/lang/String" - */ - public static String convertToArchiveEntryNameBase(String className) { - return className.replace('.', '/'); - } - - /** - * Convert a class to an archive entry name base; - * e.g. java.lang.String.class is converted to "java/lang/String" - */ - public static String convertToArchiveEntryNameBase(Class<?> javaClass) { - return convertToArchiveEntryNameBase(javaClass.getName()); - } - - /** - * Convert a class name to an archive class file entry name; - * e.g. "java.lang.String" is converted to "java/lang/String.class" - */ - public static String convertToArchiveClassFileEntryName(String className) { - return convertToArchiveEntryNameBase(className) + ".class"; //$NON-NLS-1$ - } - - /** - * Convert a class to an archive class file entry name; - * e.g. java.lang.String.class is converted to "java/lang/String.class" - */ - public static String convertToArchiveClassFileEntryName(Class<?> javaClass) { - return convertToArchiveClassFileEntryName(javaClass.getName()); - } - - - // ***** class => file (.class or .java) ***** - - /** - * Convert a class name to a file name base for the current O/S; - * e.g. "java.lang.String" is converted to "java/lang/String" on Unix - * and "java\\lang\\String" on Windows - */ - public static String convertToFileNameBase(String className) { - return className.replace('.', File.separatorChar); - } - - /** - * Convert a class to a file name base for the current O/S; - * e.g. java.lang.String.class is converted to "java/lang/String" on Unix - * and "java\\lang\\String" on Windows - */ - public static String convertToFileNameBase(Class<?> javaClass) { - return convertToFileNameBase(javaClass.getName()); - } - - /** - * Convert a class name to a class file name for the current O/S; - * e.g. "java.lang.String" is converted to "java/lang/String.class" on Unix - * and "java\\lang\\String.class" on Windows - */ - public static String convertToClassFileName(String className) { - return convertToFileNameBase(className) + ".class"; //$NON-NLS-1$ - } - - /** - * Convert a class to a class file name for the current O/S; - * e.g. java.lang.String.class is converted to "java/lang/String.class" on Unix - * and "java\\lang\\String.class" on Windows - */ - public static String convertToClassFileName(Class<?> javaClass) { - return convertToClassFileName(javaClass.getName()); - } - - /** - * Convert a class name to a class file for the current O/S; - * e.g. "java.lang.String" is converted to File(java/lang/String.class) - */ - public static File convertToClassFile(String className) { - return new File(convertToClassFileName(className)); - } - - /** - * Convert a class to a class file for the current O/S; - * e.g. java.lang.String.class is converted to File(java/lang/String.class) - */ - public static File convertToClassFile(Class<?> javaClass) { - return convertToClassFile(javaClass.getName()); - } - - /** - * Convert a class name to a java file name for the current O/S; - * e.g. "java.lang.String" is converted to "java/lang/String.java" on Unix - * and "java\\lang\\String.java" on Windows - */ - public static String convertToJavaFileName(String className) { - return convertToFileNameBase(className) + ".java"; //$NON-NLS-1$ - } - - /** - * Convert a class to a java file name for the current O/S; - * e.g. java.lang.String.class is converted to "java/lang/String.java" on Unix - * and "java\\lang\\String.java" on Windows - */ - public static String convertToJavaFileName(Class<?> javaClass) { - return convertToJavaFileName(javaClass.getName()); - } - - /** - * Convert a class name to a java file for the current O/S; - * e.g. "java.lang.String" is converted to File(java/lang/String.java) - */ - public static File convertToJavaFile(String className) { - return new File(convertToJavaFileName(className)); - } - - /** - * Convert a class to a java file for the current O/S; - * e.g. java.lang.String.class is converted to File(java/lang/String.java) - */ - public static File convertToJavaFile(Class<?> javaClass) { - return convertToJavaFile(javaClass.getName()); - } - - - // ***** class => resource ***** - - /** - * Convert a class to a resource name; - * e.g. java.lang.String.class is converted to "/java/lang/String.class". - */ - public static String convertToResourceName(Class<?> javaClass) { - return '/' + convertToArchiveClassFileEntryName(javaClass); - } - - /** - * Convert a class to a resource; - * e.g. java.lang.String.class is converted to - * URL(jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class). - */ - public static URL convertToResource(Class<?> javaClass) { - return javaClass.getResource(convertToResourceName(javaClass)); - } - - - // ***** utilities ***** - - /** - * Return whether the specified file is an archive file; - * i.e. its name ends with ".zip" or ".jar" - */ - public static boolean fileNameIsArchive(String fileName) { - String ext = FileTools.extension(fileName).toLowerCase(); - return ext.equals(".jar") || ext.equals(".zip"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Return whether the specified file is an archive file; - * i.e. its name ends with ".zip" or ".jar" - */ - public static boolean fileIsArchive(File file) { - return fileNameIsArchive(file.getName()); - } - - /** - * Return what should be the fully-qualified file name - * for the JRE runtime JAR; - * e.g. "C:\jdk1.4.2_04\jre\lib\rt.jar". - */ - public static String rtJarName() { - return locationFor(java.lang.Object.class); - } - - /** - * Return the location from where the specified class was loaded. - */ - public static String locationFor(Class<?> javaClass) { - URL url = convertToResource(javaClass); - String path; - try { - path = FileTools.buildFile(url).getPath(); - } catch (URISyntaxException ex) { - throw new RuntimeException(ex); - } - String protocol = url.getProtocol().toLowerCase(); - if (protocol.equals("jar")) { //$NON-NLS-1$ - // if the class is in a JAR, the URL will look something like this: - // jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class - return path.substring(0, path.indexOf('!')); - } else if (protocol.equals("file")) { //$NON-NLS-1$ - // if the class is in a directory, the URL will look something like this: - // file:/C:/dev/main/mwdev/class/org/eclipse/dali/utility/Classpath.class - return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1); - } else if (protocol.equals("bundleresource")) { //$NON-NLS-1$ - // if the class is in a bundle resource (Eclipse?), the URL will look something like this: - // bundleresource://43/org/eclipse/dali/utility/Classpath.class - return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1); - } - - throw new IllegalStateException(url.toString()); - } - - /** - * Return the directories used by the Java Extension Mechanism. - */ - public static File[] javaExtensionDirectories() { - return convertToFiles(javaExtensionDirectoryNames()); - } - - /** - * Return the directory names used by the Java Extension Mechanism. - */ - public static String[] javaExtensionDirectoryNames() { - return System.getProperty("java.ext.dirs").split(File.pathSeparator); //$NON-NLS-1$ - } - - - // ***** internal ***** - - private static File[] convertToFiles(String[] fileNames) { - File[] files = new File[fileNames.length]; - for (int i = fileNames.length; i-- > 0; ) { - files[i] = new File(fileNames[i]); - } - return files; - } - - private static void addJarFileNamesTo(File dir, List<String> jarFileNames) { - File[] jarFiles = jarFilesIn(dir); - for (File jarFile : jarFiles) { - jarFileNames.add(FileTools.canonicalFile(jarFile).getPath()); - } - } - - private static File[] jarFilesIn(File directory) { - return directory.listFiles(jarFileFilter()); - } - - private static FileFilter jarFileFilter() { - return new FileFilter() { - public boolean accept(File file) { - return FileTools.extension(file.getName()).toLowerCase().equals(".jar"); //$NON-NLS-1$ - } - }; - } - - - // ********** constructors ********** - - /** - * Construct a classpath with the specified entries. - */ - private Classpath(Entry[] entries) { - super(); - this.entries = entries; - } - - /** - * Construct a classpath with the specified entries. - */ - public Classpath(String[] fileNames) { - this(buildEntries(fileNames)); - } - - /** - * Skip empty file names because they will end up expanding to the current - * working directory, which is not what we want. Empty file names actually - * occur with some frequency; such as when the classpath has been built up - * dynamically with too many separators. For example: - * "C:\dev\foo.jar;;C:\dev\bar.jar" - * will be parsed into three file names: - * { "C:\dev\foo.jar", "", "C:\dev\bar.jar" } - */ - private static Entry[] buildEntries(String[] fileNames) { - List<Entry> entries = new ArrayList<Entry>(); - for (String fileName : fileNames) { - if ((fileName != null) && (fileName.length() != 0)) { - entries.add(new Entry(fileName)); - } - } - return entries.toArray(new Entry[entries.size()]); - } - - /** - * Construct a classpath with the specified path. - */ - public Classpath(String path) { - this(path.split(File.pathSeparator)); - } - - /** - * Construct a classpath with the specified entries. - */ - public Classpath(List<String> fileNames) { - this(fileNames.toArray(new String[fileNames.size()])); - } - - /** - * Consolidate the specified classpaths into a single classpath. - */ - public Classpath(Classpath[] classpaths) { - this(consolidateEntries(classpaths)); - } - - private static Entry[] consolidateEntries(Classpath[] classpaths) { - List<Entry> entries = new ArrayList<Entry>(); - for (Classpath classpath : classpaths) { - CollectionTools.addAll(entries, classpath.entries()); - } - return entries.toArray(new Entry[entries.size()]); - } - - - // ********** public API ********** - - /** - * Return the classpath's entries. - */ - public Entry[] entries() { - return this.entries; - } - - /** - * Return the classpath's path. - */ - public String path() { - Entry[] localEntries = this.entries; - int max = localEntries.length - 1; - if (max == -1) { - return ""; //$NON-NLS-1$ - } - StringBuilder sb = new StringBuilder(2000); - // stop one short of the end of the array - for (int i = 0; i < max; i++) { - sb.append(localEntries[i].fileName()); - sb.append(File.pathSeparatorChar); - } - sb.append(localEntries[max].fileName()); - return sb.toString(); - } - - /** - * Search the classpath for the specified (unqualified) file - * and return its entry. Return null if an entry is not found. - * For example, you could use this method to find the entry - * for "rt.jar" or "toplink.jar". - */ - public Entry entryForFileNamed(String shortFileName) { - Entry[] localEntries = this.entries; - for (Entry entry : localEntries) { - if (entry.file().getName().equals(shortFileName)) { - return entry; - } - } - return null; - } - - /** - * Return the first entry file in the classpath - * that contains the specified class. - * Return null if an entry is not found. - */ - public Entry entryForClassNamed(String className) { - String relativeClassFileName = convertToClassFileName(className); - String archiveEntryName = convertToArchiveClassFileEntryName(className); - Entry[] localEntries = this.entries; - for (Entry entry : localEntries) { - if (entry.contains(relativeClassFileName, archiveEntryName)) { - return entry; - } - } - return null; - } - - /** - * Return the names of all the classes discovered on the classpath, - * with duplicates removed. - */ - public String[] classNames() { - return this.classNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * and accepted by the specified filter, with duplicates removed. - */ - public String[] classNames(Filter<String> filter) { - Collection<String> classNames = new HashSet<String>(10000); - this.addClassNamesTo(classNames, filter); - return classNames.toArray(new String[classNames.size()]); - } - - /** - * Add the names of all the classes discovered on the classpath - * to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames) { - this.addClassNamesTo(classNames, Filter.Null.<String>instance()); - } - - /** - * Add the names of all the classes discovered on the classpath - * and accepted by the specified filter to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) { - Entry[] localEntries = this.entries; - for (Entry entry : localEntries) { - entry.addClassNamesTo(classNames, filter); - } - } - - /** - * Return the names of all the classes discovered on the classpath. - * Just a bit more performant than #classNames(). - */ - public Iterator<String> classNamesStream() { - return this.classNamesStream(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * that are accepted by the specified filter. - * Just a bit more performant than #classNames(Filter). - */ - public Iterator<String> classNamesStream(Filter<String> filter) { - return new CompositeIterator<String>(this.entryClassNamesStreams(filter)); - } - - private Iterator<Iterator<String>> entryClassNamesStreams(final Filter<String> filter) { - return new TransformationIterator<Entry, Iterator<String>>(new ArrayIterator<Entry>(this.entries)) { - @Override - protected Iterator<String> transform(Entry entry) { - return entry.classNamesStream(filter); - } - }; - } - - /** - * Return a "compressed" version of the classpath with its - * duplicate entries eliminated. - */ - public Classpath compressed() { - return new Classpath(CollectionTools.removeDuplicateElements(this.entries)); - } - - /** - * Convert the classpath to an array of URLs - * (that can be used to instantiate a URLClassLoader). - */ - public URL[] urls() { - Entry[] localEntries = this.entries; - int len = localEntries.length; - URL[] urls = new URL[len]; - for (int i = 0; i < len; i++) { - urls[i] = localEntries[i].url(); - } - return urls; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.path()); - } - - - // ********** inner class ********** - - /** - * TODO - */ - public static class Entry implements Serializable { - private final String fileName; - private final File file; - private final File canonicalFile; - - private static final long serialVersionUID = 1L; - - Entry(String fileName) { - super(); - if ((fileName == null) || (fileName.length() == 0)) { - throw new IllegalArgumentException("'fileName' must be non-empty"); //$NON-NLS-1$ - } - this.fileName = fileName; - this.file = new File(fileName); - this.canonicalFile = FileTools.canonicalFile(this.file); - } - - public String fileName() { - return this.fileName; - } - - public File file() { - return this.file; - } - - public File canonicalFile() { - return this.canonicalFile; - } - - public String canonicalFileName() { - return this.canonicalFile.getAbsolutePath(); - } - - @Override - public boolean equals(Object o) { - if ( ! (o instanceof Entry)) { - return false; - } - return ((Entry) o).canonicalFile.equals(this.canonicalFile); - } - - @Override - public int hashCode() { - return this.canonicalFile.hashCode(); - } - - /** - * Return the entry's "canonical" URL. - */ - public URL url() { - try { - return this.canonicalFile.toURL(); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Return whether the entry contains the specified class. - */ - public boolean contains(Class<?> javaClass) { - return this.contains(javaClass.getName()); - } - - /** - * Return whether the entry contains the specified class. - */ - public boolean contains(String className) { - return this.contains(convertToClassFileName(className), convertToArchiveClassFileEntryName(className)); - } - - /** - * Return whether the entry contains either the specified relative - * class file or the specified archive entry. - * Not the prettiest signature, but it's internal.... - */ - boolean contains(String relativeClassFileName, String archiveEntryName) { - if ( ! this.canonicalFile.exists()) { - return false; - } - if (this.canonicalFile.isDirectory() && (new File(this.canonicalFile, relativeClassFileName)).exists()) { - return true; - } - return (fileIsArchive(this.canonicalFile) && this.archiveContainsEntry(archiveEntryName)); - } - - /** - * Return whether the entry's archive contains the specified entry. - */ - private boolean archiveContainsEntry(String zipEntryName) { - ZipFile zipFile = null; - ZipEntry zipEntry = null; - try { - zipFile = new ZipFile(this.canonicalFile); - zipEntry = zipFile.getEntry(zipEntryName); - } catch (IOException ex) { - // something is wrong, leave the entry null - } finally { - try { - if (zipFile != null) { - zipFile.close(); - } - } catch (IOException ex) { - zipEntry = null; // something is wrong, clear out the entry - } - } - return zipEntry != null; - } - - /** - * Return the names of all the classes discovered in the entry. - */ - public String[] classNames() { - return this.classNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered in the entry - * and accepted by the specified filter. - */ - public String[] classNames(Filter<String> filter) { - Collection<String> classNames = new ArrayList<String>(2000); - this.addClassNamesTo(classNames, filter); - return classNames.toArray(new String[classNames.size()]); - } - - /** - * Add the names of all the classes discovered in the entry - * to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames) { - this.addClassNamesTo(classNames, Filter.Null.<String>instance()); - } - - /** - * Add the names of all the classes discovered in the entry - * and accepted by the specified filter to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) { - if (this.canonicalFile.exists()) { - if (this.canonicalFile.isDirectory()) { - this.addClassNamesForDirectoryTo(classNames, filter); - } else if (fileIsArchive(this.canonicalFile)) { - this.addClassNamesForArchiveTo(classNames, filter); - } - } - } - - /** - * Add the names of all the classes discovered - * under the entry's directory and accepted by - * the specified filter to the specified collection. - */ - private void addClassNamesForDirectoryTo(Collection<String> classNames, Filter<String> filter) { - int start = this.canonicalFile.getAbsolutePath().length() + 1; - for (Iterator<File> stream = this.classFilesForDirectory(); stream.hasNext(); ) { - String className = convertToClassName(stream.next().getAbsolutePath().substring(start)); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - - /** - * Return an iterator on all the class files discovered - * under the entry's directory. - */ - private Iterator<File> classFilesForDirectory() { - return new FilteringIterator<File, File>(FileTools.filesInTree(this.canonicalFile)) { - @Override - protected boolean accept(File next) { - return Entry.this.fileNameMightBeForClassFile(next.getName()); - } - }; - } - - /** - * Add the names of all the classes discovered - * in the entry's archive file and accepted by the - * specified filter to the specified collection. - */ - private void addClassNamesForArchiveTo(Collection<String> classNames, Filter<String> filter) { - ZipFile zipFile = null; - try { - zipFile = new ZipFile(this.canonicalFile); - } catch (IOException ex) { - return; - } - for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) { - ZipEntry zipEntry = stream.nextElement(); - String zipEntryName = zipEntry.getName(); - if (this.fileNameMightBeForClassFile(zipEntryName)) { - String className = convertToClassName(zipEntryName); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - try { - zipFile.close(); - } catch (IOException ex) { - return; - } - } - - /** - * Return whether the specified file might be a Java class file. - * The file name must at least end with ".class" and contain no spaces. - * (Neither class names nor package names may contain spaces.) - * Whether it actually is a class file will need to be determined by - * a class loader. - */ - boolean fileNameMightBeForClassFile(String name) { - return FileTools.extension(name).toLowerCase().equals(".class") //$NON-NLS-1$ - && (name.indexOf(' ') == -1); - } - - /** - * Return the names of all the classes discovered on the classpath. - * Just a bit more performant than #classNames(). - */ - public Iterator<String> classNamesStream() { - return this.classNamesStream(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * that are accepted by the specified filter. - * Just a bit more performant than #classNames(Filter). - */ - public Iterator<String> classNamesStream(Filter<String> filter) { - if (this.canonicalFile.exists()) { - if (this.canonicalFile.isDirectory()) { - return this.classNamesForDirectory(filter); - } - if (fileIsArchive(this.canonicalFile)) { - return this.classNamesForArchive(filter); - } - } - return EmptyIterator.instance(); - } - - /** - * Return the names of all the classes discovered - * under the entry's directory and accepted by - * the specified filter. - */ - private Iterator<String> classNamesForDirectory(Filter<String> filter) { - return new FilteringIterator<String, String>(this.classNamesForDirectory(), filter); - } - - /** - * Transform the class files to class names. - */ - private Iterator<String> classNamesForDirectory() { - final int start = this.canonicalFile.getAbsolutePath().length() + 1; - return new TransformationIterator<File, String>(this.classFilesForDirectory()) { - @Override - protected String transform(File f) { - return convertToClassName(f.getAbsolutePath().substring(start)); - } - }; - } - - /** - * Return the names of all the classes discovered - * in the entry's archive file and accepted by the - * specified filter. - */ - private Iterator<String> classNamesForArchive(Filter<String> filter) { - // we can't simply wrap iterators here because we need to close the archive file... - ZipFile zipFile = null; - try { - zipFile = new ZipFile(this.canonicalFile); - } catch (IOException ex) { - return EmptyIterator.instance(); - } - Collection<String> classNames = new HashSet<String>(zipFile.size()); - for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) { - ZipEntry zipEntry = stream.nextElement(); - String zipEntryName = zipEntry.getName(); - if (this.fileNameMightBeForClassFile(zipEntryName)) { - String className = convertToClassName(zipEntryName); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - try { - zipFile.close(); - } catch (IOException ex) { - return EmptyIterator.instance(); - } - return classNames.iterator(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java deleted file mode 100644 index a30650564a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java +++ /dev/null @@ -1,3918 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Random; -import java.util.RandomAccess; -import java.util.TreeSet; -import java.util.Vector; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.internal.iterators.GenericIteratorWrapper; -import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator; - -public final class CollectionTools { - - @SuppressWarnings("unchecked") - private static <E> E[] newArray(E[] array, int length) { - return (E[]) Array.newInstance(array.getClass().getComponentType(), length); - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the specified object to be added. - * java.util.Arrays#add(Object[] array, Object o) - */ - public static <E> E[] add(E[] array, E value) { - int len = array.length; - E[] result = newArray(array, len + 1); - if (len > 0) { - System.arraycopy(array, 0, result, 0, len); - } - result[len] = value; - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified object added at the specified index. - * java.util.Arrays#add(Object[] array, int index, Object o) - */ - public static <E> E[] add(E[] array, int index, E value) { - int len = array.length; - E[] result = newArray(array, len + 1); - if (index > 0) { - System.arraycopy(array, 0, result, 0, index); - } - result[index] = value; - if (len > index) { - System.arraycopy(array, index, result, index + 1, len - index); - } - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the specified value to be added. - * java.util.Arrays#add(char[] array, char value) - */ - public static char[] add(char[] array, char value) { - int len = array.length; - char[] result = new char[len + 1]; - if (len > 0) { - System.arraycopy(array, 0, result, 0, len); - } - result[len] = value; - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified value added at the specified index. - * java.util.Arrays#add(char[] array, int index, char value) - */ - public static char[] add(char[] array, int index, char value) { - int len = array.length; - char[] result = new char[len + 1]; - if (index > 0) { - System.arraycopy(array, 0, result, 0, index); - } - result[index] = value; - if (len > index) { - System.arraycopy(array, index, result, index + 1, len - index); - } - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the specified value to be added. - * java.util.Arrays#add(int[] array, int value) - */ - public static int[] add(int[] array, int value) { - int len = array.length; - int[] result = new int[len + 1]; - if (len > 0) { - System.arraycopy(array, 0, result, 0, len); - } - result[len] = value; - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified value added at the specified index. - * java.util.Arrays#add(int[] array, int index, int value) - */ - public static int[] add(int[] array, int index, int value) { - int len = array.length; - int[] result = new int[len + 1]; - if (index > 0) { - System.arraycopy(array, 0, result, 0, index); - } - result[index] = value; - if (len > index) { - System.arraycopy(array, index, result, index + 1, len - index); - } - return result; - } - - /** - * Add all the elements returned by the specified iterable - * to the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#addAll(java.lang.Iterable iterable) - */ - public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable) { - return addAll(collection, iterable.iterator()); - } - - /** - * Add all the elements returned by the specified iterable - * to the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#addAll(java.lang.Iterable iterable) - */ - public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable, int size) { - return addAll(collection, iterable.iterator(), size); - } - - /** - * Add all the elements returned by the specified iterator - * to the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#addAll(java.util.Iterator iterator) - */ - public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator) { - return (iterator.hasNext()) ? collection.addAll(list(iterator)) : false; - } - - /** - * Add all the elements returned by the specified iterator - * to the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#addAll(java.util.Iterator iterator) - */ - public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator, int size) { - return (iterator.hasNext()) ? collection.addAll(list(iterator, size)) : false; - } - - /** - * Add all the elements in the specified array - * to the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#addAll(Object[] array) - */ - public static <E> boolean addAll(Collection<? super E> collection, E[] array) { - return (array.length == 0) ? false : collection.addAll(Arrays.asList(array)); - } - - /** - * Add all the elements returned by the specified iterable - * to the specified list at the specified index. - * Return whether the list changed as a result. - * java.util.List#addAll(java.lang.Iterable iterable) - */ - public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable) { - return addAll(list, index, iterable.iterator()); - } - - /** - * Add all the elements returned by the specified iterable - * to the specified list at the specified index. - * Return whether the list changed as a result. - * java.util.List#addAll(java.lang.Iterable iterable) - */ - public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable, int size) { - return addAll(list, index, iterable.iterator(), size); - } - - /** - * Add all the elements returned by the specified iterator - * to the specified list at the specified index. - * Return whether the list changed as a result. - * java.util.List#addAll(java.util.Iterator iterator) - */ - public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) { - return (iterator.hasNext()) ? list.addAll(index, list(iterator)) : false; - } - - /** - * Add all the elements returned by the specified iterator - * to the specified list at the specified index. - * Return whether the list changed as a result. - * java.util.List#addAll(java.util.Iterator iterator) - */ - public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int size) { - return (iterator.hasNext()) ? list.addAll(index, list(iterator, size)) : false; - } - - /** - * Add all the elements in the specified array - * to the specified list at the specified index. - * Return whether the list changed as a result. - * java.util.List#addAll(Object[] array) - */ - public static <E> boolean addAll(List<? super E> list, int index, E[] array) { - return (array.length == 0) ? false : list.addAll(index, Arrays.asList(array)); - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the elements - * in the specified collection. - * java.util.Arrays#addAll(Object[] array, java.util.Collection c) - */ - public static <E> E[] addAll(E[] array, Collection<? extends E> collection) { - int size = collection.size(); - return (size == 0) ? array : addAll(array, collection, size); - } - - /** - * assume collection is non-empty - */ - private static <E> E[] addAll_(E[] array, Collection<? extends E> collection) { - return addAll(array, collection, collection.size()); - } - - /** - * assume collection is non-empty - */ - private static <E> E[] addAll(E[] array, Collection<? extends E> collection, int collectionSize) { - int len = array.length; - E[] result = newArray(array, len + collectionSize); - if (len > 0) { - System.arraycopy(array, 0, result, 0, len); - } - int i = len; - for (E item : collection) { - result[i++] = item; - } - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the elements - * in the specified iterable. - * java.util.Arrays#addAll(Object[] array, java.lang.Iterable iterable) - */ - public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable) { - return addAll(array, iterable.iterator()); - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the elements - * in the specified iterable. - * java.util.Arrays#addAll(Object[] array, java.lang.Iterable iterable) - */ - public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable, int size) { - return addAll(array, iterable.iterator(), size); - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the elements - * in the specified iterator. - * java.util.Arrays#addAll(Object[] array, java.util.Iterator iterator) - */ - public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator) { - return (iterator.hasNext()) ? addAll_(array, list(iterator)) : array; - } - - /** - * Return a new array that contains the elements in the - * specified array followed by the elements - * in the specified iterator. - * java.util.Arrays#addAll(Object[] array, java.util.Iterator iterator) - */ - public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator, int size) { - return (iterator.hasNext()) ? addAll_(array, list(iterator, size)) : array; - } - - /** - * Return a new array that contains the elements in the - * specified array 1 followed by the elements - * in the specified array 2. - * java.util.Arrays#addAll(Object[] array1, Object[] array2) - */ - public static <E> E[] addAll(E[] array1, E[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static <E> E[] addAll(E[] array1, E[] array2, int array2Length) { - int array1Length = array1.length; - return (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static <E> E[] addAll(E[] array1, E[] array2, int array1Length, int array2Length) { - E[] result = newArray(array1, array1Length + array2Length); - System.arraycopy(array1, 0, result, 0, array1Length); - System.arraycopy(array2, 0, result, array1Length, array2Length); - return result; - } - - /** - * Return a new array that contains the elements in the - * first specified array with the objects in the second - * specified array added at the specified index. - * java.util.Arrays#add(Object[] array1, int index, Object[] array2) - */ - public static <E> E[] addAll(E[] array1, int index, E[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, index, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static <E> E[] addAll(E[] array1, int index, E[] array2, int array2Length) { - int array1Length = array1.length; - return (index == array1Length) ? // array2 added to end of array1 - (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length) - : - addAll(array1, index, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static <E> E[] addAll(E[] array1, int index, E[] array2, int array1Length, int array2Length) { - E[] result = newArray(array1, array1Length + array2Length); - System.arraycopy(array1, 0, result, 0, index); - System.arraycopy(array2, 0, result, index, array2Length); - System.arraycopy(array1, index, result, index + array2Length, array1Length - index); - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the elements - * in the specified collection inserted at the specified index. - * java.util.Arrays#addAll(Object[] array, int index, java.util.Collection c) - */ - public static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection) { - int size = collection.size(); - return (size == 0) ? array : addAll(array, index, collection, size); - } - - /** - * assume collection is non-empty - */ - private static <E> E[] addAll_(E[] array, int index, Collection<? extends E> collection) { - return addAll(array, index, collection, collection.size()); - } - - /** - * assume collection is non-empty - */ - private static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection, int collectionSize) { - int arrayLength = array.length; - E[] result = newArray(array, arrayLength + collectionSize); - if ((arrayLength == 0) && (index == 0)) { - return collection.toArray(result); - } - System.arraycopy(array, 0, result, 0, index); - int i = index; - for (E item : collection) { - result[i++] = item; - } - System.arraycopy(array, index, result, index + collectionSize, arrayLength - index); - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the elements - * in the specified iterable inserted at the specified index. - * java.util.Arrays#addAll(Object[] array, int index, java.lang.Iterable iterable) - */ - public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable) { - return addAll(array, index, iterable.iterator()); - } - - /** - * Return a new array that contains the elements in the - * specified array with the elements - * in the specified iterable inserted at the specified index. - * java.util.Arrays#addAll(Object[] array, int index, java.lang.Iterable iterable) - */ - public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable, int size) { - return addAll(array, index, iterable.iterator(), size); - } - - /** - * Return a new array that contains the elements in the - * specified array with the elements - * in the specified iterator inserted at the specified index. - * java.util.Arrays#addAll(Object[] array, int index, java.util.Iterator iterator) - */ - public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator) { - return (iterator.hasNext()) ? addAll_(array, index, list(iterator)) : array; - } - - /** - * Return a new array that contains the elements in the - * specified array with the elements - * in the specified iterator inserted at the specified index. - * java.util.Arrays#addAll(Object[] array, int index, java.util.Iterator iterator) - */ - public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator, int size) { - return (iterator.hasNext()) ? addAll_(array, index, list(iterator, size)) : array; - } - - /** - * Return a new array that contains the elements in the - * specified array 1 followed by the elements - * in the specified array 2. - * java.util.Arrays#addAll(char[] array1, char[] array2) - */ - public static char[] addAll(char[] array1, char[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static char[] addAll(char[] array1, char[] array2, int array2Length) { - int array1Length = array1.length; - return (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static char[] addAll(char[] array1, char[] array2, int array1Length, int array2Length) { - char[] result = new char[array1Length + array2Length]; - System.arraycopy(array1, 0, result, 0, array1Length); - System.arraycopy(array2, 0, result, array1Length, array2Length); - return result; - } - - /** - * Return a new array that contains the elements in the - * first specified array with the objects in the second - * specified array added at the specified index. - * java.util.Arrays#add(char[] array1, int index, char[] array2) - */ - public static char[] addAll(char[] array1, int index, char[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, index, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static char[] addAll(char[] array1, int index, char[] array2, int array2Length) { - int array1Length = array1.length; - return (index == array1Length) ? // array2 added to end of array1 - (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length) - : - addAll(array1, index, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static char[] addAll(char[] array1, int index, char[] array2, int array1Length, int array2Length) { - char[] result = new char[array1Length + array2Length]; - System.arraycopy(array1, 0, result, 0, index); - System.arraycopy(array2, 0, result, index, array2Length); - System.arraycopy(array1, index, result, index + array2Length, array1Length - index); - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array 1 followed by the elements - * in the specified array 2. - * java.util.Arrays#addAll(int[] array1, int[] array2) - */ - public static int[] addAll(int[] array1, int[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static int[] addAll(int[] array1, int[] array2, int array2Length) { - int array1Length = array1.length; - return (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static int[] addAll(int[] array1, int[] array2, int array1Length, int array2Length) { - int[] result = new int[array1Length + array2Length]; - System.arraycopy(array1, 0, result, 0, array1Length); - System.arraycopy(array2, 0, result, array1Length, array2Length); - return result; - } - - /** - * Return a new array that contains the elements in the - * first specified array with the objects in the second - * specified array added at the specified index. - * java.util.Arrays#add(int[] array1, int index, int[] array2) - */ - public static int[] addAll(int[] array1, int index, int[] array2) { - int array2Length = array2.length; - return (array2Length == 0) ? array1 : addAll(array1, index, array2, array2Length); - } - - /** - * assume array2Length > 0 - */ - private static int[] addAll(int[] array1, int index, int[] array2, int array2Length) { - int array1Length = array1.length; - return (index == array1Length) ? // array2 added to end of array1 - (array1Length == 0) ? array2 : addAll(array1, array2, array1Length, array2Length) - : - addAll(array1, index, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static int[] addAll(int[] array1, int index, int[] array2, int array1Length, int array2Length) { - int[] result = new int[array1Length + array2Length]; - System.arraycopy(array1, 0, result, 0, index); - System.arraycopy(array2, 0, result, index, array2Length); - System.arraycopy(array1, index, result, index + array2Length, array1Length - index); - return result; - } - - /** - * Return an array corresponding to the specified iterable. - * @see java.util.Collection#toArray() - * java.lang.Iterable#toArray() - */ - public static Object[] array(Iterable<?> iterable) { - return array(iterable.iterator()); - } - - /** - * Return an array corresponding to the specified iterable. - * @see java.util.Collection#toArray() - * java.lang.Iterable#toArray() - */ - public static Object[] array(Iterable<?> iterable, int size) { - return array(iterable.iterator(), size); - } - - /** - * Return an array corresponding to the specified iterable; - * the runtime type of the returned array is that of the specified array. - * If the collection fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this collection. - * @see java.util.Collection#toArray(java.lang.Object[]) - * java.lang.Iterable#toArray(Object[]) - */ - public static <E> E[] array(Iterable<? extends E> iterable, E[] array) { - return array(iterable.iterator(), array); - } - - /** - * Return an array corresponding to the specified iterable; - * the runtime type of the returned array is that of the specified array. - * If the collection fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this collection. - * @see java.util.Collection#toArray(java.lang.Object[]) - * java.lang.Iterable#toArray(Object[]) - */ - public static <E> E[] array(Iterable<? extends E> iterable, int size, E[] array) { - return array(iterable.iterator(), size, array); - } - - /** - * Return an array corresponding to the specified iterator. - * @see java.util.Collection#toArray() - * java.util.Iterator#toArray() - */ - public static Object[] array(Iterator<?> iterator) { - return (iterator.hasNext()) ? list(iterator).toArray() : EMPTY_OBJECT_ARRAY; - } - private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - - /** - * Return an array corresponding to the specified iterator. - * @see java.util.Collection#toArray() - * java.util.Iterator#toArray() - */ - public static Object[] array(Iterator<?> iterator, int size) { - return (iterator.hasNext()) ? list(iterator, size).toArray() : EMPTY_OBJECT_ARRAY; - } - - /** - * Return an array corresponding to the specified iterator; - * the runtime type of the returned array is that of the specified array. - * If the collection fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this collection. - * @see java.util.Collection#toArray(java.lang.Object[]) - * java.util.Iterator#toArray(Object[]) - */ - public static <E> E[] array(Iterator<? extends E> iterator, E[] array) { - return (iterator.hasNext()) ? list(iterator).toArray(array) : newArray(array, 0); - } - - /** - * Return an array corresponding to the specified iterator; - * the runtime type of the returned array is that of the specified array. - * If the collection fits in the specified array, it is returned therein. - * Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of this collection. - * @see java.util.Collection#toArray(java.lang.Object[]) - * java.util.Iterator#toArray(Object[]) - */ - public static <E> E[] array(Iterator<? extends E> iterator, int size, E[] array) { - return (iterator.hasNext()) ? list(iterator, size).toArray(array) : newArray(array, 0); - } - - /** - * Return a bag corresponding to the specified enumeration. - * HashBag(java.util.Enumeration enumeration) - */ - public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration) { - return bag(enumeration, new HashBag<E>()); - } - - /** - * Return a bag corresponding to the specified enumeration. - * HashBag(java.util.Enumeration enumeration) - */ - public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, int size) { - return bag(enumeration, new HashBag<E>(size)); - } - - private static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, HashBag<E> bag) { - while (enumeration.hasMoreElements()) { - bag.add(enumeration.nextElement()); - } - return bag; - } - - /** - * Return a bag corresponding to the specified iterable. - * HashBag(java.lang.Iterable iterable) - */ - public static <E> HashBag<E> bag(Iterable<? extends E> iterable) { - return bag(iterable.iterator()); - } - - /** - * Return a bag corresponding to the specified iterable. - * HashBag(java.lang.Iterable iterable) - */ - public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int size) { - return bag(iterable.iterator(), size); - } - - /** - * Return a bag corresponding to the specified iterator. - * HashBag(java.util.Iterator iterator) - */ - public static <E> HashBag<E> bag(Iterator<? extends E> iterator) { - return bag(iterator, new HashBag<E>()); - } - - /** - * Return a bag corresponding to the specified iterator. - * HashBag(java.util.Iterator iterator) - */ - public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int size) { - return bag(iterator, new HashBag<E>(size)); - } - - private static <E> HashBag<E> bag(Iterator<? extends E> iterator, HashBag<E> bag) { - while (iterator.hasNext()) { - bag.add(iterator.next()); - } - return bag; - } - - /** - * Return a bag corresponding to the specified array. - * HashBag(Object[] array) - */ - public static <E> HashBag<E> bag(E... array) { - int len = array.length; - HashBag<E> bag = new HashBag<E>(len); - for (E item : array) { - bag.add(item); - } - return bag; - } - - /** - * Clear the specified array. - * java.util.Arrays#clear(Object[] array) - */ - public static <E> E[] clear(E[] array) { - if (array.length == 0) { - return array; - } - return newArray(array, 0); - } - - /** - * Return a collection corresponding to the specified enumeration. - */ - public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration) { - return bag(enumeration); - } - - /** - * Return a collection corresponding to the specified enumeration. - */ - public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration, int size) { - return bag(enumeration, size); - } - - /** - * Return a collection corresponding to the specified iterable. - */ - public static <E> HashBag<E> collection(Iterable<? extends E> iterable) { - return collection(iterable.iterator()); - } - - /** - * Return a collection corresponding to the specified iterable. - */ - public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int size) { - return collection(iterable.iterator(), size); - } - - /** - * Return a collection corresponding to the specified iterator. - */ - public static <E> HashBag<E> collection(Iterator<? extends E> iterator) { - return bag(iterator); - } - - /** - * Return a collection corresponding to the specified iterator. - */ - public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int size) { - return bag(iterator, size); - } - - /** - * Return a collection corresponding to the specified array. - */ - public static <E> HashBag<E> collection(E... array) { - return bag(array); - } - - /** - * Return whether the specified enumeration contains the - * specified element. - * java.util.Enumeration#contains(Object o) - */ - public static boolean contains(Enumeration<?> enumeration, Object value) { - if (value == null) { - while (enumeration.hasMoreElements()) { - if (enumeration.nextElement() == null) { - return true; - } - } - } else { - while (enumeration.hasMoreElements()) { - if (value.equals(enumeration.nextElement())) { - return true; - } - } - } - return false; - } - - /** - * Return whether the specified iterable contains the - * specified element. - * java.lang.Iterable#contains(Object o) - */ - public static boolean contains(Iterable<?> iterable, Object value) { - return contains(iterable.iterator(), value); - } - - /** - * Return whether the specified iterator contains the - * specified element. - * java.util.Iterator#contains(Object o) - */ - public static boolean contains(Iterator<?> iterator, Object value) { - if (value == null) { - while (iterator.hasNext()) { - if (iterator.next() == null) { - return true; - } - } - } else { - while (iterator.hasNext()) { - if (value.equals(iterator.next())) { - return true; - } - } - } - return false; - } - - /** - * Return whether the specified array contains the - * specified element. - * java.util.Arrays#contains(Object[] array, Object o) - */ - public static boolean contains(Object[] array, Object value) { - if (value == null) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == null) { - return true; - } - } - } else { - for (int i = array.length; i-- > 0; ) { - if (value.equals(array[i])) { - return true; - } - } - } - return false; - } - - /** - * Return whether the specified array contains the - * specified element. - * java.util.Arrays#contains(char[] array, char value) - */ - public static boolean contains(char[] array, char value) { - return contains(array, value, array.length); - } - - private static boolean contains(char[] array, char value, int arrayLength) { - for (int i = arrayLength; i-- > 0; ) { - if (array[i] == value) { - return true; - } - } - return false; - } - - /** - * Return whether the specified array contains the - * specified element. - * java.util.Arrays#contains(int[] array, int value) - */ - public static boolean contains(int[] array, int value) { - return contains(array, value, array.length); - } - - private static boolean contains(int[] array, int value, int arrayLength) { - for (int i = arrayLength; i-- > 0; ) { - if (array[i] == value) { - return true; - } - } - return false; - } - - /** - * Return whether the specified collection contains all of the - * elements in the specified iterable. - * java.util.Collection#containsAll(java.lang.Iterable iterable) - */ - public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) { - return containsAll(collection, iterable.iterator()); - } - - /** - * Return whether the specified collection contains all of the - * elements in the specified iterator. - * java.util.Collection#containsAll(java.util.Iterator iterator) - */ - public static boolean containsAll(Collection<?> collection, Iterator<?> iterator) { - while (iterator.hasNext()) { - if ( ! collection.contains(iterator.next())) { - return false; - } - } - return true; - } - - /** - * Return whether the specified collection contains all of the - * elements in the specified array. - * java.util.Collection#containsAll(Object[] array) - */ - public static boolean containsAll(Collection<?> collection, Object[] array) { - for (int i = array.length; i-- > 0; ) { - if ( ! collection.contains(array[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified collection. - * java.lang.Iterable#containsAll(java.util.Collection collection) - */ - public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) { - return containsAll(iterable.iterator(), collection); - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified collection. - * java.lang.Iterable#containsAll(java.util.Collection collection) - */ - public static boolean containsAll(Iterable<?> iterable, int size, Collection<?> collection) { - return containsAll(iterable.iterator(), size, collection); - } - - /** - * Return whether the specified iterable 1 contains all of the - * elements in the specified iterable 2. - * java.lang.Iterable#containsAll(java.lang.Iterable iterable) - */ - public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) { - return containsAll(iterable1.iterator(), iterable2.iterator()); - } - - /** - * Return whether the specified iterable 1 contains all of the - * elements in the specified iterable 2. - * java.lang.Iterable#containsAll(java.lang.Iterable iterable) - */ - public static boolean containsAll(Iterable<?> iterable1, int size, Iterable<?> iterable2) { - return containsAll(iterable1.iterator(), size, iterable2.iterator()); - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified iterator. - * java.lang.Iterable#containsAll(java.util.Iterator iterator) - */ - public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) { - return containsAll(iterable.iterator(), iterator); - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified iterator. - * java.lang.Iterable#containsAll(java.util.Iterator iterator) - */ - public static boolean containsAll(Iterable<?> iterable, int size, Iterator<?> iterator) { - return containsAll(iterable.iterator(), size, iterator); - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified array. - * java.lang.Iterable#containsAll(Object[] array) - */ - public static boolean containsAll(Iterable<?> iterable, Object[] array) { - return containsAll(iterable.iterator(), array); - } - - /** - * Return whether the specified iterable contains all of the - * elements in the specified array. - * java.lang.Iterable#containsAll(Object[] array) - */ - public static boolean containsAll(Iterable<?> iterable, int size, Object[] array) { - return containsAll(iterable.iterator(), size, array); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified collection. - * java.util.Iterator#containsAll(java.util.Collection collection) - */ - public static boolean containsAll(Iterator<?> iterator, Collection<?> collection) { - return collection(iterator).containsAll(collection); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified collection. - * java.util.Iterator#containsAll(java.util.Collection collection) - */ - public static boolean containsAll(Iterator<?> iterator, int size, Collection<?> collection) { - return collection(iterator, size).containsAll(collection); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified iterable. - * java.util.Iterator#containsAll(java.lang.Iterable iterable) - */ - public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) { - return containsAll(collection(iterator), iterable); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified iterable. - * java.util.Iterator#containsAll(java.lang.Iterable iterable) - */ - public static boolean containsAll(Iterator<?> iterator, int size, Iterable<?> iterable) { - return containsAll(collection(iterator, size), iterable); - } - - /** - * Return whether the specified iterator 1 contains all of the - * elements in the specified iterator 2. - * java.util.Iterator#containsAll(java.util.Iterator iterator) - */ - public static boolean containsAll(Iterator<?> iterator1, Iterator<?> iterator2) { - return containsAll(collection(iterator1), iterator2); - } - - /** - * Return whether the specified iterator 1 contains all of the - * elements in the specified iterator 2. - * java.util.Iterator#containsAll(java.util.Iterator iterator) - */ - public static boolean containsAll(Iterator<?> iterator1, int size, Iterator<?> iterator2) { - return containsAll(collection(iterator1, size), iterator2); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified array. - * java.util.Iterator#containsAll(Object[] array) - */ - public static boolean containsAll(Iterator<?> iterator, Object[] array) { - return containsAll(collection(iterator), array); - } - - /** - * Return whether the specified iterator contains all of the - * elements in the specified array. - * java.util.Iterator#containsAll(Object[] array) - */ - public static boolean containsAll(Iterator<?> iterator, int size, Object[] array) { - return containsAll(collection(iterator, size), array); - } - - /** - * Return whether the specified array contains all of the - * elements in the specified collection. - * java.util.Arrays#containsAll(Object[] array, java.util.Collection collection) - */ - public static boolean containsAll(Object[] array, Collection<?> collection) { - return containsAll(array, collection.iterator()); - } - - /** - * Return whether the specified array contains all of the - * elements in the specified iterable. - * java.util.Arrays#containsAll(Object[] array, java.lang.Iterable iterable) - */ - public static boolean containsAll(Object[] array, Iterable<?> iterable) { - return containsAll(array, iterable.iterator()); - } - - /** - * Return whether the specified array contains all of the - * elements in the specified iterator. - * java.util.Arrays#containsAll(Object[] array, java.util.Iterator iterator) - */ - public static boolean containsAll(Object[] array, Iterator<?> iterator) { - while (iterator.hasNext()) { - if ( ! contains(array, iterator.next())) { - return false; - } - } - return true; - } - - /** - * Return whether the specified array 1 contains all of the - * elements in the specified array 2. - * java.util.Arrays#containsAll(Object[] array1, Object[] array2) - */ - public static boolean containsAll(Object[] array1, Object[] array2) { - for (int i = array2.length; i-- > 0; ) { - if ( ! contains(array1, array2[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified array 1 contains all of the - * elements in the specified array 2. - * java.util.Arrays#containsAll(char[] array1, char[] array2) - */ - public static boolean containsAll(char[] array1, char[] array2) { - for (int i = array2.length; i-- > 0; ) { - if ( ! contains(array1, array2[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified array 1 contains all of the - * elements in the specified array 2. - * java.util.Arrays#containsAll(int[] array1, int[] array2) - */ - public static boolean containsAll(int[] array1, int[] array2) { - for (int i = array2.length; i-- > 0; ) { - if ( ! contains(array1, array2[i])) { - return false; - } - } - return true; - } - - /** - * Return the index of the first elements in the specified - * arrays that are different, beginning at the end. - * If the arrays are identical, return -1. - * If the arrays are different sizes, return the index of the - * last element in the longer array. - * Use the elements' #equals() method to compare the - * elements. - */ - public static int diffEnd(Object[] array1, Object[] array2) { - return diffEnd(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the index of the first elements in the specified - * lists that are different, beginning at the end. - * If the lists are identical, return -1. - * If the lists are different sizes, return the index of the - * last element in the longer list. - * Use the elements' #equals() method to compare the - * elements. - */ - public static int diffEnd(List<?> list1, List<?> list2) { - int size1 = list1.size(); - int size2 = list2.size(); - if (size1 != size2) { - return Math.max(size1, size2) - 1; - } - int end = size1 - 1; - while (end > -1) { - Object o = list1.get(end); - if (o == null) { - if (list2.get(end) == null) { - end--; - } else { - return end; - } - } else { - if (o.equals(list2.get(end))) { - end--; - } else { - return end; - } - } - } - return end; - } - - /** - * Return the range of elements in the specified - * arrays that are different. - * If the arrays are identical, return [size, -1]. - * Use the elements' #equals() method to compare the - * elements. - * @see #diffStart(Object[], Object[]) - * @see #diffEnd(Object[], Object[]) - */ - public static Range diffRange(Object[] array1, Object[] array2) { - return diffRange(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the range of elements in the specified - * arrays that are different. - * If the arrays are identical, return [size, -1]. - * Use the elements' #equals() method to compare the - * elements. - * @see #diffStart(java.util.List, java.util.List) - * @see #diffEnd(java.util.List, java.util.List) - */ - public static Range diffRange(List<?> list1, List<?> list2) { - int end = diffEnd(list1, list2); - if (end == -1) { - // the lists are identical, the start is the size of the two lists - return new Range(list1.size(), end); - } - // the lists are different, calculate the start of the range - return new Range(diffStart(list1, list2), end); - } - - /** - * Return the index of the first elements in the specified - * arrays that are different. If the arrays are identical, return - * the size of the two arrays (i.e. one past the last index). - * If the arrays are different sizes and all the elements in - * the shorter array match their corresponding elements in - * the longer array, return the size of the shorter array - * (i.e. one past the last index of the shorter array). - * Use the elements' #equals() method to compare the - * elements. - */ - public static int diffStart(Object[] array1, Object[] array2) { - return diffStart(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the index of the first elements in the specified - * lists that are different. If the lists are identical, return - * the size of the two lists (i.e. one past the last index). - * If the lists are different sizes and all the elements in - * the shorter list match their corresponding elements in - * the longer list, return the size of the shorter list - * (i.e. one past the last index of the shorter list). - * Use the elements' #equals() method to compare the - * elements. - */ - public static int diffStart(List<?> list1, List<?> list2) { - int end = Math.min(list1.size(), list2.size()); - int start = 0; - while (start < end) { - Object o = list1.get(start); - if (o == null) { - if (list2.get(start) == null) { - start++; - } else { - return start; - } - } else { - if (o.equals(list2.get(start))) { - start++; - } else { - return start; - } - } - } - return start; - } - - /** - * Return whether the specified iterators return equal elements. - * java.util.Iterator#equals(java.util.Iterator iterator) - */ - public static boolean equals(Iterator<?> iterator1, Iterator<?> iterator2) { - while (iterator1.hasNext() && iterator2.hasNext()) { - Object o1 = iterator1.next(); - Object o2 = iterator2.next(); - if ( ! (o1 == null ? o2 == null : o1.equals(o2))) { - return false; - } - } - return ! (iterator1.hasNext() || iterator2.hasNext()); - } - - /** - * Return the element corresponding to the specified index - * in the specified iterator. - * java.util.ListIterator#get(int index) - */ - public static <E> E get(ListIterator<? extends E> iterator, int index) { - while (iterator.hasNext()) { - E next = iterator.next(); - if (iterator.previousIndex() == index) { - return next; - } - } - throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(iterator.previousIndex())); - } - - /** - * Return whether the specified arrays contain the same elements. - * java.util.Arrays#identical(Object[] array1, Object[] array2) - */ - public static boolean identical(Object[] array1, Object[] array2) { - if (array1 == array2) { - return true; - } - if (array1 == null || array2 == null) { - return false; - } - int length = array1.length; - if (array2.length != length) { - return false; - } - for (int i = length; i-- > 0; ) { - if (array1[i] != array2[i]) { - return false; - } - } - return true; - } - - /** - * Return whether the specified iterators return the same elements. - * java.util.Iterator#identical(java.util.Iterator iterator) - */ - public static boolean identical(Iterator<?> iterator1, Iterator<?> iterator2) { - while (iterator1.hasNext() && iterator2.hasNext()) { - if (iterator1.next() != iterator2.next()) { - return false; - } - } - return ! (iterator1.hasNext() || iterator2.hasNext()); - } - - /** - * Return the index of the first elements in the specified - * arrays that are different, beginning at the end. - * If the arrays are identical, return -1. - * If the arrays are different sizes, return the index of the - * last element in the longer array. - * Use object identity to compare the elements. - */ - public static int identityDiffEnd(Object[] array1, Object[] array2) { - return identityDiffEnd(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the index of the first elements in the specified - * lists that are different, beginning at the end. - * If the lists are identical, return -1. - * If the lists are different sizes, return the index of the - * last element in the longer list. - * Use object identity to compare the elements. - */ - public static int identityDiffEnd(List<?> list1, List<?> list2) { - int size1 = list1.size(); - int size2 = list2.size(); - if (size1 != size2) { - return Math.max(size1, size2) - 1; - } - int end = size1 - 1; - while (end > -1) { - if (list1.get(end) == list2.get(end)) { - end--; - } else { - return end; - } - } - return end; - } - - /** - * Return the range of elements in the specified - * arrays that are different. - * If the arrays are identical, return [size, -1]. - * Use object identity to compare the elements. - * @see #identityDiffStart(Object[], Object[]) - * @see #identityDiffEnd(Object[], Object[]) - */ - public static Range identityDiffRange(Object[] array1, Object[] array2) { - return identityDiffRange(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the range of elements in the specified - * arrays that are different. - * If the arrays are identical, return [size, -1]. - * Use object identity to compare the elements. - * @see #identityDiffStart(java.util.List, java.util.List) - * @see #identityDiffEnd(java.util.List, java.util.List) - */ - public static Range identityDiffRange(List<?> list1, List<?> list2) { - int end = identityDiffEnd(list1, list2); - if (end == -1) { - // the lists are identical, the start is the size of the two lists - return new Range(list1.size(), end); - } - // the lists are different, calculate the start of the range - return new Range(identityDiffStart(list1, list2), end); - } - - /** - * Return the index of the first elements in the specified - * arrays that are different. If the arrays are identical, return - * the size of the two arrays (i.e. one past the last index). - * If the arrays are different sizes and all the elements in - * the shorter array match their corresponding elements in - * the longer array, return the size of the shorter array - * (i.e. one past the last index of the shorter array). - * Use object identity to compare the elements. - */ - public static int identityDiffStart(Object[] array1, Object[] array2) { - return identityDiffStart(Arrays.asList(array1), Arrays.asList(array2)); - } - - /** - * Return the index of the first elements in the specified - * lists that are different. If the lists are identical, return - * the size of the two lists (i.e. one past the last index). - * If the lists are different sizes and all the elements in - * the shorter list match their corresponding elements in - * the longer list, return the size of the shorter list - * (i.e. one past the last index of the shorter list). - * Use object identity to compare the elements. - */ - public static int identityDiffStart(List<?> list1, List<?> list2) { - int end = Math.min(list1.size(), list2.size()); - int start = 0; - while (start < end) { - if (list1.get(start) == list2.get(start)) { - start++; - } else { - return start; - } - } - return start; - } - - /** - * Return the index of the first occurrence of the - * specified element in the specified iterator, - * or return -1 if there is no such index. - * java.util.Iterator#indexOf(Object o) - */ - public static int indexOf(Iterator<?> iterator, Object value) { - if (value == null) { - for (int i = 0; iterator.hasNext(); i++) { - if (iterator.next() == null) { - return i; - } - } - } else { - for (int i = 0; iterator.hasNext(); i++) { - if (value.equals(iterator.next())) { - return i; - } - } - } - return -1; - } - - /** - * Return the index of the first occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#indexOf(Object[] array, Object o) - */ - public static int indexOf(Object[] array, Object value) { - int len = array.length; - if (value == null) { - for (int i = 0; i < len; i++) { - if (array[i] == null) { - return i; - } - } - } else { - for (int i = 0; i < len; i++) { - if (value.equals(array[i])) { - return i; - } - } - } - return -1; - } - - /** - * Return the index of the first occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#indexOf(char[] array, char value) - */ - public static int indexOf(char[] array, char value) { - int len = array.length; - for (int i = 0; i < len; i++) { - if (array[i] == value) { - return i; - } - } - return -1; - } - - /** - * Return the index of the first occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#indexOf(int[] array, int value) - */ - public static int indexOf(int[] array, int value) { - int len = array.length; - for (int i = 0; i < len; i++) { - if (array[i] == value) { - return i; - } - } - return -1; - } - - /** - * Return the maximum index of where the specified comparable object - * should be inserted into the specified sorted list and still keep - * the list sorted. - */ - public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) { - int len = sortedList.size(); - for (int i = 0; i < len; i++) { - if (value.compareTo(sortedList.get(i)) < 0) { - return i; - } - } - return len; - } - - /** - * Return the maximum index of where the specified object - * should be inserted into the specified sorted list and still keep - * the list sorted. - */ - public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) { - int len = sortedList.size(); - for (int i = 0; i < len; i++) { - if (comparator.compare(value, sortedList.get(i)) < 0) { - return i; - } - } - return len; - } - - /** - * Return the maximum index of where the specified comparable object - * should be inserted into the specified sorted array and still keep - * the array sorted. - */ - public static <E extends Comparable<? super E>> int insertionIndexOf(E[] sortedArray, Comparable<E> value) { - int len = sortedArray.length; - for (int i = 0; i < len; i++) { - if (value.compareTo(sortedArray[i]) < 0) { - return i; - } - } - return len; - } - - /** - * Return the maximum index of where the specified comparable object - * should be inserted into the specified sorted array and still keep - * the array sorted. - */ - public static <E> int insertionIndexOf(E[] sortedArray, E value, Comparator<? super E> comparator) { - int len = sortedArray.length; - for (int i = 0; i < len; i++) { - if (comparator.compare(value, sortedArray[i]) < 0) { - return i; - } - } - return len; - } - - /** - * Return a one-use Iterable for the Iterator given. - * Throws an IllegalStateException if iterable() is called more than once. - * As such, this utility should only be used in one-use situations, such as - * a "for" loop. - */ - public static <E> Iterable<E> iterable(Iterator<? extends E> iterator) { - return new SingleUseIterable<E>(iterator); - } - - /** - * Return an iterable on the elements in the specified array. - * java.util.Arrays#iterable(Object[] array) - */ - public static <E> Iterable<E> iterable(E... array) { - return Arrays.asList(array); - } - - /** - * Return an iterator on the elements in the specified array. - * java.util.Arrays#iterator(Object[] array) - */ - public static <E> Iterator<E> iterator(E... array) { - return new ArrayIterator<E>(array); - } - - /** - * Return the index of the last occurrence of the - * specified element in the specified iterator, - * or return -1 if there is no such index. - * java.util.Iterator#lastIndexOf(Object o) - */ - public static int lastIndexOf(Iterator<?> iterator, Object value) { - return (iterator.hasNext()) ? list(iterator).lastIndexOf(value) : -1; - } - - /** - * Return the index of the last occurrence of the - * specified element in the specified iterator, - * or return -1 if there is no such index. - * java.util.Iterator#lastIndexOf(Object o) - */ - public static int lastIndexOf(Iterator<?> iterator, int size, Object value) { - return (iterator.hasNext()) ? list(iterator, size).lastIndexOf(value) : -1; - } - - /** - * Return the index of the last occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#lastIndexOf(Object[] array, Object o) - */ - public static int lastIndexOf(Object[] array, Object value) { - int len = array.length; - if (value == null) { - for (int i = len; i-- > 0; ) { - if (array[i] == null) { - return i; - } - } - } else { - for (int i = len; i-- > 0; ) { - if (value.equals(array[i])) { - return i; - } - } - } - return -1; - } - - /** - * Return the index of the last occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#lastIndexOf(char[] array, char value) - */ - public static int lastIndexOf(char[] array, char value) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == value) { - return i; - } - } - return -1; - } - - /** - * Return the index of the last occurrence of the - * specified element in the specified array, - * or return -1 if there is no such index. - * java.util.Arrays#lastIndexOf(int[] array, int value) - */ - public static int lastIndexOf(int[] array, int value) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == value) { - return i; - } - } - return -1; - } - - /** - * Return a list corresponding to the specified iterable. - * java.lang.Iterable#toList() - */ - public static <E> ArrayList<E> list(Iterable<? extends E> iterable) { - return list(iterable.iterator()); - } - - /** - * Return a list corresponding to the specified iterable. - * java.lang.Iterable#toList() - */ - public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int size) { - return list(iterable.iterator(), size); - } - - /** - * Return a list corresponding to the specified iterator. - * java.util.Iterator#toList() - */ - public static <E> ArrayList<E> list(Iterator<? extends E> iterator) { - return list(iterator, new ArrayList<E>()); - } - - /** - * Return a list corresponding to the specified iterator. - * java.util.Iterator#toList() - */ - public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int size) { - return list(iterator, new ArrayList<E>(size)); - } - - private static <E> ArrayList<E> list(Iterator<? extends E> iterator, ArrayList<E> list) { - while (iterator.hasNext()) { - list.add(iterator.next()); - } - return list; - } - - /** - * Return a list corresponding to the specified array. - * Unlike java.util.Arrays.asList(Object[]), the list - * is modifiable and is not backed by the array. - */ - public static <E> ArrayList<E> list(E... array) { - ArrayList<E> list = new ArrayList<E>(array.length); - for (E item : array) { - list.add(item); - } - return list; - } - - /** - * Return a list iterator for the specified array. - * java.util.Arrays#listIterator(Object[] array) - */ - public static <E> ListIterator<E> listIterator(E... array) { - return listIterator(array, 0); - } - - /** - * Return a list iterator for the specified array - * starting at the specified position in the array. - * java.util.Arrays#listIterator(Object[] array, int index) - */ - public static <E> ListIterator<E> listIterator(E[] array, int index) { - return Arrays.asList(array).listIterator(index); - } - - /** - * Return the character from the specified array with the maximum value. - * java.util.Arrays#max(char[] array) - */ - public static char max(char... array) { - int len = array.length; - if (len == 0) { - throw new IndexOutOfBoundsException(); - } - char max = array[0]; - // start at 1 - for (int i = 1; i < len; i++) { - char next = array[i]; - if (next > max) { - max = next; - } - } - return max; - } - - /** - * Return the integer from the specified array with the maximum value. - * java.util.Arrays#max(int[] array) - */ - public static int max(int... array) { - int len = array.length; - if (len == 0) { - throw new IndexOutOfBoundsException(); - } - int max = array[0]; - // start at 1 - for (int i = 1; i < len; i++) { - int next = array[i]; - if (next > max) { - max = next; - } - } - return max; - } - - /** - * Return the character from the specified array with the minimum value. - * java.util.Arrays#min(char[] array) - */ - public static char min(char... array) { - int len = array.length; - if (len == 0) { - throw new IndexOutOfBoundsException(); - } - char min = array[0]; - // start at 1 - for (int i = 1; i < len; i++) { - char next = array[i]; - if (next < min) { - min = next; - } - } - return min; - } - - /** - * Return the integer from the specified array with the minimum value. - * java.util.Arrays#min(int[] array) - */ - public static int min(int... array) { - int len = array.length; - if (len == 0) { - throw new IndexOutOfBoundsException(); - } - int min = array[0]; - // start at 1 - for (int i = 1; i < len; i++) { - int next = array[i]; - if (next < min) { - min = next; - } - } - return min; - } - - /** - * Move an element from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(Object[] array, int targetIndex, int sourceIndex) - */ - public static <E> E[] move(E[] array, int targetIndex, int sourceIndex) { - return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex); - } - - /** - * assume targetIndex != sourceIndex - */ - private static <E> E[] move_(E[] array, int targetIndex, int sourceIndex) { - E temp = array[sourceIndex]; - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex); - } - array[targetIndex] = temp; - return array; - } - - /** - * Move elements from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(Object[] array, int targetIndex, int sourceIndex, int length) - */ - public static <E> E[] move(E[] array, int targetIndex, int sourceIndex, int length) { - if ((targetIndex == sourceIndex) || (length == 0)) { - return array; - } - if (length == 1) { - return move_(array, targetIndex, sourceIndex); - } - E[] temp = newArray(array, length); - System.arraycopy(array, sourceIndex, temp, 0, length); - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex); - } - System.arraycopy(temp, 0, array, targetIndex, length); - return array; - } - - /** - * Move an element from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(int[] array, int targetIndex, int sourceIndex) - */ - public static int[] move(int[] array, int targetIndex, int sourceIndex) { - return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex); - } - - /** - * assume targetIndex != sourceIndex - */ - private static int[] move_(int[] array, int targetIndex, int sourceIndex) { - int temp = array[sourceIndex]; - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex); - } - array[targetIndex] = temp; - return array; - } - - /** - * Move elements from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(int[] array, int targetIndex, int sourceIndex, int length) - */ - public static int[] move(int[] array, int targetIndex, int sourceIndex, int length) { - if ((targetIndex == sourceIndex) || (length == 0)) { - return array; - } - if (length == 1) { - return move_(array, targetIndex, sourceIndex); - } - int[] temp = new int[length]; - System.arraycopy(array, sourceIndex, temp, 0, length); - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex); - } - System.arraycopy(temp, 0, array, targetIndex, length); - return array; - } - - /** - * Move an element from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(char[] array, int targetIndex, int sourceIndex) - */ - public static char[] move(char[] array, int targetIndex, int sourceIndex) { - return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex); - } - - /** - * assume targetIndex != sourceIndex - */ - private static char[] move_(char[] array, int targetIndex, int sourceIndex) { - char temp = array[sourceIndex]; - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex); - } - array[targetIndex] = temp; - return array; - } - - /** - * Move elements from the specified source index to the specified target - * index. Return the altered array. - * java.util.Arrays#move(char[] array, int targetIndex, int sourceIndex, int length) - */ - public static char[] move(char[] array, int targetIndex, int sourceIndex, int length) { - if ((targetIndex == sourceIndex) || (length == 0)) { - return array; - } - if (length == 1) { - return move_(array, targetIndex, sourceIndex); - } - char[] temp = new char[length]; - System.arraycopy(array, sourceIndex, temp, 0, length); - if (targetIndex < sourceIndex) { - System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex); - } else { - System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex); - } - System.arraycopy(temp, 0, array, targetIndex, length); - return array; - } - - /** - * Move an element from the specified source index to the specified target - * index. Return the altered list. - * java.util.List#move(int targetIndex, int sourceIndex) - */ - public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) { - return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex); - } - - /** - * assume targetIndex != sourceIndex - */ - private static <E> List<E> move_(List<E> list, int targetIndex, int sourceIndex) { - if (list instanceof RandomAccess) { - // move elements, leaving the list in place - E temp = list.get(sourceIndex); - if (targetIndex < sourceIndex) { - for (int i = sourceIndex; i-- > targetIndex; ) { - list.set(i + 1, list.get(i)); - } - } else { - for (int i = sourceIndex; i < targetIndex; i++) { - list.set(i, list.get(i + 1)); - } - } - list.set(targetIndex, temp); - } else { - // remove the element and re-add it at the target index - list.add(targetIndex, list.remove(sourceIndex)); - } - return list; - } - - /** - * Move elements from the specified source index to the specified target - * index. Return the altered list. - * java.util.List#move(int targetIndex, int sourceIndex, int length) - */ - public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) { - if ((targetIndex == sourceIndex) || (length == 0)) { - return list; - } - if (length == 1) { - return move_(list, targetIndex, sourceIndex); - } - if (list instanceof RandomAccess) { - // move elements, leaving the list in place - ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length)); - if (targetIndex < sourceIndex) { - for (int i = sourceIndex; i-- > targetIndex; ) { - list.set(i + length, list.get(i)); - } - } else { - for (int i = sourceIndex; i < targetIndex; i++) { - list.set(i, list.get(i + length)); - } - } - for (int i = 0; i < length; i++) { - list.set(targetIndex + i, temp.get(i)); - } - } else { - // remove the elements and re-add them at the target index - list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length)); - } - return list; - } - - /** - * Replace all occurrences of the specified old value with - * the specified new value. - * java.util.Arrays#replaceAll(Object[] array, Object oldValue, Object newValue) - */ - public static <E> E[] replaceAll(E[] array, Object oldValue, E newValue) { - if (oldValue == null) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == null) { - array[i] = newValue; - } - } - } else { - for (int i = array.length; i-- > 0; ) { - if (oldValue.equals(array[i])) { - array[i] = newValue; - } - } - } - return array; - } - - /** - * Replace all occurrences of the specified old value with - * the specified new value. - * java.util.Arrays#replaceAll(int[] array, int oldValue, int newValue) - */ - public static int[] replaceAll(int[] array, int oldValue, int newValue) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == oldValue) { - array[i] = newValue; - } - } - return array; - } - - /** - * Replace all occurrences of the specified old value with - * the specified new value. - * java.util.Arrays#replaceAll(char[] array, char oldValue, char newValue) - */ - public static char[] replaceAll(char[] array, char oldValue, char newValue) { - for (int i = array.length; i-- > 0; ) { - if (array[i] == oldValue) { - array[i] = newValue; - } - } - return array; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#remove(Object[] array, Object value) - */ - public static <E> E[] remove(E[] array, Object value) { - return removeElementAtIndex(array, indexOf(array, value)); - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#remove(char[] array, char value) - */ - public static char[] remove(char[] array, char value) { - return removeElementAtIndex(array, indexOf(array, value)); - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#remove(int[] array, int value) - */ - public static int[] remove(int[] array, int value) { - return removeElementAtIndex(array, indexOf(array, value)); - } - - /** - * Remove all the elements returned by the specified iterable - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAll(java.lang.Iterable iterable) - */ - public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) { - return removeAll(collection, iterable.iterator()); - } - - /** - * Remove all the elements returned by the specified iterable - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAll(java.lang.Iterable iterable) - */ - public static boolean removeAll(Collection<?> collection, Iterable<?> iterable, int size) { - return removeAll(collection, iterable.iterator(), size); - } - - /** - * Remove all the elements returned by the specified iterator - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAll(java.util.Iterator iterator) - */ - public static boolean removeAll(Collection<?> collection, Iterator<?> iterator) { - return (iterator.hasNext()) ? collection.removeAll(set(iterator)) : false; - } - - /** - * Remove all the elements returned by the specified iterator - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAll(java.util.Iterator iterator) - */ - public static boolean removeAll(Collection<?> collection, Iterator<?> iterator, int size) { - return (iterator.hasNext()) ? collection.removeAll(set(iterator, size)) : false; - } - - /** - * Remove all the elements in the specified array - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAll(Object[] array) - */ - public static boolean removeAll(Collection<?> collection, Object[] array) { - return collection.removeAll(set(array)); - } - - /** - * Remove from the specified array all the elements in - * the specified iterable and return the result. - * java.util.Arrays#removeAll(Object[] array, Iterable iterable) - */ - public static <E> E[] removeAll(E[] array, Iterable<?> iterable) { - return removeAll(array, iterable.iterator()); - } - - /** - * Remove from the specified array all the elements in - * the specified iterable and return the result. - * java.util.Arrays#removeAll(Object[] array, Iterable iterable) - */ - public static <E> E[] removeAll(E[] array, Iterable<?> iterable, int size) { - return removeAll(array, iterable.iterator(), size); - } - - /** - * Remove from the specified array all the elements in - * the specified iterator and return the result. - * java.util.Arrays#removeAll(Object[] array, Iterator iterator) - */ - public static <E> E[] removeAll(E[] array, Iterator<?> iterator) { - return (iterator.hasNext()) ? removeAll_(array, set(iterator)) : array; - } - - /** - * Remove from the specified array all the elements in - * the specified iterator and return the result. - * java.util.Arrays#removeAll(Object[] array, Iterator iterator) - */ - public static <E> E[] removeAll(E[] array, Iterator<?> iterator, int size) { - return (iterator.hasNext()) ? removeAll_(array, set(iterator, size)) : array; - } - - /** - * Remove from the specified array all the elements in - * the specified collection and return the result. - * java.util.Arrays#removeAll(Object[] array, Collection collection) - */ - public static <E> E[] removeAll(E[] array, Collection<?> collection) { - return (collection.isEmpty()) ? array : removeAll_(array, collection); - } - - /** - * assume the collection is non-empty - */ - private static <E> E[] removeAll_(E[] array, Collection<?> collection) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : removeAll(array, collection, arrayLength); - } - - /** - * assume the collection is non-empty and arrayLength > 0 - */ - private static <E> E[] removeAll(E[] array, Collection<?> collection, int arrayLength) { - int[] indices = new int[arrayLength]; - int j = 0; - for (int i = 0; i < arrayLength; i++) { - if ( ! collection.contains(array[i])) { - indices[j++] = i; - } - } - if (j == arrayLength) { - return array; // nothing was removed - } - E[] result = newArray(array, j); - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array[indices[i]]; - } - return result; - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#removeAll(Object[] array1, Object[] array2) - */ - public static <E> E[] removeAll(E[] array1, Object[] array2) { - // convert to a bag to take advantage of hashed look-up - return (array2.length == 0) ? array1 : removeAll_(array1, set(array2)); - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#removeAll(char[] array1, char[] array2) - */ - public static char[] removeAll(char[] array1, char[] array2) { - if (array2.length == 0) { - return array1; - } - int array1Length = array1.length; - if (array1Length == 0) { - return array1; - } - int[] indices = new int[array1Length]; - int j = 0; - for (int i = 0; i < array1Length; i++) { - if ( ! contains(array2, array1[i])) { - indices[j++] = i; - } - } - if (j == array1Length) { - return array1; // nothing was removed - } - char[] result = new char[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array1[indices[i]]; - } - return result; - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#removeAll(int[] array1, int[] array2) - */ - public static int[] removeAll(int[] array1, int[] array2) { - if (array2.length == 0) { - return array1; - } - int array1Length = array1.length; - if (array1Length == 0) { - return array1; - } - int[] indices = new int[array1Length]; - int j = 0; - for (int i = 0; i < array1Length; i++) { - if ( ! contains(array2, array1[i])) { - indices[j++] = i; - } - } - if (j == array1Length) { - return array1; // nothing was removed - } - int[] result = new int[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array1[indices[i]]; - } - return result; - } - - /** - * Remove all occurrences of the specified element - * from the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#removeAllOccurrences(Object value) - */ - public static boolean removeAllOccurrences(Collection<?> collection, Object value) { - boolean modified = false; - Iterator<?> stream = collection.iterator(); - if (value == null) { - while (stream.hasNext()) { - if (stream.next() == null) { - stream.remove(); - modified = true; - } - } - } else { - while (stream.hasNext()) { - if (value.equals(stream.next())) { - stream.remove(); - modified = true; - } - } - } - return modified; - } - - /** - * Remove from the specified array all occurrences of - * the specified element and return the result. - * java.util.Arrays#removeAllOccurrences(Object[] array, Object value) - */ - public static <E> E[] removeAllOccurrences(E[] array, Object value) { - int arrayLength = array.length; - if (arrayLength == 0) { - return array; - } - int[] indices = new int[arrayLength]; - int j = 0; - if (value == null) { - for (int i = arrayLength; i-- > 0; ) { - if (array[i] != null) { - indices[j++] = i; - } - } - } else { - for (int i = array.length; i-- > 0; ) { - if ( ! value.equals(array[i])) { - indices[j++] = i; - } - } - } - if (j == arrayLength) { - return array; // nothing was removed - } - E[] result = newArray(array, j); - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array[indices[i]]; - } - return result; - } - - /** - * Remove from the specified array all occurrences of - * the specified element and return the result. - * java.util.Arrays#removeAllOccurrences(char[] array, char value) - */ - public static char[] removeAllOccurrences(char[] array, char value) { - int arrayLength = array.length; - if (arrayLength == 0) { - return array; - } - int[] indices = new int[arrayLength]; - int j = 0; - for (int i = arrayLength; i-- > 0; ) { - if (array[i] != value) { - indices[j++] = i; - } - } - if (j == arrayLength) { - return array; // nothing was removed - } - char[] result = new char[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array[indices[i]]; - } - return result; - } - - /** - * Remove from the specified array all occurrences of - * the specified element and return the result. - * java.util.Arrays#removeAllOccurrences(int[] array, int value) - */ - public static int[] removeAllOccurrences(int[] array, int value) { - int arrayLength = array.length; - if (arrayLength == 0) { - return array; - } - int[] indices = new int[arrayLength]; - int j = 0; - for (int i = arrayLength; i-- > 0; ) { - if (array[i] != value) { - indices[j++] = i; - } - } - if (j == arrayLength) { - return array; // nothing was removed - } - int[] result = new int[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array[indices[i]]; - } - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#removeElementAtIndex(Object[] array, int index) - */ - public static <E> E[] removeElementAtIndex(E[] array, int index) { - return removeElementsAtIndex(array, index, 1); - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#removeElementAtIndex(char[] array, int index) - */ - public static char[] removeElementAtIndex(char[] array, int index) { - return removeElementsAtIndex(array, index, 1); - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified element removed. - * java.util.Arrays#removeElementAtIndex(int[] array, int index) - */ - public static int[] removeElementAtIndex(int[] array, int index) { - return removeElementsAtIndex(array, index, 1); - } - - /** - * Remove the elements at the specified index. - * Return the removed elements. - * java.util.List#remove(int index, int length) - */ - public static <E> ArrayList<E> removeElementsAtIndex(List<E> list, int index, int length) { - List<E> subList = list.subList(index, index + length); - ArrayList<E> result = new ArrayList<E>(subList); - subList.clear(); - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified elements removed. - * java.util.Arrays#removeElementsAtIndex(Object[] array, int index, int length) - */ - public static <E> E[] removeElementsAtIndex(E[] array, int index, int length) { - int arrayLength = array.length; - int newLength = arrayLength - length; - E[] result = newArray(array, newLength); - if ((newLength == 0) && (index == 0)) { - return result; // performance tweak - } - System.arraycopy(array, 0, result, 0, index); - System.arraycopy(array, index + length, result, index, newLength - index); - return result; - } - - /** - * Return a new array that contains the elements in the - * specified array with the specified elements removed. - * java.util.Arrays#removeElementAtIndex(char[] array, int index, int length) - */ - public static char[] removeElementsAtIndex(char[] array, int index, int length) { - int arrayLength = array.length; - int newLength = arrayLength - length; - if ((newLength == 0) && (index == 0)) { - return EMPTY_CHAR_ARRAY; // performance tweak - } - char[] result = new char[newLength]; - System.arraycopy(array, 0, result, 0, index); - System.arraycopy(array, index + length, result, index, newLength - index); - return result; - } - private static final char[] EMPTY_CHAR_ARRAY = new char[0]; - - /** - * Return a new array that contains the elements in the - * specified array with the specified elements removed. - * java.util.Arrays#removeElementAtIndex(int[] array, int index, int length) - */ - public static int[] removeElementsAtIndex(int[] array, int index, int length) { - int arrayLength = array.length; - int newLength = arrayLength - length; - if ((newLength == 0) && (index == 0)) { - return EMPTY_INT_ARRAY; // performance tweak - } - int[] result = new int[newLength]; - System.arraycopy(array, 0, result, 0, index); - System.arraycopy(array, index + length, result, index, newLength - index); - return result; - } - private static final int[] EMPTY_INT_ARRAY = new int[0]; - - /** - * Remove any duplicate elements from the specified array, - * while maintaining the order. - */ - public static <E> E[] removeDuplicateElements(E... array) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - ArrayList<E> temp = list(array); - return removeDuplicateElements(temp, len) ? - temp.toArray(newArray(array, temp.size())) - : - array; - } - - /** - * Remove any duplicate elements from the specified list, - * while maintaining the order. - * Return whether the list changed as a result. - */ - public static <E> boolean removeDuplicateElements(List<E> list) { - int size = list.size(); - if ((size == 0) || (size == 1)) { - return false; - } - return removeDuplicateElements(list, size); - } - - /** - * assume list is non-empty - */ - private static <E> boolean removeDuplicateElements(List<E> list, int size) { - LinkedHashSet<E> temp = new LinkedHashSet<E>(size); // take advantage of hashed look-up - boolean changed = false; - for (E item : list) { - if ( ! temp.add(item)) { - changed = true; // duplicate item - } - } - if (changed) { - int i = 0; - for (Iterator<E> stream = temp.iterator(); stream.hasNext(); ) { - list.set(i, stream.next()); - i++; - } - int tempSize = temp.size(); - for (i = list.size(); i-- > tempSize; ) { - list.remove(i); // pull off the end - } - } - return changed; - } - - /** - * Retain only the elements in the specified iterable - * in the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#retainAll(java.lang.Iterable iterable) - */ - public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) { - return retainAll(collection, iterable.iterator()); - } - - /** - * Retain only the elements in the specified iterable - * in the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#retainAll(java.lang.Iterable iterable) - */ - public static boolean retainAll(Collection<?> collection, Iterable<?> iterable, int size) { - return retainAll(collection, iterable.iterator(), size); - } - - /** - * Retain only the elements in the specified iterator - * in the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#retainAll(java.util.Iterator iterator) - */ - public static boolean retainAll(Collection<?> collection, Iterator<?> iterator) { - if (iterator.hasNext()) { - return collection.retainAll(set(iterator)); - } - if (collection.isEmpty()) { - return false; - } - collection.clear(); - return true; - } - - /** - * Retain only the elements in the specified iterator - * in the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#retainAll(java.util.Iterator iterator) - */ - public static boolean retainAll(Collection<?> collection, Iterator<?> iterator, int size) { - if (iterator.hasNext()) { - return collection.retainAll(set(iterator, size)); - } - if (collection.isEmpty()) { - return false; - } - collection.clear(); - return true; - } - - /** - * Retain only the elements in the specified array - * in the specified collection. - * Return whether the collection changed as a result. - * java.util.Collection#retainAll(Object[] array) - */ - public static boolean retainAll(Collection<?> collection, Object[] array) { - if (array.length > 0) { - return collection.retainAll(set(array)); - } - if (collection.isEmpty()) { - return false; - } - collection.clear(); - return true; - } - - /** - * Retain in the specified array all the elements in - * the specified iterable and return the result. - * java.util.Arrays#retainAll(Object[] array, Iterable iterable) - */ - public static <E> E[] retainAll(E[] array, Iterable<?> iterable) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterable.iterator()); - } - - /** - * Retain in the specified array all the elements in - * the specified iterable and return the result. - * java.util.Arrays#retainAll(Object[] array, Iterable iterable) - */ - public static <E> E[] retainAll(E[] array, Iterable<?> iterable, int size) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterable.iterator(), size); - } - - /** - * Retain in the specified array all the elements in - * the specified iterator and return the result. - * java.util.Arrays#retainAll(Object[] array, Iterator iterator) - */ - public static <E> E[] retainAll(E[] array, Iterator<?> iterator) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterator); - } - - /** - * Retain in the specified array all the elements in - * the specified iterator and return the result. - * java.util.Arrays#retainAll(Object[] array, Iterator iterator) - */ - public static <E> E[] retainAll(E[] array, Iterator<?> iterator, int size) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterator, size); - } - - /** - * assume arrayLength > 0 - */ - private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator) { - return (iterator.hasNext()) ? - retainAll_(array, set(iterator), arrayLength) - : - newArray(array, 0); - } - - /** - * assume arrayLength > 0 - */ - private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator, int iteratorSize) { - return (iterator.hasNext()) ? - retainAll_(array, set(iterator, iteratorSize), arrayLength) - : - newArray(array, 0); - } - - /** - * Retain in the specified array all the elements in - * the specified collection and return the result. - * java.util.Arrays#retainAll(Object[] array, Collection collection) - */ - public static <E> E[] retainAll(E[] array, Collection<?> collection) { - int arrayLength = array.length; - return (arrayLength == 0) ? array : retainAll(array, collection, arrayLength); - } - - /** - * assume arrayLength > 0 - */ - private static <E> E[] retainAll(E[] array, Collection<?> collection, int arrayLength) { - return (collection.isEmpty()) ? - newArray(array, 0) - : - retainAll_(array, collection, arrayLength); - } - - /** - * assume collection is non-empty and arrayLength > 0 - */ - private static <E> E[] retainAll_(E[] array, Collection<?> collection, int arrayLength) { - int[] indices = new int[arrayLength]; - int j = 0; - for (int i = 0; i < arrayLength; i++) { - if (collection.contains(array[i])) { - indices[j++] = i; - } - } - if (j == arrayLength) { - return array; // everything was retained - } - E[] result = newArray(array, j); - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array[indices[i]]; - } - return result; - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#retainAll(Object[] array1, Object[] array2) - */ - public static <E> E[] retainAll(E[] array1, Object[] array2) { - int array1Length = array1.length; - return (array2.length == 0) ? - (array1Length == 0) ? array1 : newArray(array1, 0) - : - retainAll(array1, set(array2), array1Length); - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#retainAll(char[] array1, char[] array2) - */ - public static char[] retainAll(char[] array1, char[] array2) { - int array1Length = array1.length; - return (array1Length == 0) ? array1 : retainAll(array1, array2, array1Length); - } - - /** - * assume array1Length > 0 - */ - private static char[] retainAll(char[] array1, char[] array2, int array1Length) { - int array2Length = array2.length; - return (array2Length == 0) ? EMPTY_CHAR_ARRAY : retainAll(array1, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static char[] retainAll(char[] array1, char[] array2, int array1Length, int array2Length) { - int[] indices = new int[array1Length]; - int j = 0; - for (int i = 0; i < array1Length; i++) { - if (contains(array2, array1[i], array2Length)) { - indices[j++] = i; - } - } - if (j == array1Length) { - return array1; // everything was retained - } - char[] result = new char[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array1[indices[i]]; - } - return result; - } - - /** - * Remove from the first specified array all the elements in - * the second specified array and return the result. - * java.util.Arrays#retainAll(int[] array1, int[] array2) - */ - public static int[] retainAll(int[] array1, int[] array2) { - int array1Length = array1.length; - return (array1Length == 0) ? array1 : retainAll(array1, array2, array1Length); - } - - /** - * assume array1Length > 0 - */ - private static int[] retainAll(int[] array1, int[] array2, int array1Length) { - int array2Length = array2.length; - return (array2Length == 0) ? EMPTY_INT_ARRAY : retainAll(array1, array2, array1Length, array2Length); - } - - /** - * assume array1Length > 0 and array2Length > 0 - */ - private static int[] retainAll(int[] array1, int[] array2, int array1Length, int array2Length) { - int[] indices = new int[array1Length]; - int j = 0; - for (int i = 0; i < array1Length; i++) { - if (contains(array2, array1[i], array2Length)) { - indices[j++] = i; - } - } - if (j == array1Length) { - return array1; // everything was retained - } - int[] result = new int[j]; - int resultLength = result.length; - for (int i = 0; i < resultLength; i++) { - result[i] = array1[indices[i]]; - } - return result; - } - - /** - * Return the array reversed. - * java.util.Arrays.reverse(Object[] array) - */ - public static <E> E[] reverse(E... array) { - int len = array.length; - for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) { - swap(array, i, j); - } - return array; - } - - /** - * Return the array reversed. - * java.util.Arrays.reverse(char[] array) - */ - public static char[] reverse(char... array) { - int len = array.length; - for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) { - swap(array, i, j); - } - return array; - } - - /** - * Return the array reversed. - * java.util.Arrays.reverse(int[] array) - */ - public static int[] reverse(int... array) { - int len = array.length; - for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) { - swap(array, i, j); - } - return array; - } - - /** - * Return a list with entries in reverse order from those - * returned by the specified iterable. - */ - public static <E> List<E> reverseList(Iterable<? extends E> iterable) { - return reverse(list(iterable)); - } - - /** - * Return a list with entries in reverse order from those - * returned by the specified iterable. - */ - public static <E> List<E> reverseList(Iterable<? extends E> iterable, int size) { - return reverse(list(iterable, size)); - } - - /** - * Return a list with entries in reverse order from those - * returned by the specified iterator. - */ - public static <E> List<E> reverseList(Iterator<? extends E> iterator) { - return reverse(list(iterator)); - } - - /** - * Return a list with entries in reverse order from those - * returned by the specified iterator. - */ - public static <E> List<E> reverseList(Iterator<? extends E> iterator, int size) { - return reverse(list(iterator, size)); - } - - /** - * Return the rotated array after rotating it one position. - * java.util.Arrays.rotate(Object[] array) - */ - public static <E> E[] rotate(E... array) { - return rotate(array, 1); - } - - /** - * Return the rotated array after rotating it the specified distance. - * java.util.Arrays.rotate(Object[] array, int distance) - */ - public static <E> E[] rotate(E[] array, int distance) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - distance = distance % len; - if (distance < 0) { - distance += len; - } - if (distance == 0) { - return array; - } - for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) { - E displaced = array[cycleStart]; - int i = cycleStart; - do { - i += distance; - if (i >= len) { - i -= len; - } - E temp = array[i]; - array[i] = displaced; - displaced = temp; - nMoved ++; - } while (i != cycleStart); - } - return array; - } - - /** - * Return the rotated array after rotating it one position. - * java.util.Arrays.rotate(char[] array) - */ - public static char[] rotate(char... array) { - return rotate(array, 1); - } - - /** - * Return the rotated array after rotating it the specified distance. - * java.util.Arrays.rotate(char[] array, int distance) - */ - public static char[] rotate(char[] array, int distance) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - distance = distance % len; - if (distance < 0) { - distance += len; - } - if (distance == 0) { - return array; - } - for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) { - char displaced = array[cycleStart]; - int i = cycleStart; - do { - i += distance; - if (i >= len) { - i -= len; - } - char temp = array[i]; - array[i] = displaced; - displaced = temp; - nMoved ++; - } while (i != cycleStart); - } - return array; - } - - /** - * Return the rotated array after rotating it one position. - * java.util.Arrays.rotate(int[] array) - */ - public static int[] rotate(int... array) { - return rotate(array, 1); - } - - /** - * Return the rotated array after rotating it the specified distance. - * java.util.Arrays.rotate(int[] array, int distance) - */ - public static int[] rotate(int[] array, int distance) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - distance = distance % len; - if (distance < 0) { - distance += len; - } - if (distance == 0) { - return array; - } - for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) { - int displaced = array[cycleStart]; - int i = cycleStart; - do { - i += distance; - if (i >= len) { - i -= len; - } - int temp = array[i]; - array[i] = displaced; - displaced = temp; - nMoved ++; - } while (i != cycleStart); - } - return array; - } - - /** - * Return a set corresponding to the specified iterable. - * java.util.HashSet(java.lang.Iterable iterable) - */ - public static <E> HashSet<E> set(Iterable<? extends E> iterable) { - return set(iterable.iterator()); - } - - /** - * Return a set corresponding to the specified iterable. - * java.util.HashSet(java.lang.Iterable iterable) - */ - public static <E> HashSet<E> set(Iterable<? extends E> iterable, int size) { - return set(iterable.iterator(), size); - } - - /** - * Return a set corresponding to the specified iterator. - * java.util.HashSet(java.util.Iterator iterator) - */ - public static <E> HashSet<E> set(Iterator<? extends E> iterator) { - return set(iterator, new HashSet<E>()); - } - - /** - * Return a set corresponding to the specified iterator. - * java.util.HashSet(java.util.Iterator iterator) - */ - public static <E> HashSet<E> set(Iterator<? extends E> iterator, int size) { - return set(iterator, new HashSet<E>(size)); - } - - private static <E> HashSet<E> set(Iterator<? extends E> iterator, HashSet<E> set) { - while (iterator.hasNext()) { - set.add(iterator.next()); - } - return set; - } - - /** - * Return a set corresponding to the specified array. - * java.util.HashSet(Object[] array) - */ - public static <E> HashSet<E> set(E... array) { - HashSet<E> set = new HashSet<E>(array.length); - for (E item : array) { - set.add(item); - } - return set; - } - - private static final Random RANDOM = new Random(); - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(Object[] array) - */ - public static <E> E[] shuffle(E... array) { - return shuffle(array, RANDOM); - } - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(Object[] array, Random r) - */ - public static <E> E[] shuffle(E[] array, Random random) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - for (int i = len; i-- > 0; ) { - swap(array, i, random.nextInt(len)); - } - return array; - } - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(char[] array) - */ - public static char[] shuffle(char... array) { - return shuffle(array, RANDOM); - } - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(char[] array, Random r) - */ - public static char[] shuffle(char[] array, Random random) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - for (int i = len; i-- > 0; ) { - swap(array, i, random.nextInt(len)); - } - return array; - } - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(int[] array) - */ - public static int[] shuffle(int... array) { - return shuffle(array, RANDOM); - } - - /** - * Return the array after "shuffling" it. - * java.util.Arrays#shuffle(int[] array, Random r) - */ - public static int[] shuffle(int[] array, Random random) { - int len = array.length; - if ((len == 0) || (len == 1)) { - return array; - } - for (int i = len; i-- > 0; ) { - swap(array, i, random.nextInt(len)); - } - return array; - } - - /** - * Return an iterator that returns only the single, - * specified object. - * Object#toIterator() ?! - */ - public static <E> Iterator<E> singletonIterator(E value) { - return new SingleElementIterator<E>(value); - } - - /** - * Return the number of elements returned by the specified iterable. - * java.lang.Iterable#size() - */ - public static int size(Iterable<?> iterable) { - return size(iterable.iterator()); - } - - /** - * Return the number of elements returned by the specified iterator. - * java.util.Iterator#size() - */ - public static int size(Iterator<?> iterator) { - int size = 0; - while (iterator.hasNext()) { - iterator.next(); - size++; - } - return size; - } - - /** - * Return a sorted set corresponding to the specified iterable. - * java.util.TreeSet(java.lang.Iterable iterable) - */ - public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable) { - return sortedSet(iterable, null); - } - - /** - * Return a sorted set corresponding to the specified iterable. - * java.util.TreeSet(java.lang.Iterable iterable) - */ - public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int size) { - return sortedSet(iterable, size, null); - } - - /** - * Return a sorted set corresponding to the specified iterable - * and comparator. - * java.util.TreeSet(java.lang.Iterable iterable, java.util.Comparator c) - */ - public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) { - return sortedSet(iterable.iterator(), comparator); - } - - /** - * Return a sorted set corresponding to the specified iterable - * and comparator. - * java.util.TreeSet(java.lang.Iterable iterable, java.util.Comparator c) - */ - public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int size, Comparator<? super E> comparator) { - return sortedSet(iterable.iterator(), size, comparator); - } - - /** - * Return a sorted set corresponding to the specified iterator. - * java.util.TreeSet(java.util.Iterator iterator) - */ - public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator) { - return sortedSet(iterator, null); - } - - /** - * Return a sorted set corresponding to the specified iterator. - * java.util.TreeSet(java.util.Iterator iterator) - */ - public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int size) { - return sortedSet(iterator, size, null); - } - - /** - * Return a sorted set corresponding to the specified iterator - * and comparator. - * java.util.TreeSet(java.util.Iterator iterator, java.util.Comparator c) - */ - public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator) { - return sortedSet(list(iterator), comparator); - } - - /** - * Return a sorted set corresponding to the specified iterator - * and comparator. - * java.util.TreeSet(java.util.Iterator iterator, java.util.Comparator c) - */ - public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int size, Comparator<? super E> comparator) { - return sortedSet(list(iterator, size), comparator); - } - - private static <E> TreeSet<E> sortedSet(List<E> list, Comparator<? super E> comparator) { - TreeSet<E> sortedSet = new TreeSet<E>(comparator); - sortedSet.addAll(list); - return sortedSet; - } - - /** - * Return a sorted set corresponding to the specified array. - * java.util.TreeSet(Object[] array) - */ - public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(E... array) { - return sortedSet(array, null); - } - - /** - * Return a sorted set corresponding to the specified array - * and comparator. - * java.util.TreeSet(Object[] array, java.util.Comparator c) - */ - public static <E> TreeSet<E> sortedSet(E[] array, Comparator<? super E> comparator) { - TreeSet<E> sortedSet = new TreeSet<E>(comparator); - sortedSet.addAll(Arrays.asList(array)); - return sortedSet; - } - - /** - * Return a sub-array of the specified array, starting at the specified - * position with the specified length. - * java.util.Arrays#subArray(E[] array, int start, int length) - */ - public static <E> E[] subArray(E[] array, int start, int length) { - E[] result = newArray(array, length); - if (length > 0) { - System.arraycopy(array, start, result, 0, length); - } - return result; - } - - /** - * Return a sub-array of the specified array, starting at the specified - * position with the specified length. - * java.util.Arrays#subArray(int[] array, int start, int length) - */ - public static int[] subArray(int[] array, int start, int length) { - int[] result = new int[length]; - if (length > 0) { - System.arraycopy(array, start, result, 0, length); - } - return result; - } - - /** - * Return a sub-array of the specified array, starting at the specified - * position with the specified length. - * java.util.Arrays#subArray(char[] array, int start, int length) - */ - public static char[] subArray(char[] array, int start, int length) { - char[] result = new char[length]; - if (length > 0) { - System.arraycopy(array, start, result, 0, length); - } - return result; - } - - /** - * Return the array after the specified elements have been "swapped". - * java.util.Arrays#swap(Object[] array, int i, int j) - */ - public static <E> E[] swap(E[] array, int i, int j) { - E temp = array[i]; - array[i] = array[j]; - array[j] = temp; - return array; - } - - /** - * Return the array after the specified elements have been "swapped". - * java.util.Arrays#swap(char[] array, int i, int j) - */ - public static char[] swap(char[] array, int i, int j) { - char temp = array[i]; - array[i] = array[j]; - array[j] = temp; - return array; - } - - /** - * Return the array after the specified elements have been "swapped". - * java.util.Arrays#swap(int[] array, int i, int j) - */ - public static int[] swap(int[] array, int i, int j) { - int temp = array[i]; - array[i] = array[j]; - array[j] = temp; - return array; - } - - /** - * Return a vector corresponding to the specified iterable. - * This is useful for legacy code that requires a java.util.Vector. - * java.util.Vector(java.lang.Iterable iterable) - */ - public static <E> Vector<E> vector(Iterable<? extends E> iterable) { - return vector(iterable.iterator()); - } - - /** - * Return a vector corresponding to the specified iterable. - * This is useful for legacy code that requires a java.util.Vector. - * java.util.Vector(java.lang.Iterable iterable) - */ - public static <E> Vector<E> vector(Iterable<? extends E> iterable, int size) { - return vector(iterable.iterator(), size); - } - - /** - * Return a vector corresponding to the specified iterator. - * This is useful for legacy code that requires a java.util.Vector. - * java.util.Vector(java.util.Iterator iterator) - */ - public static <E> Vector<E> vector(Iterator<? extends E> iterator) { - return vector(iterator, new Vector<E>()); - } - - /** - * Return a vector corresponding to the specified iterator. - * This is useful for legacy code that requires a java.util.Vector. - * java.util.Vector(java.util.Iterator iterator) - */ - public static <E> Vector<E> vector(Iterator<? extends E> iterator, int size) { - return vector(iterator, new Vector<E>(size)); - } - - private static <E> Vector<E> vector(Iterator<? extends E> iterator, Vector<E> v) { - while (iterator.hasNext()) { - v.addElement(iterator.next()); - } - return v; - } - - /** - * Return a vector corresponding to the specified array. - * This is useful for legacy code that requires a java.util.Vector. - * java.util.Vector(Object[] array) - */ - public static <E> Vector<E> vector(E... array) { - Vector<E> v = new Vector<E>(array.length); - for (E item : array) { - v.addElement(item); - } - return v; - } - - - // ********** single-use Iterable ********** - - /** - * This is a one-time use iterable that can return a single iterator. - * Once the iterator is returned the iterable is no longer valid. - * As such, this utility should only be used in one-time use situations, - * such as a 'for-each' loop. - */ - public static class SingleUseIterable<E> implements Iterable<E> { - private Iterator<E> iterator; - - public SingleUseIterable(Iterator<? extends E> iterator) { - super(); - if (iterator == null) { - throw new NullPointerException(); - } - this.iterator = new GenericIteratorWrapper<E>(iterator); - } - - public Iterator<E> iterator() { - if (this.iterator == null) { - throw new IllegalStateException("This method has already been called."); //$NON-NLS-1$ - } - Iterator<E> result = this.iterator; - this.iterator = null; - return result; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterator); - } - - } - - - // ********** java.util.Collections enhancements ********** - - /** - * Return the destination list after the source list has been copied into it. - * @see java.util.Collections#copy(java.util.List, java.util.List) - */ - public static <E> List<? super E> copy(List<? super E> dest, List<? extends E> src) { - Collections.copy(dest, src); - return dest; - } - - /** - * Return the list after it has been "filled". - * @see java.util.Collections#fill(java.util.List, java.lang.Object) - */ - public static <E> List<? super E> fill(List<? super E> list, E value) { - Collections.fill(list, value); - return list; - } - - /** - * Return the list after it has been "reversed". - * @see java.util.Collections#reverse(java.util.List) - */ - public static <E> List<E> reverse(List<E> list) { - Collections.reverse(list); - return list; - } - - /** - * Return the list after it has been "rotated" by one position. - * @see java.util.Collections#rotate(java.util.List, int) - */ - public static <E> List<E> rotate(List<E> list) { - return rotate(list, 1); - } - - /** - * Return the list after it has been "rotated". - * @see java.util.Collections#rotate(java.util.List, int) - */ - public static <E> List<E> rotate(List<E> list, int distance) { - Collections.rotate(list, distance); - return list; - } - - /** - * Return the list after it has been "shuffled". - * @see java.util.Collections#shuffle(java.util.List) - */ - public static <E> List<E> shuffle(List<E> list) { - Collections.shuffle(list); - return list; - } - - /** - * Return the list after it has been "shuffled". - * @see java.util.Collections#shuffle(java.util.List, java.util.Random) - */ - public static <E> List<E> shuffle(List<E> list, Random random) { - Collections.shuffle(list, random); - return list; - } - - /** - * Return the list after it has been "sorted". - * @see java.util.Collections#sort(java.util.List) - */ - public static <E extends Comparable<? super E>> List<E> sort(List<E> list) { - Collections.sort(list); - return list; - } - - /** - * Return the list after it has been "sorted". - * @see java.util.Collections#sort(java.util.List, java.util.Comparator) - */ - public static <E> List<E> sort(List<E> list, Comparator<? super E> comparator) { - Collections.sort(list, comparator); - return list; - } - - /** - * Return the iterable after it has been "sorted". - */ - public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) { - return sort(iterable, null); - } - - /** - * Return the iterable after it has been "sorted". - */ - public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) { - return sort(list(iterable), comparator); - } - - /** - * Return the iterator after it has been "sorted". - */ - public static <E extends Comparable<? super E>> Iterator<E> sort(Iterator<? extends E> iterator) { - return sort(iterator, null); - } - - /** - * Return the iterator after it has been "sorted". - */ - public static <E> Iterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator) { - return sort(list(iterator), comparator).iterator(); - } - - /** - * Return the list after the specified elements have been "swapped". - * @see java.util.Collections#swap(java.util.List, int, int) - */ - public static <E> List<E> swap(List<E> list, int i, int j) { - Collections.swap(list, i, j); - return list; - } - - - // ********** java.util.Arrays enhancements ********** - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(boolean[], boolean) - */ - public static boolean[] fill(boolean[] array, boolean value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(boolean[], int, int, boolean) - */ - public static boolean[] fill(boolean[] array, int fromIndex, int toIndex, boolean value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(byte[], byte) - */ - public static byte[] fill(byte[] array, byte value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(byte[], int, int, byte) - */ - public static byte[] fill(byte[] array, int fromIndex, int toIndex, byte value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(char[], char) - */ - public static char[] fill(char[] array, char value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(char[], int, int, char) - */ - public static char[] fill(char[] array, int fromIndex, int toIndex, char value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(double[], double) - */ - public static double[] fill(double[] array, double value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(double[], int, int, double) - */ - public static double[] fill(double[] array, int fromIndex, int toIndex, double value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(float[], float) - */ - public static float[] fill(float[] array, float value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(float[], int, int, float) - */ - public static float[] fill(float[] array, int fromIndex, int toIndex, float value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(int[], int) - */ - public static int[] fill(int[] array, int value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(int[], int, int, int) - */ - public static int[] fill(int[] array, int fromIndex, int toIndex, int value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(Object[], Object) - */ - public static <E> E[] fill(E[] array, E value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(Object[], int, int, Object) - */ - public static <E> E[] fill(E[] array, int fromIndex, int toIndex, E value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(long[], long) - */ - public static long[] fill(long[] array, long value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(long[], int, int, long) - */ - public static long[] fill(long[] array, int fromIndex, int toIndex, long value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(short[], short) - */ - public static short[] fill(short[] array, short value) { - Arrays.fill(array, value); - return array; - } - - /** - * Return the array after it has been "filled". - * @see java.util.Arrays#fill(short[], int, int, short) - */ - public static short[] fill(short[] array, int fromIndex, int toIndex, short value) { - Arrays.fill(array, fromIndex, toIndex, value); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(byte[]) - */ - public static byte[] sort(byte... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(byte[], int, int) - */ - public static byte[] sort(byte[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(char[]) - */ - public static char[] sort(char... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(char[], int, int) - */ - public static char[] sort(char[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(double[]) - */ - public static double[] sort(double... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(double[], int, int) - */ - public static double[] sort(double[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(float[]) - */ - public static float[] sort(float... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(float[], int, int) - */ - public static float[] sort(float[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(int[]) - */ - public static int[] sort(int... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(int[], int, int) - */ - public static int[] sort(int[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(Object[]) - */ - public static <E> E[] sort(E... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(Object[], java.util.Comparator) - */ - public static <E> E[] sort(E[] array, Comparator<? super E> comparator) { - Arrays.sort(array, comparator); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(Object[], int, int) - */ - public static <E> E[] sort(E[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(Object[], int, int, java.util.Comparator) - */ - public static <E> E[] sort(E[] array, int fromIndex, int toIndex, Comparator<? super E> comparator) { - Arrays.sort(array, fromIndex, toIndex, comparator); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(long[]) - */ - public static long[] sort(long... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(long[], int, int) - */ - public static long[] sort(long[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(short[]) - */ - public static short[] sort(short... array) { - Arrays.sort(array); - return array; - } - - /** - * Return the array after it has been "sorted". - * @see java.util.Arrays#sort(short[], int, int) - */ - public static short[] sort(short[] array, int fromIndex, int toIndex) { - Arrays.sort(array, fromIndex, toIndex); - return array; - } - - - // ********** constructor ********** - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private CollectionTools() { - super(); - throw new UnsupportedOperationException(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandRunnable.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandRunnable.java deleted file mode 100644 index c2bd4e23fe..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandRunnable.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import org.eclipse.jpt.utility.Command; - -/** - * Wrap a Command so it can be used as a Runnable. - */ -public class CommandRunnable implements Runnable { - protected final Command command; - - public CommandRunnable(Command command) { - super(); - if (command == null) { - throw new NullPointerException(); - } - this.command = command; - } - - public void run() { - this.command.execute(); - } - - @Override - public String toString() { - return "Runnable[" + this.command.toString() +']'; //$NON-NLS-1$ - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Counter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Counter.java deleted file mode 100644 index fbe3cde738..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Counter.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; - -/** - * This class can be used wherever a mutable integer object is needed. - * It is a cross between an int and an Integer. It can be stored in a standard - * container (e.g. Collection) but can be modified. - */ -public final class Counter - implements Cloneable, Serializable -{ - private int count = 0; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a counter with the specified initial value. - */ - public Counter(int count) { - super(); - this.count = count; - } - - /** - * Construct a counter with an initial value of zero. - */ - public Counter() { - this(0); - } - - /** - * Return the current count of the counter. - */ - public synchronized int count() { - return this.count; - } - - /** - * Increment and return the current count of the counter. - */ - public synchronized int increment() { - return ++this.count; - } - - /** - * Increment and return the current count of the counter. - */ - public synchronized int increment(int increment) { - return this.count += increment; - } - - /** - * Derement and return the current count of the counter. - */ - public synchronized int decrement() { - return --this.count; - } - - /** - * Derement and return the current count of the counter. - */ - public synchronized int decrement(int decrement) { - return this.count -= decrement; - } - - @Override - public synchronized boolean equals(Object o) { - if ( ! (o instanceof Counter)) { - return false; - } - return this.count == ((Counter) o).count; - } - - @Override - public synchronized int hashCode() { - return this.count; - } - - @Override - public synchronized Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public synchronized String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(ClassTools.shortClassNameForObject(this)); - sb.append('('); - sb.append(this.count); - sb.append(')'); - return sb.toString(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/EmptyIterable.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/EmptyIterable.java deleted file mode 100644 index 1f90f3d4f0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/EmptyIterable.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; - -/** - * An <code>EmptyIterable</code> is just that. - */ -public final class EmptyIterable<E> - implements Iterable<E> -{ - - // singleton - @SuppressWarnings("unchecked") - private static final EmptyIterable INSTANCE = new EmptyIterable(); - - /** - * Return the singleton. - */ - @SuppressWarnings("unchecked") - public static <T> Iterable<T> instance() { - return INSTANCE; - } - - /** - * Ensure single instance. - */ - private EmptyIterable() { - super(); - } - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/FileTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/FileTools.java deleted file mode 100644 index 44154c4ed5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/FileTools.java +++ /dev/null @@ -1,1006 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.channels.FileChannel; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; - -/** - * Assorted file tools: - * - delete entire trees of directories and files - * - build iterators on entire trees of directories and files - * - build a temporary directory - * - "canonize" files - */ -public final class FileTools { - - public static final String USER_HOME_DIRECTORY_NAME = System.getProperty("user.home"); - public static final String USER_TEMPORARY_DIRECTORY_NAME = System.getProperty("java.io.tmpdir"); - public static String DEFAULT_TEMPORARY_DIRECTORY_NAME = "tmpdir"; - public static final String CURRENT_WORKING_DIRECTORY_NAME = System.getProperty("user.dir"); - - /** A list of some invalid file name characters. - : is the filename separator in MacOS and the drive indicator in DOS - * is a DOS wildcard character - | is a DOS redirection character - & is our own escape character - / is the filename separator in Unix and the command option tag in DOS - \ is the filename separator in DOS/Windows and the escape character in Unix - ; is ??? - ? is a DOS wildcard character - [ is ??? - ] is ??? - = is ??? - + is ??? - < is a DOS redirection character - > is a DOS redirection character - " is used by DOS to delimit file names with spaces - , is ??? - */ - public static final char[] INVALID_FILENAME_CHARACTERS = { ':', '*', '|', '&', '/', '\\', ';', '?', '[', ']', '=', '+', '<', '>', '"', ',' }; - - /** This encoder will convert strings into valid file names. */ - public static final XMLStringEncoder FILE_NAME_ENCODER = new XMLStringEncoder(INVALID_FILENAME_CHARACTERS); - - /** Windows files that are redirected to devices etc. */ - private static final String[] WINDOWS_RESERVED_FILE_NAMES = { - "con", - "aux", - "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", - "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", - "prn", - "nul" - }; - - /** The default length of a shortened file name. */ - public static final int MAXIMUM_SHORTENED_FILE_NAME_LENGTH = 60; - - - // ********** deleting directories ********** - - /** - * Delete the specified directory and all of its contents. - * <em>USE WITH CARE.</em> - * File#deleteAll()? - */ - public static void deleteDirectory(String directoryName) { - deleteDirectory(new File(directoryName)); - } - - /** - * Delete the specified directory and all of its contents. - * <em>USE WITH CARE.</em> - * File#deleteAll()? - */ - public static void deleteDirectory(File directory) { - deleteDirectoryContents(directory); - if ( ! directory.delete()) { - throw new RuntimeException("unable to delete directory: " + directory.getAbsolutePath()); - } - } - - /** - * Delete the contents of the specified directory - * (but not the directory itself). - * <em>USE WITH CARE.</em> - * File#deleteFiles() - */ - public static void deleteDirectoryContents(String directoryName) { - deleteDirectoryContents(new File(directoryName)); - } - - /** - * Delete the contents of the specified directory - * (but not the directory itself). - * <em>USE WITH CARE.</em> - * File#deleteFiles() - */ - public static void deleteDirectoryContents(File directory) { - for (File file : directory.listFiles()) { - if (file.isDirectory()) { - deleteDirectory(file); // recurse through subdirectories - } else { - if ( ! file.delete()) { - throw new RuntimeException("unable to delete file: " + file.getAbsolutePath()); - } - } - } - } - - - // ********** copying files ********** - - /** - * Copies the content of the source file to the destination file. - * File#copy(File destinationFile) - */ - public static void copyToFile(File sourceFile, File destinationFile) - throws IOException - { - FileChannel sourceChannel = new FileInputStream(sourceFile).getChannel(); - FileChannel destinationChannel = new FileOutputStream(destinationFile).getChannel(); - try { - destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size()); - } finally { - sourceChannel.close(); - destinationChannel.close(); - } - } - - /** - * Copies the content of the source file to a file by - * the same name in the destination directory. - * File#copyToDirectory(File destinationDirectory) - */ - public static void copyToDirectory(File sourceFile, File destinationDirectory) - throws IOException - { - File destinationFile = new File(destinationDirectory, sourceFile.getName()); - destinationFile.createNewFile(); - copyToFile(sourceFile, destinationFile); - } - - - // ********** iteratoring over files and directories ********** - - /** - * Return an iterator on all the files in the specified directory. - * The iterator will skip over subdirectories. - * File#files() - */ - public static Iterator<File> filesIn(String directoryName) { - return filesIn(new File(directoryName)); - } - - /** - * Return an iterator on all the files in the specified directory. - * The iterator will skip over subdirectories. - * File#files() - */ - public static Iterator<File> filesIn(File directory) { - return filesIn(directory.listFiles()); - } - - private static Iterator<File> filesIn(File[] files) { - return new FilteringIterator<File, File>(new ArrayIterator<File>(files)) { - @Override - protected boolean accept(File next) { - return next.isFile(); - } - }; - } - - /** - * Return an iterator on all the subdirectories - * in the specified directory. - * File#subDirectories() - */ - public static Iterator<File> directoriesIn(String directoryName) { - return directoriesIn(new File(directoryName)); - } - - /** - * Return an iterator on all the subdirectories - * in the specified directory. - * File#subDirectories() - */ - public static Iterator<File> directoriesIn(File directory) { - return directoriesIn(directory.listFiles()); - } - - private static Iterator<File> directoriesIn(File[] files) { - return new FilteringIterator<File, File>(new ArrayIterator<File>(files)) { - @Override - protected boolean accept(File next) { - return next.isDirectory(); - } - }; - } - - /** - * Return an iterator on all the files under the specified - * directory, recursing into subdirectories. - * The iterator will skip over the subdirectories themselves. - * File#filesRecurse() - */ - public static Iterator<File> filesInTree(String directoryName) { - return filesInTree(new File(directoryName)); - } - - /** - * Return an iterator on all the files under the specified - * directory, recursing into subdirectories. - * The iterator will skip over the subdirectories themselves. - * File#filesRecurse() - */ - public static Iterator<File> filesInTree(File directory) { - return filesInTreeAsSet(directory).iterator(); - } - - private static Set<File> filesInTreeAsSet(File directory) { - Set<File> files = new HashSet<File>(10000); - addFilesInTreeTo(directory, files); - return files; - } - - private static void addFilesInTreeTo(File directory, Collection<File> allFiles) { - for (File file : directory.listFiles()) { - if (file.isFile()) { - allFiles.add(file); - } else if (file.isDirectory()) { - addFilesInTreeTo(file, allFiles); - } - } - } - - /** - * Return an iterator on all the directories under the specified - * directory, recursing into subdirectories. - * File#subDirectoriesRecurse() - */ - public static Iterator<File> directoriesInTree(String directoryName) { - return directoriesInTree(new File(directoryName)); - } - - /** - * Return an iterator on all the directories under the specified - * directory, recursing into subdirectories. - * File#subDirectoriesRecurse() - */ - @SuppressWarnings("unchecked") - public static Iterator<File> directoriesInTree(File directory) { - File[] files = directory.listFiles(); - return new CompositeIterator<File>(directoriesIn(files), directoriesInTrees(directoriesIn(files))); - } - - private static Iterator<File> directoriesInTrees(Iterator<File> directories) { - return new CompositeIterator<File>( - new TransformationIterator<File, Iterator<File>>(directories) { - @Override - protected Iterator<File> transform(File next) { - return FileTools.directoriesInTree(next); - } - } - ); - } - - - // ********** short file name manipulation ********** - - /** - * Strip the extension from the specified file name - * and return the result. If the file name has no - * extension, it is returned unchanged - * File#basePath() - */ - public static String stripExtension(String fileName) { - int index = fileName.lastIndexOf('.'); - if (index == -1) { - return fileName; - } - return fileName.substring(0, index); - } - - /** - * Strip the extension from the specified file's name - * and return the result. If the file's name has no - * extension, it is returned unchanged - * File#basePath() - */ - public static String stripExtension(File file) { - return stripExtension(file.getPath()); - } - - /** - * Return the extension, including the dot, of the specified file name. - * If the file name has no extension, return an empty string. - * File#extension() - */ - public static String extension(String fileName) { - int index = fileName.lastIndexOf('.'); - if (index == -1) { - return ""; - } - return fileName.substring(index); - } - - /** - * Return the extension, including the dot, of the specified file's name. - * If the file's name has no extension, return an empty string. - * File#extension() - */ - public static String extension(File file) { - return extension(file.getPath()); - } - - - // ********** temporary directories ********** - - /** - * Build and return an empty temporary directory with the specified - * name. If the directory already exists, it will be cleared out. - * This directory will be a subdirectory of the Java temporary directory, - * as indicated by the System property "java.io.tmpdir". - */ - public static File emptyTemporaryDirectory(String name) { - File dir = new File(userTemporaryDirectory(), name); - if (dir.exists()) { - deleteDirectoryContents(dir); - } else { - dir.mkdirs(); - } - return dir; - } - - /** - * Build and return an empty temporary directory with a - * name of "tmpdir". If the directory already exists, it will be cleared out. - * This directory will be a subdirectory of the Java temporary directory, - * as indicated by the System property "java.io.tmpdir". - */ - public static File emptyTemporaryDirectory() { - return emptyTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME); - } - - /** - * Build and return a temporary directory with the specified - * name. If the directory already exists, it will be left unchanged; - * if it does not already exist, it will be created. - * This directory will be a subdirectory of the Java temporary directory, - * as indicated by the System property "java.io.tmpdir". - */ - public static File temporaryDirectory(String name) { - File dir = new File(userTemporaryDirectory(), name); - if ( ! dir.exists()) { - dir.mkdirs(); - } - return dir; - } - - /** - * Build and return a temporary directory with a name of - * "tmpdir". If the directory already exists, it will be left unchanged; - * if it does not already exist, it will be created. - * This directory will be a subdirectory of the Java temporary directory, - * as indicated by the System property "java.io.tmpdir". - */ - public static File temporaryDirectory() { - return temporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME); - } - - /** - * Build and return a *new* temporary directory with the specified - * prefix. The prefix will be appended with a number that - * is incremented, starting with 1, until a non-pre-existing directory - * is found and successfully created. This directory will be a - * subdirectory of the Java temporary directory, as indicated by - * the System property "java.io.tmpdir". - */ - public static File newTemporaryDirectory(String prefix) { - if ( ! prefix.endsWith(".")) { - prefix = prefix + "."; - } - File dir; - int i = 0; - do { - i++; - dir = new File(userTemporaryDirectory(), prefix + i); - } while ( ! dir.mkdirs()); - return dir; - } - - /** - * Build and return a *new* temporary directory with a - * prefix of "tmpdir". This prefix will be appended with a number that - * is incremented, starting with 1, until a non-pre-existing directory - * is found and successfully created. This directory will be a - * subdirectory of the Java temporary directory, as indicated by - * the System property "java.io.tmpdir". - */ - public static File newTemporaryDirectory() { - return newTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME); - } - - - // ********** resource files ********** - - /** - * Build and return a file for the specified resource. - * The resource name must be fully-qualified, i.e. it cannot be relative - * to the package name/directory. - * NB: There is a bug in jdk1.4.x the prevents us from getting - * a resource that has spaces (or other special characters) in - * its name.... (see Sun's Java bug 4466485) - */ - public static File resourceFile(String resourceName) throws URISyntaxException { - if ( ! resourceName.startsWith("/")) { - throw new IllegalArgumentException(resourceName); - } - return resourceFile(resourceName, FileTools.class); - } - - /** - * Build and return a file for the specified resource. - * NB: There is a bug in jdk1.4.x the prevents us from getting - * a resource that has spaces (or other special characters) in - * its name.... (see Sun's Java bug 4466485) - */ - public static File resourceFile(String resourceName, Class<?> javaClass) throws URISyntaxException { - URL url = javaClass.getResource(resourceName); - return buildFile(url); - } - - /** - * Build and return a file for the specified URL. - * NB: There is a bug in jdk1.4.x the prevents us from getting - * a resource that has spaces (or other special characters) in - * its name.... (see Sun's Java bug 4466485) - */ - public static File buildFile(URL url) throws URISyntaxException { - return buildFile(url.getFile()); - } - - /** - * Build and return a file for the specified file name. - * NB: There is a bug in jdk1.4.x the prevents us from getting - * a resource that has spaces (or other special characters) in - * its name.... (see Sun's Java bug 4466485) - */ - public static File buildFile(String fileName) throws URISyntaxException { - URI uri = new URI(fileName); - File file = new File(uri.getPath()); - return file; - } - - - // ********** "canonical" files ********** - - /** - * Convert the specified file into a "canonical" file. - */ - public static File canonicalFile(File file) { - try { - return file.getCanonicalFile(); - } catch (IOException ioexception) { - // settle for the absolute file - return file.getAbsoluteFile(); - } - } - - /** - * Build an iterator that will convert the specified files - * into "canonical" files. - */ - public static Iterator<File> canonicalFiles(Iterator<File> files) { - return new TransformationIterator<File, File>(files) { - @Override - protected File transform(File next) { - return canonicalFile(next); - } - }; - } - - /** - * Build an iterator that will convert the specified files - * into "canonical" files. - */ - public static Iterator<File> canonicalFiles(Collection<File> files) { - return canonicalFiles(files.iterator()); - } - - /** - * Convert the specified file name into a "canonical" file name. - */ - public static String canonicalFileName(String fileName) { - return canonicalFile(new File(fileName)).getAbsolutePath(); - } - - /** - * Build an iterator that will convert the specified file names - * into "canonical" file names. - */ - public static Iterator<String> canonicalFileNames(Iterator<String> fileNames) { - return new TransformationIterator<String, String>(fileNames) { - @Override - protected String transform(String next) { - return canonicalFileName(next); - } - }; - } - - /** - * Build an iterator that will convert the specified file names - * into "canonical" file names. - */ - public static Iterator<String> canonicalFileNames(Collection<String> fileNames) { - return canonicalFileNames(fileNames.iterator()); - } - - - // ********** file name validation ********** - - /** - * Return whether the specified file name is invalid. - */ - public static boolean fileNameIsInvalid(String filename) { - return ! fileNameIsValid(filename); - } - - /** - * Return whether the specified file name is valid. - */ - public static boolean fileNameIsValid(String filename) { - int len = filename.length(); - for (int i = 0; i < len; i++) { - char filenameChar = filename.charAt(i); - if (CollectionTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) { - return false; - } - } - return true; - } - - /** - * Convert the illegal characters in the specified file name to - * the specified character and return the result. - */ - public static String convertToValidFileName(String filename, char replacementChar) { - int len = filename.length(); - StringBuilder sb = new StringBuilder(len); - for (int i = 0; i < len; i++) { - char filenameChar = filename.charAt(i); - if (CollectionTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) { - sb.append(replacementChar); - } else { - sb.append(filenameChar); - } - } - return sb.toString(); - } - - /** - * Convert the illegal characters in the specified file name to - * periods ('.') and return the result. - */ - public static String convertToValidFileName(String filename) { - return convertToValidFileName(filename, '.'); - } - - /** - * Return whether the specified file name is "reserved" - * (i.e. it cannot be used for "user" files). Windows reserves - * a number of file names (e.g. CON, AUX, PRN). - */ - public static boolean fileNameIsReserved(String fileName) { - if (executingOnWindows()) { - return CollectionTools.contains(WINDOWS_RESERVED_FILE_NAMES, fileName.toLowerCase()); - } - return false; // Unix does not have any "reserved" file names (I think...) - } - - /** - * Return whether the specified file contains any "reserved" - * components. - * Windows reserves a number of file names (e.g. CON, AUX, PRN); - * and these file names cannot be used for either the names of - * files or directories. - */ - public static boolean fileHasAnyReservedComponents(File file) { - File temp = file; - while (temp != null) { - if (fileNameIsReserved(temp.getName())) { - return true; - } - temp = temp.getParentFile(); - } - return false; - } - - - // ********** shortened file names ********** - - /** - * Return a shorter version of the absolute file name for the specified file. - * The shorter version will not be longer than the maximum length. - * The first directory (usually the drive letter) and the file name or the - * last directory will always be added to the generated string regardless of - * the maximum length allowed. - */ - public static String shortenFileName(URL url) { - return shortenFileName(url, MAXIMUM_SHORTENED_FILE_NAME_LENGTH); - } - - /** - * Return a shorter version of the absolute file name for the specified file. - * The shorter version will not be longer than the maximum length. - * The first directory (usually the drive letter) and the file name or the - * last directory will always be added to the generated string regardless of - * the maximum length allowed. - */ - public static String shortenFileName(URL url, int maxLength) { - File file; - try { - file = buildFile(url); - } catch (URISyntaxException e) { - file = new File(url.getFile()); - } - return shortenFileName(file, maxLength); - } - - /** - * Return a shorter version of the absolute file name for the specified file. - * The shorter version will not be longer than the maximum length. - * The first directory (usually the drive letter) and the file name or the - * last directory will always be added to the generated string regardless of - * the maximum length allowed. - */ - public static String shortenFileName(File file) { - return shortenFileName(file, MAXIMUM_SHORTENED_FILE_NAME_LENGTH); - } - - /** - * Return a shorter version of the absolute file name for the specified file. - * The shorter version will not be longer than the maximum length. - * The first directory (usually the drive letter) and the file name or the - * last directory will always be added to the generated string regardless of - * the maximum length allowed. - */ - public static String shortenFileName(File file, int maxLength) { - String absoluteFileName = canonicalFile(file).getAbsolutePath(); - if (absoluteFileName.length() <= maxLength) { - // no need to shorten - return absoluteFileName; - } - - // break down the path into its components - String fs = File.separator; - String[] paths = absoluteFileName.split("\\" + fs); - - if (paths.length <= 1) { - // e.g. "C:\" - return paths[0]; - } - - if (paths.length == 2) { - // e.g. "C:\MyReallyLongFileName.ext" or "C:\MyReallyLongDirectoryName" - // return the complete file name since this is a minimum requirement, - // regardless of the maximum length allowed - return absoluteFileName; - } - - StringBuilder sb = new StringBuilder(); - sb.append(paths[0]); // always add the first directory, which is usually the drive letter - - // Keep the index of insertion into the string buffer - int insertIndex = sb.length(); - - sb.append(fs); - sb.append(paths[paths.length - 1]); // append the file name or the last directory - - maxLength -= 4; // -4 for "/..." - - int currentLength = sb.length() - 4; // -4 for "/..." - int leftIndex = 1; // 1 to skip the root directory - int rightIndex = paths.length - 2; // -1 for the file name or the last directory - - boolean canAddFromLeft = true; - boolean canAddFromRight = true; - - // Add each directory, the insertion is going in both direction: left and - // right, once a side can't be added, the other side is still continuing - // until both can't add anymore - while (true) { - if (!canAddFromLeft && !canAddFromRight) - break; - - if (canAddFromRight) { - String rightDirectory = paths[rightIndex]; - int rightLength = rightDirectory.length(); - - // Add the directory on the right side of the loop - if (currentLength + rightLength + 1 <= maxLength) { - sb.insert(insertIndex, fs); - sb.insert(insertIndex + 1, rightDirectory); - - currentLength += rightLength + 1; - rightIndex--; - - // The right side is now overlapping the left side, that means - // we can't add from the right side anymore - if (leftIndex >= rightIndex) { - canAddFromRight = false; - } - } else { - canAddFromRight = false; - } - } - - if (canAddFromLeft) { - String leftDirectory = paths[leftIndex]; - int leftLength = leftDirectory.length(); - - // Add the directory on the left side of the loop - if (currentLength + leftLength + 1 <= maxLength) { - sb.insert(insertIndex, fs); - sb.insert(insertIndex + 1, leftDirectory); - - insertIndex += leftLength + 1; - currentLength += leftLength + 1; - leftIndex++; - - // The left side is now overlapping the right side, that means - // we can't add from the left side anymore - if (leftIndex >= rightIndex) { - canAddFromLeft = false; - } - } else { - canAddFromLeft = false; - } - } - } - - if (leftIndex <= rightIndex) { - sb.insert(insertIndex, fs); - sb.insert(insertIndex + 1, "..."); - } - - return sb.toString(); - } - - - // ********** system properties ********** - - /** - * Return a file representing the user's home directory. - */ - public static File userHomeDirectory() { - return new File(USER_HOME_DIRECTORY_NAME); - } - - /** - * Return a file representing the user's temporary directory. - */ - public static File userTemporaryDirectory() { - return new File(USER_TEMPORARY_DIRECTORY_NAME); - } - - /** - * Return a file representing the current working directory. - */ - public static File currentWorkingDirectory() { - return new File(CURRENT_WORKING_DIRECTORY_NAME); - } - - - // ********** miscellaneous ********** - - private static boolean executingOnWindows() { - return executingOn("Windows"); - } - -// private static boolean executingOnLinux() { -// return executingOn("Linux"); -// } -// - private static boolean executingOn(String osName) { - return System.getProperty("os.name").indexOf(osName) != -1; - } - - /** - * Return only the files that fit the filter. - * File#files(FileFilter fileFilter) - */ - public static Iterator<File> filter(Iterator<File> files, final FileFilter fileFilter) { - return new FilteringIterator<File, File>(files) { - @Override - protected boolean accept(File next) { - return fileFilter.accept(next); - } - }; - } - - /** - * Return a file that is a re-specification of the specified - * file, relative to the specified directory. - * Linux/Unix/Mac: - * convertToRelativeFile(/foo/bar/baz.java, /foo) - * => bar/baz.java - * Windows: - * convertToRelativeFile(C:\foo\bar\baz.java, C:\foo) - * => bar/baz.java - * The file can be either a file or a directory; the directory - * *should* be a directory. - * If the file is already relative or it cannot be made relative - * to the directory, it will be returned unchanged. - * - * NB: This method has been tested on Windows and Linux, - * but not Mac (but the Mac is Unix-based these days, so - * it shouldn't be a problem...). - */ - public static File convertToRelativeFile(final File file, final File dir) { - // check whether the file is already relative - if ( ! file.isAbsolute()) { - return file; // return unchanged - } - - File cFile = canonicalFile(file); - File cDir = canonicalFile(dir); - - // the two are the same directory - if (cFile.equals(cDir)) { - return new File("."); - } - - File[] filePathFiles = pathFiles(cFile); - File[] dirPathFiles = pathFiles(cDir); - - // Windows only (?): the roots are different - e.g. D:\ vs. C:\ - if ( ! dirPathFiles[0].equals(filePathFiles[0])) { - return file; // return unchanged - } - - // at this point we know the root is the same, now find how much is in common - int i = 0; // this will point at the first miscompare - while ((i < dirPathFiles.length) && (i < filePathFiles.length)) { - if (dirPathFiles[i].equals(filePathFiles[i])) { - i++; - } else { - break; - } - } - // save our current position - int firstMismatch = i; - - // check whether the file is ABOVE the directory: ../.. - if (firstMismatch == filePathFiles.length) { - return relativeParentFile(dirPathFiles.length - firstMismatch); - } - - // build a new file from the path beyond the matching portions - File diff = new File(filePathFiles[i].getName()); - while (++i < filePathFiles.length) { - diff = new File(diff, filePathFiles[i].getName()); - } - - // check whether the file is BELOW the directory: subdir1/subdir2/file.ext - if (firstMismatch == dirPathFiles.length) { - return diff; - } - - // the file must be a PEER of the directory: ../../subdir1/subdir2/file.ext - return new File(relativeParentFile(dirPathFiles.length - firstMismatch), diff.getPath()); - } - - /** - * Return a file that is a re-specification of the specified - * file, relative to the current working directory. - * Linux/Unix/Mac (CWD = /foo): - * convertToRelativeFile(/foo/bar/baz.java) - * => bar/baz.java - * Windows (CWD = C:\foo): - * convertToRelativeFile(C:\foo\bar\baz.java) - * => bar/baz.java - * The file can be either a file or a directory. - * If the file is already relative or it cannot be made relative - * to the directory, it will be returned unchanged. - * - * NB: This method has been tested on Windows and Linux, - * but not Mac (but the Mac is Unix-based these days, so - * it shouldn't be a problem...). - */ - public static File convertToRelativeFile(final File file) { - return convertToRelativeFile(file, currentWorkingDirectory()); - } - - /** - * Return an array of files representing the path to the specified - * file. For example: - * C:/foo/bar/baz.txt => - * { C:/, C:/foo, C:/foo/bar, C:/foo/bar/baz.txt } - */ - private static File[] pathFiles(File file) { - List<File> path = new ArrayList<File>(); - for (File f = file; f != null; f = f.getParentFile()) { - path.add(f); - } - Collections.reverse(path); - return path.toArray(new File[path.size()]); - } - - /** - * Return a file with the specified (non-zero) number of relative - * file names, e.g. xxx(3) => ../../.. - */ - private static File relativeParentFile(int len) { - if (len <= 0) { - throw new IllegalArgumentException("length must be greater than zero: " + len); - } - File result = new File(".."); - for (int i = len - 1; i-- > 0; ) { - result = new File(result, ".."); - } - return result; - } - - /** - * Return a file that is a re-specification of the specified - * file, absolute to the specified directory. - * Linux/Unix/Mac: - * convertToAbsoluteFile(bar/baz.java, /foo) - * => /foo/bar/baz.java - * Windows: - * convertToAbsoluteFile(bar/baz.java, C:\foo) - * => C:\foo\bar\baz.java - * The file can be either a file or a directory; the directory - * *should* be a directory. - * If the file is already absolute, it will be returned unchanged. - * - * NB: This method has been tested on Windows and Linux, - * but not Mac (but the Mac is Unix-based these days, so - * it shouldn't be a problem...). - */ - public static File convertToAbsoluteFile(final File file, final File dir) { - // check whether the file is already absolute - if (file.isAbsolute()) { - return file; // return unchanged - } - return canonicalFile(new File(dir, file.getPath())); - } - - /** - * Return a file that is a re-specification of the specified - * file, absolute to the current working directory. - * Linux/Unix/Mac (CWD = /foo): - * convertToAbsoluteFile(bar/baz.java) - * => /foo/bar/baz.java - * Windows (CWD = C:\foo): - * convertToAbsoluteFile(bar/baz.java) - * => C:\foo\bar\baz.java - * The file can be either a file or a directory. - * If the file is already absolute, it will be returned unchanged. - * - * NB: This method has been tested on Windows and Linux, - * but not Mac (but the Mac is Unix-based these days, so - * it shouldn't be a problem...). - */ - public static File convertToAbsoluteFile(final File file) { - return convertToAbsoluteFile(file, currentWorkingDirectory()); - } - - - // ********** constructor ********** - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private FileTools() { - super(); - throw new UnsupportedOperationException(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java deleted file mode 100644 index ccf3c54d2f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java +++ /dev/null @@ -1,914 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * This class implements the <code>Bag</code> interface, backed by a - * hash table. It makes no guarantees as to the iteration order of - * the bag's elements; in particular, it does not guarantee that the order - * will remain constant over time. This class permits the <code>null</code> - * element. - * <p> - * This class offers constant time performance for the basic operations - * (<code>add</code>, <code>remove</code>, <code>contains</code> and - * <code>size</code>), assuming the hash function disperses the elements - * properly among the buckets. Iterating over this bag requires time - * proportional to the sum of the bag's size (the number of elements) plus the - * "capacity" of the backing hash table (the number of buckets). Thus, it is - * important not to set the initial capacity too high (or the load factor too - * low) if iteration performance is important. - * <p> - * <b>Note that this implementation is not synchronized.</b> If multiple - * threads access a bag concurrently, and at least one of the threads modifies - * the bag, it <i>must</i> be synchronized externally. This is typically - * accomplished by synchronizing on some object that naturally encapsulates - * the bag. If no such object exists, the bag should be "wrapped" using the - * <code>Collections.synchronizedCollection</code> method. This is - * best done at creation time, to prevent accidental unsynchronized access - * to the bag: - * <pre> - * Collection c = Collections.synchronizedCollection(new HashBag(...)); - * </pre> - * <p> - * The iterators returned by this class's <code>iterator</code> method are - * <i>fail-fast</i>: if the bag is modified at any time after the iterator is - * created, in any way except through the iterator's own <code>remove</code> - * method, the iterator throws a <code>ConcurrentModificationException</code>. - * Thus, in the face of concurrent modification, the iterator fails quickly - * and cleanly, rather than risking arbitrary, non-deterministic behavior at - * an undetermined time in the future. - * - * @see Collections#synchronizedCollection(Collection) - */ -public class HashBag<E> - extends AbstractCollection<E> - implements Bag<E>, Cloneable, Serializable -{ - - /** The hash table. */ - transient Entry<E>[] table; - - /** The total number of entries in the bag. */ - transient int count = 0; - - /** The number of unique entries in the bag. */ - transient int uniqueCount = 0; - - /** - * The hash table is rehashed when its size exceeds this threshold. (The - * value of this field is (int)(capacity * loadFactor).) - * - * @serial - */ - private int threshold; - - /** - * The load factor for the hash table. - * - * @serial - */ - private float loadFactor; - - /** - * The number of times this bag has been structurally modified. - * Structural modifications are those that change the number of entries in - * the bag or otherwise modify its internal structure (e.g. rehash). - * This field is used to make iterators on this bag fail-fast. - * - * @see java.util.ConcurrentModificationException - */ - transient int modCount = 0; - - /** - * Constructs a new, empty bag with the - * default capacity, which is 11, and load factor, which is 0.75. - */ - public HashBag() { - this(11, 0.75f); - } - - /** - * Constructs a new, empty bag with the specified initial capacity - * and default load factor, which is 0.75. - * - * @param initialCapacity the initial capacity of the backing map. - * @throws IllegalArgumentException if the initial capacity is less - * than zero. - */ - public HashBag(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty bag with - * the specified initial capacity and the specified load factor. - * - * @param initialCapacity the initial capacity of the backing map. - * @param loadFactor the load factor of the backing map. - * @throws IllegalArgumentException if the initial capacity is less - * than zero, or if the load factor is nonpositive. - */ - public HashBag(int initialCapacity, float loadFactor) { - if (initialCapacity < 0) { - throw new IllegalArgumentException("Illegal Initial Capacity: " + initialCapacity); - } - if (loadFactor <= 0 || Float.isNaN(loadFactor)) { - throw new IllegalArgumentException("Illegal Load factor: " + loadFactor); - } - if (initialCapacity == 0) { - initialCapacity = 1; - } - this.loadFactor = loadFactor; - this.table = this.buildTable(initialCapacity); - this.threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new bag containing the elements in the specified - * collection. The capacity of the bag is - * twice the size of the specified collection or 11 (whichever is - * greater), and the default load factor, which is 0.75, is used. - * - * @param c the collection whose elements are to be placed into this bag. - */ - public HashBag(Collection<? extends E> c) { - this(Math.max(2*c.size(), 11)); - this.addAll(c); - } - - /** - * This implementation simply returns the maintained count. - */ - @Override - public int size() { - return this.count; - } - - /** - * This implementation simply compares the maintained count to zero. - */ - @Override - public boolean isEmpty() { - return this.count == 0; - } - - /** - * This implementation searches for the object in the hash table by calculating - * the object's hash code and examining the entries in the corresponding hash - * table bucket. - */ - @Override - public boolean contains(Object o) { - Entry<E>[] tab = this.table; - if (o == null) { - for (Entry<E> e = tab[0]; e != null; e = e.next) { - if (e.object == null) { - return true; - } - } - } else { - int hash = o.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - return true; - } - } - } - return false; - } - - public int count(Object o) { - Entry<E>[] tab = this.table; - if (o == null) { - for (Entry<E> e = tab[0]; e != null; e = e.next) { - if (e.object == null) { - return e.count; - } - } - } else { - int hash = o.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - return e.count; - } - } - } - return 0; - } - - /** - * Rehashes the contents of this bag into a new hash table - * with a larger capacity. This method is called when the - * number of different elements in this map exceeds its - * capacity and load factor. - */ - private void rehash() { - Entry<E>[] oldMap = this.table; - int oldCapacity = oldMap.length; - - int newCapacity = oldCapacity * 2 + 1; - Entry<E>[] newTable = this.buildTable(newCapacity); - - this.modCount++; - this.threshold = (int) (newCapacity * this.loadFactor); - this.table = newTable; - - for (int i = oldCapacity; i-- > 0; ) { - for (Entry<E> old = oldMap[i]; old != null; ) { - Entry<E> e = old; - old = old.next; - - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } - } - } - - @SuppressWarnings("unchecked") - private Entry<E>[] buildTable(int capacity) { - return new Entry[capacity]; - } - - @SuppressWarnings("unchecked") - private <T> Entry<E> buildEntry(int hash, Object o, Entry<T> next) { - return new Entry(hash, o, next); - } - - @SuppressWarnings("unchecked") - private <T> Entry<E> buildEntry(int hash, Object o, int cnt, Entry<T> next) { - return new Entry(hash, o, cnt, next); - } - - /** - * This implementation searches for the object in the hash table by calculating - * the object's hash code and examining the entries in the corresponding hash - * table bucket. - */ - @Override - public boolean add(E o) { - this.modCount++; - Entry<E>[] tab = this.table; - int hash = 0; - int index = 0; - - // if the object is already in the bag, simply bump its count - if (o == null) { - for (Entry<E> e = tab[0]; e != null; e = e.next) { - if (e.object == null) { - e.count++; - this.count++; - return true; - } - } - } else { - hash = o.hashCode(); - index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - e.count++; - this.count++; - return true; - } - } - } - - // rehash the table if the threshold is exceeded - if (this.uniqueCount >= this.threshold) { - this.rehash(); - tab = this.table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // create the new entry and put it in the table - Entry<E> e = this.buildEntry(hash, o, tab[index]); - tab[index] = e; - this.count++; - this.uniqueCount++; - return true; - } - - /** - * This implementation searches for the object in the hash table by calculating - * the object's hash code and examining the entries in the corresponding hash - * table bucket. - */ - public boolean add(E o, int cnt) { - if (cnt <= 0) { - return false; - } - this.modCount++; - Entry<E>[] tab = this.table; - int hash = 0; - int index = 0; - - // if the object is already in the bag, simply bump its count - if (o == null) { - for (Entry<E> e = tab[0]; e != null; e = e.next) { - if (e.object == null) { - e.count += cnt; - this.count += cnt; - return true; - } - } - } else { - hash = o.hashCode(); - index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - e.count += cnt; - this.count += cnt; - return true; - } - } - } - - // rehash the table if the threshold is exceeded - if (this.uniqueCount >= this.threshold) { - this.rehash(); - tab = this.table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // create the new entry and put it in the table - Entry<E> e = this.buildEntry(hash, o, cnt, tab[index]); - tab[index] = e; - this.count += cnt; - this.uniqueCount++; - return true; - } - - /** - * This implementation searches for the object in the hash table by calculating - * the object's hash code and examining the entries in the corresponding hash - * table bucket. - */ - @Override - public boolean remove(Object o) { - Entry<E>[] tab = this.table; - if (o == null) { - for (Entry<E> e = tab[0], prev = null; e != null; prev = e, e = e.next) { - if (e.object == null) { - this.modCount++; - e.count--; - // if we are removing the last one, remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[0] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count--; - return true; - } - } - } else { - int hash = o.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - this.modCount++; - e.count--; - // if we are removing the last one, remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[index] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count--; - return true; - } - } - } - - return false; - } - - /** - * This implementation searches for the object in the hash table by calculating - * the object's hash code and examining the entries in the corresponding hash - * table bucket. - */ - public boolean remove(Object o, int cnt) { - if (cnt <= 0) { - return false; - } - Entry<E>[] tab = this.table; - if (o == null) { - for (Entry<E> e = tab[0], prev = null; e != null; prev = e, e = e.next) { - if (e.object == null) { - this.modCount++; - int cnt2 = (cnt < e.count) ? cnt : e.count; - e.count -= cnt2; - // if we are removing the last element(s), remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[0] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count -= cnt2; - return true; - } - } - } else { - int hash = o.hashCode(); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && o.equals(e.object)) { - this.modCount++; - int cnt2 = (cnt < e.count) ? cnt : e.count; - e.count -= cnt2; - // if we are removing the last element(s), remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[index] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count -= cnt2; - return true; - } - } - } - - return false; - } - - /** - * This implementation simply clears out all of the hash table buckets. - */ - @Override - public void clear() { - Entry<E>[] tab = this.table; - this.modCount++; - for (int i = tab.length; --i >= 0; ) { - tab[i] = null; - } - this.count = 0; - this.uniqueCount = 0; - } - - /** - * Returns a shallow copy of this bag: the elements - * themselves are not cloned. - * - * @return a shallow copy of this bag. - */ - @Override - public HashBag<E> clone() { - try { - @SuppressWarnings("unchecked") - HashBag<E> clone = (HashBag<E>) super.clone(); - clone.table = this.buildTable(this.table.length); - for (int i = this.table.length; i-- > 0; ) { - clone.table[i] = (this.table[i] == null) - ? null : (Entry<E>) this.table[i].clone(); - } - clone.modCount = 0; - return clone; - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } - } - - - /** - * Hash table collision list entry. - */ - private static class Entry<E> implements Bag.Entry<E> { - int hash; - E object; - int count; - Entry<E> next; - - Entry(int hash, E object, Entry<E> next) { - this(hash, object, 1, next); - } - - Entry(int hash, E object, int count, Entry<E> next) { - this.hash = hash; - this.object = object; - this.count = count; - this.next = next; - } - - /** - * Cascade the clone to all the entries in the same bucket. - */ - @Override - @SuppressWarnings("unchecked") - protected Entry<E> clone() { - return new Entry(this.hash, this.object, this.count, - (this.next == null ? null : this.next.clone())); - } - - // ***** Bag.Entry implementation - public E getElement() { - return this.object; - } - - public int getCount() { - return this.count; - } - - public int setCount(int count) { - if (count <= 0) { - throw new IllegalArgumentException("count must be greater than zero: " + count); - } - int old = this.count; - this.count = count; - return old; - } - - @Override - public boolean equals(Object o) { - if ( ! (o instanceof Bag.Entry)) { - return false; - } - @SuppressWarnings("unchecked") - Bag.Entry e = (Bag.Entry) o; - if (this.count != e.getCount()) { - return false; - } - Object o1 = this.object; - Object o2 = e.getElement(); - if (o1 == o2) { - return true; - } - if (o1 == null) { - return false; - } - return o1.equals(o2); - } - - @Override - public int hashCode() { - E o = this.object; - return (o == null) ? 0 : (this.count * o.hashCode()); - } - - @Override - public String toString() { - return this.object + "=>" + this.count; - } - } - - - @Override - @SuppressWarnings("unchecked") - public Iterator<E> iterator() { - return (this.count == 0) ? EMPTY_ITERATOR : new HashIterator(); - } - - @SuppressWarnings("unchecked") - public Iterator<E> uniqueIterator() { - return (this.count == 0) ? EMPTY_ITERATOR : new UniqueIterator(); - } - - @SuppressWarnings("unchecked") - public Iterator<Bag.Entry<E>> entries() { - return (this.count == 0) ? EMPTY_ITERATOR : new EntryIterator(); - } - - - /** - * Empty iterator that does just about nothing. - */ - @SuppressWarnings("unchecked") - private static final Iterator EMPTY_ITERATOR = new EmptyIterator(); - - @SuppressWarnings("unchecked") - private static class EmptyIterator implements Iterator { - - EmptyIterator() { - super(); - } - - public boolean hasNext() { - return false; - } - - public Object next() { - throw new NoSuchElementException(); - } - - public void remove() { - throw new IllegalStateException(); - } - } - - - private class HashIterator implements Iterator<E> { - private Entry<E>[] localTable = HashBag.this.table; - private int index = this.localTable.length; // start at the end of the table - private Entry<E> nextEntry = null; - private int nextEntryCount = 0; - private Entry<E> lastReturnedEntry = null; - - /** - * The modCount value that the iterator believes that the backing - * bag should have. If this expectation is violated, the iterator - * has detected a concurrent modification. - */ - private int expectedModCount = HashBag.this.modCount; - - HashIterator() { - super(); - } - - public boolean hasNext() { - Entry<E> e = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((e == null) && (i > 0)) { - e = tab[--i]; // move backwards through the table - } - this.nextEntry = e; - this.index = i; - return e != null; - } - - public E next() { - if (HashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E> et = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((et == null) && (i > 0)) { - et = tab[--i]; // move backwards through the table - } - this.nextEntry = et; - this.index = i; - if (et == null) { - throw new NoSuchElementException(); - } - Entry<E> e = this.lastReturnedEntry = this.nextEntry; - this.nextEntryCount++; - if (this.nextEntryCount == e.count) { - this.nextEntry = e.next; - this.nextEntryCount = 0; - } - return e.object; - } - - public void remove() { - if (this.lastReturnedEntry == null) { - throw new IllegalStateException(); - } - if (HashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E>[] tab = this.localTable; - int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) { - if (e == this.lastReturnedEntry) { - HashBag.this.modCount++; - this.expectedModCount++; - e.count--; - if (e.count == 0) { - // if we are removing the last one, remove the entry from the table - if (prev == null) { - tab[slot] = e.next; - } else { - prev.next = e.next; - } - HashBag.this.uniqueCount--; - } else { - // slide back the count to account for the just-removed element - this.nextEntryCount--; - } - HashBag.this.count--; - this.lastReturnedEntry = null; // it cannot be removed again - return; - } - } - throw new ConcurrentModificationException(); - } - - } - - - private class EntryIterator implements Iterator<Entry<E>> { - private Entry<E>[] localTable = HashBag.this.table; - private int index = this.localTable.length; // start at the end of the table - private Entry<E> nextEntry = null; - private Entry<E> lastReturnedEntry = null; - - /** - * The modCount value that the iterator believes that the backing - * bag should have. If this expectation is violated, the iterator - * has detected a concurrent modification. - */ - private int expectedModCount = HashBag.this.modCount; - - EntryIterator() { - super(); - } - - public boolean hasNext() { - Entry<E> e = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((e == null) && (i > 0)) { - e = tab[--i]; // move backwards through the table - } - this.nextEntry = e; - this.index = i; - return e != null; - } - - public Entry<E> next() { - if (HashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E> et = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((et == null) && (i > 0)) { - et = tab[--i]; // move backwards through the table - } - this.nextEntry = et; - this.index = i; - if (et == null) { - throw new NoSuchElementException(); - } - Entry<E> e = this.lastReturnedEntry = this.nextEntry; - this.nextEntry = e.next; - return e; - } - - public void remove() { - if (this.lastReturnedEntry == null) { - throw new IllegalStateException(); - } - if (HashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E>[] tab = this.localTable; - int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) { - if (e == this.lastReturnedEntry) { - HashBag.this.modCount++; - this.expectedModCount++; - // remove the entry from the table - if (prev == null) { - tab[slot] = e.next; - } else { - prev.next = e.next; - } - HashBag.this.uniqueCount--; - HashBag.this.count -= this.lastReturnedEntry.count; - this.lastReturnedEntry = null; // it cannot be removed again - return; - } - } - throw new ConcurrentModificationException(); - } - - } - - - private class UniqueIterator implements Iterator<E> { - private EntryIterator entryIterator = new EntryIterator(); - - UniqueIterator() { - super(); - } - - public boolean hasNext() { - return this.entryIterator.hasNext(); - } - - public E next() { - return this.entryIterator.next().object; - } - - public void remove() { - this.entryIterator.remove(); - } - - } - - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ( ! (o instanceof Bag)) { - return false; - } - @SuppressWarnings("unchecked") - Bag<E> b = (Bag<E>) o; - if (b.size() != this.size()) { - return false; - } - Bag<E> clone = this.clone(); - for (E e : b) { - if ( ! clone.remove(e)) { - return false; - } - } - return clone.isEmpty(); - } - - @Override - public int hashCode() { - int h = 0; - for (Iterator<E> stream = this.iterator(); stream.hasNext(); ) { - Object next = stream.next(); - if (next != null) { - h += next.hashCode(); - } - } - return h; - } - - /** - * Save the state of this bag to a stream (i.e. serialize it). - * - * @serialData Emit the capacity of the bag (int), - * followed by the number of unique elements in the bag (int), - * followed by all of the bag's elements (each an Object) and - * their counts (each an int), in no particular order. - */ - private synchronized void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - // write out the threshold, load factor, and any hidden stuff - s.defaultWriteObject(); - - // write out number of buckets - s.writeInt(this.table.length); - - // write out number of unique elements - s.writeInt(this.uniqueCount); - - Entry<E>[] tab = this.table; - // write out elements and counts (alternating) - for (Entry<E> entry : tab) { - while (entry != null) { - s.writeObject(entry.object); - s.writeInt(entry.count); - entry = entry.next; - } - } - } - - private static final long serialVersionUID = 1L; - - /** - * Reconstitute the bag from a stream (i.e. deserialize it). - */ - private synchronized void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // read in the threshold, loadfactor, and any hidden stuff - s.defaultReadObject(); - - // read in number of buckets and allocate the bucket array - this.table = this.buildTable(s.readInt()); - - // read in number of unique elements - int unique = s.readInt(); - - // read the elements and counts, and put the elements in the bag - for (int i = 0; i < unique; i++) { - @SuppressWarnings("unchecked") - E element = (E) s.readObject(); - int elementCount = s.readInt(); - this.add(element, elementCount); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java deleted file mode 100644 index d56f521cac..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java +++ /dev/null @@ -1,879 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * This class implements the <code>Bag</code> interface with a - * hash table, using object-identity in place of object-equality when - * comparing elements. In other words, in an <code>IdentityHashBag</code>, - * two objects <code>k1</code> and <code>k2</code> are considered - * equal if and only if <code>(k1 == k2)</code>. (In normal <code>Bag</code> - * implementations (like <code>HashBag</code>) two objects <code>k1</code> - * and <code>k2</code> are considered equal if and only if - * <code>(k1 == null ? k2 == null : k1.equals(k2))</code>.) - * <p> - * <b> - * This class is <i>not</i> a general-purpose <code>Bag</code> - * implementation! While this class implements the <code>Bag</code> interface, it - * intentionally violates <code>Bag's</code> general contract, which mandates the - * use of the <code>equals</code> method when comparing objects. This class is - * designed for use only in the rare cases wherein object-identity - * semantics are required. - * </b> - * <p> - * This class makes no guarantees as to the iteration order of - * the bag's elements; in particular, it does not guarantee that the order - * will remain constant over time. This class permits the <code>null</code> - * element. - * <p> - * This class offers constant time performance for the basic operations - * (<code>add</code>, <code>remove</code>, <code>contains</code> and - * <code>size</code>), assuming the system identity hash function - * ({@link System#identityHashCode(Object)}) disperses elements properly - * among the buckets. Iterating over this bag requires time - * proportional to the sum of the bag's size (the number of elements) plus the - * "capacity" of the backing hash table (the number of buckets). Thus, it is - * important not to set the initial capacity too high (or the load factor too - * low) if iteration performance is important. - * <p> - * <b>Note that this implementation is not synchronized.</b> If multiple - * threads access a bag concurrently, and at least one of the threads modifies - * the bag, it <i>must</i> be synchronized externally. This is typically - * accomplished by synchronizing on some object that naturally encapsulates - * the bag. If no such object exists, the bag should be "wrapped" using the - * <code>Collections.synchronizedCollection</code> method. This is - * best done at creation time, to prevent accidental unsynchronized access - * to the bag: - * <pre> - * Collection c = Collections.synchronizedCollection(new IdentityHashBag(...)); - * </pre> - * <p> - * The iterators returned by this class's <code>iterator</code> method are - * <i>fail-fast</i>: if the bag is modified at any time after the iterator is - * created, in any way except through the iterator's own <code>remove</code> - * method, the iterator throws a <code>ConcurrentModificationException</code>. - * Thus, in the face of concurrent modification, the iterator fails quickly - * and cleanly, rather than risking arbitrary, non-deterministic behavior at - * an undetermined time in the future. - * - * @see Collections#synchronizedCollection(Collection) - */ - -public class IdentityHashBag<E> - extends AbstractCollection<E> - implements Bag<E>, Cloneable, Serializable -{ - - /** The hash table. */ - transient Entry<E>[] table; - - /** The total number of entries in the bag. */ - transient int count = 0; - - /** The number of unique entries in the bag. */ - transient int uniqueCount = 0; - - /** - * The hash table is rehashed when its size exceeds this threshold. (The - * value of this field is (int)(capacity * loadFactor).) - * - * @serial - */ - private int threshold; - - /** - * The load factor for the hash table. - * - * @serial - */ - private float loadFactor; - - /** - * The number of times this bag has been structurally modified. - * Structural modifications are those that change the number of entries in - * the bag or otherwise modify its internal structure (e.g. rehash). - * This field is used to make iterators on this bag fail-fast. - * - * @see java.util.ConcurrentModificationException - */ - transient int modCount = 0; - - /** - * Constructs a new, empty bag with the - * default capacity, which is 11, and load factor, which is 0.75. - */ - public IdentityHashBag() { - this(11, 0.75f); - } - - /** - * Constructs a new, empty bag with the specified initial capacity - * and default load factor, which is 0.75. - * - * @param initialCapacity the initial capacity of the backing map. - * @throws IllegalArgumentException if the initial capacity is less - * than zero. - */ - public IdentityHashBag(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty bag with - * the specified initial capacity and the specified load factor. - * - * @param initialCapacity the initial capacity of the backing map. - * @param loadFactor the load factor of the backing map. - * @throws IllegalArgumentException if the initial capacity is less - * than zero, or if the load factor is nonpositive. - */ - public IdentityHashBag(int initialCapacity, float loadFactor) { - if (initialCapacity < 0) { - throw new IllegalArgumentException("Illegal Initial Capacity: " + initialCapacity); - } - if (loadFactor <= 0 || Float.isNaN(loadFactor)) { - throw new IllegalArgumentException("Illegal Load factor: " + loadFactor); - } - if (initialCapacity == 0) { - initialCapacity = 1; - } - this.loadFactor = loadFactor; - this.table = this.buildTable(initialCapacity); - this.threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new bag containing the elements in the specified - * collection. The capacity of the bag is - * twice the size of the specified collection or 11 (whichever is - * greater), and the default load factor, which is 0.75, is used. - * - * @param c the collection whose elements are to be placed into this bag. - */ - public IdentityHashBag(Collection<? extends E> c) { - this(Math.max(2*c.size(), 11)); - this.addAll(c); - } - - /** - * This implementation simply returns the maintained count. - */ - @Override - public int size() { - return this.count; - } - - /** - * This implementation simply compares the maintained count to zero. - */ - @Override - public boolean isEmpty() { - return this.count == 0; - } - - /** - * This implementation searches for the object in the hash table by - * calculating the object's identity hash code and examining the - * entries in the corresponding hash table bucket. - */ - @Override - public boolean contains(Object o) { - Entry<E>[] tab = this.table; - int hash = System.identityHashCode(o); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - return true; - } - } - return false; - } - - public int count(Object o) { - Entry<E>[] tab = this.table; - int hash = System.identityHashCode(o); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - return e.count; - } - } - return 0; - } - - /** - * Rehashes the contents of this bag into a new hash table - * with a larger capacity. This method is called when the - * number of different elements in this map exceeds its - * capacity and load factor. - */ - private void rehash() { - Entry<E>[] oldMap = this.table; - int oldCapacity = oldMap.length; - - int newCapacity = oldCapacity * 2 + 1; - Entry<E>[] newTable = this.buildTable(newCapacity); - - this.modCount++; - this.threshold = (int) (newCapacity * this.loadFactor); - this.table = newTable; - - for (int i = oldCapacity; i-- > 0; ) { - for (Entry<E> old = oldMap[i]; old != null; ) { - Entry<E> e = old; - old = old.next; - - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } - } - } - - @SuppressWarnings("unchecked") - private Entry<E>[] buildTable(int capacity) { - return new Entry[capacity]; - } - - @SuppressWarnings("unchecked") - private <T> Entry<E> buildEntry(int hash, Object o, Entry<T> next) { - return new Entry(hash, o, next); - } - - @SuppressWarnings("unchecked") - private <T> Entry<E> buildEntry(int hash, Object o, int cnt, Entry<T> next) { - return new Entry(hash, o, cnt, next); - } - - /** - * This implementation searches for the object in the hash table by - * calculating the object's identity hash code and examining the - * entries in the corresponding hash table bucket. - */ - @Override - public boolean add(E o) { - this.modCount++; - Entry<E>[] tab = this.table; - int hash = 0; - int index = 0; - - // if the object is already in the bag, simply bump its count - hash = System.identityHashCode(o); - index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - e.count++; - this.count++; - return true; - } - } - - // rehash the table if the threshold is exceeded - if (this.uniqueCount >= this.threshold) { - this.rehash(); - tab = this.table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // create the new entry and put it in the table - Entry<E> e = this.buildEntry(hash, o, tab[index]); - tab[index] = e; - this.count++; - this.uniqueCount++; - return true; - } - - /** - * This implementation searches for the object in the hash table by - * calculating the object's identity hash code and examining the - * entries in the corresponding hash table bucket. - */ - public boolean add(E o, int cnt) { - if (cnt <= 0) { - return false; - } - this.modCount++; - Entry<E>[] tab = this.table; - int hash = 0; - int index = 0; - - // if the object is already in the bag, simply bump its count - hash = System.identityHashCode(o); - index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - e.count += cnt; - this.count += cnt; - return true; - } - } - - // rehash the table if the threshold is exceeded - if (this.uniqueCount >= this.threshold) { - this.rehash(); - tab = this.table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // create the new entry and put it in the table - Entry<E> e = this.buildEntry(hash, o, cnt, tab[index]); - tab[index] = e; - this.count += cnt; - this.uniqueCount++; - return true; - } - - /** - * This implementation searches for the object in the hash table by - * calculating the object's identity hash code and examining the - * entries in the corresponding hash table bucket. - */ - @Override - public boolean remove(Object o) { - Entry<E>[] tab = this.table; - int hash = System.identityHashCode(o); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - this.modCount++; - e.count--; - // if we are removing the last one, remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[index] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count--; - return true; - } - } - return false; - } - - /** - * This implementation searches for the object in the hash table by - * calculating the object's identity hash code and examining the - * entries in the corresponding hash table bucket. - */ - public boolean remove(Object o, int cnt) { - if (cnt <= 0) { - return false; - } - Entry<E>[] tab = this.table; - int hash = System.identityHashCode(o); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && (e.object == o)) { - this.modCount++; - int cnt2 = (cnt < e.count) ? cnt : e.count; - e.count -= cnt2; - // if we are removing the last element(s), remove the entry from the table - if (e.count == 0) { - if (prev == null) { - tab[index] = e.next; - } else { - prev.next = e.next; - } - this.uniqueCount--; - } - this.count -= cnt2; - return true; - } - } - return false; - } - - /** - * This implementation uses object-identity to determine whether - * specified collection contains a particular element. - */ - @Override - public boolean removeAll(Collection<?> c) { - return super.removeAll(this.buildIdentityHashBag(c)); - } - - /** - * This implementation uses object-identity to determine whether - * specified collection contains a particular element. - */ - @Override - public boolean retainAll(Collection<?> c) { - return super.retainAll(this.buildIdentityHashBag(c)); - } - - @SuppressWarnings("unchecked") - private Collection<?> buildIdentityHashBag(Collection<?> c) { - return new IdentityHashBag(c); - } - - /** - * This implementation simply clears out all of the hash table buckets. - */ - @Override - public void clear() { - Entry<E>[] tab = this.table; - this.modCount++; - for (int i = tab.length; --i >= 0; ) { - tab[i] = null; - } - this.count = 0; - this.uniqueCount = 0; - } - - /** - * Returns a shallow copy of this bag: the elements - * themselves are not cloned. - * - * @return a shallow copy of this bag. - */ - @Override - public IdentityHashBag<E> clone() { - try { - @SuppressWarnings("unchecked") - IdentityHashBag<E> clone = (IdentityHashBag<E>) super.clone(); - clone.table = this.buildTable(this.table.length); - for (int i = this.table.length; i-- > 0; ) { - clone.table[i] = (this.table[i] == null) - ? null : (Entry<E>) this.table[i].clone(); - } - clone.modCount = 0; - return clone; - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } - } - - - /** - * Hash table collision list entry. - */ - private static class Entry<E> implements Bag.Entry<E> { - int hash; - E object; - int count; - Entry<E> next; - - Entry(int hash, E object, Entry<E> next) { - this(hash, object, 1, next); - } - - Entry(int hash, E object, int count, Entry<E> next) { - this.hash = hash; - this.object = object; - this.count = count; - this.next = next; - } - - /** - * Cascade the clone to all the entries in the same bucket. - */ - @Override - @SuppressWarnings("unchecked") - protected Entry<E> clone() { - return new Entry(this.hash, this.object, this.count, - (this.next == null ? null : this.next.clone())); - } - - - // ***** Bag.Entry implementation - public E getElement() { - return this.object; - } - - public int getCount() { - return this.count; - } - - public int setCount(int count) { - if (count <= 0) { - throw new IllegalArgumentException("count must be greater than zero: " + count); - } - int old = this.count; - this.count = count; - return old; - } - - @Override - public boolean equals(Object o) { - if ( ! (o instanceof Bag.Entry)) { - return false; - } - @SuppressWarnings("unchecked") - Bag.Entry e = (Bag.Entry) o; - return (this.object == e.getElement()) - && (this.count == e.getCount()); - } - - @Override - public int hashCode() { - E o = this.object; - return (o == null) ? 0 : (this.count * o.hashCode()); - } - - @Override - public String toString() { - return this.object + "=>" + this.count; - } - } - - - @Override - @SuppressWarnings("unchecked") - public Iterator<E> iterator() { - return (this.count == 0) ? EMPTY_ITERATOR : new HashIterator(); - } - - /** - * Return an iterator that returns each item in the bag - * once and only once, irrespective of how many times - * the item was added to the bag. - */ - @SuppressWarnings("unchecked") - public Iterator<E> uniqueIterator() { - return (this.count == 0) ? EMPTY_ITERATOR : new UniqueIterator(); - } - - @SuppressWarnings("unchecked") - public Iterator<Bag.Entry<E>> entries() { - return (this.count == 0) ? EMPTY_ITERATOR : new EntryIterator(); - } - - - /** - * Empty iterator that does just about nothing. - */ - @SuppressWarnings("unchecked") - private static final Iterator EMPTY_ITERATOR = new EmptyIterator(); - - @SuppressWarnings("unchecked") - private static class EmptyIterator implements Iterator { - - EmptyIterator() { - super(); - } - - public boolean hasNext() { - return false; - } - - public Object next() { - throw new NoSuchElementException(); - } - - public void remove() { - throw new IllegalStateException(); - } - } - - - private class HashIterator implements Iterator<E> { - private Entry<E>[] localTable = IdentityHashBag.this.table; - private int index = this.localTable.length; // start at the end of the table - private Entry<E> nextEntry = null; - private int nextEntryCount = 0; - private Entry<E> lastReturnedEntry = null; - - /** - * The modCount value that the iterator believes that the backing - * bag should have. If this expectation is violated, the iterator - * has detected a concurrent modification. - */ - private int expectedModCount = IdentityHashBag.this.modCount; - - HashIterator() { - super(); - } - - public boolean hasNext() { - Entry<E> e = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((e == null) && (i > 0)) { - e = tab[--i]; // move backwards through the table - } - this.nextEntry = e; - this.index = i; - return e != null; - } - - public E next() { - if (IdentityHashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E> et = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((et == null) && (i > 0)) { - et = tab[--i]; // move backwards through the table - } - this.nextEntry = et; - this.index = i; - if (et == null) { - throw new NoSuchElementException(); - } - Entry<E> e = this.lastReturnedEntry = this.nextEntry; - this.nextEntryCount++; - if (this.nextEntryCount == e.count) { - this.nextEntry = e.next; - this.nextEntryCount = 0; - } - return e.object; - } - - public void remove() { - if (this.lastReturnedEntry == null) { - throw new IllegalStateException(); - } - if (IdentityHashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E>[] tab = this.localTable; - int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) { - if (e == this.lastReturnedEntry) { - IdentityHashBag.this.modCount++; - this.expectedModCount++; - e.count--; - if (e.count == 0) { - // if we are removing the last one, remove the entry from the table - if (prev == null) { - tab[slot] = e.next; - } else { - prev.next = e.next; - } - IdentityHashBag.this.uniqueCount--; - } else { - // slide back the count to account for the just-removed element - this.nextEntryCount--; - } - IdentityHashBag.this.count--; - this.lastReturnedEntry = null; // it cannot be removed again - return; - } - } - throw new ConcurrentModificationException(); - } - } - - - private class EntryIterator implements Iterator<Entry<E>> { - private Entry<E>[] localTable = IdentityHashBag.this.table; - private int index = this.localTable.length; // start at the end of the table - private Entry<E> nextEntry = null; - private Entry<E> lastReturnedEntry = null; - - /** - * The modCount value that the iterator believes that the backing - * bag should have. If this expectation is violated, the iterator - * has detected a concurrent modification. - */ - private int expectedModCount = IdentityHashBag.this.modCount; - - EntryIterator() { - super(); - } - - public boolean hasNext() { - Entry<E> e = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((e == null) && (i > 0)) { - e = tab[--i]; // move backwards through the table - } - this.nextEntry = e; - this.index = i; - return e != null; - } - - public Entry<E> next() { - if (IdentityHashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E> et = this.nextEntry; - int i = this.index; - Entry<E>[] tab = this.localTable; - // Use locals for faster loop iteration - while ((et == null) && (i > 0)) { - et = tab[--i]; // move backwards through the table - } - this.nextEntry = et; - this.index = i; - if (et == null) { - throw new NoSuchElementException(); - } - Entry<E> e = this.lastReturnedEntry = this.nextEntry; - this.nextEntry = e.next; - return e; - } - - public void remove() { - if (this.lastReturnedEntry == null) { - throw new IllegalStateException(); - } - if (IdentityHashBag.this.modCount != this.expectedModCount) { - throw new ConcurrentModificationException(); - } - Entry<E>[] tab = this.localTable; - int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length; - for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) { - if (e == this.lastReturnedEntry) { - IdentityHashBag.this.modCount++; - this.expectedModCount++; - // remove the entry from the table - if (prev == null) { - tab[slot] = e.next; - } else { - prev.next = e.next; - } - IdentityHashBag.this.uniqueCount--; - IdentityHashBag.this.count -= this.lastReturnedEntry.count; - this.lastReturnedEntry = null; // it cannot be removed again - return; - } - } - throw new ConcurrentModificationException(); - } - - } - - - private class UniqueIterator implements Iterator<E> { - private EntryIterator entryIterator = new EntryIterator(); - - UniqueIterator() { - super(); - } - - public boolean hasNext() { - return this.entryIterator.hasNext(); - } - - public E next() { - return this.entryIterator.next().object; - } - - public void remove() { - this.entryIterator.remove(); - } - - } - - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof IdentityHashBag) { - @SuppressWarnings("unchecked") - IdentityHashBag<E> b = (IdentityHashBag<E>) o; - if (b.size() != this.size()) { - return false; - } - IdentityHashBag<E> clone = this.clone(); - for (E e : b) { - if ( ! clone.remove(e)) { - return false; - } - } - return clone.isEmpty(); - } else if (o instanceof Bag) { - // hmmm... - return this.buildBag().equals(o); - } else { - return false; - } - } - - @SuppressWarnings("unchecked") - private Bag<E> buildBag() { - return new HashBag(this); - } - - @Override - public int hashCode() { - int h = 0; - for (E e : this) { - h += System.identityHashCode(e); - } - return h; - } - - /** - * Save the state of this bag to a stream (i.e. serialize it). - * - * @serialData Emit the capacity of the bag (int), - * followed by the number of unique elements in the bag (int), - * followed by all of the bag's elements (each an Object) and - * their counts (each an int), in no particular order. - */ - private synchronized void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - // write out the threshold, load factor, and any hidden stuff - s.defaultWriteObject(); - - // write out number of buckets - s.writeInt(this.table.length); - - // write out number of unique elements - s.writeInt(this.uniqueCount); - - Entry<E>[] tab = this.table; - // write out elements and counts (alternating) - for (Entry<E> entry : tab) { - while (entry != null) { - s.writeObject(entry.object); - s.writeInt(entry.count); - entry = entry.next; - } - } - } - - private static final long serialVersionUID = 1L; - - /** - * Reconstitute the bag from a stream (i.e. deserialize it). - */ - private synchronized void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // read in the threshold, loadfactor, and any hidden stuff - s.defaultReadObject(); - - // read in number of buckets and allocate the bucket array - this.table = this.buildTable(s.readInt()); - - // read in number of unique elements - int unique = s.readInt(); - - // read the elements and counts, and put the elements in the bag - for (int i = 0; i < unique; i++) { - @SuppressWarnings("unchecked") - E element = (E) s.readObject(); - int elementCount = s.readInt(); - for (int j = 0; j < elementCount; j++) { - this.add(element); - } - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IndentingPrintWriter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IndentingPrintWriter.java deleted file mode 100644 index f2afb1d4e6..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IndentingPrintWriter.java +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.PrintWriter; -import java.io.Writer; - -/** - * Extend PrintWriter to automatically indent new lines. - */ -public class IndentingPrintWriter extends PrintWriter { - - private final String indent; - private int indentLevel; - private boolean needsIndent; - - public static String DEFAULT_INDENT = "\t"; - - - /** - * Construct a writer that indents with tabs. - */ - public IndentingPrintWriter(Writer out) { - this(out, DEFAULT_INDENT); - } - - /** - * Construct a writer that indents with the specified string. - */ - public IndentingPrintWriter(Writer out, String indent) { - super(out); - this.indent = indent; - this.indentLevel = 0; - this.needsIndent = true; - } - - /** - * Set flag so following line is indented. - */ - @Override - public void println() { - synchronized (this.lock) { - super.println(); - this.needsIndent = true; - } - } - - /** - * Print the appropriate indent. - */ - private void printIndent() { - if (this.needsIndent) { - this.needsIndent = false; - for (int i = this.indentLevel; i-- > 0; ) { - this.print(this.indent); - } - } - } - - /** - * Write a portion of an array of characters. - */ - @Override - public void write(char buf[], int off, int len) { - synchronized (this.lock) { - this.printIndent(); - super.write(buf, off, len); - } - } - - /** - * Write a single character. - */ - @Override - public void write(int c) { - synchronized (this.lock) { - this.printIndent(); - super.write(c); - } - } - - /** - * Write a portion of a string. - */ - @Override - public void write(String s, int off, int len) { - synchronized (this.lock) { - this.printIndent(); - super.write(s, off, len); - } - } - - /** - * Bump the indent level. - */ - public void indent() { - this.incrementIndentLevel(); - } - - /** - * Decrement the indent level. - */ - public void undent() { - this.decrementIndentLevel(); - } - - /** - * Bump the indent level. - */ - public void incrementIndentLevel() { - synchronized (this.lock) { - this.indentLevel++; - } - } - - /** - * Decrement the indent level. - */ - public void decrementIndentLevel() { - synchronized (this.lock) { - this.indentLevel--; - } - } - - /** - * Return the current indent level. - */ - public int indentLevel() { - return this.indentLevel; - } - - /** - * Allow the indent level to be set directly. - */ - public void setIndentLevel(int indentLevel) { - synchronized (this.lock) { - this.indentLevel = indentLevel; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java deleted file mode 100644 index 34aff52d7a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.sql.Types; -import java.util.HashMap; -import org.eclipse.jpt.utility.JavaType; - -/** - * Helper methods for dealing with the JDBC API. - */ -public final class JDBCTools { - - - /** - * Return the JDBC type corresponding to the specified class. - * @see java.sql.Types - */ - public static JDBCType jdbcTypeForClassNamed(String className) { - JavaToJDBCTypeMapping mapping = javaToJDBCTypeMapping(className); - return (mapping == null) ? DEFAULT_JDBC_TYPE : mapping.getJDBCType(); - } - - /** - * Return the JDBC type corresponding to the specified class. - * @see java.sql.Types - */ - public static JDBCType jdbcTypeFor(Class<?> javaClass) { - return jdbcTypeForClassNamed(javaClass.getName()); - } - - /** - * Return the JDBC type corresponding to the specified class. - * @see java.sql.Types - */ - public static JDBCType jdbcTypeFor(JavaType javaType) { - return jdbcTypeForClassNamed(javaType.getJavaClassName()); - } - - /** - * Return the Java type corresponding to the specified JDBC type. - * @see java.sql.Types - */ - public static JavaType javaTypeForJDBCTypeNamed(String jdbcTypeName) { - JDBCToJavaTypeMapping mapping = jdbcToJavaTypeMapping(jdbcTypeName); - return (mapping == null) ? DEFAULT_JAVA_TYPE : mapping.getJavaType(); - } - - /** - * Return the Java type corresponding to the specified JDBC type. - * @see java.sql.Types - */ - public static JavaType javaTypeFor(JDBCType jdbcType) { - return javaTypeForJDBCTypeNamed(jdbcType.name()); - } - - /** - * Return the Java type corresponding to the specified JDBC type. - * @see java.sql.Types - */ - public static JavaType javaTypeForJDBCTypeCode(int jdbcTypeCode) { - return javaTypeFor(JDBCType.type(jdbcTypeCode)); - } - - - // ********** internal stuff ********** - - - // ********** JDBC => Java ********** - - /** - * JDBC => Java type mappings, keyed by JDBC type name (e.g. "VARCHAR") - */ - private static HashMap<String, JDBCToJavaTypeMapping> JDBC_TO_JAVA_TYPE_MAPPINGS; // pseudo 'final' - lazy-initialized - private static final JavaType DEFAULT_JAVA_TYPE = new SimpleJavaType(java.lang.Object.class); // TODO Object is the default? - - - private static JDBCToJavaTypeMapping jdbcToJavaTypeMapping(String jdbcTypeName) { - return jdbcToJavaTypeMappings().get(jdbcTypeName); - } - - private static synchronized HashMap<String, JDBCToJavaTypeMapping> jdbcToJavaTypeMappings() { - if (JDBC_TO_JAVA_TYPE_MAPPINGS == null) { - JDBC_TO_JAVA_TYPE_MAPPINGS = buildJDBCToJavaTypeMappings(); - } - return JDBC_TO_JAVA_TYPE_MAPPINGS; - } - - private static HashMap<String, JDBCToJavaTypeMapping> buildJDBCToJavaTypeMappings() { - HashMap<String, JDBCToJavaTypeMapping> mappings = new HashMap<String, JDBCToJavaTypeMapping>(); - addJDBCToJavaTypeMappingsTo(mappings); - return mappings; - } - - /** - * hard code the default mappings from the JDBC types to the - * appropriate Java types - * @see java.sql.Types - * see "JDBC 3.0 Specification" Appendix B - */ - private static void addJDBCToJavaTypeMappingsTo(HashMap<String, JDBCToJavaTypeMapping> mappings) { - addJDBCToJavaTypeMappingTo(Types.ARRAY, java.sql.Array.class, mappings); - addJDBCToJavaTypeMappingTo(Types.BIGINT, long.class, mappings); - addJDBCToJavaTypeMappingTo(Types.BINARY, byte[].class, mappings); - addJDBCToJavaTypeMappingTo(Types.BIT, boolean.class, mappings); - addJDBCToJavaTypeMappingTo(Types.BLOB, java.sql.Blob.class, mappings); - addJDBCToJavaTypeMappingTo(Types.BOOLEAN, boolean.class, mappings); - addJDBCToJavaTypeMappingTo(Types.CHAR, java.lang.String.class, mappings); - addJDBCToJavaTypeMappingTo(Types.CLOB, java.sql.Clob.class, mappings); - addJDBCToJavaTypeMappingTo(Types.DATALINK, java.net.URL.class, mappings); - addJDBCToJavaTypeMappingTo(Types.DATE, java.sql.Date.class, mappings); - addJDBCToJavaTypeMappingTo(Types.DECIMAL, java.math.BigDecimal.class, mappings); - addJDBCToJavaTypeMappingTo(Types.DISTINCT, java.lang.Object.class, mappings); // ??? - addJDBCToJavaTypeMappingTo(Types.DOUBLE, double.class, mappings); - addJDBCToJavaTypeMappingTo(Types.FLOAT, double.class, mappings); - addJDBCToJavaTypeMappingTo(Types.INTEGER, int.class, mappings); - addJDBCToJavaTypeMappingTo(Types.JAVA_OBJECT, java.lang.Object.class, mappings); // ??? - addJDBCToJavaTypeMappingTo(Types.LONGVARBINARY, byte[].class, mappings); - addJDBCToJavaTypeMappingTo(Types.LONGVARCHAR, java.lang.String.class, mappings); - // not sure why this is defined in java.sql.Types -// addJDBCToJavaTypeMappingTo(Types.NULL, java.lang.Object.class, mappings); - addJDBCToJavaTypeMappingTo(Types.NUMERIC, java.math.BigDecimal.class, mappings); - addJDBCToJavaTypeMappingTo(Types.OTHER, java.lang.Object.class, mappings); // ??? - addJDBCToJavaTypeMappingTo(Types.REAL, float.class, mappings); - addJDBCToJavaTypeMappingTo(Types.REF, java.sql.Ref.class, mappings); - addJDBCToJavaTypeMappingTo(Types.SMALLINT, short.class, mappings); - addJDBCToJavaTypeMappingTo(Types.STRUCT, java.sql.Struct.class, mappings); - addJDBCToJavaTypeMappingTo(Types.TIME, java.sql.Time.class, mappings); - addJDBCToJavaTypeMappingTo(Types.TIMESTAMP, java.sql.Timestamp.class, mappings); - addJDBCToJavaTypeMappingTo(Types.TINYINT, byte.class, mappings); - addJDBCToJavaTypeMappingTo(Types.VARBINARY, byte[].class, mappings); - addJDBCToJavaTypeMappingTo(Types.VARCHAR, java.lang.String.class, mappings); - } - - private static void addJDBCToJavaTypeMappingTo(int jdbcTypeCode, Class<?> javaClass, HashMap<String, JDBCToJavaTypeMapping> mappings) { - // check for duplicates - JDBCType jdbcType = JDBCType.type(jdbcTypeCode); - Object prev = mappings.put(jdbcType.name(), buildJDBCToJavaTypeMapping(jdbcType, javaClass)); - if (prev != null) { - throw new IllegalArgumentException("duplicate JDBC type: " + jdbcType.name()); - } - } - - private static JDBCToJavaTypeMapping buildJDBCToJavaTypeMapping(JDBCType jdbcType, Class<?> javaClass) { - return new JDBCToJavaTypeMapping(jdbcType, new SimpleJavaType(javaClass)); - } - - - // ********** Java => JDBC ********** - - /** - * Java => JDBC type mappings, keyed by Java class name (e.g. "java.lang.Object") - */ - private static HashMap<String, JavaToJDBCTypeMapping> JAVA_TO_JDBC_TYPE_MAPPINGS; // pseudo 'final' - lazy-initialized - private static final JDBCType DEFAULT_JDBC_TYPE = JDBCType.type(Types.VARCHAR); // TODO VARCHAR is the default? - - - private static JavaToJDBCTypeMapping javaToJDBCTypeMapping(String className) { - return javaToJDBCTypeMappings().get(className); - } - - private static synchronized HashMap<String, JavaToJDBCTypeMapping> javaToJDBCTypeMappings() { - if (JAVA_TO_JDBC_TYPE_MAPPINGS == null) { - JAVA_TO_JDBC_TYPE_MAPPINGS = buildJavaToJDBCTypeMappings(); - } - return JAVA_TO_JDBC_TYPE_MAPPINGS; - } - - private static HashMap<String, JavaToJDBCTypeMapping> buildJavaToJDBCTypeMappings() { - HashMap<String, JavaToJDBCTypeMapping> mappings = new HashMap<String, JavaToJDBCTypeMapping>(); - addJavaToJDBCTypeMappingsTo(mappings); - return mappings; - } - - /** - * hard code the default mappings from the Java types to the - * appropriate JDBC types - * @see java.sql.Types - * see "JDBC 3.0 Specification" Appendix B - */ - private static void addJavaToJDBCTypeMappingsTo(HashMap<String, JavaToJDBCTypeMapping> mappings) { - // primitives - addJavaToJDBCTypeMappingTo(boolean.class, Types.BIT, mappings); - addJavaToJDBCTypeMappingTo(byte.class, Types.TINYINT, mappings); - addJavaToJDBCTypeMappingTo(double.class, Types.DOUBLE, mappings); - addJavaToJDBCTypeMappingTo(float.class, Types.REAL, mappings); - addJavaToJDBCTypeMappingTo(int.class, Types.INTEGER, mappings); - addJavaToJDBCTypeMappingTo(long.class, Types.BIGINT, mappings); - addJavaToJDBCTypeMappingTo(short.class, Types.SMALLINT, mappings); - - // reference classes - addJavaToJDBCTypeMappingTo(java.lang.Boolean.class, Types.BIT, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Byte.class, Types.TINYINT, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Double.class, Types.DOUBLE, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Float.class, Types.REAL, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Integer.class, Types.INTEGER, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Long.class, Types.BIGINT, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Short.class, Types.SMALLINT, mappings); - addJavaToJDBCTypeMappingTo(java.lang.String.class, Types.VARCHAR, mappings); - addJavaToJDBCTypeMappingTo(java.math.BigDecimal.class, Types.NUMERIC, mappings); - addJavaToJDBCTypeMappingTo(java.net.URL.class, Types.DATALINK, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Array.class, Types.ARRAY, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Blob.class, Types.BLOB, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Clob.class, Types.CLOB, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Date.class, Types.DATE, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Ref.class, Types.REF, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Struct.class, Types.STRUCT, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Time.class, Types.TIME, mappings); - addJavaToJDBCTypeMappingTo(java.sql.Timestamp.class, Types.TIMESTAMP, mappings); - - // arrays - addJavaToJDBCTypeMappingTo(byte[].class, Types.VARBINARY, mappings); - addJavaToJDBCTypeMappingTo(java.lang.Byte[].class, Types.VARBINARY, mappings); - } - - private static void addJavaToJDBCTypeMappingTo(Class<?> javaClass, int jdbcTypeCode, HashMap<String, JavaToJDBCTypeMapping> mappings) { - // check for duplicates - Object prev = mappings.put(javaClass.getName(), buildJavaToJDBCTypeMapping(javaClass, jdbcTypeCode)); - if (prev != null) { - throw new IllegalArgumentException("duplicate Java class: " + ((JavaToJDBCTypeMapping) prev).getJavaType().declaration()); - } - } - - private static JavaToJDBCTypeMapping buildJavaToJDBCTypeMapping(Class<?> javaClass, int jdbcTypeCode) { - return new JavaToJDBCTypeMapping(new SimpleJavaType(javaClass), JDBCType.type(jdbcTypeCode)); - } - - - // ********** constructor ********** - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private JDBCTools() { - super(); - throw new UnsupportedOperationException(); - } - - - // ********** member classes ********** - - /** - * JDBC => Java - */ - private static class JDBCToJavaTypeMapping { - private final JDBCType jdbcType; - private final JavaType javaType; - - JDBCToJavaTypeMapping(JDBCType jdbcType, JavaType javaType) { - super(); - this.jdbcType = jdbcType; - this.javaType = javaType; - } - - public JDBCType getJDBCType() { - return this.jdbcType; - } - - public JavaType getJavaType() { - return this.javaType; - } - - public boolean maps(int jdbcTypeCode) { - return this.jdbcType.code() == jdbcTypeCode; - } - - public boolean maps(String jdbcTypeName) { - return this.jdbcType.name().equals(jdbcTypeName); - } - - public boolean maps(JDBCType type) { - return this.jdbcType == type; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - this.appendTo(sb); - return sb.toString(); - } - - public void appendTo(StringBuilder sb) { - this.jdbcType.appendTo(sb); - sb.append(" => "); - this.javaType.appendDeclarationTo(sb); - } - - } - - /** - * Java => JDBC - */ - private static class JavaToJDBCTypeMapping { - private final JavaType javaType; - private final JDBCType jdbcType; - - JavaToJDBCTypeMapping(JavaType javaType, JDBCType jdbcType) { - super(); - this.javaType = javaType; - this.jdbcType = jdbcType; - } - - public JavaType getJavaType() { - return this.javaType; - } - - public JDBCType getJDBCType() { - return this.jdbcType; - } - - public boolean maps(JavaType jt) { - return this.javaType.equals(jt); - } - - public boolean maps(String elementTypeName, int arrayDepth) { - return this.javaType.equals(elementTypeName, arrayDepth); - } - - public boolean maps(String javaClassName) { - return this.javaType.describes(javaClassName); - } - - public boolean maps(Class<?> javaClass) { - return this.javaType.describes(javaClass); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - this.appendTo(sb); - return sb.toString(); - } - - public void appendTo(StringBuilder sb) { - this.javaType.appendDeclarationTo(sb); - sb.append(" => "); - this.jdbcType.appendTo(sb); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCType.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCType.java deleted file mode 100644 index 82ae294c34..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCType.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.lang.reflect.Field; -import java.sql.Types; -import java.text.Collator; - -/** - * Associate the Java constant and the JDBC type name. - * These are derived from java.sql.Types. - * - * @see java.sql.Types - */ -public final class JDBCType - implements Comparable<JDBCType>, Cloneable, Serializable -{ - - /** - * the constant name (e.g. VARCHAR) - */ - private final String name; - - /** - * the JDBC code used by JDBC drivers - */ - private final int code; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a JDBC type with the specified name and type code. - * This is private because all the possible JDBC types are built and - * stored in the static array TYPES. - * @see #types() - */ - private JDBCType(String name, int code) { - super(); - this.name = name; - this.code = code; - } - - - // ********** accessors ********** - - /** - * Return the name of the type, as defined in java.sql.Types. - */ - public String name() { - return this.name; - } - - - /** - * Return the type code, as defined in java.sql.Types. - */ - public int code() { - return this.code; - } - - - // ********** printing and displaying ********** - - public void appendTo(StringBuilder sb) { - sb.append(this.name); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(ClassTools.shortClassNameForObject(this)); - sb.append('('); - this.appendTo(sb); - sb.append(')'); - return sb.toString(); - } - - @Override - public JDBCType clone() { - try { - return (JDBCType) super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - public int compareTo(JDBCType type) { - return Collator.getInstance().compare(this.name, type.name); - } - - - // ********** static stuff ********** - - /** - * all the JDBC type defined in java.sql.Types - */ - private static JDBCType[] TYPES; // pseudo 'final' - lazy-initialized - - - public synchronized static JDBCType[] types() { - if (TYPES == null) { - TYPES = buildTypes(); - } - return TYPES; - } - - /** - * Return the JDBC type for the specified type code (e.g. Types.VARCHAR). - * @see java.sql.Types - */ - public static JDBCType type(int code) { - JDBCType[] types = types(); - for (int i = types.length; i-- > 0; ) { - if (types[i].code() == code) { - return types[i]; - } - } - throw new IllegalArgumentException("invalid JDBC type code: " + code); - } - - /** - * Return the JDBC type for the specified type name (e.g. "VARCHAR"). - * @see java.sql.Types - */ - public static JDBCType type(String name) { - JDBCType[] types = types(); - for (int i = types.length; i-- > 0; ) { - if (types[i].name().equals(name)) { - return types[i]; - } - } - throw new IllegalArgumentException("invalid JDBC type name: " + name); - } - - /** - * build up the JDBC types via reflection - * @see java.sql.Types - */ - private static JDBCType[] buildTypes() { - Field[] fields = Types.class.getDeclaredFields(); - int len = fields.length; - JDBCType[] types = new JDBCType[len]; - for (int i = len; i-- > 0; ) { - String name = fields[i].getName(); - int code; - try { - code = ((Integer) fields[i].get(null)).intValue(); - } catch (IllegalAccessException ex) { - throw new RuntimeException(ex); // shouldn't happen... - } - types[i] = new JDBCType(name, code); - } - return types; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ListenerList.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ListenerList.java deleted file mode 100644 index a7749bd731..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ListenerList.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.EventListener; - -/** - * Maintain a thread-safe list of listeners that does not allow duplicates. - */ -public class ListenerList<L extends EventListener> - implements Serializable -{ - private transient volatile L[] listeners; - - private static final long serialVersionUID = 1L; - - - public ListenerList(Class<L> listenerClass) { - super(); - this.listeners = this.buildEmptyArray(listenerClass); - } - - @SuppressWarnings("unchecked") - private L[] buildEmptyArray(Class<L> listenerClass) { - return (L[]) Array.newInstance(listenerClass, 0); - } - - public L[] getListeners() { - return this.listeners; - } - - public int size() { - return this.listeners.length; - } - - public boolean isEmpty() { - return this.listeners.length == 0; - } - - public synchronized void add(L listener) { - if (listener == null) { - throw new NullPointerException(); - } - if (CollectionTools.contains(this.listeners, listener)) { - return;//throw new IllegalArgumentException("duplicate listener: " + listener); //$NON-NLS-1$ - } - this.listeners = CollectionTools.add(this.listeners, listener); - } - - public synchronized void remove(L listener) { - if (listener == null) { - throw new NullPointerException(); - } - int index = CollectionTools.indexOf(this.listeners, listener); - if (index == -1) { - return;//throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$ - } - this.listeners = CollectionTools.removeElementAtIndex(this.listeners, index); - } - - public synchronized void clear() { - this.listeners = CollectionTools.clear(this.listeners); - } - - @Override - public String toString() { - return Arrays.toString(this.listeners); - } - - - // ********** serialization ********** - - private synchronized void writeObject(ObjectOutputStream s) throws IOException { - // write out any hidden stuff - s.defaultWriteObject(); - - @SuppressWarnings("unchecked") - Class<L> listenerClass = (Class<L>) this.listeners.getClass().getComponentType(); - s.writeObject(listenerClass); - - // only write out serializable listeners - for (L listener : this.listeners) { - if (listener instanceof Serializable) { - s.writeObject(listener); - } - } - - s.writeObject(null); - } - - @SuppressWarnings("unchecked") - private synchronized void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { - // read in any hidden stuff - s.defaultReadObject(); - - Class<L> listenerClass = (Class<L>) s.readObject(); - this.listeners = this.buildEmptyArray(listenerClass); - Object o; - while ((o = s.readObject()) != null) { - this.add((L) o); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NameTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NameTools.java deleted file mode 100644 index 570398445e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NameTools.java +++ /dev/null @@ -1,358 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.SortedSet; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; - -/** - * Various helper methods for generating names. - */ -public final class NameTools { - - /** - * Given a "root" name and a set of existing names, generate a unique - * name that is either the "root" name or some variation on the "root" - * name (e.g. "root2", "root3",...). The names are case-sensitive - * (i.e. "Root" and "root" are both allowed). - */ - public static String uniqueNameFor(String rootName, Iterator<String> existingNames) { - return uniqueNameFor(rootName, CollectionTools.set(existingNames)); - } - - /** - * Given a "root" name and a set of existing names, generate a unique - * name that is either the "root" name or some variation on the "root" - * name (e.g. "root2", "root3",...). The names are case-sensitive - * (i.e. "Root" and "root" are both allowed). - */ - public static String uniqueNameFor(String rootName, Collection<String> existingNames) { - return uniqueNameFor(rootName, existingNames, rootName); - } - - /** - * Given a "root" name and a set of existing names, generate a unique - * name that is either the "root" name or some variation on the "root" - * name (e.g. "root2", "root3",...). The names are NOT case-sensitive - * (i.e. "Root" and "root" are NOT both allowed). - */ - public static String uniqueNameForIgnoreCase(String rootName, Iterator<String> existingNames) { - return uniqueNameForIgnoreCase(rootName, CollectionTools.set(existingNames)); - } - - /** - * Given a "root" name and a set of existing names, generate a unique - * name that is either the "root" name or some variation on the "root" - * name (e.g. "root2", "root3",...). The names are NOT case-sensitive - * (i.e. "Root" and "root" are NOT both allowed). - */ - public static String uniqueNameForIgnoreCase(String rootName, Collection<String> existingNames) { - return uniqueNameFor(rootName, convertToLowerCase(existingNames), rootName.toLowerCase()); - } - - /** - * use the suffixed "template" name to perform the comparisons, but RETURN - * the suffixed "root" name; this allows case-insensitive comparisons - * (i.e. the "template" name has been morphed to the same case as - * the "existing" names, while the "root" name has not, but the "root" name - * is what the client wants morphed to be unique) - */ - private static String uniqueNameFor(String rootName, Collection<String> existingNames, String templateName) { - if ( ! existingNames.contains(templateName)) { - return rootName; - } - String uniqueName = templateName; - for (int suffix = 2; true; suffix++) { - if ( ! existingNames.contains(uniqueName + suffix)) { - return rootName.concat(String.valueOf(suffix)); - } - } - } - - /** - * Convert the specified collection of strings to a collection of the same - * strings converted to lower case. - */ - private static HashSet<String> convertToLowerCase(Collection<String> strings) { - HashSet<String> result = new HashSet<String>(strings.size()); - for (String string : strings) { - result.add(string.toLowerCase()); - } - return result; - } - - /** - * Build a fully-qualified name for the specified database object. - * Variations: - * catalog.schema.name - * catalog..name - * schema.name - * name - */ - public static String buildQualifiedDatabaseObjectName(String catalog, String schema, String name) { - if (name == null) { - return null; - } - if ((catalog == null) && (schema == null)) { - return name; - } - - StringBuilder sb = new StringBuilder(100); - if (catalog != null) { - sb.append(catalog); - sb.append('.'); - } - if (schema != null) { - sb.append(schema); - } - sb.append('.'); - sb.append(name); - return sb.toString(); - } - - /** - * The set of reserved words in the Java programming language. - * These words cannot be used as identifiers (i.e. names). - * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html - */ - @SuppressWarnings("nls") - public static final String[] JAVA_RESERVED_WORDS = new String[] { - "abstract", - "assert", // jdk 1.4 - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", // unused - "continue", - "default", - "do", - "double", - "else", - "enum", // jdk 1.5 - "extends", - "false", - "final", - "finally", - "float", - "for", - "goto", // unused - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "new", - "null", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "strictfp", // jdk 1.2 - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "true", - "try", - "void", - "volatile", - "while" - }; - - /** - * The set of reserved words in the Java programming language. - * These words cannot be used as identifiers (i.e. names). - * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html - */ - public static final SortedSet<String> JAVA_RESERVED_WORDS_SET = - Collections.unmodifiableSortedSet(CollectionTools.sortedSet(JAVA_RESERVED_WORDS)); - - /** - * Return the set of Java programming language reserved words. - * These words cannot be used as identifiers (i.e. names). - * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html - */ - public static Iterator<String> javaReservedWords() { - return new ArrayIterator<String>(JAVA_RESERVED_WORDS); - } - - /** - * Return whether the specified string consists of Java identifier - * characters (but may be a reserved word). - */ - public static boolean stringConsistsOfJavaIdentifierCharacters(String string) { - if (string.length() == 0) { - return false; - } - return stringConsistsOfJavaIdentifierCharacters_(string.toCharArray()); - } - - /** - * Return whether the specified string consists of Java identifier - * characters (but may be a reserved word). - */ - public static boolean stringConsistsOfJavaIdentifierCharacters(char[] string) { - if (string.length == 0) { - return false; - } - return stringConsistsOfJavaIdentifierCharacters_(string); - } - - /** - * The specified string must not be empty. - */ - private static boolean stringConsistsOfJavaIdentifierCharacters_(char[] string) { - if ( ! Character.isJavaIdentifierStart(string[0])) { - return false; - } - for (int i = string.length; i-- > 1; ) { // NB: end with 1 - if ( ! Character.isJavaIdentifierPart(string[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified string is a valid Java identifier. - */ - public static boolean stringIsLegalJavaIdentifier(String string) { - return stringConsistsOfJavaIdentifierCharacters(string) - && ! JAVA_RESERVED_WORDS_SET.contains(string); - } - - /** - * Return whether the specified string is a valid Java identifier. - */ - public static boolean stringIsLegalJavaIdentifier(char[] string) { - return stringConsistsOfJavaIdentifierCharacters(string) - && ! JAVA_RESERVED_WORDS_SET.contains(new String(string)); - } - - /** - * Convert the specified string to a valid Java identifier - * by substituting an underscore '_' for any invalid characters - * in the string and appending an underscore '_' to the string if - * it is a Java reserved word. - */ - public static String convertToJavaIdentifier(String string) { - return convertToJavaIdentifier(string, '_'); - } - - /** - * Convert the specified string to a valid Java identifier - * by substituting the specified character for any invalid characters - * in the string and, if necessary, appending the specified character - * to the string until it is not a Java reserved word. - */ - public static String convertToJavaIdentifier(String string, char c) { - if (string.length() == 0) { - return string; - } - if (JAVA_RESERVED_WORDS_SET.contains(string)) { - // a reserved word is a valid identifier, we just need to tweak it a bit - checkCharIsJavaIdentifierPart(c); - return convertToJavaIdentifier(string + c, c); - } - char[] array = string.toCharArray(); - return convertToJavaIdentifier_(array, c) ? new String(array) : string; - } - - /** - * Convert the specified string to a valid Java identifier - * by substituting an underscore '_' for any invalid characters - * in the string and appending an underscore '_' to the string if - * it is a Java reserved word. - */ - public static char[] convertToJavaIdentifier(char[] string) { - return convertToJavaIdentifier(string, '_'); - } - - /** - * Convert the specified string to a valid Java identifier - * by substituting the specified character for any invalid characters - * in the string and, if necessary, appending the specified character - * to the string until it is not a Java reserved word. - */ - public static char[] convertToJavaIdentifier(char[] string, char c) { - if (string.length == 0) { - return string; - } - if (JAVA_RESERVED_WORDS_SET.contains(new String(string))) { - // a reserved word is a valid identifier, we just need to tweak it a bit - checkCharIsJavaIdentifierPart(c); - return convertToJavaIdentifier(CollectionTools.add(string, c), c); - } - convertToJavaIdentifier_(string, c); - return string; - } - - /** - * The specified string must not be empty. - * Return whether the string was modified. - */ - private static boolean convertToJavaIdentifier_(char[] string, char c) { - boolean mod = false; - if ( ! Character.isJavaIdentifierStart(string[0])) { - checkCharIsJavaIdentifierStart(c); - string[0] = c; - mod = true; - } - checkCharIsJavaIdentifierPart(c); - for (int i = string.length; i-- > 1; ) { // NB: end with 1 - if ( ! Character.isJavaIdentifierPart(string[i])) { - string[i] = c; - mod = true; - } - } - return mod; - } - - private static void checkCharIsJavaIdentifierStart(char c) { - if ( ! Character.isJavaIdentifierStart(c)) { - throw new IllegalArgumentException("invalid Java identifier start char: '" + c + '\''); //$NON-NLS-1$ - } - } - - private static void checkCharIsJavaIdentifierPart(char c) { - if ( ! Character.isJavaIdentifierPart(c)) { - throw new IllegalArgumentException("invalid Java identifier part char: '" + c + '\''); //$NON-NLS-1$ - } - } - - - // ********** constructor ********** - - /** - * Suppress default constructor, ensuring non-instantiability. - */ - private NameTools() { - super(); - throw new UnsupportedOperationException(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NullList.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NullList.java deleted file mode 100644 index 9c9b4eaafd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/NullList.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; - -/** - * A "null" list is a bit different from an "empty" list: it allows clients to - * add/remove elements to/from it but never changes. This is useful - * for passing to methods that require a "collecting parameter" but the - * client will ignore the resulting "collection". - * - * NB: We return 'null' from the following methods (as opposed to throwing - * an exception): - * get(int) : E - * remove(int) : E - * set(int, E) : E - */ -public final class NullList<E> implements List<E> { - - // singleton - @SuppressWarnings("unchecked") - private static final NullList INSTANCE = new NullList(); - - /** - * Return the singleton. - */ - @SuppressWarnings("unchecked") - public static <E> List<E> instance() { - return INSTANCE; - } - - /** - * Ensure single instance. - */ - private NullList() { - super(); - } - - public boolean add(E o) { - return false; // the list did not change - } - - public void add(int index, E element) { - // ignore - } - - public boolean addAll(Collection<? extends E> c) { - return false; // the list did not change - } - - public boolean addAll(int index, Collection<? extends E> c) { - return false; // the list did not change - } - - public void clear() { - // ignore - } - - public boolean contains(Object o) { - return false; - } - - public boolean containsAll(Collection<?> c) { - return c.isEmpty(); - } - - public E get(int index) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); - } - - public int indexOf(Object o) { - return -1; - } - - public boolean isEmpty() { - return true; - } - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - public int lastIndexOf(Object o) { - return -1; - } - - public ListIterator<E> listIterator() { - return EmptyListIterator.instance(); - } - - public ListIterator<E> listIterator(int index) { - return EmptyListIterator.instance(); - } - - public boolean remove(Object o) { - return false; // the list did not change - } - - public E remove(int index) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); - } - - public boolean removeAll(Collection<?> c) { - return false; // the list did not change - } - - public boolean retainAll(Collection<?> c) { - return false; // the list did not change - } - - public E set(int index, E element) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); - } - - public int size() { - return 0; - } - - public List<E> subList(int fromIndex, int toIndex) { - return this; - } - - private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - public Object[] toArray() { - return EMPTY_OBJECT_ARRAY; - } - - public <T> T[] toArray(T[] a) { - return a; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Range.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Range.java deleted file mode 100644 index 176918d635..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Range.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; - -/** - * This simple container class simply puts a bit of semantics - * around a pair of numbers. - */ -public class Range - implements Cloneable, Serializable -{ - /** The starting index of the range. */ - public final int start; - - /** The ending index of the range. */ - public final int end; - - /** - * The size can be negative if the ending index - * is less than the starting index. - */ - public final int size; - - private static final long serialVersionUID = 1L; - - - /** - * Construct with the specified start and end, - * both of which are immutable. - */ - public Range(int start, int end) { - super(); - this.start = start; - this.end = end; - this.size = end - start + 1; - } - - /** - * Return whether the range includes the specified - * index. - */ - public boolean includes(int index) { - return (this.start <= index) && (index <= this.end); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if ( ! (o instanceof Range)) { - return false; - } - Range otherRange = (Range) o; - return (this.start == otherRange.start) - && (this.end == otherRange.end); - } - - @Override - public int hashCode() { - return this.start ^ this.end; - } - - @Override - public Range clone() { - try { - return (Range) super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public String toString() { - return '[' + this.start + ", " + this.end + ']'; //$NON-NLS-1$ - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ReverseComparator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ReverseComparator.java deleted file mode 100644 index 10c01f80f0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ReverseComparator.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.Comparator; - -/** - * This comparator will reverse the order of the specified comparator. - * If the comparator is null, the natural ordering of the objects will be used. - */ -public class ReverseComparator<E extends Comparable<? super E>> - implements Comparator<E>, Serializable -{ - private final Comparator<E> comparator; - - public ReverseComparator() { - this(null); - } - - public ReverseComparator(Comparator<E> comparator) { - super(); - this.comparator = comparator; - } - - public int compare(E e1, E e2) { - return (this.comparator == null) ? - e2.compareTo(e1) - : - this.comparator.compare(e2, e1); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/RunnableCommand.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/RunnableCommand.java deleted file mode 100644 index 5b15ee088e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/RunnableCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import org.eclipse.jpt.utility.Command; - -/** - * Wrap a Runnable so it can be used as a Command. - */ -public class RunnableCommand implements Command { - protected final Runnable runnable; - - public RunnableCommand(Runnable runnable) { - super(); - if (runnable == null) { - throw new NullPointerException(); - } - this.runnable = runnable; - } - - public void execute() { - this.runnable.run(); - } - - @Override - public String toString() { - return "Command[" + this.runnable.toString() +']'; //$NON-NLS-1$ - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleAssociation.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleAssociation.java deleted file mode 100644 index 7c9b0a7401..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleAssociation.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; - -/** - * Straightforward implementation of Association. - */ -public class SimpleAssociation<K, V> - extends AbstractAssociation<K, V> - implements Cloneable, Serializable -{ - private final K key; - private V value; - - private static final long serialVersionUID = 1L; - - - /** - * Construct an association with the specified key - * and a null value. - */ - public SimpleAssociation(K key) { - super(); - this.key = key; - } - - /** - * Construct an association with the specified key and value. - */ - public SimpleAssociation(K key, V value) { - this(key); - this.value = value; - } - - - public K key() { - return this.key; - } - - public synchronized V value() { - return this.value; - } - - public synchronized V setValue(V value) { - V old = this.value; - this.value = value; - return old; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized SimpleAssociation<K, V> clone() { - try { - return (SimpleAssociation<K, V>) super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleFilter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleFilter.java deleted file mode 100644 index 80e21f939b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleFilter.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import org.eclipse.jpt.utility.Filter; - -/** - * Simple, abstract implementation of <code>Filter</code> - * that holds on to a criterion object that can be used in the - * <code>accept(Object)</code> or <code>reject(Object)</code> - * methods. Subclasses can override either of these methods, - * depending on which is easier to implement. Note that at least - * one of these methods <em>must</em> be overridden or - * an infinite loop will occur. If both of them are overridden, - * only the <code>accept(Object)</code> method will be used. - * <p> - * Simplifies the implementation of straightforward inner classes. - * Here is an example of a filter that can be used by a - * <code>FilteringIterator</code> to return only those strings - * in the nested iterator start with "prefix": - * <pre> - * Filter<String> filter = new SimpleFilter<String>("prefix") { - * public boolean accept(String o) { - * return o.startsWith((String) criterion); - * } - * }; - * </pre> - */ -public abstract class SimpleFilter<T, S> - implements Filter<T>, Cloneable, Serializable -{ - protected final S criterion; - - private static final long serialVersionUID = 1L; - - - /** - * More useful constructor. The specified criterion can - * be used by a subclass to "accept" or "reject" objects. - */ - protected SimpleFilter(S criterion) { - super(); - this.criterion = criterion; - } - - /** - * Construct a simple filter with a null criterion - */ - protected SimpleFilter() { - this(null); - } - - /** - * Return whether the the specified object should be "rejected". - * The semantics of "rejected" is determined by the client. - */ - protected boolean reject(T o) { - return ! this.accept(o); - } - - /** - * Return whether the the specified object should be "accepted". - * The semantics of "accepted" is determined by the client. - */ - public boolean accept(T o) { - return ! this.reject(o); - } - - @Override - @SuppressWarnings("unchecked") - public SimpleFilter<T, S> clone() { - try { - return (SimpleFilter<T, S>) super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public boolean equals(Object o) { - if ( ! (o instanceof SimpleFilter)) { - return false; - } - SimpleFilter<?, ?> other = (SimpleFilter<?, ?>) o; - return (this.criterion == null) ? - (other.criterion == null) : this.criterion.equals(other.criterion); - } - - @Override - public int hashCode() { - return (this.criterion == null) ? 0 : this.criterion.hashCode(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.criterion); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java deleted file mode 100644 index 0c64eafef3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.PrintWriter; -import java.io.Serializable; -import java.text.Collator; -import org.eclipse.jpt.utility.JavaType; - -/** - * Straightforward implementation of the JavaType interface. - */ -public final class SimpleJavaType - implements JavaType, Cloneable, Serializable -{ - - /** - * store the type as a name, so we can reference classes - * that are not loaded - */ - private final String elementTypeName; - - /** - * non-array types have an array depth of zero - */ - private final int arrayDepth; - - private static final String BRACKETS = "[]"; //$NON-NLS-1$ - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a Java type with the specified element type and array depth. - */ - public SimpleJavaType(String elementTypeName, int arrayDepth) { - super(); - if ((elementTypeName == null) || (elementTypeName.length() == 0)) { - throw new IllegalArgumentException("The element type name is required."); //$NON-NLS-1$ - } - if (ClassTools.arrayDepthForClassNamed(elementTypeName) != 0) { // e.g. "[Ljava.lang.Object;" - throw new IllegalArgumentException("The element type must not be an array: " + elementTypeName + '.'); //$NON-NLS-1$ - } - if (arrayDepth < 0) { - throw new IllegalArgumentException("The array depth must be greater than or equal to zero: " + arrayDepth + '.'); //$NON-NLS-1$ - } - if (elementTypeName.equals(void.class.getName()) && (arrayDepth != 0)) { - throw new IllegalArgumentException("'void' must have an array depth of zero: " + arrayDepth + '.'); //$NON-NLS-1$ - } - this.elementTypeName = elementTypeName; - this.arrayDepth = arrayDepth; - } - - /** - * Construct a Java type for the specified class. - * The class name can be in one of the following forms: - * java.lang.Object - * int - * java.util.Map$Entry - * [Ljava.lang.Object; - * [I - * [Ljava.util.Map$Entry; - */ - public SimpleJavaType(String javaClassName) { - this(ClassTools.elementTypeNameForClassNamed(javaClassName), ClassTools.arrayDepthForClassNamed(javaClassName)); - } - - /** - * Construct a Java type for the specified class. - */ - public SimpleJavaType(Class<?> javaClass) { - this(javaClass.getName()); - } - - - // ********** accessors ********** - - public String getElementTypeName() { - return this.elementTypeName; - } - - public int getArrayDepth() { - return this.arrayDepth; - } - - - // ********** queries ********** - - public boolean isArray() { - return this.arrayDepth > 0; - } - - public boolean isPrimitive() { - return (this.arrayDepth == 0) && ClassTools.classNamedIsPrimitive(this.elementTypeName); - } - - public boolean isPrimitiveWrapper() { - return (this.arrayDepth == 0) && ClassTools.classNamedIsPrimitiveWrapperClass(this.elementTypeName); - } - - public boolean isVariablePrimitive() { - return (this.arrayDepth == 0) && ClassTools.classNamedIsVariablePrimitive(this.elementTypeName); - } - - public boolean isVariablePrimitiveWrapper() { - return (this.arrayDepth == 0) && ClassTools.classNamedIsVariablePrimitiveWrapperClass(this.elementTypeName); - } - - public Class<?> getJavaClass() throws ClassNotFoundException { - return ClassTools.classForTypeDeclaration(this.elementTypeName, this.arrayDepth); - } - - public String getJavaClassName() { - return ClassTools.classNameForTypeDeclaration(this.elementTypeName, this.arrayDepth); - } - - - // ********** comparison ********** - - public boolean equals(String otherElementTypeName, int otherArrayDepth) { - return (this.arrayDepth == otherArrayDepth) - && this.elementTypeName.equals(otherElementTypeName); - } - - public boolean describes(String className) { - return this.equals(ClassTools.elementTypeNameForClassNamed(className), ClassTools.arrayDepthForClassNamed(className)); - } - - public boolean describes(Class<?> javaClass) { - return this.describes(javaClass.getName()); - } - - public boolean equals(JavaType other) { - return this.equals(other.getElementTypeName(), other.getArrayDepth()); - } - - @Override - public boolean equals(Object o) { - return (this == o) ? true : (o instanceof JavaType) ? this.equals((JavaType) o) : false; - } - - @Override - public int hashCode() { - return this.elementTypeName.hashCode() ^ this.arrayDepth; - } - - public int compareTo(JavaType jt) { - int x = Collator.getInstance().compare(this.elementTypeName, jt.getElementTypeName()); - return (x != 0) ? x : (this.arrayDepth - jt.getArrayDepth()); - } - - - // ********** printing and displaying ********** - - /** - * Return the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - public String declaration() { - if (this.arrayDepth == 0) { - return this.getElementTypeNameDeclaration(); - } - StringBuilder sb = new StringBuilder(this.elementTypeName.length() + (2 * this.arrayDepth)); - this.appendDeclarationTo(sb); - return sb.toString(); - } - - /** - * Append the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - public void appendDeclarationTo(StringBuilder sb) { - sb.append(this.getElementTypeNameDeclaration()); - for (int i = this.arrayDepth; i-- > 0; ) { - sb.append(BRACKETS); - } - } - - /** - * Print the version of the type's name that can be used in source code: - * "[[J" => "long[][]" - * "java.util.Map$Entry" => "java.util.Map.Entry" - */ - public void printDeclarationOn(PrintWriter pw) { - pw.print(this.getElementTypeNameDeclaration()); - for (int i = this.arrayDepth; i-- > 0; ) { - pw.print(BRACKETS); - } - } - - /** - * The '$' version of the name is used in Class.forName(String), - * but the '.' verions of the name is used in source code. - * Very irritating.... - */ - private String getElementTypeNameDeclaration() { - return this.elementTypeName.replace('$', '.'); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(ClassTools.shortClassNameForObject(this)); - sb.append('('); - this.appendDeclarationTo(sb); - sb.append(')'); - return sb.toString(); - } - - - // ********** cloning ********** - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java deleted file mode 100644 index a02891379d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.PrintWriter; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.text.Collator; -import java.util.Arrays; -import org.eclipse.jpt.utility.JavaType; -import org.eclipse.jpt.utility.MethodSignature; - -/** - * Straightforward implementation of the MethodSignature interface. - */ -public final class SimpleMethodSignature - implements MethodSignature, Cloneable, Serializable -{ - private final String name; - - /** - * store the parameter types as names, so we can reference classes - * that are not loaded - */ - private final JavaType[] parameterTypes; - - public static final JavaType[] EMPTY_PARAMETER_TYPES = new JavaType[0]; - - private static final String PARAMETER_SEPARATOR = ", "; //$NON-NLS-1$ - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a method signature with the specified name and - * no parameter types. - */ - public SimpleMethodSignature(String name) { - this(name, EMPTY_PARAMETER_TYPES); - } - - /** - * Construct a method signature with the specified name and parameter - * types. - */ - public SimpleMethodSignature(String name, JavaType... parameterTypes) { - super(); - if ((name == null) || (name.length() == 0)) { - throw new IllegalArgumentException("The name is required."); //$NON-NLS-1$ - } - if (parameterTypes == null) { - throw new IllegalArgumentException("The parameter types are required."); //$NON-NLS-1$ - } - checkParameterTypes(parameterTypes); - this.name = name; - this.parameterTypes = parameterTypes; - } - - private static void checkParameterTypes(JavaType[] parameterTypes) { - for (int i = 0; i < parameterTypes.length; i++) { - if (parameterTypes[i] == null) { - throw new IllegalArgumentException("Missing parameter type: " + i); //$NON-NLS-1$ - } - if (parameterTypes[i].getElementTypeName().equals(void.class.getName())) { - throw new IllegalArgumentException("A parameter type of 'void' is not allowed: " + i); //$NON-NLS-1$ - } - } - } - - /** - * Construct a method signature with the specified name and parameter - * types. - */ - public SimpleMethodSignature(String name, String... parameterTypeNames) { - this(name, buildParameterTypes(parameterTypeNames)); - } - - private static JavaType[] buildParameterTypes(String[] parameterTypeNames) { - if (parameterTypeNames == null) { - throw new IllegalArgumentException("The parameter type names are required."); //$NON-NLS-1$ - } - JavaType[] parameterTypes = new JavaType[parameterTypeNames.length]; - for (int i = 0; i < parameterTypeNames.length; i++) { - if (parameterTypeNames[i] == null) { - throw new IllegalArgumentException("Missing parameter type name: " + i); //$NON-NLS-1$ - } - parameterTypes[i] = new SimpleJavaType(parameterTypeNames[i]); - } - return parameterTypes; - } - - /** - * Construct a method signature with the specified name and parameter - * types. - */ - public SimpleMethodSignature(String name, Class<?>... parameterJavaClasses) { - this(name, buildParameterTypeNames(parameterJavaClasses)); - } - - private static String[] buildParameterTypeNames(Class<?>[] parameterJavaClasses) { - if (parameterJavaClasses == null) { - throw new IllegalArgumentException("The parameter Java classes are required."); //$NON-NLS-1$ - } - String[] parameterTypeNames = new String[parameterJavaClasses.length]; - for (int i = 0; i < parameterJavaClasses.length; i++) { - if (parameterJavaClasses[i] == null) { - throw new IllegalArgumentException("Missing parameter Java class: " + i); //$NON-NLS-1$ - } - parameterTypeNames[i] = parameterJavaClasses[i].getName(); - } - return parameterTypeNames; - } - - /** - * Construct a method signature for the specified Java method. - */ - public SimpleMethodSignature(Method method) { - this(method.getName(), method.getParameterTypes()); - } - - - // ********** accessors ********** - - public String getName() { - return this.name; - } - - public JavaType[] getParameterTypes() { - return this.parameterTypes; - } - - - // ********** comparison ********** - - public boolean describes(Method method) { - return this.name.equals(method.getName()) - && this.parameterTypesDescribe(method.getParameterTypes()); - } - - private boolean parameterTypesDescribe(Class<?>[] otherParameterTypes) { - JavaType[] localParameterTypes = this.parameterTypes; - int len = localParameterTypes.length; - if (otherParameterTypes.length != len) { - return false; - } - for (int i = len; i-- > 0; ) { - if ( ! localParameterTypes[i].describes(otherParameterTypes[i])) { - return false; - } - } - return true; - } - - public boolean equals(String otherName, JavaType[] otherParameterTypes) { - return this.name.equals(otherName) - && Arrays.equals(this.parameterTypes, otherParameterTypes); - } - - public boolean equals(MethodSignature other) { - return this.equals(other.getName(), other.getParameterTypes()); - } - - @Override - public boolean equals(Object o) { - return (this == o) ? true : (o instanceof MethodSignature) ? this.equals((MethodSignature) o) : false; - } - - @Override - public int hashCode() { - return this.name.hashCode() ^ Arrays.hashCode(this.parameterTypes); - } - - public int compareTo(MethodSignature ms) { - int compare = Collator.getInstance().compare(this.name, ms.getName()); - return (compare != 0) ? compare : this.compareParameterTypes(ms.getParameterTypes()); - } - - private int compareParameterTypes(JavaType[] otherParameterTypes) { - JavaType[] localParameterTypes = this.parameterTypes; - int len1 = localParameterTypes.length; - int len2 = otherParameterTypes.length; - int min = Math.min(len1, len2); - for (int i = 0; i < min; i++) { - int compare = localParameterTypes[i].compareTo(otherParameterTypes[i]); - if (compare != 0) { - return compare; - } - } - return (len1 == len2) ? 0 : (len1 < len2) ? -1 : 1; - } - - - // ********** printing and displaying ********** - - public String getSignature() { - StringBuilder sb = new StringBuilder(200); - this.appendSignatureTo(sb); - return sb.toString(); - } - - public void appendSignatureTo(StringBuilder sb) { - sb.append(this.name); - sb.append('('); - JavaType[] localParameterTypes = this.parameterTypes; - int len = localParameterTypes.length; - for (int i = 0; i < len; i++) { - if (i != 0) { - sb.append(PARAMETER_SEPARATOR); - } - localParameterTypes[i].appendDeclarationTo(sb); - } - sb.append(')'); - } - - public void printSignatureOn(PrintWriter pw) { - pw.print(this.name); - pw.print('('); - JavaType[] localParameterTypes = this.parameterTypes; - int len = localParameterTypes.length; - for (int i = 0; i < len; i++) { - if (i != 0) { - pw.print(PARAMETER_SEPARATOR); - } - localParameterTypes[i].printDeclarationOn(pw); - } - pw.print(')'); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(200); - sb.append(ClassTools.shortClassNameForObject(this)); - sb.append('('); - this.appendSignatureTo(sb); - sb.append(')'); - return sb.toString(); - } - - - // ********** cloning ********** - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java deleted file mode 100644 index f183943d9a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.Collection; -import java.util.EmptyStackException; -import java.util.LinkedList; -import java.util.NoSuchElementException; - -/** - * Straightforward implementation of the Stack interface. - */ -public class SimpleStack<E> - implements Stack<E>, Cloneable, Serializable -{ - private LinkedList<E> elements; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct an empty stack. - */ - public SimpleStack() { - super(); - this.elements = new LinkedList<E>(); - } - - /** - * Construct a stack containing the elements of the specified - * collection. The stack will pop its elements in reverse of the - * order they are returned by the collection's iterator (i.e. the - * last element returned by the collection's iterator will be the - * first element returned by #pop()). - */ - public SimpleStack(Collection<? extends E> c) { - super(); - this.elements = new LinkedList<E>(c); - } - - - // ********** Stack implementation ********** - - public void push(E o) { - this.elements.addLast(o); - } - - public E pop() { - try { - return this.elements.removeLast(); - } catch (NoSuchElementException ex) { - throw new EmptyStackException(); - } - } - - public E peek() { - try { - return this.elements.getLast(); - } catch (NoSuchElementException ex) { - throw new EmptyStackException(); - } - } - - public boolean isEmpty() { - return this.elements.isEmpty(); - } - - - // ********** Cloneable implementation ********** - - @Override - public SimpleStack<E> clone() { - try { - @SuppressWarnings("unchecked") - SimpleStack<E> clone = (SimpleStack<E>) super.clone(); - @SuppressWarnings("unchecked") - LinkedList<E> ll = (LinkedList<E>) this.elements.clone(); - clone.elements = ll; - return clone; - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStringMatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStringMatcher.java deleted file mode 100644 index 5631b623c8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStringMatcher.java +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.regex.Pattern; -import org.eclipse.jpt.utility.Filter; - -// TODO the regex code is not very fast - we could probably do better, -// hand-coding the matching algorithm (eclipse StringMatcher?) -/** - * This class implements a simple string-matching algorithm that is a little - * more user-friendly than standard regular expressions. Instantiate a - * string matcher with a filter pattern and then you can use the matcher - * to determine whether another string (or object) matches the pattern. - * You can also specify whether the matching should be case-sensitive. - * - * The pattern can contain two "meta-characters": - * '*' will match any set of zero or more characters - * '?' will match any single character - * - * Subclasses can override #prefix() and/or #suffix() to change what - * strings are prepended or appended to the original pattern string. - * This can offer a slight performance improvement over concatenating - * strings before calling #setPatternString(String). - * By default, a '*' is appended to every string. - * - * This class also uses the string-matching algorithm to "filter" objects - * (and, as a result, also implements the Filter interface). - * A string converter is used to determine what string aspect of the - * object is compared to the pattern. By default the string returned - * by the object's #toString() method is passed to the pattern matcher. - */ -public class SimpleStringMatcher<T> - implements StringMatcher, Filter<T>, Serializable -{ - - /** An adapter that converts the objects into strings to be matched with the pattern. */ - private StringConverter<T> stringConverter; - - /** The string used to construct the regular expression pattern. */ - private String patternString; - - /** Whether the matcher ignores case - the default is true. */ - private boolean ignoresCase; - - /** The regular expression pattern built from the pattern string. */ - private Pattern pattern; - - /** A list of the meta-characters we need to escape if found in the pattern string. */ - public static final char[] REG_EX_META_CHARS = { '(', '[', '{', '\\', '^', '$', '|', ')', '?', '*', '+', '.' }; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a string matcher with an pattern that will match - * any string and ignore case. - */ - public SimpleStringMatcher() { - this("*"); - } - - /** - * Construct a string matcher with the specified pattern - * that will ignore case. - */ - public SimpleStringMatcher(String patternString) { - this(patternString, true); - } - - /** - * Construct a string matcher with the specified pattern that will - * ignore case as specified. - */ - public SimpleStringMatcher(String patternString, boolean ignoresCase) { - super(); - this.patternString = patternString; - this.ignoresCase = ignoresCase; - this.initialize(); - } - - - // ********** initialization ********** - - protected void initialize() { - this.stringConverter = StringConverter.Default.instance(); - this.rebuildPattern(); - } - - /** - * Given the current pattern string and case-sensitivity setting, - * re-build the regular expression pattern. - */ - protected synchronized void rebuildPattern() { - this.pattern = this.buildPattern(); - } - - /** - * Given the current pattern string and case-sensitivity setting, - * build and return a regular expression pattern that can be used - * to match strings. - */ - protected Pattern buildPattern() { - int patternFlags = 0x0; - if (this.ignoresCase) { - patternFlags = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE; - } - return Pattern.compile(this.convertToRegEx(this.patternString), patternFlags); - } - - - // ********** StringMatcher implementation ********** - - public synchronized void setPatternString(String patternString) { - this.patternString = patternString; - this.rebuildPattern(); - } - - /** - * Return whether the specified string matches the pattern. - */ - public synchronized boolean matches(String string) { - return this.pattern.matcher(string).matches(); - } - - - // ********** Filter implementation ********** - - public synchronized boolean accept(T o) { - return this.matches(this.stringConverter.convertToString(o)); - } - - - // ********** accessors ********** - - /** - * Return the string converter used to convert the objects - * passed to the matcher into strings. - */ - public synchronized StringConverter<T> stringConverter() { - return this.stringConverter; - } - - /** - * Set the string converter used to convert the objects - * passed to the matcher into strings. - */ - public synchronized void setStringConverter(StringConverter<T> stringConverter) { - this.stringConverter = stringConverter; - } - - /** - * Return the original pattern string. - */ - public synchronized String patternString() { - return this.patternString; - } - - /** - * Return whether the matcher ignores case. - */ - public synchronized boolean ignoresCase() { - return this.ignoresCase; - } - - /** - * Set whether the matcher ignores case. - */ - public synchronized void setIgnoresCase(boolean ignoresCase) { - this.ignoresCase = ignoresCase; - this.rebuildPattern(); - } - - /** - * Return the regular expression pattern. - */ - public synchronized Pattern pattern() { - return this.pattern; - } - - - // ********** other public API ********** - - /** - * Return the regular expression corresponding to - * the original pattern string. - */ - public synchronized String regularExpression() { - return this.convertToRegEx(this.patternString); - } - - - // ********** converting ********** - - /** - * Convert the specified string to a regular expression. - */ - protected String convertToRegEx(String string) { - StringBuffer sb = new StringBuffer(string.length() + 10); - this.convertToRegExOn(this.prefix(), sb); - this.convertToRegExOn(string, sb); - this.convertToRegExOn(this.suffix(), sb); - return sb.toString(); - } - - /** - * Return any prefix that should be prepended to the original - * string. By default, there is no prefix. - */ - protected String prefix() { - return ""; - } - - /** - * Return any suffix that should be appended to the original - * string. Since this class is typically used in UI situation where - * the user is typing in a pattern used to filter a list, the default - * suffix is a wildcard character. - */ - protected String suffix() { - return "*"; - } - - /** - * Convert the specified string to a regular expression. - */ - protected void convertToRegExOn(String string, StringBuffer sb) { - char[] charArray = string.toCharArray(); - int length = charArray.length; - for (int i = 0; i < length; i++) { - char c = charArray[i]; - // convert user-friendly meta-chars into regex meta-chars - if (c == '*') { - sb.append(".*"); - continue; - } - if (c == '?') { - sb.append('.'); - continue; - } - // escape regex meta-chars - if (CollectionTools.contains(REG_EX_META_CHARS, c)) { - sb.append('\\'); - } - sb.append(c); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java deleted file mode 100644 index 93bef64f4b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.EmptyStackException; - -/** - * Interface defining the classic stack behavior, - * without the backdoors allowed by java.util.Stack. - * E is the type of elements contained by the Stack. - */ -public interface Stack<E> { - - /** - * "Push" the specified item on to the top of the stack. - */ - void push(E o); - - /** - * "Pop" an item from the top of the stack. - */ - E pop(); - - /** - * Return the item on the top of the stack - * without removing it from the stack. - */ - E peek(); - - /** - * Return whether the stack is empty. - */ - boolean isEmpty(); - - - final class Empty<E> implements Stack<E>, Serializable { - @SuppressWarnings("unchecked") - public static final Stack INSTANCE = new Empty(); - @SuppressWarnings("unchecked") - public static <T> Stack<T> instance() { - return INSTANCE; - } - // ensure single instance - private Empty() { - super(); - } - public void push(E o) { - throw new UnsupportedOperationException(); - } - public E pop() { - throw new EmptyStackException(); - } - public E peek() { - throw new EmptyStackException(); - } - public boolean isEmpty() { - return true; - } - private static final long serialVersionUID = 1L; - private Object readResolve() { - return INSTANCE; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java deleted file mode 100644 index 556b530862..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Used by various "pluggable" classes to transform objects - * into strings. - */ -public interface StringConverter<T> { - - /** - * Convert the specified object into a string. - * The semantics of "convert" is determined by the - * contract between the client and the server. - */ - String convertToString(T o); - - - final class Default<S> implements StringConverter<S> { - @SuppressWarnings("unchecked") - public static final StringConverter INSTANCE = new Default(); - @SuppressWarnings("unchecked") - public static <R> StringConverter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Default() { - super(); - } - // simply return the object's #toString() result - public String convertToString(S o) { - return (o == null) ? null : o.toString(); - } - @Override - public String toString() { - return "StringConverter.Default"; - } - } - - final class Disabled<S> implements StringConverter<S> { - @SuppressWarnings("unchecked") - public static final StringConverter INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> StringConverter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public String convertToString(S o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "StringConverter.Disabled"; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringMatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringMatcher.java deleted file mode 100644 index 5f769d7040..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringMatcher.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * This interface defines a simple API for allowing "pluggable" - * string matchers that can be configured with a pattern string - * then used to determine what strings match the pattern. - */ -public interface StringMatcher { - - /** - * Set the pattern string used to determine future - * matches. The format and semantics of the pattern - * string are determined by the contract between the - * client and the server. - */ - void setPatternString(String patternString); - - /** - * Return whether the specified string matches the - * established pattern string. The semantics of a match - * is determined by the contract between the - * client and the server. - */ - boolean matches(String string); - - - final class Null implements StringMatcher { - public static final StringMatcher INSTANCE = new Null(); - public static StringMatcher instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - public void setPatternString(String patternString) { - // ignore the pattern string - } - public boolean matches(String string) { - // everything is a match - return true; - } - @Override - public String toString() { - return "StringMatcher.Null"; - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringTools.java deleted file mode 100644 index 4fd0a82dac..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringTools.java +++ /dev/null @@ -1,4108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.IOException; -import java.io.Writer; -import java.util.Arrays; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; - -/** - * Convenience methods related to the java.lang.String class. - * - * As of jdk 1.5, it's tempting to convert all of these methods to use - * java.lang.Appendable (instead of StringBuffer, StringBuilder, and Writer); - * but all the Appendable methods throw java.io.IOException (yech) and we - * [might?] get a bit better performance invoking methods on classes than - * we get on interfaces. :-) - */ -public final class StringTools { - - /** carriage return */ - public static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$ - - /** double quote */ - public static final char QUOTE = '"'; - - /** parenthesis */ - public static final char OPEN_PARENTHESIS = '('; - public static final char CLOSE_PARENTHESIS = ')'; - - /** brackets */ - public static final char OPEN_BRACKET = '['; - public static final char CLOSE_BRACKET = ']'; - - /** brackets */ - public static final char OPEN_BRACE = '{'; - public static final char CLOSE_BRACE = '}'; - - /** brackets */ - public static final char OPEN_CHEVRON = '<'; - public static final char CLOSE_CHEVRON = '>'; - - /** empty string */ - public static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - /** empty char array */ - public static final char[] EMPTY_CHAR_ARRAY = new char[0]; - - - - // ********** padding/truncating ********** - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#pad(int) - */ - public static String pad(String string, int length) { - return pad(string, length, ' '); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, Writer) - */ - public static void padOn(String string, int length, Writer writer) { - padOn(string, length, ' ', writer); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, StringBuffer) - */ - public static void padOn(String string, int length, StringBuffer sb) { - padOn(string, length, ' ', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, StringBuilder) - */ - public static void padOn(String string, int length, StringBuilder sb) { - padOn(string, length, ' ', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#pad(int, char) - */ - public static String pad(String string, int length, char c) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - return string; - } - return pad_(string, length, c); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, Writer) - */ - public static void padOn(String string, int length, char c, Writer writer) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - writeStringOn(string, writer); - } else { - padOn_(string, length, c, writer); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, StringBuffer) - */ - public static void padOn(String string, int length, char c, StringBuffer sb) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, StringBuilder) - */ - public static void padOn(String string, int length, char c, StringBuilder sb) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#pad(int) - */ - public static char[] pad(char[] string, int length) { - return pad(string, length, ' '); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, writer) - */ - public static void padOn(char[] string, int length, Writer writer) { - padOn(string, length, ' ', writer); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, StringBuffer) - */ - public static void padOn(char[] string, int length, StringBuffer sb) { - padOn(string, length, ' ', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOn(int, StringBuilder) - */ - public static void padOn(char[] string, int length, StringBuilder sb) { - padOn(string, length, ' ', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#pad(int, char) - */ - public static char[] pad(char[] string, int length, char c) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - return string; - } - return pad_(string, length, c); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, Writer) - */ - public static void padOn(char[] string, int length, char c, Writer writer) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - writeStringOn(string, writer); - } else { - padOn_(string, length, c, writer); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, StringBuffer) - */ - public static void padOn(char[] string, int length, char c, StringBuffer sb) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOn(int, char, StringBuilder) - */ - public static void padOn(char[] string, int length, char c, StringBuilder sb) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncate(int) - */ - public static String padOrTruncate(String string, int length) { - return padOrTruncate(string, length, ' '); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, Writer) - */ - public static void padOrTruncateOn(String string, int length, Writer writer) { - padOrTruncateOn(string, length, ' ', writer); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, StringBuffer) - */ - public static void padOrTruncateOn(String string, int length, StringBuffer sb) { - padOrTruncateOn(string, length, ' ', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, StringBuilder) - */ - public static void padOrTruncateOn(String string, int length, StringBuilder sb) { - padOrTruncateOn(string, length, ' ', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncate(int, char) - */ - public static String padOrTruncate(String string, int length, char c) { - int stringLength = string.length(); - if (stringLength == length) { - return string; - } - if (stringLength > length) { - return string.substring(0, length); - } - return pad_(string, length, c); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, Writer) - */ - public static void padOrTruncateOn(String string, int length, char c, Writer writer) { - int stringLength = string.length(); - if (stringLength == length) { - writeStringOn(string, writer); - } else if (stringLength > length) { - writeStringOn(string.substring(0, length), writer); - } else { - padOn_(string, length, c, writer); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, StringBuffer) - */ - public static void padOrTruncateOn(String string, int length, char c, StringBuffer sb) { - int stringLength = string.length(); - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string.substring(0, length)); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, StringBuilder) - */ - public static void padOrTruncateOn(String string, int length, char c, StringBuilder sb) { - int stringLength = string.length(); - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string.substring(0, length)); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncate(int) - */ - public static char[] padOrTruncate(char[] string, int length) { - return padOrTruncate(string, length, ' '); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, Writer) - */ - public static void padOrTruncateOn(char[] string, int length, Writer writer) { - padOrTruncateOn(string, length, ' ', writer); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, StringBuffer) - */ - public static void padOrTruncate(char[] string, int length, StringBuffer sb) { - padOrTruncateOn(string, length, ' ', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with spaces at the end. - * String#padOrTruncateOn(int, StringBuilder) - */ - public static void padOrTruncate(char[] string, int length, StringBuilder sb) { - padOrTruncateOn(string, length, ' ', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncate(int, char) - */ - public static char[] padOrTruncate(char[] string, int length, char c) { - int stringLength = string.length; - if (stringLength == length) { - return string; - } - if (stringLength > length) { - char[] result = new char[length]; - System.arraycopy(string, 0, result, 0, length); - return result; - } - return pad_(string, length, c); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, Writer) - */ - public static void padOrTruncateOn(char[] string, int length, char c, Writer writer) { - int stringLength = string.length; - if (stringLength == length) { - writeStringOn(string, writer); - } else if (stringLength > length) { - writeStringOn(string, 0, length, writer); - } else { - padOn_(string, length, c, writer); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, StringBuffer) - */ - public static void padOrTruncateOn(char[] string, int length, char c, StringBuffer sb) { - int stringLength = string.length; - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string, 0, length); - } else { - padOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, it is truncated. - * If it is shorter than the specified length, it is padded with the - * specified character at the end. - * String#padOrTruncateOn(int, char, StringBuilder) - */ - public static void padOrTruncateOn(char[] string, int length, char c, StringBuilder sb) { - int stringLength = string.length; - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string, 0, length); - } else { - padOn_(string, length, c, sb); - } - } - - /* - * Pad the specified string without validating the parms. - */ - private static String pad_(String string, int length, char c) { - return new String(pad_(string.toCharArray(), length, c)); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(String string, int length, char c, Writer writer) { - writeStringOn(string, writer); - fill_(string, length, c, writer); - } - - /* - * Add enough characters to the specified writer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(String string, int length, char c, Writer writer) { - fill_(string.length(), length, c, writer); - } - - /* - * Add enough characters to the specified writer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(char[] string, int length, char c, Writer writer) { - fill_(string.length, length, c, writer); - } - - /* - * Add enough characters to the specified writer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(int stringLength, int length, char c, Writer writer) { - writeStringOn(CollectionTools.fill(new char[length - stringLength], c), writer); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(String string, int length, char c, StringBuffer sb) { - sb.append(string); - fill_(string, length, c, sb); - } - - /* - * Add enough characters to the specified string buffer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(String string, int length, char c, StringBuffer sb) { - fill_(string.length(), length, c, sb); - } - - /* - * Add enough characters to the specified string buffer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(char[] string, int length, char c, StringBuffer sb) { - fill_(string.length, length, c, sb); - } - - /* - * Add enough characters to the specified string buffer to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(int stringLength, int length, char c, StringBuffer sb) { - sb.append(CollectionTools.fill(new char[length - stringLength], c)); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(String string, int length, char c, StringBuilder sb) { - sb.append(string); - fill_(string, length, c, sb); - } - - /* - * Add enough characters to the specified string builder to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(String string, int length, char c, StringBuilder sb) { - fill_(string.length(), length, c, sb); - } - - /* - * Add enough characters to the specified string builder to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(char[] string, int length, char c, StringBuilder sb) { - fill_(string.length, length, c, sb); - } - - /* - * Add enough characters to the specified string builder to compensate for - * the difference between the specified string and specified length. - */ - private static void fill_(int stringLength, int length, char c, StringBuilder sb) { - sb.append(CollectionTools.fill(new char[length - stringLength], c)); - } - - /* - * Pad the specified string without validating the parms. - */ - private static char[] pad_(char[] string, int length, char c) { - char[] result = new char[length]; - int stringLength = string.length; - System.arraycopy(string, 0, result, 0, stringLength); - Arrays.fill(result, stringLength, length, c); - return result; - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(char[] string, int length, char c, Writer writer) { - writeStringOn(string, writer); - fill_(string, length, c, writer); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(char[] string, int length, char c, StringBuffer sb) { - sb.append(string); - fill_(string, length, c, sb); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void padOn_(char[] string, int length, char c, StringBuilder sb) { - sb.append(string); - fill_(string, length, c, sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPad(int) - */ - public static String zeroPad(String string, int length) { - return frontPad(string, length, '0'); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, Writer) - */ - public static void zeroPadOn(String string, int length, Writer writer) { - frontPadOn(string, length, '0', writer); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, StringBuffer) - */ - public static void zeroPadOn(String string, int length, StringBuffer sb) { - frontPadOn(string, length, '0', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, StringBuilder) - */ - public static void zeroPadOn(String string, int length, StringBuilder sb) { - frontPadOn(string, length, '0', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPad(int, char) - */ - public static String frontPad(String string, int length, char c) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - return string; - } - return frontPad_(string, length, c); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, Writer) - */ - public static void frontPadOn(String string, int length, char c, Writer writer) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - writeStringOn(string, writer); - } else { - frontPadOn_(string, length, c, writer); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, StringBuffer) - */ - public static void frontPadOn(String string, int length, char c, StringBuffer sb) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, StringBuilder) - */ - public static void frontPadOn(String string, int length, char c, StringBuilder sb) { - int stringLength = string.length(); - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPad(int) - */ - public static char[] zeroPad(char[] string, int length) { - return frontPad(string, length, '0'); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, Writer) - */ - public static void zeroPadOn(char[] string, int length, Writer writer) { - frontPadOn(string, length, '0', writer); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, StringBuffer) - */ - public static void zeroPadOn(char[] string, int length, StringBuffer sb) { - frontPadOn(string, length, '0', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOn(int, StringBuilder) - */ - public static void zeroPadOn(char[] string, int length, StringBuilder sb) { - frontPadOn(string, length, '0', sb); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPad(int, char) - */ - public static char[] frontPad(char[] string, int length, char c) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - return string; - } - return frontPad_(string, length, c); - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, Writer) - */ - public static void frontPadOn(char[] string, int length, char c, Writer writer) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - writeStringOn(string, writer); - } else { - frontPadOn_(string, length, c, writer); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, StringBuffer) - */ - public static void frontPadOn(char[] string, int length, char c, StringBuffer sb) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, an IllegalArgumentException is thrown. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOn(int, char, StringBuilder) - */ - public static void frontPadOn(char[] string, int length, char c, StringBuilder sb) { - int stringLength = string.length; - if (stringLength > length) { - throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (stringLength == length) { - sb.append(string); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncate(int) - */ - public static String zeroPadOrTruncate(String string, int length) { - return frontPadOrTruncate(string, length, '0'); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, Writer) - */ - public static void zeroPadOrTruncateOn(String string, int length, Writer writer) { - frontPadOrTruncateOn(string, length, '0', writer); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, StringBuffer) - */ - public static void zeroPadOrTruncateOn(String string, int length, StringBuffer sb) { - frontPadOrTruncateOn(string, length, '0', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, StringBuilder) - */ - public static void zeroPadOrTruncateOn(String string, int length, StringBuilder sb) { - frontPadOrTruncateOn(string, length, '0', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncate(int, char) - */ - public static String frontPadOrTruncate(String string, int length, char c) { - int stringLength = string.length(); - if (stringLength == length) { - return string; - } - if (stringLength > length) { - return string.substring(stringLength - length); - } - return frontPad_(string, length, c); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, Writer) - */ - public static void frontPadOrTruncateOn(String string, int length, char c, Writer writer) { - int stringLength = string.length(); - if (stringLength == length) { - writeStringOn(string, writer); - } else if (stringLength > length) { - writeStringOn(string.substring(stringLength - length), writer); - } else { - frontPadOn_(string, length, c, writer); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, StringBuffer) - */ - public static void frontPadOrTruncateOn(String string, int length, char c, StringBuffer sb) { - int stringLength = string.length(); - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string.substring(stringLength - length)); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, StringBuilder) - */ - public static void frontPadOrTruncateOn(String string, int length, char c, StringBuilder sb) { - int stringLength = string.length(); - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string.substring(stringLength - length)); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncate(int) - */ - public static char[] zeroPadOrTruncate(char[] string, int length) { - return frontPadOrTruncate(string, length, '0'); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, Writer) - */ - public static void zeroPadOrTruncateOn(char[] string, int length, Writer writer) { - frontPadOrTruncateOn(string, length, '0', writer); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, StringBuffer) - */ - public static void zeroPadOrTruncateOn(char[] string, int length, StringBuffer sb) { - frontPadOrTruncateOn(string, length, '0', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with zeros at the front. - * String#zeroPadOrTruncateOn(int, StringBuilder) - */ - public static void zeroPadOrTruncateOn(char[] string, int length, StringBuilder sb) { - frontPadOrTruncateOn(string, length, '0', sb); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncate(int, char) - */ - public static char[] frontPadOrTruncate(char[] string, int length, char c) { - int stringLength = string.length; - if (stringLength == length) { - return string; - } - if (stringLength > length) { - char[] result = new char[length]; - System.arraycopy(string, stringLength - length, result, 0, length); - return result; - } - return frontPad_(string, length, c); - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, Writer) - */ - public static void frontPadOrTruncateOn(char[] string, int length, char c, Writer writer) { - int stringLength = string.length; - if (stringLength == length) { - writeStringOn(string, writer); - } else if (stringLength > length) { - writeStringOn(string, stringLength - length, length, writer); - } else { - frontPadOn_(string, length, c, writer); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, StringBuffer) - */ - public static void frontPadOrTruncateOn(char[] string, int length, char c, StringBuffer sb) { - int stringLength = string.length; - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string, stringLength - length, length); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /** - * Pad or truncate the specified string to the specified length. - * If the string is already the specified length, it is returned unchanged. - * If it is longer than the specified length, only the last part of the string is returned. - * If it is shorter than the specified length, it is padded with the - * specified character at the front. - * String#frontPadOrTruncateOn(int, char, StringBuilder) - */ - public static void frontPadOrTruncateOn(char[] string, int length, char c, StringBuilder sb) { - int stringLength = string.length; - if (stringLength == length) { - sb.append(string); - } else if (stringLength > length) { - sb.append(string, stringLength - length, length); - } else { - frontPadOn_(string, length, c, sb); - } - } - - /* - * Front-pad the specified string without validating the parms. - */ - private static String frontPad_(String string, int length, char c) { - return new String(frontPad_(string.toCharArray(), length, c)); - } - - /* - * Zero-pad the specified string without validating the parms. - */ - private static char[] frontPad_(char[] string, int length, char c) { - char[] result = new char[length]; - int stringLength = string.length; - int padLength = length - stringLength; - System.arraycopy(string, 0, result, padLength, stringLength); - Arrays.fill(result, 0, padLength, c); - return result; - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(String string, int length, char c, Writer writer) { - fill_(string, length, c, writer); - writeStringOn(string, writer); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(char[] string, int length, char c, Writer writer) { - fill_(string, length, c, writer); - writeStringOn(string, writer); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(String string, int length, char c, StringBuffer sb) { - fill_(string, length, c, sb); - sb.append(string); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(char[] string, int length, char c, StringBuffer sb) { - fill_(string, length, c, sb); - sb.append(string); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(String string, int length, char c, StringBuilder sb) { - fill_(string, length, c, sb); - sb.append(string); - } - - /* - * Pad the specified string without validating the parms. - */ - private static void frontPadOn_(char[] string, int length, char c, StringBuilder sb) { - fill_(string, length, c, sb); - sb.append(string); - } - - - // ********** delimiting/quoting ********** - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static String quote(String string) { - return delimit(string, QUOTE); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(String string, Writer writer) { - delimitOn(string, QUOTE, writer); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(String string, StringBuffer sb) { - delimitOn(string, QUOTE, sb); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(String string, StringBuilder sb) { - delimitOn(string, QUOTE, sb); - } - - /** - * Delimit each of the specified strings with double quotes. - * Escape any occurrences of a double quote in a string with another - * double quote. - */ - public static Iterator<String> quote(Iterator<String> strings) { - return delimit(strings, QUOTE); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static String delimit(String string, char delimiter) { - return new String(delimit(string.toCharArray(), delimiter)); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(String string, char delimiter, Writer writer) { - delimitOn(string.toCharArray(), delimiter, writer); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(String string, char delimiter, StringBuffer sb) { - delimitOn(string.toCharArray(), delimiter, sb); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(String string, char delimiter, StringBuilder sb) { - delimitOn(string.toCharArray(), delimiter, sb); - } - - /** - * Delimit each of the specified strings with the specified delimiter; i.e. put a - * copy of the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in a string with another delimiter. - */ - public static Iterator<String> delimit(Iterator<String> strings, final char delimiter) { - return new TransformationIterator<String, String>(strings) { - @Override - protected String transform(String string) { - return StringTools.delimit(string, delimiter); - } - }; - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static String delimit(String string, String delimiter) { - if (delimiter.length() == 1) { - return delimit(string, delimiter.charAt(0)); - } - return new String(delimit(string.toCharArray(), delimiter.toCharArray())); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(String string, String delimiter, Writer writer) { - if (delimiter.length() == 1) { - delimitOn(string, delimiter.charAt(0), writer); - } else { - delimitOn(string.toCharArray(), delimiter.toCharArray(), writer); - } - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(String string, String delimiter, StringBuffer sb) { - if (delimiter.length() == 1) { - delimitOn(string, delimiter.charAt(0), sb); - } else { - delimitOn(string.toCharArray(), delimiter.toCharArray(), sb); - } - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(String string, String delimiter, StringBuilder sb) { - if (delimiter.length() == 1) { - delimitOn(string, delimiter.charAt(0), sb); - } else { - delimitOn(string.toCharArray(), delimiter.toCharArray(), sb); - } - } - - /** - * Delimit each of the specified strings with the specified delimiter; i.e. put a - * copy of the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in a string with - * another delimiter. - */ - public static Iterator<String> delimit(Iterator<String> strings, final String delimiter) { - if (delimiter.length() == 1) { - return delimit(strings, delimiter.charAt(0)); - } - return new TransformationIterator<String, String>(strings) { - @Override - protected String transform(String string) { - return StringTools.delimit(string, delimiter); - } - }; - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static char[] quote(char[] string) { - return delimit(string, QUOTE); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(char[] string, Writer writer) { - delimitOn(string, QUOTE, writer); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(char[] string, StringBuffer sb) { - delimitOn(string, QUOTE, sb); - } - - /** - * Delimit the specified string with double quotes. - * Escape any occurrences of a double quote in the string with another - * double quote. - */ - public static void quoteOn(char[] string, StringBuilder sb) { - delimitOn(string, QUOTE, sb); - } - - /** - * Delimit each of the specified strings with double quotes. - * Escape any occurrences of a double quote in a string with another - * double quote. - */ - // cannot name method simply 'quote' because of type-erasure... - public static Iterator<char[]> quoteCharArrays(Iterator<char[]> strings) { - return delimitCharArrays(strings, QUOTE); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static char[] delimit(char[] string, char delimiter) { - StringBuilder sb = new StringBuilder(string.length + 2); - delimitOn(string, delimiter, sb); - return convertToCharArray(sb); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(char[] string, char delimiter, Writer writer) { - writeCharOn(delimiter, writer); - writeStringOn(string, delimiter, writer); - writeCharOn(delimiter, writer); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(char[] string, char delimiter, StringBuffer sb) { - sb.append(delimiter); - for (char c : string) { - if (c == delimiter) { - sb.append(c); - } - sb.append(c); - } - sb.append(delimiter); - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in the string with another delimiter. - */ - public static void delimitOn(char[] string, char delimiter, StringBuilder sb) { - sb.append(delimiter); - for (char c : string) { - if (c == delimiter) { - sb.append(c); - } - sb.append(c); - } - sb.append(delimiter); - } - - /** - * Delimit each of the specified strings with the specified delimiter; i.e. put a - * copy of the delimiter at the front and back of the resulting string. - * Escape any occurrences of the delimiter in a string with another delimiter. - */ - // cannot name method simply 'delimit' because of type-erasure... - public static Iterator<char[]> delimitCharArrays(Iterator<char[]> strings, final char delimiter) { - return new TransformationIterator<char[], char[]>(strings) { - @Override - protected char[] transform(char[] string) { - return StringTools.delimit(string, delimiter); - } - }; - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static char[] delimit(char[] string, char[] delimiter) { - int delimiterLength = delimiter.length; - if (delimiterLength == 1) { - return delimit(string, delimiter[0]); - } - int stringLength = string.length; - char[] result = new char[stringLength+(2*delimiterLength)]; - System.arraycopy(delimiter, 0, result, 0, delimiterLength); - System.arraycopy(string, 0, result, delimiterLength, stringLength); - System.arraycopy(delimiter, 0, result, stringLength+delimiterLength, delimiterLength); - return result; - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(char[] string, char[] delimiter, Writer writer) { - if (delimiter.length == 1) { - delimitOn(string, delimiter[0], writer); - } else { - writeStringOn(delimiter, writer); - writeStringOn(string, writer); - writeStringOn(delimiter, writer); - } - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(char[] string, char[] delimiter, StringBuffer sb) { - if (delimiter.length == 1) { - delimitOn(string, delimiter[0], sb); - } else { - sb.append(delimiter); - sb.append(string); - sb.append(delimiter); - } - } - - /** - * Delimit the specified string with the specified delimiter; i.e. put a copy of - * the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in the string with - * another delimiter. - */ - public static void delimitOn(char[] string, char[] delimiter, StringBuilder sb) { - if (delimiter.length == 1) { - delimitOn(string, delimiter[0], sb); - } else { - sb.append(delimiter); - sb.append(string); - sb.append(delimiter); - } - } - - /** - * Delimit each of the specified strings with the specified delimiter; i.e. put a - * copy of the delimiter at the front and back of the resulting string. - * Escape any occurrences of a single-character delimiter in a string with - * another delimiter. - */ - // cannot name method simply 'delimit' because of type-erasure... - public static Iterator<char[]> delimitCharArrays(Iterator<char[]> strings, final char[] delimiter) { - return new TransformationIterator<char[], char[]>(strings) { - @Override - protected char[] transform(char[] string) { - return StringTools.delimit(string, delimiter); - } - }; - } - - - // ********** delimiting queries ********** - - /** - * Return whether the specified string is quoted: "\"foo\"". - */ - public static boolean stringIsQuoted(String string) { - return stringIsDelimited(string, QUOTE); - } - - /** - * Return whether the specified string is parenthetical: "(foo)". - */ - public static boolean stringIsParenthetical(String string) { - return stringIsDelimited(string, OPEN_PARENTHESIS, CLOSE_PARENTHESIS); - } - - /** - * Return whether the specified string is bracketed: "[foo]". - */ - public static boolean stringIsBracketed(String string) { - return stringIsDelimited(string, OPEN_BRACKET, CLOSE_BRACKET); - } - - /** - * Return whether the specified string is braced: "{foo}". - */ - public static boolean stringIsBraced(String string) { - return stringIsDelimited(string, OPEN_BRACE, CLOSE_BRACE); - } - - /** - * Return whether the specified string is chevroned: "<foo>". - */ - public static boolean stringIsChevroned(String string) { - return stringIsDelimited(string, OPEN_CHEVRON, CLOSE_CHEVRON); - } - - /** - * Return whether the specified string is delimited by the specified - * character. - */ - public static boolean stringIsDelimited(String string, char c) { - return stringIsDelimited(string, c, c); - } - - /** - * Return whether the specified string is delimited by the specified - * characters. - */ - public static boolean stringIsDelimited(String string, char start, char end) { - int len = string.length(); - if (len < 2) { - return false; - } - return stringIsDelimited(string.toCharArray(), start, end, len); - } - - /** - * Return whether the specified string is quoted: "\"foo\"". - */ - public static boolean stringIsQuoted(char[] string) { - return stringIsDelimited(string, QUOTE); - } - - /** - * Return whether the specified string is parenthetical: "(foo)". - */ - public static boolean stringIsParenthetical(char[] string) { - return stringIsDelimited(string, OPEN_PARENTHESIS, CLOSE_PARENTHESIS); - } - - /** - * Return whether the specified string is bracketed: "[foo]". - */ - public static boolean stringIsBracketed(char[] string) { - return stringIsDelimited(string, OPEN_BRACKET, CLOSE_BRACKET); - } - - /** - * Return whether the specified string is braced: "{foo}". - */ - public static boolean stringIsBraced(char[] string) { - return stringIsDelimited(string, OPEN_BRACE, CLOSE_BRACE); - } - - /** - * Return whether the specified string is chevroned: "<foo>". - */ - public static boolean stringIsChevroned(char[] string) { - return stringIsDelimited(string, OPEN_CHEVRON, CLOSE_CHEVRON); - } - - /** - * Return whether the specified string is delimited by the specified - * character. - */ - public static boolean stringIsDelimited(char[] string, char c) { - return stringIsDelimited(string, c, c); - } - - /** - * Return whether the specified string is delimited by the specified - * characters. - */ - public static boolean stringIsDelimited(char[] string, char start, char end) { - int len = string.length; - if (len < 2) { - return false; - } - return stringIsDelimited(string, start, end, len); - } - - private static boolean stringIsDelimited(char[] s, char start, char end, int len) { - return (s[0] == start) && (s[len - 1] == end); - } - - - // ********** undelimiting ********** - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static String undelimit(String string) { - int len = string.length() - 2; - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + string + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return EMPTY_STRING; - } - return new String(undelimit_(string.toCharArray(), len)); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static String undelimit(String string, int count) { - int len = string.length() - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + string + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return EMPTY_STRING; - } - return new String(undelimit(string.toCharArray(), len, count)); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static char[] undelimit(char[] string) { - int len = string.length - 2; - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return EMPTY_CHAR_ARRAY; - } - return undelimit_(string, len); - } - - private static char[] undelimit_(char[] string, int length) { - StringBuilder sb = new StringBuilder(length); - undelimitOn_(string, sb); - return convertToCharArray(sb); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static char[] undelimit(char[] string, int count) { - int len = string.length - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return EMPTY_CHAR_ARRAY; - } - return undelimit(string, len, count); - } - - private static char[] undelimit(char[] string, int len, int count) { - char[] result = new char[len]; - System.arraycopy(string, count, result, 0, len); - return result; - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(String string, Writer writer) { - undelimitOn(string.toCharArray(), writer); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(String string, int count, Writer writer) { - int len = string.length() - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + string + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - writeStringOn(string, count, len, writer); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(String string, StringBuffer sb) { - undelimitOn(string.toCharArray(), sb); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(String string, int count, StringBuffer sb) { - int len = string.length() - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + string + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - sb.append(string, count, count + len); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(String string, StringBuilder sb) { - undelimitOn(string.toCharArray(), sb); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(String string, int count, StringBuilder sb) { - int len = string.length() - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + string + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - sb.append(string, count, count + len); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(char[] string, Writer writer) { - int len = string.length - 2; - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - undelimitOn_(string, writer); - } - - /** - * pre-condition: string is at least 3 characters long - */ - private static void undelimitOn_(char[] string, Writer writer) { - char delimiter = string[0]; // the first char is the delimiter - char c = string[0]; - char next = string[1]; - int i = 1; - int last = string.length - 1; - do { - c = next; - writeCharOn(c, writer); - i++; - next = string[i]; - if (c == delimiter) { - if ((next != delimiter) || (i == last)) { - // an embedded delimiter must be followed by another delimiter - return; - } - i++; - next = string[i]; - } - } while (i != last); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(char[] string, int count, Writer writer) { - int len = string.length - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - writeStringOn(string, count, len, writer); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(char[] string, StringBuffer sb) { - int len = string.length - 2; - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - undelimitOn_(string, sb); - } - - /** - * pre-condition: string is at least 3 characters long - */ - private static void undelimitOn_(char[] string, StringBuffer sb) { - char delimiter = string[0]; // the first char is the delimiter - char c = string[0]; - char next = string[1]; - int i = 1; - int last = string.length - 1; - do { - c = next; - sb.append(c); - i++; - next = string[i]; - if (c == delimiter) { - if ((next != delimiter) || (i == last)) { - // an embedded delimiter must be followed by another delimiter - return; - } - i++; - next = string[i]; - } - } while (i != last); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(char[] string, int count, StringBuffer sb) { - int len = string.length - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - sb.append(string, count, len); - } - - /** - * Remove the delimiters from the specified string, removing any escape - * characters. Throw an IllegalArgumentException if the string is too short - * to undelimit (i.e. length < 2). - */ - public static void undelimitOn(char[] string, StringBuilder sb) { - int len = string.length - 2; - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - undelimitOn_(string, sb); - } - - /** - * pre-condition: string is at least 3 characters long - */ - private static void undelimitOn_(char[] string, StringBuilder sb) { - char delimiter = string[0]; // the first char is the delimiter - char c = string[0]; - char next = string[1]; - int i = 1; - int last = string.length - 1; - do { - c = next; - sb.append(c); - i++; - next = string[i]; - if (c == delimiter) { - if ((next != delimiter) || (i == last)) { - // an embedded delimiter must be followed by another delimiter - return; - } - i++; - next = string[i]; - } - } while (i != last); - } - - /** - * Remove the first and last count characters from the specified string. - * If the string is too short to be undelimited, throw an - * IllegalArgumentException. - * Use this method to undelimit strings that do not escape embedded - * delimiters. - */ - public static void undelimitOn(char[] string, int count, StringBuilder sb) { - int len = string.length - (2 * count); - if (len < 0) { - throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"'); //$NON-NLS-1$ - } - if (len == 0) { - return; - } - sb.append(string, count, len); - } - - - // ********** removing characters ********** - - /** - * Remove the first occurrence of the specified character - * from the specified string and return the result. - * String#removeFirstOccurrence(char) - */ - public static String removeFirstOccurrence(String string, char c) { - int index = string.indexOf(c); - if (index == -1) { - // character not found - return string; - } - if (index == 0) { - // character found at the front of string - return string.substring(1); - } - int last = string.length() - 1; - if (index == last) { - // character found at the end of string - return string.substring(0, last); - } - // character found somewhere in the middle of the string - return string.substring(0, index).concat(string.substring(index + 1)); - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, Writer) - */ - public static void removeFirstOccurrenceOn(String string, char c, Writer writer) { - int index = string.indexOf(c); - if (index == -1) { - writeStringOn(string, writer); - } else { - removeCharAtIndexOn(string.toCharArray(), index, writer); - } - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, StringBuffer) - */ - public static void removeFirstOccurrenceOn(String string, char c, StringBuffer sb) { - int index = string.indexOf(c); - if (index == -1) { - sb.append(string); - } else { - removeCharAtIndexOn(string.toCharArray(), index, sb); - } - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, StringBuilder) - */ - public static void removeFirstOccurrenceOn(String string, char c, StringBuilder sb) { - int index = string.indexOf(c); - if (index == -1) { - sb.append(string); - } else { - removeCharAtIndexOn(string.toCharArray(), index, sb); - } - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and return the result. - * String#removeFirstOccurrence(char) - */ - public static char[] removeFirstOccurrence(char[] string, char c) { - int index = CollectionTools.indexOf(string, c); - if (index == -1) { - // character not found - return string; - } - int last = string.length - 1; - char[] result = new char[last]; - if (index == 0) { - // character found at the front of string - System.arraycopy(string, 1, result, 0, last); - } else if (index == last) { - // character found at the end of string - System.arraycopy(string, 0, result, 0, last); - } else { - // character found somewhere in the middle of the string - System.arraycopy(string, 0, result, 0, index); - System.arraycopy(string, index + 1, result, index, last - index); - } - return result; - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, Writer) - */ - public static void removeFirstOccurrenceOn(char[] string, char c, Writer writer) { - int index = CollectionTools.indexOf(string, c); - if (index == -1) { - writeStringOn(string, writer); - } else { - removeCharAtIndexOn(string, index, writer); - } - } - - private static void removeCharAtIndexOn(char[] string, int index, Writer writer) { - int last = string.length - 1; - if (index == 0) { - // character found at the front of string - writeStringOn(string, 1, last, writer); - } else if (index == last) { - // character found at the end of string - writeStringOn(string, 0, last, writer); - } else { - // character found somewhere in the middle of the string - writeStringOn(string, 0, index, writer); - writeStringOn(string, index + 1, last - index, writer); - } - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, StringBuffer) - */ - public static void removeFirstOccurrenceOn(char[] string, char c, StringBuffer sb) { - int index = CollectionTools.indexOf(string, c); - if (index == -1) { - sb.append(string); - } else { - removeCharAtIndexOn(string, index, sb); - } - } - - private static void removeCharAtIndexOn(char[] string, int index, StringBuffer sb) { - int last = string.length - 1; - if (index == 0) { - // character found at the front of string - sb.append(string, 1, last); - } else if (index == last) { - // character found at the end of string - sb.append(string, 0, last); - } else { - // character found somewhere in the middle of the string - sb.append(string, 0, index); - sb.append(string, index + 1, last - index); - } - } - - /** - * Remove the first occurrence of the specified character - * from the specified string and print the result on the specified stream. - * String#removeFirstOccurrenceOn(char, StringBuilder) - */ - public static void removeFirstOccurrenceOn(char[] string, char c, StringBuilder sb) { - int index = CollectionTools.indexOf(string, c); - if (index == -1) { - sb.append(string); - } else { - removeCharAtIndexOn(string, index, sb); - } - } - - private static void removeCharAtIndexOn(char[] string, int index, StringBuilder sb) { - int last = string.length - 1; - if (index == 0) { - // character found at the front of string - sb.append(string, 1, last); - } else if (index == last) { - // character found at the end of string - sb.append(string, 0, last); - } else { - // character found somewhere in the middle of the string - sb.append(string, 0, index); - sb.append(string, index + 1, last - index); - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and return the result. - * String#removeAllOccurrences(char) - */ - public static String removeAllOccurrences(String string, char c) { - int first = string.indexOf(c); - return (first == -1) ? string : new String(removeAllOccurrences_(string.toCharArray(), c, first)); - } - - /** - * Remove all occurrences of the specified character - * from the specified string and write the result to the specified stream. - * String#removeAllOccurrencesOn(char, Writer) - */ - public static void removeAllOccurrencesOn(String string, char c, Writer writer) { - int first = string.indexOf(c); - if (first == -1) { - writeStringOn(string, writer); - } else { - removeAllOccurrencesOn_(string.toCharArray(), c, first, writer); - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and write the result to the specified stream. - * String#removeAllOccurrencesOn(char, StringBuffer) - */ - public static void removeAllOccurrencesOn(String string, char c, StringBuffer sb) { - int first = string.indexOf(c); - if (first == -1) { - sb.append(string); - } else { - removeAllOccurrencesOn_(string.toCharArray(), c, first, sb); - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and write the result to the specified stream. - * String#removeAllOccurrencesOn(char, StringBuilder) - */ - public static void removeAllOccurrencesOn(String string, char c, StringBuilder sb) { - int first = string.indexOf(c); - if (first == -1) { - sb.append(string); - } else { - removeAllOccurrencesOn_(string.toCharArray(), c, first, sb); - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and return the result. - * String#removeAllOccurrences(char) - */ - public static char[] removeAllOccurrences(char[] string, char c) { - int first = CollectionTools.indexOf(string, c); - return (first == -1) ? string : removeAllOccurrences_(string, c, first); - } - - /* - * The index of the first matching character is passed in. - */ - private static char[] removeAllOccurrences_(char[] string, char c, int first) { - StringBuilder sb = new StringBuilder(string.length); - removeAllOccurrencesOn_(string, c, first, sb); - return convertToCharArray(sb); - } - - /** - * Remove all occurrences of the specified character - * from the specified string and write the result to the - * specified writer. - * String#removeAllOccurrencesOn(char, Writer) - */ - public static void removeAllOccurrencesOn(char[] string, char c, Writer writer) { - int first = CollectionTools.indexOf(string, c); - if (first == -1) { - writeStringOn(string, writer); - } else { - removeAllOccurrencesOn_(string, c, first, writer); - } - } - - /* - * The index of the first matching character is passed in. - */ - private static void removeAllOccurrencesOn_(char[] string, char c, int first, Writer writer) { - writeStringOn(string, 0, first, writer); - int len = string.length; - for (int i = first; i < len; i++) { - char d = string[i]; - if (d != c) { - writeCharOn(d, writer); - } - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and append the result to the - * specified string buffer. - * String#removeAllOccurrencesOn(char, StringBuffer) - */ - public static void removeAllOccurrencesOn(char[] string, char c, StringBuffer sb) { - int first = CollectionTools.indexOf(string, c); - if (first == -1) { - sb.append(string); - } else { - removeAllOccurrencesOn_(string, c, first, sb); - } - } - - /* - * The index of the first matching character is passed in. - */ - private static void removeAllOccurrencesOn_(char[] string, char c, int first, StringBuffer sb) { - sb.append(string, 0, first); - int len = string.length; - for (int i = first; i < len; i++) { - char d = string[i]; - if (d != c) { - sb.append(d); - } - } - } - - /** - * Remove all occurrences of the specified character - * from the specified string and append the result to the - * specified string builder. - * String#removeAllOccurrencesOn(char, StringBuilder) - */ - public static void removeAllOccurrencesOn(char[] string, char c, StringBuilder sb) { - int first = CollectionTools.indexOf(string, c); - if (first == -1) { - sb.append(string); - } else { - removeAllOccurrencesOn_(string, c, first, sb); - } - } - - /* - * The index of the first matching character is passed in. - */ - private static void removeAllOccurrencesOn_(char[] string, char c, int first, StringBuilder sb) { - sb.append(string, 0, first); - int len = string.length; - for (int i = first; i < len; i++) { - char d = string[i]; - if (d != c) { - sb.append(d); - } - } - } - - /** - * Remove all the spaces from the specified string and return the result. - * String#removeAllSpaces() - */ - public static String removeAllSpaces(String string) { - return removeAllOccurrences(string, ' '); - } - - /** - * Remove all the spaces - * from the specified string and write the result to the specified writer. - * String#removeAllSpacesOn(Writer) - */ - public static void removeAllSpacesOn(String string, Writer writer) { - removeAllOccurrencesOn(string, ' ', writer); - } - - /** - * Remove all the spaces - * from the specified string and write the result to the specified - * string buffer. - * String#removeAllSpacesOn(StringBuffer) - */ - public static void removeAllSpacesOn(String string, StringBuffer sb) { - removeAllOccurrencesOn(string, ' ', sb); - } - - /** - * Remove all the spaces - * from the specified string and write the result to the specified - * string builder. - * String#removeAllSpacesOn(StringBuilder) - */ - public static void removeAllSpacesOn(String string, StringBuilder sb) { - removeAllOccurrencesOn(string, ' ', sb); - } - - /** - * Remove all the spaces from the specified string and return the result. - * String#removeAllSpaces() - */ - public static char[] removeAllSpaces(char[] string) { - return removeAllOccurrences(string, ' '); - } - - /** - * Remove all the spaces - * from the specified string and write the result to the - * specified writer. - * String#removeAllSpacesOn(Writer) - */ - public static void removeAllSpacesOn(char[] string, Writer writer) { - removeAllOccurrencesOn(string, ' ', writer); - } - - /** - * Remove all the spaces - * from the specified string and append the result to the - * specified string buffer. - * String#removeAllSpacesOn(StringBuffer) - */ - public static void removeAllSpacesOn(char[] string, StringBuffer sb) { - removeAllOccurrencesOn(string, ' ', sb); - } - - /** - * Remove all the spaces - * from the specified string and append the result to the - * specified string builder. - * String#removeAllSpacesOn(StringBuilder) - */ - public static void removeAllSpacesOn(char[] string, StringBuilder sb) { - removeAllOccurrencesOn(string, ' ', sb); - } - - /** - * Remove all the whitespace from the specified string and return the result. - * String#removeAllWhitespace() - */ - public static String removeAllWhitespace(String string) { - char[] string2 = string.toCharArray(); - int first = indexOfWhitespace_(string2); - return (first == -1) ? string : new String(removeAllWhitespace_(string2, first)); - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified writer. - * String#removeAllWhitespaceOn(Writer) - */ - public static void removeAllWhitespaceOn(String string, Writer writer) { - char[] string2 = string.toCharArray(); - int first = indexOfWhitespace_(string2); - if (first == -1) { - writeStringOn(string, writer); - } else { - removeAllWhitespaceOn_(string2, first, writer); - } - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified string buffer. - * String#removeAllWhitespaceOn(StringBuffer) - */ - public static void removeAllWhitespaceOn(String string, StringBuffer sb) { - char[] string2 = string.toCharArray(); - int first = indexOfWhitespace_(string2); - if (first == -1) { - sb.append(string); - } else { - removeAllWhitespaceOn_(string2, first, sb); - } - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified string builder. - * String#removeAllWhitespaceOn(StringBuilder) - */ - public static void removeAllWhitespaceOn(String string, StringBuilder sb) { - char[] string2 = string.toCharArray(); - int first = indexOfWhitespace_(string2); - if (first == -1) { - sb.append(string); - } else { - removeAllWhitespaceOn_(string2, first, sb); - } - } - - /** - * Remove all the whitespace from the specified string and return the result. - * String#removeAllWhitespace() - */ - public static char[] removeAllWhitespace(char[] string) { - int first = indexOfWhitespace_(string); - return (first == -1) ? string : removeAllWhitespace_(string, first); - } - - private static int indexOfWhitespace_(char[] string) { - int len = string.length; - for (int i = 0; i < len; i++) { - if (Character.isWhitespace(string[i])) { - return i; - } - } - return -1; - } - - /* - * The index of the first non-whitespace character is passed in. - */ - private static char[] removeAllWhitespace_(char[] string, int first) { - StringBuilder sb = new StringBuilder(string.length); - removeAllWhitespaceOn_(string, first, sb); - return convertToCharArray(sb); - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified writer. - * String#removeAllWhitespaceOn(Writer) - */ - public static void removeAllWhitespaceOn(char[] string, Writer writer) { - int first = indexOfWhitespace_(string); - if (first == -1) { - writeStringOn(string, writer); - } else { - removeAllWhitespaceOn_(string, first, writer); - } - } - - /* - * The index of the first non-whitespace character is passed in. - */ - private static void removeAllWhitespaceOn_(char[] string, int first, Writer writer) { - writeStringOn(string, 0, first, writer); - int len = string.length; - for (int i = first; i < len; i++) { - char c = string[i]; - if ( ! Character.isWhitespace(c)) { - writeCharOn(c, writer); - } - } - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified string buffer. - * String#removeAllWhitespaceOn(StringBuffer) - */ - public static void removeAllWhitespaceOn(char[] string, StringBuffer sb) { - int first = indexOfWhitespace_(string); - if (first == -1) { - sb.append(string); - } else { - removeAllWhitespaceOn_(string, first, sb); - } - } - - /* - * The index of the first non-whitespace character is passed in. - */ - private static void removeAllWhitespaceOn_(char[] string, int first, StringBuffer sb) { - sb.append(string, 0, first); - int len = string.length; - for (int i = first; i < len; i++) { - char c = string[i]; - if ( ! Character.isWhitespace(c)) { - sb.append(c); - } - } - } - - /** - * Remove all the whitespace - * from the specified string and append the result to the - * specified string builder. - * String#removeAllWhitespaceOn(StringBuilder) - */ - public static void removeAllWhitespaceOn(char[] string, StringBuilder sb) { - int first = indexOfWhitespace_(string); - if (first == -1) { - sb.append(string); - } else { - removeAllWhitespaceOn_(string, first, sb); - } - } - - /* - * The index of the first non-whitespace character is passed in. - */ - private static void removeAllWhitespaceOn_(char[] string, int first, StringBuilder sb) { - sb.append(string, 0, first); - int len = string.length; - for (int i = first; i < len; i++) { - char c = string[i]; - if ( ! Character.isWhitespace(c)) { - sb.append(c); - } - } - } - - - // ********** common prefix ********** - - /** - * Return the length of the common prefix shared by the specified strings. - * String#commonPrefixLength(String) - */ - public static int commonPrefixLength(String s1, String s2) { - return commonPrefixLength(s1.toCharArray(), s2.toCharArray()); - } - - /** - * Return the length of the common prefix shared by the specified strings. - */ - public static int commonPrefixLength(char[] s1, char[] s2) { - return commonPrefixLength_(s1, s2, Math.min(s1.length, s2.length)); - } - - /** - * Return the length of the common prefix shared by the specified strings; - * but limit the length to the specified maximum. - * String#commonPrefixLength(String, int) - */ - public static int commonPrefixLength(String s1, String s2, int max) { - return commonPrefixLength(s1.toCharArray(), s2.toCharArray(), max); - } - - /** - * Return the length of the common prefix shared by the specified strings; - * but limit the length to the specified maximum. - */ - public static int commonPrefixLength(char[] s1, char[] s2, int max) { - return commonPrefixLength_(s1, s2, Math.min(max, Math.min(s1.length, s2.length))); - } - - /* - * Return the length of the common prefix shared by the specified strings; - * but limit the length to the specified maximum. Assume the specified - * maximum is less than the lengths of the specified strings. - */ - private static int commonPrefixLength_(char[] s1, char[] s2, int max) { - for (int i = 0; i < max; i++) { - if (s1[i] != s2[i]) { - return i; - } - } - return max; // all the characters up to 'max' are the same - } - - - // ********** capitalization ********** - - /* - * no zero-length check or lower case check - */ - private static char[] capitalize_(char[] string) { - string[0] = Character.toUpperCase(string[0]); - return string; - } - - /** - * Modify and return the specified string with - * its first letter capitalized. - */ - public static char[] capitalize(char[] string) { - if ((string.length == 0) || Character.isUpperCase(string[0])) { - return string; - } - return capitalize_(string); - } - - /** - * Return the specified string with its first letter capitalized. - * String#capitalize() - */ - public static String capitalize(String string) { - if ((string.length() == 0) || Character.isUpperCase(string.charAt(0))) { - return string; - } - return new String(capitalize_(string.toCharArray())); - } - - /** - * Modify each of the specified strings, capitalizing the first letter of - * each. - */ - public static Iterator<String> capitalize(Iterator<String> strings) { - return new TransformationIterator<String, String>(strings) { - @Override - protected String transform(String string) { - return StringTools.capitalize(string); - } - }; - } - - /** - * Modify each of the specified strings, capitalizing the first letter of - * each. - */ - // cannot name method simply 'capitalize' because of type-erasure... - public static Iterator<char[]> capitalizeCharArrays(Iterator<char[]> strings) { - return new TransformationIterator<char[], char[]>(strings) { - @Override - protected char[] transform(char[] string) { - return StringTools.capitalize(string); - } - }; - } - - /* - * no zero-length check or upper case check - */ - private static void capitalizeOn_(char[] string, StringBuffer sb) { - sb.append(Character.toUpperCase(string[0])); - sb.append(string, 1, string.length - 1); - } - - /** - * Append the specified string to the specified string buffer - * with its first letter capitalized. - */ - public static void capitalizeOn(char[] string, StringBuffer sb) { - if (string.length == 0) { - return; - } - if (Character.isUpperCase(string[0])) { - sb.append(string); - } else { - capitalizeOn_(string, sb); - } - } - - /** - * Append the specified string to the specified string buffer - * with its first letter capitalized. - * String#capitalizeOn(StringBuffer) - */ - public static void capitalizeOn(String string, StringBuffer sb) { - if (string.length() == 0) { - return; - } - if (Character.isUpperCase(string.charAt(0))) { - sb.append(string); - } else { - capitalizeOn_(string.toCharArray(), sb); - } - } - - /* - * no zero-length check or upper case check - */ - private static void capitalizeOn_(char[] string, StringBuilder sb) { - sb.append(Character.toUpperCase(string[0])); - sb.append(string, 1, string.length - 1); - } - - /** - * Append the specified string to the specified string builder - * with its first letter capitalized. - */ - public static void capitalizeOn(char[] string, StringBuilder sb) { - if (string.length == 0) { - return; - } - if (Character.isUpperCase(string[0])) { - sb.append(string); - } else { - capitalizeOn_(string, sb); - } - } - - /** - * Append the specified string to the specified string builder - * with its first letter capitalized. - * String#capitalizeOn(StringBuffer) - */ - public static void capitalizeOn(String string, StringBuilder sb) { - if (string.length() == 0) { - return; - } - if (Character.isUpperCase(string.charAt(0))) { - sb.append(string); - } else { - capitalizeOn_(string.toCharArray(), sb); - } - } - - /* - * no zero-length check or upper case check - */ - private static void capitalizeOn_(char[] string, Writer writer) { - writeCharOn(Character.toUpperCase(string[0]), writer); - writeStringOn(string, 1, string.length - 1, writer); - } - - /** - * Append the specified string to the specified string buffer - * with its first letter capitalized. - */ - public static void capitalizeOn(char[] string, Writer writer) { - if (string.length == 0) { - return; - } - if (Character.isUpperCase(string[0])) { - writeStringOn(string, writer); - } else { - capitalizeOn_(string, writer); - } - } - - /** - * Append the specified string to the specified string buffer - * with its first letter capitalized. - * String#capitalizeOn(Writer) - */ - public static void capitalizeOn(String string, Writer writer) { - if (string.length() == 0) { - return; - } - if (Character.isUpperCase(string.charAt(0))) { - writeStringOn(string, writer); - } else { - capitalizeOn_(string.toCharArray(), writer); - } - } - - /* - * no zero-length check or lower case check - */ - private static char[] uncapitalize_(char[] string) { - string[0] = Character.toLowerCase(string[0]); - return string; - } - - private static boolean stringNeedNotBeUncapitalized_(char[] string) { - if (string.length == 0) { - return true; - } - if (Character.isLowerCase(string[0])) { - return true; - } - // if both the first and second characters are capitalized, - // return the string unchanged - if ((string.length > 1) - && Character.isUpperCase(string[1]) - && Character.isUpperCase(string[0])){ - return true; - } - return false; - } - - /** - * Modify and return the specified string with its - * first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - */ - public static char[] uncapitalize(char[] string) { - if (stringNeedNotBeUncapitalized_(string)) { - return string; - } - return uncapitalize_(string); - } - - private static boolean stringNeedNotBeUncapitalized_(String string) { - if (string.length() == 0) { - return true; - } - if (Character.isLowerCase(string.charAt(0))) { - return true; - } - // if both the first and second characters are capitalized, - // return the string unchanged - if ((string.length() > 1) - && Character.isUpperCase(string.charAt(1)) - && Character.isUpperCase(string.charAt(0))){ - return true; - } - return false; - } - - /** - * Return the specified string with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - * String#uncapitalize() - */ - public static String uncapitalize(String string) { - if (stringNeedNotBeUncapitalized_(string)) { - return string; - } - return new String(uncapitalize_(string.toCharArray())); - } - - /* - * no zero-length check or lower case check - */ - private static void uncapitalizeOn_(char[] string, StringBuffer sb) { - sb.append(Character.toLowerCase(string[0])); - sb.append(string, 1, string.length - 1); - } - - /** - * Append the specified string to the specified string buffer - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - */ - public static void uncapitalizeOn(char[] string, StringBuffer sb) { - if (stringNeedNotBeUncapitalized_(string)) { - sb.append(string); - } else { - uncapitalizeOn_(string, sb); - } - } - - /** - * Append the specified string to the specified string buffer - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - * String#uncapitalizeOn(StringBuffer) - */ - public static void uncapitalizeOn(String string, StringBuffer sb) { - if (stringNeedNotBeUncapitalized_(string)) { - sb.append(string); - } else { - uncapitalizeOn_(string.toCharArray(), sb); - } - } - - /* - * no zero-length check or lower case check - */ - private static void uncapitalizeOn_(char[] string, StringBuilder sb) { - sb.append(Character.toLowerCase(string[0])); - sb.append(string, 1, string.length - 1); - } - - /** - * Append the specified string to the specified string builder - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - */ - public static void uncapitalizeOn(char[] string, StringBuilder sb) { - if (stringNeedNotBeUncapitalized_(string)) { - sb.append(string); - } else { - uncapitalizeOn_(string, sb); - } - } - - /** - * Append the specified string to the specified string builder - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - * String#uncapitalizeOn(StringBuffer) - */ - public static void uncapitalizeOn(String string, StringBuilder sb) { - if (stringNeedNotBeUncapitalized_(string)) { - sb.append(string); - } else { - uncapitalizeOn_(string.toCharArray(), sb); - } - } - - /* - * no zero-length check or upper case check - */ - private static void uncapitalizeOn_(char[] string, Writer writer) { - writeCharOn(Character.toLowerCase(string[0]), writer); - writeStringOn(string, 1, string.length - 1, writer); - } - - /** - * Append the specified string to the specified string buffer - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - */ - public static void uncapitalizeOn(char[] string, Writer writer) { - if (stringNeedNotBeUncapitalized_(string)) { - writeStringOn(string, writer); - } else { - uncapitalizeOn_(string, writer); - } - } - - /** - * Append the specified string to the specified string buffer - * with its first letter converted to lower case. - * (Unless both the first and second letters are upper case, - * in which case the string is returned unchanged.) - * String#uncapitalizeOn(Writer) - */ - public static void uncapitalizeOn(String string, Writer writer) { - if (stringNeedNotBeUncapitalized_(string)) { - writeStringOn(string, writer); - } else { - uncapitalizeOn_(string.toCharArray(), writer); - } - } - - - // ********** #toString() helper methods ********** - - /** - * Build a "standard" #toString() result for the specified object - * and additional information: - * ClassName[00F3EE42] (add'l info) - */ - public static String buildToStringFor(Object o, Object additionalInfo) { - StringBuilder sb = new StringBuilder(); - buildSimpleToStringOn(o, sb); - sb.append(" ("); //$NON-NLS-1$ - sb.append(additionalInfo); - sb.append(')'); - return sb.toString(); - } - - /** - * Build a "standard" simple #toString() result for the specified object: - * ClassName[00F3EE42] - */ - public static String buildToStringFor(Object o) { - StringBuilder sb = new StringBuilder(); - buildSimpleToStringOn(o, sb); - return sb.toString(); - } - - /** - * Append a "standard" simple #toString() for the specified object to - * the specified string buffer: - * ClassName[00F3EE42] - */ - public static void buildSimpleToStringOn(Object o, StringBuffer sb) { - sb.append(ClassTools.toStringClassNameForObject(o)); - sb.append('['); - // use System#identityHashCode(Object), since Object#hashCode() may be overridden - sb.append(zeroPad(Integer.toHexString(System.identityHashCode(o)).toUpperCase(), 8)); - sb.append(']'); - } - - /** - * Append a "standard" simple #toString() for the specified object to - * the specified string builder: - * ClassName[00F3EE42] - */ - public static void buildSimpleToStringOn(Object o, StringBuilder sb) { - sb.append(ClassTools.toStringClassNameForObject(o)); - sb.append('['); - // use System#identityHashCode(Object), since Object#hashCode() may be overridden - sb.append(zeroPad(Integer.toHexString(System.identityHashCode(o)).toUpperCase(), 8)); - sb.append(']'); - } - - - // ********** queries ********** - - /** - * Return whether the specified string is null, empty, or contains - * only whitespace characters. - */ - public static boolean stringIsEmpty(String string) { - if (string == null) { - return true; - } - int len = string.length(); - if (len == 0) { - return true; - } - return stringIsEmpty_(string.toCharArray(), len); - } - - /** - * Return whether the specified string is null, empty, or contains - * only whitespace characters. - */ - public static boolean stringIsEmpty(char[] string) { - if (string == null) { - return true; - } - int len = string.length; - if (len == 0) { - return true; - } - return stringIsEmpty_(string, len); - } - - private static boolean stringIsEmpty_(char[] s, int len) { - for (int i = len; i-- > 0; ) { - if ( ! Character.isWhitespace(s[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified string is non-null, non-empty, and does - * not contain only whitespace characters. - */ - public static boolean stringIsNotEmpty(String string) { - return ! stringIsEmpty(string); - } - - /** - * Return whether the specified string is non-null, non-empty, and does - * not contain only whitespace characters. - */ - public static boolean stringIsNotEmpty(char[] string) { - return ! stringIsEmpty(string); - } - - /** - * Return whether the specified strings are equal, ignoring case. - * Check for nulls. - */ - public static boolean stringsAreEqualIgnoreCase(String s1, String s2) { - if ((s1 == null) && (s2 == null)) { - return true; // both are null - } - if ((s1 == null) || (s2 == null)) { - return false; // one is null but the other is not - } - return s1.equalsIgnoreCase(s2); - } - - /** - * Return whether the specified strings are equal, ignoring case. - * Check for nulls. - */ - public static boolean stringsAreEqualIgnoreCase(char[] s1, char[] s2) { - if ((s1 == null) && (s2 == null)) { - return true; // both are null - } - if ((s1 == null) || (s2 == null)) { - return false; // one is null but the other is not - } - int len = s1.length; - if (len != s2.length) { - return false; - } - for (int i = len; i-- > 0; ) { - if ( ! charactersAreEqualIgnoreCase(s1[i], s2[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified string starts with the specified prefix, - * ignoring case. - */ - public static boolean stringStartsWithIgnoreCase(char[] string, char[] prefix) { - int prefixLength = prefix.length; - if (string.length < prefixLength) { - return false; - } - for (int i = prefixLength; i-- > 0; ) { - if ( ! charactersAreEqualIgnoreCase(string[i], prefix[i])) { - return false; - } - } - return true; - } - - /** - * Return whether the specified string starts with the specified prefix, - * ignoring case. - */ - public static boolean stringStartsWithIgnoreCase(String string, String prefix) { - return string.regionMatches(true, 0, prefix, 0, prefix.length()); - } - - /** - * Return whether the specified characters are are equal, ignoring case. - * @see java.lang.String#regionMatches(boolean, int, String, int, int) - */ - public static boolean charactersAreEqualIgnoreCase(char c1, char c2) { - // something about the Georgian alphabet requires us to check lower case also - return (c1 == c2) - || (Character.toUpperCase(c1) == Character.toUpperCase(c2)) - || (Character.toLowerCase(c1) == Character.toLowerCase(c2)); - } - - /** - * Return whether the specified string is uppercase. - */ - public static boolean stringIsUppercase(String string) { - return (string.length() == 0) ? false : stringIsUppercase_(string); - } - - /** - * Return whether the specified string is uppercase. - */ - public static boolean stringIsUppercase(char[] string) { - return (string.length == 0) ? false : stringIsUppercase_(new String(string)); - } - - private static boolean stringIsUppercase_(String string) { - return string.equals(string.toUpperCase()); - } - - /** - * Return whether the specified string is lowercase. - */ - public static boolean stringIsLowercase(String string) { - return (string.length() == 0) ? false : stringIsLowercase_(string); - } - - /** - * Return whether the specified string is lowercase. - */ - public static boolean stringIsLowercase(char[] string) { - return (string.length == 0) ? false : stringIsLowercase_(new String(string)); - } - - private static boolean stringIsLowercase_(String string) { - return string.equals(string.toLowerCase()); - } - - - // ********** convert camel case to all caps ********** - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static String convertCamelCaseToAllCaps(String camelCaseString) { - int len = camelCaseString.length(); - if (len == 0) { - return camelCaseString; - } - return new String(convertCamelCaseToAllCaps_(camelCaseString.toCharArray(), len)); - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static char[] convertCamelCaseToAllCaps(char[] camelCaseString) { - int len = camelCaseString.length; - if (len == 0) { - return camelCaseString; - } - return convertCamelCaseToAllCaps_(camelCaseString, len); - } - - private static char[] convertCamelCaseToAllCaps_(char[] camelCaseString, int len) { - StringBuilder sb = new StringBuilder(len * 2); - convertCamelCaseToAllCapsOn_(camelCaseString, len, sb); - return convertToCharArray(sb); - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, StringBuffer sb) { - int len = camelCaseString.length(); - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, sb); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, StringBuffer sb) { - int len = camelCaseString.length; - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString, len, sb); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, StringBuffer sb) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - sb.append('_'); - } - sb.append(Character.toUpperCase(c)); - prev = c; - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, StringBuilder sb) { - int len = camelCaseString.length(); - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, sb); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, StringBuilder sb) { - int len = camelCaseString.length; - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString, len, sb); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, StringBuilder sb) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - sb.append('_'); - } - sb.append(Character.toUpperCase(c)); - prev = c; - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, Writer writer) { - int len = camelCaseString.length(); - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, writer); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, Writer writer) { - int len = camelCaseString.length; - if (len != 0) { - convertCamelCaseToAllCapsOn_(camelCaseString, len, writer); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, Writer writer) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - writeCharOn('_', writer); - } - writeCharOn(Character.toUpperCase(c), writer); - prev = c; - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static String convertCamelCaseToAllCaps(String camelCaseString, int maxLength) { - int len = camelCaseString.length(); - if ((len == 0) || (maxLength == 0)) { - return camelCaseString; - } - return new String(convertCamelCaseToAllCaps_(camelCaseString.toCharArray(), maxLength, len)); - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static char[] convertCamelCaseToAllCaps(char[] camelCaseString, int maxLength) { - int len = camelCaseString.length; - if ((len == 0) || (maxLength == 0)) { - return camelCaseString; - } - return convertCamelCaseToAllCaps_(camelCaseString, maxLength, len); - } - - private static char[] convertCamelCaseToAllCaps_(char[] camelCaseString, int maxLength, int len) { - StringBuilder sb = new StringBuilder(maxLength); - convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb); - return convertToCharArray(sb); - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, StringBuffer sb) { - int len = camelCaseString.length(); - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, sb); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, StringBuffer sb) { - int len = camelCaseString.length; - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, StringBuffer sb) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - sb.append('_'); - if (sb.length() == maxLength) { - return; - } - } - sb.append(Character.toUpperCase(c)); - if (sb.length() == maxLength) { - return; - } - prev = c; - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, StringBuilder sb) { - int len = camelCaseString.length(); - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, sb); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, StringBuilder sb) { - int len = camelCaseString.length; - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, StringBuilder sb) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - sb.append('_'); - if (sb.length() == maxLength) { - return; - } - } - sb.append(Character.toUpperCase(c)); - if (sb.length() == maxLength) { - return; - } - prev = c; - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, Writer writer) { - int len = camelCaseString.length(); - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, writer); - } - } - - /** - * Convert the specified "camel case" string to an "all caps" string: - * "largeProject" -> "LARGE_PROJECT" - * Limit the resulting string to the specified maximum length. - */ - public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, Writer writer) { - int len = camelCaseString.length; - if ((len != 0) && (maxLength != 0)) { - convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, writer); - } - } - - private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, Writer writer) { - char prev = 0; // assume 0 is not a valid char - char c = 0; - char next = camelCaseString[0]; - int writerLength = 0; - for (int i = 1; i <= len; i++) { // NB: start at 1 and end at len! - c = next; - next = ((i == len) ? 0 : camelCaseString[i]); - if (camelCaseWordBreak_(prev, c, next)) { - writeCharOn('_', writer); - if (++writerLength == maxLength) { - return; - } - } - writeCharOn(Character.toUpperCase(c), writer); - if (++writerLength == maxLength) { - return; - } - prev = c; - } - } - - /* - * Return whether the specified series of characters occur at - * a "camel case" work break: - * "*aa" -> false - * "*AA" -> false - * "*Aa" -> false - * "AaA" -> false - * "AAA" -> false - * "aa*" -> false - * "AaA" -> false - * "aAa" -> true - * "AA*" -> false - * "AAa" -> true - * where '*' == any char - */ - private static boolean camelCaseWordBreak_(char prev, char c, char next) { - if (prev == 0) { // start of string - return false; - } - if (Character.isLowerCase(c)) { - return false; - } - if (Character.isLowerCase(prev)) { - return true; - } - if (next == 0) { // end of string - return false; - } - return Character.isLowerCase(next); - } - - - // ********** convert underscores to camel case ********** - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "LargeProject" - * Capitalize the first letter. - */ - public static String convertUnderscoresToCamelCase(String underscoreString) { - return convertUnderscoresToCamelCase(underscoreString, true); - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "LargeProject" - * Capitalize the first letter. - */ - public static char[] convertUnderscoresToCamelCase(char[] underscoreString) { - return convertUnderscoresToCamelCase(underscoreString, true); - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static String convertUnderscoresToCamelCase(String underscoreString, boolean capitalizeFirstLetter) { - int len = underscoreString.length(); - if (len == 0) { - return underscoreString; - } - return new String(convertUnderscoresToCamelCase_(underscoreString.toCharArray(), capitalizeFirstLetter, len)); - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static char[] convertUnderscoresToCamelCase(char[] underscoreString, boolean capitalizeFirstLetter) { - int len = underscoreString.length; - if (len == 0) { - return underscoreString; - } - return convertUnderscoresToCamelCase_(underscoreString, capitalizeFirstLetter, len); - } - - private static char[] convertUnderscoresToCamelCase_(char[] underscoreString, boolean capitalizeFirstLetter, int len) { - StringBuilder sb = new StringBuilder(len); - convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb); - return convertToCharArray(sb); - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, StringBuffer sb) { - int len = underscoreString.length(); - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, sb); - } - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, StringBuffer sb) { - int len = underscoreString.length; - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb); - } - } - - private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, StringBuffer sb) { - char prev = 0; - char c = 0; - boolean first = true; - for (int i = 0; i < len; i++) { - prev = c; - c = underscoreString[i]; - if (c == '_') { - continue; - } - if (first) { - first = false; - sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c)); - } else { - sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c)); - } - } - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, StringBuilder sb) { - int len = underscoreString.length(); - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, sb); - } - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, StringBuilder sb) { - int len = underscoreString.length; - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb); - } - } - - private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, StringBuilder sb) { - char prev = 0; - char c = 0; - boolean first = true; - for (int i = 0; i < len; i++) { - prev = c; - c = underscoreString[i]; - if (c == '_') { - continue; - } - if (first) { - first = false; - sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c)); - } else { - sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c)); - } - } - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, Writer writer) { - int len = underscoreString.length(); - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, writer); - } - } - - /** - * Convert the specified "underscore" string to a "camel case" string: - * "LARGE_PROJECT" -> "largeProject" - * Optionally capitalize the first letter. - */ - public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, Writer writer) { - int len = underscoreString.length; - if (len != 0) { - convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, writer); - } - } - - private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, Writer writer) { - char prev = 0; - char c = 0; - boolean first = true; - for (int i = 0; i < len; i++) { - prev = c; - c = underscoreString[i]; - if (c == '_') { - continue; - } - if (first) { - first = false; - writeCharOn(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c), writer); - } else { - writeCharOn((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c), writer); - } - } - } - - - // ********** convert to Java string literal ********** - - public static final String EMPTY_JAVA_STRING_LITERAL = "\"\""; //$NON-NLS-1$ - public static final char[] EMPTY_JAVA_STRING_LITERAL_CHAR_ARRAY = EMPTY_JAVA_STRING_LITERAL.toCharArray(); - - public static String convertToJavaStringLiteral(String string) { - int len = string.length(); - if (len == 0) { - return EMPTY_JAVA_STRING_LITERAL; - } - StringBuilder sb = new StringBuilder(len + 5); - convertToJavaStringLiteralOn_(string.toCharArray(), sb, len); - return sb.toString(); - } - - public static char[] convertToJavaStringLiteral(char[] string) { - int len = string.length; - if (len == 0) { - return EMPTY_JAVA_STRING_LITERAL_CHAR_ARRAY; - } - StringBuilder sb = new StringBuilder(len + 5); - convertToJavaStringLiteralOn_(string, sb, len); - len = sb.length(); - char[] result = new char[len]; - sb.getChars(0, len, result, 0); - return result; - } - - public static Iterator<String> convertToJavaStringLiterals(Iterator<String> strings) { - return new TransformationIterator<String, String>(strings) { - @Override - protected String transform(String string) { - return StringTools.convertToJavaStringLiteral(string); - } - }; - } - - // cannot name method simply 'convertToJavaStringLiterals' because of type-erasure... - public static Iterator<char[]> convertToJavaCharArrayLiterals(Iterator<char[]> strings) { - return new TransformationIterator<char[], char[]>(strings) { - @Override - protected char[] transform(char[] string) { - return StringTools.convertToJavaStringLiteral(string); - } - }; - } - - public static void convertToJavaStringLiteralOn(String string, StringBuffer sb) { - int len = string.length(); - if (len == 0) { - sb.append(EMPTY_JAVA_STRING_LITERAL); - } else { - convertToJavaStringLiteralOn_(string.toCharArray(), sb, len); - } - } - - public static void convertToJavaStringLiteralOn(char[] string, StringBuffer sb) { - int len = string.length; - if (len == 0) { - sb.append(EMPTY_JAVA_STRING_LITERAL); - } else { - convertToJavaStringLiteralOn_(string, sb, len); - } - } - - /* - * no length checks - */ - private static void convertToJavaStringLiteralOn_(char[] string, StringBuffer sb, int len) { - sb.ensureCapacity(sb.length() + len + 5); - sb.append(QUOTE); - for (char c : string) { - switch (c) { - case '\b': // backspace - sb.append("\\b"); //$NON-NLS-1$ - break; - case '\t': // horizontal tab - sb.append("\\t"); //$NON-NLS-1$ - break; - case '\n': // line-feed LF - sb.append("\\n"); //$NON-NLS-1$ - break; - case '\f': // form-feed FF - sb.append("\\f"); //$NON-NLS-1$ - break; - case '\r': // carriage-return CR - sb.append("\\r"); //$NON-NLS-1$ - break; - case '"': // double-quote - sb.append("\\\""); //$NON-NLS-1$ - break; -// case '\'': // single-quote -// sb.append("\\'"); //$NON-NLS-1$ -// break; - case '\\': // backslash - sb.append("\\\\"); //$NON-NLS-1$ - break; - default: - sb.append(c); - break; - } - } - sb.append(QUOTE); - } - - public static void convertToJavaStringLiteralOn(String string, StringBuilder sb) { - int len = string.length(); - if (len == 0) { - sb.append(EMPTY_JAVA_STRING_LITERAL); - } else { - convertToJavaStringLiteralOn_(string.toCharArray(), sb, len); - } - } - - public static void convertToJavaStringLiteralOn(char[] string, StringBuilder sb) { - int len = string.length; - if (len == 0) { - sb.append(EMPTY_JAVA_STRING_LITERAL); - } else { - convertToJavaStringLiteralOn_(string, sb, len); - } - } - - /* - * no length checks - */ - private static void convertToJavaStringLiteralOn_(char[] string, StringBuilder sb, int len) { - sb.ensureCapacity(sb.length() + len + 5); - sb.append(QUOTE); - for (char c : string) { - switch (c) { - case '\b': // backspace - sb.append("\\b"); //$NON-NLS-1$ - break; - case '\t': // horizontal tab - sb.append("\\t"); //$NON-NLS-1$ - break; - case '\n': // line-feed LF - sb.append("\\n"); //$NON-NLS-1$ - break; - case '\f': // form-feed FF - sb.append("\\f"); //$NON-NLS-1$ - break; - case '\r': // carriage-return CR - sb.append("\\r"); //$NON-NLS-1$ - break; - case '"': // double-quote - sb.append("\\\""); //$NON-NLS-1$ - break; -// case '\'': // single-quote -// sb.append("\\'"); //$NON-NLS-1$ -// break; - case '\\': // backslash - sb.append("\\\\"); //$NON-NLS-1$ - break; - default: - sb.append(c); - break; - } - } - sb.append(QUOTE); - } - - public static void convertToJavaStringLiteralOn(String string, Writer writer) { - if (string.length() == 0) { - writeStringOn(EMPTY_JAVA_STRING_LITERAL, writer); - } else { - convertToJavaStringLiteralOn_(string.toCharArray(), writer); - } - } - - public static void convertToJavaStringLiteralOn(char[] string, Writer writer) { - if (string.length == 0) { - writeStringOn(EMPTY_JAVA_STRING_LITERAL, writer); - } else { - convertToJavaStringLiteralOn_(string, writer); - } - } - - /* - * no length checks - */ - private static void convertToJavaStringLiteralOn_(char[] string, Writer writer) { - writeCharOn(QUOTE, writer); - for (char c : string) { - switch (c) { - case '\b': // backspace - writeStringOn("\\b", writer); //$NON-NLS-1$ - break; - case '\t': // horizontal tab - writeStringOn("\\t", writer); //$NON-NLS-1$ - break; - case '\n': // line-feed LF - writeStringOn("\\n", writer); //$NON-NLS-1$ - break; - case '\f': // form-feed FF - writeStringOn("\\f", writer); //$NON-NLS-1$ - break; - case '\r': // carriage-return CR - writeStringOn("\\r", writer); //$NON-NLS-1$ - break; - case '"': // double-quote - writeStringOn("\\\"", writer); //$NON-NLS-1$ - break; -// case '\'': // single-quote -// writeStringOn("\\'", writer); //$NON-NLS-1$ -// break; - case '\\': // backslash - writeStringOn("\\\\", writer); //$NON-NLS-1$ - break; - default: - writeCharOn(c, writer); - break; - } - } - writeCharOn(QUOTE, writer); - } - - - // ********** convenience ********** - - public static char[] convertToCharArray(StringBuffer sb) { - int len = sb.length(); - char[] result = new char[len]; - sb.getChars(0, len, result, 0); - return result; - } - - public static char[] convertToCharArray(StringBuilder sb) { - int len = sb.length(); - char[] result = new char[len]; - sb.getChars(0, len, result, 0); - return result; - } - - private static void writeStringOn(char[] string, Writer writer) { - try { - writer.write(string); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private static void writeStringOn(char[] string, char escape, Writer writer) { - try { - for (char c : string) { - if (c == escape) { - writer.write(c); - } - writer.write(c); - } - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private static void writeStringOn(char[] string, int off, int len, Writer writer) { - try { - writer.write(string, off, len); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private static void writeStringOn(String string, int off, int len, Writer writer) { - try { - writer.write(string, off, len); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private static void writeStringOn(String string, Writer writer) { - try { - writer.write(string); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private static void writeCharOn(char c, Writer writer) { - try { - writer.write(c); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - - // ********** constructor ********** - - /* - * Suppress default constructor, ensuring non-instantiability. - */ - private StringTools() { - super(); - throw new UnsupportedOperationException(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java deleted file mode 100644 index 001aa64bd6..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java +++ /dev/null @@ -1,374 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import org.eclipse.jpt.utility.Command; - -/** - * This class provides synchronized access to a boolean value. - * It also provides protocol for suspending a thread until the - * boolean value is set to true or false, with optional time-outs. - * @see BooleanHolder - */ -public class SynchronizedBoolean - implements Cloneable, Serializable -{ - /** Backing boolean. */ - private boolean value; - - /** Object to synchronize on. */ - private final Object mutex; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Create a synchronized boolean with the specified initial value - * and mutex. - */ - public SynchronizedBoolean(boolean value, Object mutex) { - super(); - this.value = value; - this.mutex = mutex; - } - - /** - * Create a synchronized boolean with the specified initial value. - */ - public SynchronizedBoolean(boolean value) { - super(); - this.value = value; - this.mutex = this; - } - - /** - * Create a synchronized boolean with an initial value of false - * and specified mutex. - */ - public SynchronizedBoolean(Object mutex) { - this(false, mutex); - } - - /** - * Create a synchronized boolean with an initial value of false. - */ - public SynchronizedBoolean() { - this(false); - } - - - // ********** accessors ********** - - /** - * Return the current boolean value. - */ - public boolean value() { - synchronized (this.mutex) { - return this.value; - } - } - - /** - * Return whether the current boolean value is true. - */ - public boolean isTrue() { - synchronized (this.mutex) { - return this.value; - } - } - - /** - * Return whether the current boolean value is false. - */ - public boolean isFalse() { - synchronized (this.mutex) { - return ! this.value; - } - } - - /** - * Return whether the current boolean value is the specified value. - */ - public boolean is(boolean v) { - synchronized (this.mutex) { - return this.value == v; - } - } - - /** - * Set the boolean value. If the value changes, all waiting - * threads are notified. - */ - public void setValue(boolean value) { - synchronized (this.mutex) { - if (this.value != value) { - this.value = value; - this.mutex.notifyAll(); - } - } - } - - /** - * Set the boolean value to true. If the value changes, all waiting - * threads are notified. - */ - public void setTrue() { - synchronized (this.mutex) { - this.setValue(true); - } - } - - /** - * Set the boolean value to false. If the value changes, all waiting - * threads are notified. - */ - public void setFalse() { - synchronized (this.mutex) { - this.setValue(false); - } - } - - /** - * Return the object this object locks on while performing - * its operations. - */ - public Object mutex() { - return this.mutex; - } - - - // ********** indefinite waits ********** - - /** - * Suspend the current thread until the boolean value changes - * to the specified value. If the boolean value is already the - * specified value, return immediately. - */ - public void waitUntilValueIs(boolean v) throws InterruptedException { - synchronized (this.mutex) { - while (this.value != v) { - this.mutex.wait(); - } - } - } - - /** - * Suspend the current thread until the boolean value changes to true. - * If the boolean value is already true, return immediately. - */ - public void waitUntilTrue() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIs(true); - } - } - - /** - * Suspend the current thread until the boolean value changes to false. - * If the boolean value is already false, return immediately. - */ - public void waitUntilFalse() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIs(false); - } - } - - /** - * Suspend the current thread until the boolean value changes to - * NOT the specified value, then change it back to the specified - * value and continue executing. If the boolean value is already - * NOT the specified value, set the value to the specified value - * immediately. - */ - public void waitToSetValue(boolean v) throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIs( ! v); - this.setValue(v); - } - } - - /** - * Suspend the current thread until the boolean value changes to false, - * then change it back to true and continue executing. If the boolean - * value is already false, set the value to true immediately. - */ - public void waitToSetTrue() throws InterruptedException { - synchronized (this.mutex) { - this.waitToSetValue(true); - } - } - - /** - * Suspend the current thread until the boolean value changes to true, - * then change it back to false and continue executing. If the boolean - * value is already true, set the value to false immediately. - */ - public void waitToSetFalse() throws InterruptedException { - synchronized (this.mutex) { - this.waitToSetValue(false); - } - } - - - // ********** timed waits ********** - - /** - * Suspend the current thread until the boolean value changes - * to the specified value or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the boolean value is already the specified value, return true - * immediately. - */ - public boolean waitUntilValueIs(boolean v, long timeout) throws InterruptedException { - synchronized (this.mutex) { - if (timeout == 0L) { - this.waitUntilValueIs(v); // wait indefinitely until notified - return true; // if it ever comes back, the condition was met - } - - long stop = System.currentTimeMillis() + timeout; - long remaining = timeout; - while ((this.value != v) && (remaining > 0L)) { - this.mutex.wait(remaining); - remaining = stop - System.currentTimeMillis(); - } - return (this.value == v); - } - } - - /** - * Suspend the current thread until the boolean value changes - * to true or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the boolean value is already true, return true immediately. - */ - public boolean waitUntilTrue(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilValueIs(true, timeout); - } - } - - /** - * Suspend the current thread until the boolean value changes - * to false or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the boolean value is already true, return true immediately. - */ - public boolean waitUntilFalse(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilValueIs(false, timeout); - } - } - - /** - * Suspend the current thread until the boolean value changes to NOT the - * specified value, then change it back to the specified value and continue - * executing. If the boolean value does not change to false before the - * time-out, simply continue executing without changing the value. - * The time-out is specified in milliseconds. Return true if the value was - * set to the specified value; return false if a time-out occurred. - * If the boolean value is already NOT the specified value, set the value - * to the specified value immediately and return true. - */ - public boolean waitToSetValue(boolean v, long timeout) throws InterruptedException { - synchronized (this.mutex) { - boolean success = this.waitUntilValueIs( ! v, timeout); - if (success) { - this.setValue(v); - } - return success; - } - } - - /** - * Suspend the current thread until the boolean value changes to false, - * then change it back to true and continue executing. If the boolean - * value does not change to false before the time-out, simply continue - * executing without changing the value. The time-out is specified in - * milliseconds. Return true if the value was set to true; return false - * if a time-out occurred. If the boolean value is already false, set the - * value to true immediately and return true. - */ - public boolean waitToSetTrue(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitToSetValue(true, timeout); - } - } - - /** - * Suspend the current thread until the boolean value changes to true, - * then change it back to false and continue executing. If the boolean - * value does not change to true before the time-out, simply continue - * executing without changing the value. The time-out is specified in - * milliseconds. Return true if the value was set to false; return false - * if a time-out occurred. If the boolean value is already true, set the - * value to false immediately and return true. - */ - public boolean waitToSetFalse(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitToSetValue(false, timeout); - } - } - - - // ********** synchronized behavior ********** - - /** - * If the current thread is not interrupted, execute the specified command - * with the mutex locked. This is useful for initializing the value in another - * thread. - */ - public void execute(Command command) throws InterruptedException { - if (Thread.interrupted()) { - throw new InterruptedException(); - } - synchronized (this.mutex) { - command.execute(); - } - } - - - // ********** standard methods ********** - - @Override - public Object clone() { - try { - synchronized (this.mutex) { - return super.clone(); - } - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public boolean equals(Object o) { - if (o instanceof SynchronizedBoolean) { - return this.value() == ((SynchronizedBoolean) o).value(); - } - return false; - } - - @Override - public int hashCode() { - return this.value() ? 1 : 0; - } - - @Override - public String toString() { - return String.valueOf(this.value()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java deleted file mode 100644 index bcf83dbfa9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java +++ /dev/null @@ -1,372 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import org.eclipse.jpt.utility.Command; - -/** - * This class provides synchronized access to an object of type T. - * It also provides protocol for suspending a thread until the - * value is set to null or a non-null value, with optional time-outs. - */ -public class SynchronizedObject<T> - implements Cloneable, Serializable -{ - /** Backing value. */ - private T value; - - /** Object to synchronize on. */ - private final Object mutex; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Create a synchronized object with the specified initial value - * and mutex. - */ - public SynchronizedObject(T value, Object mutex) { - super(); - this.value = value; - this.mutex = mutex; - } - - /** - * Create a synchronized object with the specified initial value. - */ - public SynchronizedObject(T value) { - super(); - this.value = value; - this.mutex = this; - } - - /** - * Create a synchronized object with an initial value of null. - */ - public SynchronizedObject() { - this(null); - } - - - // ********** accessors ********** - - /** - * Return the current value. - */ - public T value() { - synchronized (this.mutex) { - return this.value; - } - } - - /** - * Return whether the current value is null. - */ - public boolean isNull() { - synchronized (this.mutex) { - return this.value == null; - } - } - - /** - * Return whether the current value is not null. - */ - public boolean isNotNull() { - synchronized (this.mutex) { - return this.value != null; - } - } - - /** - * Set the value. If the value changes, all waiting - * threads are notified. - */ - public void setValue(T value) { - synchronized (this.mutex) { - if (this.value != value) { - this.value = value; - this.mutex.notifyAll(); - } - } - } - - /** - * Set the value to null. If the value changes, all waiting - * threads are notified. - */ - public void setNull() { - synchronized (this.mutex) { - this.setValue(null); - } - } - - /** - * Return the object this object locks on while performing - * its operations. - */ - public Object mutex() { - return this.mutex; - } - - - // ********** indefinite waits ********** - - /** - * Suspend the current thread until the value changes - * to the specified value. If the value is already the - * specified value, return immediately. - */ - public void waitUntilValueIs(T v) throws InterruptedException { - synchronized (this.mutex) { - while (this.value != v) { - this.mutex.wait(); - } - } - } - - /** - * Suspend the current thread until the value changes - * to something other than the specified value. If the - * value is already NOT the specified value, return immediately. - */ - public void waitUntilValueIsNot(T v) throws InterruptedException { - synchronized (this.mutex) { - while (this.value == v) { - this.mutex.wait(); - } - } - } - - /** - * Suspend the current thread until the value changes to null. - * If the value is already null, return immediately. - */ - public void waitUntilNull() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIs(null); - } - } - - /** - * Suspend the current thread until the value changes - * to something other than null. - * If the value is already NOT null, return immediately. - */ - public void waitUntilNotNull() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIsNot(null); - } - } - - /** - * Suspend the current thread until the value changes to - * something other than the specified value, then change - * it back to the specified value and continue executing. - * If the value is already NOT the specified value, set - * the value immediately. - */ - public void waitToSetValue(T v) throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilValueIsNot(v); - this.setValue(v); - } - } - - /** - * Suspend the current thread until the value changes to - * something other than null, then change it back to null - * and continue executing. If the value is already NOT null, - * set the value to null immediately. - */ - public void waitToSetNull() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilNotNull(); - this.setValue(null); - } - } - - - // ********** timed waits ********** - - /** - * Suspend the current thread until the value changes - * to the specified value or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the value is already the specified value, return true immediately. - */ - public boolean waitUntilValueIs(T v, long timeout) throws InterruptedException { - synchronized (this.mutex) { - if (timeout == 0L) { - this.waitUntilValueIs(v); // wait indefinitely until notified - return true; // if it ever comes back, the condition was met - } - - long stop = System.currentTimeMillis() + timeout; - long remaining = timeout; - while ((this.value != v) && (remaining > 0L)) { - this.mutex.wait(remaining); - remaining = stop - System.currentTimeMillis(); - } - return (this.value == v); - } - } - - /** - * Suspend the current thread until the value changes to something - * other than the specified value or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was removed; return false if a time-out occurred. - * If the value is already NOT the specified value, return true immediately. - */ - public boolean waitUntilValueIsNot(T v, long timeout) throws InterruptedException { - synchronized (this.mutex) { - if (timeout == 0L) { - this.waitUntilValueIsNot(v); // wait indefinitely until notified - return true; // if it ever comes back, the condition was met - } - - long stop = System.currentTimeMillis() + timeout; - long remaining = timeout; - while ((this.value == v) && (remaining > 0L)) { - this.mutex.wait(remaining); - remaining = stop - System.currentTimeMillis(); - } - return (this.value != v); - } - } - - /** - * Suspend the current thread until the value changes - * to null or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the value is already null, return true immediately. - */ - public boolean waitUntilNull(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilValueIs(null, timeout); - } - } - - /** - * Suspend the current thread until the value changes - * to something other than null or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - * If the value is already NOT null, return true immediately. - */ - public boolean waitUntilNotNull(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilValueIsNot(null, timeout); - } - } - - /** - * Suspend the current thread until the value changes to - * something other than the specified value, then change - * it back to the specified value and continue executing. - * If the value does not change to something other than the - * specified before the time-out, simply continue executing - * without changing the value. - * The time-out is specified in milliseconds. Return true if the value was - * set to true; return false if a time-out occurred. - * If the value is already something other than the specified value, set - * the value immediately and return true. - */ - public boolean waitToSetValue(T v, long timeout) throws InterruptedException { - synchronized (this.mutex) { - boolean success = this.waitUntilValueIsNot(v, timeout); - if (success) { - this.setValue(v); - } - return success; - } - } - - /** - * Suspend the current thread until the value changes to something - * other than null, then change it back to null and continue executing. - * If the value does not change to something other than null before - * the time-out, simply continue executing without changing the value. - * The time-out is specified in milliseconds. Return true if the value was - * set to false; return false if a time-out occurred. - * If the value is already something other than null, set - * the value to null immediately and return true. - */ - public boolean waitToSetNull(long timeout) throws InterruptedException { - synchronized (this.mutex) { - boolean success = this.waitUntilNotNull(timeout); - if (success) { - this.setValue(null); - } - return success; - } - } - - - // ********** synchronized behavior ********** - - /** - * If current thread is not interrupted, execute the specified command - * with the mutex locked. This is useful for initializing the value in another - * thread. - */ - public void execute(Command command) throws InterruptedException { - if (Thread.interrupted()) { - throw new InterruptedException(); - } - synchronized (this.mutex) { - command.execute(); - } - } - - - // ********** standard methods ********** - - @Override - public SynchronizedObject<T> clone() { - try { - synchronized (this.mutex) { - @SuppressWarnings("unchecked") - SynchronizedObject<T> clone = (SynchronizedObject<T>) super.clone(); - return clone; - } - } catch (CloneNotSupportedException ex) { - throw new InternalError(); - } - } - - @Override - public boolean equals(Object obj) { - if ( ! (obj instanceof SynchronizedObject)) { - return false; - } - Object v1 = this.value(); - Object v2 = ((SynchronizedObject<?>) obj).value(); - return (v1 == null) ? - (v2 == null) : v1.equals(v2); - } - - @Override - public int hashCode() { - Object v = this.value(); - return (v == null) ? 0 : v.hashCode(); - } - - @Override - public String toString() { - return String.valueOf(this.value()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java deleted file mode 100644 index e232c402ff..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.Serializable; -import java.util.EmptyStackException; -import org.eclipse.jpt.utility.Command; - -/** - * Thread-safe implementation of the Stack interface. - * This also provides protocol for suspending a thread until the - * stack is empty or not empty, with optional time-outs. - */ -public class SynchronizedStack<E> - implements Stack<E>, Serializable -{ - /** Backing stack. */ - private Stack<E> stack; - - /** Object to synchronize on. */ - private final Object mutex; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a synchronized stack that wraps the - * specified stack and locks on the specified mutex. - */ - public SynchronizedStack(Stack<E> stack, Object mutex) { - super(); - this.stack = stack; - this.mutex = mutex; - } - - /** - * Construct a synchronized stack that wraps the - * specified stack and locks on itself. - */ - public SynchronizedStack(Stack<E> stack) { - super(); - this.stack = stack; - this.mutex = this; - } - - /** - * Construct a synchronized stack that locks on the specified mutex. - */ - public SynchronizedStack(Object mutex) { - this(new SimpleStack<E>(), mutex); - } - - /** - * Construct a synchronized stack that locks on itself. - */ - public SynchronizedStack() { - this(new SimpleStack<E>()); - } - - - // ********** Stack implementation ********** - - public void push(E o) { - synchronized (this.mutex) { - this.stack.push(o); - this.mutex.notifyAll(); - } - } - - public E pop() { - synchronized (this.mutex) { - E o = this.stack.pop(); - this.mutex.notifyAll(); - return o; - } - } - - public E peek() { - synchronized (this.mutex) { - return this.stack.peek(); - } - } - - public boolean isEmpty() { - synchronized (this.mutex) { - return this.stack.isEmpty(); - } - } - - - // ********** indefinite waits ********** - - /** - * Suspend the current thread until the stack's empty status changes - * to the specified value. - */ - public void waitUntilEmptyIs(boolean empty) throws InterruptedException { - synchronized (this.mutex) { - while (this.isEmpty() != empty) { - this.mutex.wait(); - } - } - } - - /** - * Suspend the current thread until the stack is empty. - */ - public void waitUntilEmpty() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilEmptyIs(true); - } - } - - /** - * Suspend the current thread until the stack has something on it. - */ - public void waitUntilNotEmpty() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilEmptyIs(false); - } - } - - /** - * Suspend the current thread until the stack is empty, - * then "push" the specified item on to the top of the stack - * and continue executing. - */ - public void waitToPush(E o) throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilEmpty(); - this.push(o); - } - } - - /** - * Suspend the current thread until the stack has something on it, - * then "pop" an item from the top of the stack and return it. - */ - public Object waitToPop() throws InterruptedException { - synchronized (this.mutex) { - this.waitUntilNotEmpty(); - return this.pop(); - } - } - - - // ********** timed waits ********** - - /** - * Suspend the current thread until the stack's empty status changes - * to the specified value or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if the specified - * value was achieved; return false if a time-out occurred. - */ - public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException { - synchronized (this.mutex) { - if (timeout == 0L) { - this.waitUntilEmptyIs(empty); // wait indefinitely until notified - return true; // if it ever comes back, the condition was met - } - - long stop = System.currentTimeMillis() + timeout; - long remaining = timeout; - while ((this.isEmpty() != empty) && (remaining > 0L)) { - this.mutex.wait(remaining); - remaining = stop - System.currentTimeMillis(); - } - return (this.isEmpty() == empty); - } - } - - /** - * Suspend the current thread until the stack is empty - * or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if - * the stack is empty; return false if a time-out occurred. - */ - public boolean waitUntilEmpty(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilEmptyIs(true, timeout); - } - } - - /** - * Suspend the current thread until the stack has something on it. - * or the specified time-out occurs. - * The time-out is specified in milliseconds. Return true if - * the stack has something on it; return false if a time-out occurred. - */ - public boolean waitUntilNotEmpty(long timeout) throws InterruptedException { - synchronized (this.mutex) { - return this.waitUntilEmptyIs(false, timeout); - } - } - - /** - * Suspend the current thread until the stack is empty, - * then "push" the specified item on to the top of the stack - * and continue executing. If the stack is not emptied out - * before the time-out, simply continue executing without - * "pushing" the item. - * The time-out is specified in milliseconds. Return true if the - * item was pushed; return false if a time-out occurred. - */ - public boolean waitToPush(E o, long timeout) throws InterruptedException { - synchronized (this.mutex) { - boolean success = this.waitUntilEmpty(timeout); - if (success) { - this.push(o); - } - return success; - } - } - - /** - * Suspend the current thread until the stack has something on it, - * then "pop" an item from the top of the stack and return it. - * If the stack is empty and nothing is "pushed" on to it before the - * time-out, throw an empty stack exception. - * The time-out is specified in milliseconds. - */ - public Object waitToPop(long timeout) throws InterruptedException { - synchronized (this.mutex) { - boolean success = this.waitUntilNotEmpty(timeout); - if (success) { - return this.pop(); - } - throw new EmptyStackException(); - } - } - - - // ********** synchronized behavior ********** - - /** - * If the current thread is not interrupted, execute the specified command - * with the mutex locked. This is useful for initializing the stack in another - * thread. - */ - public void execute(Command command) throws InterruptedException { - if (Thread.interrupted()) { - throw new InterruptedException(); - } - synchronized (this.mutex) { - command.execute(); - } - } - - - // ********** additional public protocol ********** - - /** - * Return the object this object locks on while performing - * its operations. - */ - public Object mutex() { - return this.mutex; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - synchronized (this.mutex) { - return this.stack.toString(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommand.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommand.java deleted file mode 100644 index c12038e502..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommand.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import org.eclipse.jpt.utility.Command; - -/** - * This implementation of the Command interface allows the client to - * specify a different Command for each thread. - */ -public class ThreadLocalCommand implements Command { - protected final ThreadLocal<Command> threadLocal; - protected final Command defaultCommand; - - /** - * The default command does nothing. - */ - public ThreadLocalCommand() { - this(Command.Null.instance()); - } - - public ThreadLocalCommand(Command defaultCommand) { - super(); - this.defaultCommand = defaultCommand; - this.threadLocal = this.buildThreadLocal(); - } - - protected ThreadLocal<Command> buildThreadLocal() { - return new ThreadLocal<Command>(); - } - - public void execute() { - this.get().execute(); - } - - protected Command get() { - Command command = this.threadLocal.get(); - return (command != null) ? command : this.defaultCommand; - } - - /** - * Set the current thread's command to the specified value. - */ - public void set(Command command) { - this.threadLocal.set(command); - } - - /** - * Return the string representation of the current thread's command. - */ - @Override - public String toString() { - return this.get().toString(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommandExecutor.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommandExecutor.java deleted file mode 100644 index 7cb49b4e93..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ThreadLocalCommandExecutor.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import org.eclipse.jpt.utility.Command; -import org.eclipse.jpt.utility.CommandExecutor; - -/** - * This implementation of the CommandExecutor interface allows the client to - * specify a different Command Executor for each thread. - */ -public class ThreadLocalCommandExecutor implements CommandExecutor { - protected final ThreadLocal<CommandExecutor> threadLocal; - protected final CommandExecutor defaultCommandExecutor; - - /** - * The default command executor simply executes the command directly. - */ - public ThreadLocalCommandExecutor() { - this(CommandExecutor.Default.instance()); - } - - public ThreadLocalCommandExecutor(CommandExecutor defaultCommandExecutor) { - super(); - this.defaultCommandExecutor = defaultCommandExecutor; - this.threadLocal = this.buildThreadLocal(); - } - - protected ThreadLocal<CommandExecutor> buildThreadLocal() { - return new ThreadLocal<CommandExecutor>(); - } - - public void execute(Command command) { - this.get().execute(command); - } - - protected CommandExecutor get() { - CommandExecutor ce = this.threadLocal.get(); - return (ce != null) ? ce : this.defaultCommandExecutor; - } - - /** - * Set the current thread's command executor to the specified value. - */ - public void set(CommandExecutor commandExecutor) { - this.threadLocal.set(commandExecutor); - } - - /** - * Return the string representation of the current thread's command - * executor. - */ - @Override - public String toString() { - return this.get().toString(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Transformer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Transformer.java deleted file mode 100644 index 946e69783f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Transformer.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -/** - * Used by various "pluggable" classes to transform objects. - * Transform an object of type T1 to an object of type T2. - */ -public interface Transformer<T1, T2> { - - /** - * Return the transformed object. - * The semantics of "transform" is determined by the - * contract between the client and the server. - */ - T2 transform(T1 o); - - - final class Null<S1, S2> implements Transformer<S1, S2> { - @SuppressWarnings("unchecked") - public static final Transformer INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R1, R2> Transformer<R1, R2> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // simply return the object, unchanged - @SuppressWarnings("unchecked") - public S2 transform(S1 o) { - return (S2) o; - } - @Override - public String toString() { - return "Transformer.Null"; //$NON-NLS-1$ - } - } - - final class Disabled<S1, S2> implements Transformer<S1, S2> { - @SuppressWarnings("unchecked") - public static final Transformer INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R1, R2> Transformer<R1, R2> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public S2 transform(S1 o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "Transformer.Disabled"; //$NON-NLS-1$ - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/XMLStringEncoder.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/XMLStringEncoder.java deleted file mode 100644 index fcc359de00..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/XMLStringEncoder.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; - -/** - * This encoder will replace any of a specified set of characters with an XML - * "character reference": '/' => "/" - */ -public final class XMLStringEncoder { - - /** The set of characters to be converted into XML character references. */ - private final char[] chars; - - /** Cache the value of the highest character in the set above. */ - private final char maxChar; - - - // ********** constructors/initialization ********** - - /** - * Construct an encoder that converts the specified set of characters - * into XML character references. - */ - public XMLStringEncoder(char[] chars) { - super(); - if (chars == null) { - throw new NullPointerException(); - } - // the ampersand must be included since it is the escape character - if (CollectionTools.contains(chars, '&')) { - this.chars = chars; - } else { - this.chars = CollectionTools.add(chars, '&'); - } - this.maxChar = this.calculateMaxInvalidFileNameChar(); - } - - /** - * Calculate the maximum value of the set of characters to be converted - * into XML character references. This will be used to short-circuit the - * search for a character in the set. - * @see #charIsToBeEncoded(char) - */ - private char calculateMaxInvalidFileNameChar() { - char[] localChars = this.chars; - char max = 0; - for (int i = localChars.length; i-- > 0; ) { - char c = localChars[i]; - if (max < c) { - max = c; - } - } - return max; - } - - - // ********** API ********** - - /** - * Return the specified string with any characters in the set - * replaced with XML character references. - */ - public String encode(String s) { - int len = s.length(); - // allow for a few encoded characters - StringBuilder sb = new StringBuilder(len + 20); - for (int i = 0; i < len; i++) { - this.appendCharacterTo(s.charAt(i), sb); - } - return sb.toString(); - } - - /** - * Return the specified string with any XML character references - * replaced by the characters themselves. - */ - public String decode(String s) { - StringBuilder sb = new StringBuilder(s.length()); - StringBuilder temp = new StringBuilder(); // performance tweak - this.decodeTo(new StringReader(s), sb, temp); - return sb.toString(); - } - - - // ********** internal methods ********** - - /** - * Append the specified character to the string buffer, - * converting it to an XML character reference if necessary. - */ - private void appendCharacterTo(char c, StringBuilder sb) { - if (this.charIsToBeEncoded(c)) { - this.appendCharacterReferenceTo(c, sb); - } else { - sb.append(c); - } - } - - /** - * Return whether the specified character is one of the characters - * to be converted to XML character references. - */ - private boolean charIsToBeEncoded(char c) { - return (c <= this.maxChar) && CollectionTools.contains(this.chars, c); - } - - /** - * Append the specified character's XML character reference to the - * specified string buffer (e.g. '/' => "/"). - */ - private void appendCharacterReferenceTo(char c, StringBuilder sb) { - sb.append("&#x"); - sb.append(Integer.toString(c, 16)); - sb.append(';'); - } - - private void decodeTo(Reader reader, StringBuilder sb, StringBuilder temp) { - try { - this.decodeTo_(reader, sb, temp); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - private void decodeTo_(Reader reader, StringBuilder sb, StringBuilder temp) throws IOException { - int c = reader.read(); - while (c != -1) { - if (c == '&') { - this.decodeCharacterReferenceTo(reader, sb, temp); - } else { - sb.append((char) c); - } - c = reader.read(); - } - reader.close(); - } - - private void decodeCharacterReferenceTo(Reader reader, StringBuilder sb, StringBuilder temp) throws IOException { - int c = reader.read(); - this.checkChar(c, '#'); - c = reader.read(); - this.checkChar(c, 'x'); - - temp.setLength(0); // re-use temp - c = reader.read(); - while (c != ';') { - this.checkEndOfStream(c); - temp.append((char) c); - c = reader.read(); - } - String charValue = temp.toString(); - if (charValue.length() == 0) { - throw new IllegalStateException("missing numeric string"); - } - sb.append((char) Integer.parseInt(charValue, 16)); - } - - private void checkChar(int c, int expected) { - this.checkEndOfStream(c); - if (c != expected) { - throw new IllegalStateException("expected '" + (char) expected + "', but encountered '" + (char) c + "'"); - } - } - - private void checkEndOfStream(int c) { - if (c == -1) { - throw new IllegalStateException("unexpected end of string"); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java deleted file mode 100644 index 2874af48ad..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * An <code>ArrayIterator</code> provides an <code>Iterator</code> - * for an array of objects of type E. - */ -public class ArrayIterator<E> - implements Iterator<E> -{ - final E[] array; // private-protected - int nextIndex; // private-protected - private final int maxIndex; - - /** - * Construct an iterator for the specified array. - */ - public ArrayIterator(E... array) { - this(array, 0, array.length); - } - - /** - * Construct an iterator for the specified array, - * starting at the specified start index and continuing for - * the specified length. - */ - public ArrayIterator(E[] array, int start, int length) { - if ((start < 0) || (start > array.length)) { - throw new IllegalArgumentException("start: " + start); - } - if ((length < 0) || (length > array.length - start)) { - throw new IllegalArgumentException("length: " + length); - } - this.array = array; - this.nextIndex = start; - this.maxIndex = start + length; - } - - public boolean hasNext() { - return this.nextIndex < this.maxIndex; - } - - public E next() { - if (this.hasNext()) { - return this.array[this.nextIndex++]; - } - throw new NoSuchElementException(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, CollectionTools.list(this.array)); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java deleted file mode 100644 index 5b70ed4721..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.ListIterator; -import java.util.NoSuchElementException; - -/** - * An <code>ArrayListIterator</code> provides a <code>ListIterator</code> - * for an array of objects. - * - * The name might be a bit confusing: - * This is a <code>ListIterator</code> for an <code>Array</code>; - * <em>not</em> an <code>Iterator</code> for an <code>ArrayList</code>. - */ -public class ArrayListIterator<E> - extends ArrayIterator<E> - implements ListIterator<E> -{ - private final int minIndex; - - /** - * Construct a list iterator for the specified array. - */ - public ArrayListIterator(E... array) { - this(array, 0, array.length); - } - - /** - * Construct a list iterator for the specified array, - * starting at the specified start index and continuing for - * the specified length. - */ - public ArrayListIterator(E[] array, int start, int length) { - super(array, start, length); - this.minIndex = start; - } - - public int nextIndex() { - return this.nextIndex; - } - - public int previousIndex() { - return this.nextIndex - 1; - } - - public boolean hasPrevious() { - return this.nextIndex > this.minIndex; - } - - public E previous() { - if (this.hasPrevious()) { - return this.array[--this.nextIndex]; - } - throw new NoSuchElementException(); - } - - public void add(E e) { - throw new UnsupportedOperationException(); - } - - public void set(E e) { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return super.toString(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ChainIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ChainIterator.java deleted file mode 100644 index ea5076e854..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ChainIterator.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>ChainIterator</code> provides a pluggable <code>Iterator</code> - * that loops over a chain of arbitrarily linked objects. The chain - * should be null-terminated (i.e. a call to the <code>nextLink(Object)</code> - * method should return <code>null</code> when it is passed the last - * link of the chain). - * To use, supply a starting link and supply a <code>Linker</code> or - * subclass <code>ChainIterator</code> and override the - * <code>nextLink(Object)</code> method. - * The starting link will be the first object returned by the iterator. - * If the starting link is <code>null</code>, the iterator will be empty. - * Note that the iterator does not support <code>null</code> elements. - */ -public class ChainIterator<E> - implements Iterator<E> -{ - private E nextLink; - private final Linker<E> linker; - - - /** - * Construct an iterator with the specified starting link - * and a disabled linker. - * Use this constructor if you want to override the - * <code>nextLink(Object)</code> method instead of building - * a <code>Linker</code>. - */ - public ChainIterator(E startLink) { - this(startLink, Linker.Disabled.<E>instance()); - } - - /** - * Construct an iterator with the specified starting link - * and linker. - */ - public ChainIterator(E startLink, Linker<E> linker) { - super(); - this.nextLink = startLink; - this.linker = linker; - } - - public boolean hasNext() { - return this.nextLink != null; - } - - public E next() { - if (this.nextLink == null) { - throw new NoSuchElementException(); - } - E result = this.nextLink; - this.nextLink = this.nextLink(this.nextLink); - return result; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - /** - * Return the next link in the chain. - */ - protected E nextLink(E currentLink) { - return this.linker.nextLink(currentLink); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nextLink); - } - - - //********** inner classes ********** - - /** - * Used by <code>ChainIterator</code> to link - * the elements in the chain. - */ - public interface Linker<T> { - - /** - * Return the next link in the chain. - */ - T nextLink(T currentLink); - - - final class Null<S> implements Linker<S> { - @SuppressWarnings("unchecked") - public static final Linker INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R> Linker<R> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // simply return null, indicating the chain is ended - public S nextLink(S currentLink) { - return null; - } - @Override - public String toString() { - return "ChainIterator.Linker.Null"; - } - } - - final class Disabled<S> implements Linker<S> { - @SuppressWarnings("unchecked") - public static final Linker INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> Linker<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public S nextLink(S currentLink) { - throw new UnsupportedOperationException(); // ChainIterator.nextLink(Object) was not implemented - } - @Override - public String toString() { - return "ChainIterator.Linker.Disabled"; - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java deleted file mode 100644 index 7976439a03..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>CloneIterator</code> iterates over a copy of a collection, - * allowing for concurrent access to the original collection. - * <p> - * The original collection passed to the <code>CloneIterator</code>'s - * constructor should be synchronized; otherwise you run the risk of - * a corrupted collection. - * <p> - * By default, a <code>CloneIterator</code> does not support the - * <code>#remove()</code> operation; this is because it does not have - * access to the original collection. But if the <code>CloneIterator</code> - * is supplied with an <code>Mutator</code> it will delegate the - * <code>#remove()</code> operation to the <code>Mutator</code>. - * Alternatively, a subclass can override the <code>#remove(Object)</code> - * method. - */ -public class CloneIterator<E> - implements Iterator<E> -{ - private final Iterator<Object> nestedIterator; - private E current; - private final Mutator<E> mutator; - private boolean removeAllowed; - - - // ********** constructors ********** - - /** - * Construct an iterator on a copy of the specified collection. - * The <code>#remove()</code> method will not be supported, - * unless a subclass overrides the <code>#remove(Object)</code>. - */ - public CloneIterator(Collection<? extends E> c) { - this(c, Mutator.ReadOnly.<E>instance()); - } - - /** - * Construct an iterator on a copy of the specified collection. - * Use the specified mutator to remove objects from the - * original collection. - */ - public CloneIterator(Collection<? extends E> c, Mutator<E> mutator) { - super(); - this.nestedIterator = new ArrayIterator<Object>(c.toArray()); - this.current = null; - this.mutator = mutator; - this.removeAllowed = false; - } - - - // ********** Iterator implementation ********** - - public boolean hasNext() { - return this.nestedIterator.hasNext(); - } - - public E next() { - this.current = this.nestedNext(); - this.removeAllowed = true; - return this.current; - } - - public void remove() { - if ( ! this.removeAllowed) { - throw new IllegalStateException(); - } - this.remove(this.current); - this.removeAllowed = false; - } - - - // ********** internal methods ********** - - /** - * The collection passed in during construction held Es, - * so this cast is not a problem. We need this cast because - * all the elements of the original collection were copied into - * an object array (Object[]). - */ - @SuppressWarnings("unchecked") - protected E nestedNext() { - return (E) this.nestedIterator.next(); - } - - /** - * Remove the specified element from the original collection. - * <p> - * This method can be overridden by a subclass as an - * alternative to building an <code>Mutator</code>. - */ - protected void remove(E e) { - this.mutator.remove(e); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - - - //********** member interface ********** - - /** - * Used by <code>CloneIterator</code> to remove - * elements from the original collection; since the iterator - * does not have direct access to the original collection. - */ - public interface Mutator<T> { - - /** - * Remove the specified object from the original collection. - */ - void remove(T current); - - - final class ReadOnly<S> implements Mutator<S> { - @SuppressWarnings("unchecked") - public static final Mutator INSTANCE = new ReadOnly(); - @SuppressWarnings("unchecked") - public static <R> Mutator<R> instance() { - return INSTANCE; - } - // ensure single instance - private ReadOnly() { - super(); - } - // remove is not supported - public void remove(Object current) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "CloneIterator.Mutator.ReadOnly"; //$NON-NLS-1$ - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java deleted file mode 100644 index c4b5837ba1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java +++ /dev/null @@ -1,253 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>CloneListIterator</code> iterates over a copy of a list, - * allowing for concurrent access to the original list. - * <p> - * The original list passed to the <code>CloneListIterator</code>'s - * constructor should be synchronized; otherwise you run the risk of - * a corrupted list. - * <p> - * By default, a <code>CloneListIterator</code> does not support the - * modification operations; this is because it does not have - * access to the original list. But if the <code>CloneListIterator</code> - * is supplied with a <code>Mutator</code> it will delegate the - * modification operations to the <code>Mutator</code>. - * Alternatively, a subclass can override the modification methods. - */ -public class CloneListIterator<E> - implements ListIterator<E> -{ - private final ListIterator<Object> nestedListIterator; - private int cursor; - private String state; - private final Mutator<E> mutator; - - private static final String UNKNOWN = "unknown"; - private static final String PREVIOUS = "previous"; - private static final String NEXT = "next"; - - - // ********** constructors ********** - - /** - * Construct a list iterator on a copy of the specified list. - * The modification methods will not be supported, - * unless a subclass overrides them. - */ - public CloneListIterator(List<? extends E> list) { - this(list, Mutator.ReadOnly.<E>instance()); - } - - /** - * Construct a list iterator on a copy of the specified list. - * Use the specified list mutator to modify the original list. - */ - public CloneListIterator(List<? extends E> list, Mutator<E> mutator) { - super(); - // build a copy of the list and keep it in synch with original (if the mutator allows changes) - // that way the nested list iterator will maintain some of our state - this.nestedListIterator = CollectionTools.list(list.toArray()).listIterator(); - this.mutator = mutator; - this.cursor = 0; - this.state = UNKNOWN; - } - - - // ********** ListIterator implementation ********** - - public boolean hasNext() { - return this.nestedListIterator.hasNext(); - } - - public E next() { - // allow the nested iterator to throw an exception before we modify the index - E next = this.nestedNext(); - this.cursor++; - this.state = NEXT; - return next; - } - - public void remove() { - // allow the nested iterator to throw an exception before we modify the original list - this.nestedListIterator.remove(); - if (this.state == PREVIOUS) { - this.remove(this.cursor); - } else { - this.cursor--; - this.remove(this.cursor); - } - } - - public int nextIndex() { - return this.nestedListIterator.nextIndex(); - } - - public int previousIndex() { - return this.nestedListIterator.previousIndex(); - } - - public boolean hasPrevious() { - return this.nestedListIterator.hasPrevious(); - } - - public E previous() { - // allow the nested iterator to throw an exception before we modify the index - E previous = this.nestedPrevious(); - this.cursor--; - this.state = PREVIOUS; - return previous; - } - - public void add(E o) { - // allow the nested iterator to throw an exception before we modify the original list - this.nestedListIterator.add(o); - this.add(this.cursor, o); - this.cursor++; - } - - public void set(E o) { - // allow the nested iterator to throw an exception before we modify the original list - this.nestedListIterator.set(o); - if (this.state == PREVIOUS) { - this.set(this.cursor, o); - } else { - this.set(this.cursor - 1, o); - } - } - - - // ********** internal methods ********** - - /** - * The list passed in during construction held Es, - * so this cast is not a problem. We need this cast because - * all the elements of the original collection were copied into - * an object array (Object[]). - */ - @SuppressWarnings("unchecked") - protected E nestedNext() { - return (E) this.nestedListIterator.next(); - } - - /** - * The list passed in during construction held Es, - * so this cast is not a problem. We need this cast because - * all the elements of the original collection were copied into - * an object array (Object[]). - */ - @SuppressWarnings("unchecked") - protected E nestedPrevious() { - return (E) this.nestedListIterator.previous(); - } - - /** - * Add the specified element to the original list. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Mutator</code>. - */ - protected void add(int index, E o) { - this.mutator.add(index, o); - } - - /** - * Remove the specified element from the original list. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Mutator</code>. - */ - protected void remove(int index) { - this.mutator.remove(index); - } - - /** - * Set the specified element in the original list. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Mutator</code>. - */ - protected void set(int index, E o) { - this.mutator.set(index, o); - } - - - // ********** overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - - - //********** member interface ********** - - /** - * Used by <code>CloneListIterator</code> to remove - * elements from the original list; since the list iterator - * does not have direct access to the original list. - */ - public interface Mutator<T> { - - /** - * Add the specified object to the original list. - */ - void add(int index, T o); - - /** - * Remove the specified object from the original list. - */ - void remove(int index); - - /** - * Set the specified object in the original list. - */ - void set(int index, T o); - - - final class ReadOnly<S> implements Mutator<S> { - @SuppressWarnings("unchecked") - public static final Mutator INSTANCE = new ReadOnly(); - @SuppressWarnings("unchecked") - public static <R> Mutator<R> instance() { - return INSTANCE; - } - // ensure single instance - private ReadOnly() { - super(); - } - // add is not supported - public void add(int index, Object o) { - throw new UnsupportedOperationException(); - } - // remove is not supported - public void remove(int index) { - throw new UnsupportedOperationException(); - } - // set is not supported - public void set(int index, Object o) { - throw new UnsupportedOperationException(); - } - @Override - public String toString() { - return "CloneListIterator.Mutator.ReadOnly"; - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java deleted file mode 100644 index 083f535b4a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>CompositeIterator</code> wraps a collection - * of <code>Iterator</code>s and makes them appear to be a single - * <code>Iterator</code>. - */ -public class CompositeIterator<E> - implements Iterator<E> -{ - private final Iterator<? extends Iterator<? extends E>> iterators; - private Iterator<? extends E> currentIterator; - private Iterator<? extends E> lastIteratorToReturnNext; - - - // ********** constructors ********** - - /** - * Construct an iterator with the specified collection of iterators. - */ - public CompositeIterator(Collection<? extends Iterator<? extends E>> iterators) { - this(iterators.iterator()); - } - - /** - * Construct an iterator with the specified collection of iterators. - */ - public CompositeIterator(Iterator<? extends Iterator<? extends E>> iterators) { - super(); - this.iterators = iterators; - } - - /** - * Construct an iterator with the specified object prepended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public CompositeIterator(E object, Iterator<? extends E> iterator) { - this(new SingleElementIterator<E>(object), iterator); - } - - /** - * Construct an iterator with the specified object appended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public CompositeIterator(Iterator<? extends E> iterator, E object) { - this(iterator, new SingleElementIterator<E>(object)); - } - - /** - * Construct an iterator with the specified iterators. - */ - public CompositeIterator(Iterator<? extends E>... iterators) { - this(new ArrayIterator<Iterator<? extends E>>(iterators)); - } - - - // ********** Iterator implementation ********** - - public boolean hasNext() { - try { - this.loadCurrentIterator(); - } catch (NoSuchElementException ex) { - // this occurs if there are no iterators at all - return false; - } - return this.currentIterator.hasNext(); - } - - public E next() { - this.loadCurrentIterator(); - E result = this.currentIterator.next(); - - // the statement above will throw a NoSuchElementException - // if the current iterator is at the end of the line; - // so if we get here, we can set 'lastIteratorToReturnNext' - this.lastIteratorToReturnNext = this.currentIterator; - - return result; - } - - public void remove() { - if (this.lastIteratorToReturnNext == null) { - // CompositeIterator#next() has never been called - throw new IllegalStateException(); - } - this.lastIteratorToReturnNext.remove(); - } - - /** - * Load currentIterator with the first iterator that <code>hasNext()</code> - * or the final iterator if all the elements have already been retrieved. - */ - private void loadCurrentIterator() { - if (this.currentIterator == null) { - this.currentIterator = this.iterators.next(); - } - while (( ! this.currentIterator.hasNext()) && this.iterators.hasNext()) { - this.currentIterator = this.iterators.next(); - } - } - - - // ********** overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterators); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeListIterator.java deleted file mode 100644 index c2037f053d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeListIterator.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>CompositeListIterator</code> wraps a list - * of <code>ListIterator</code>s and makes them appear to be a single - * <code>ListIterator</code>. - */ -public class CompositeListIterator<E> - implements ListIterator<E> -{ - private final ListIterator<? extends ListIterator<E>> iterators; - private ListIterator<E> nextIterator; - private int nextIndex; - /** - * true if "next" was last returned; false if "previous" was last returned; - * this determines the effect of remove(Object) on nextIndex - */ - private boolean nextReturned; - private ListIterator<E> lastIteratorToReturnElement; - - - /** - * Construct a list iterator with the specified list of list iterators. - */ - public CompositeListIterator(List<? extends ListIterator<E>> iterators) { - this(iterators.listIterator()); - } - - /** - * Construct a list iterator with the specified list of list iterators. - */ - public CompositeListIterator(ListIterator<? extends ListIterator<E>> iterators) { - super(); - this.iterators = iterators; - this.nextIndex = 0; - this.nextReturned = false; - } - - /** - * Construct a list iterator with the specified object prepended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public CompositeListIterator(E object, ListIterator<E> iterator) { - this(new SingleElementListIterator<E>(object), iterator); - } - - /** - * Construct a list iterator with the specified object appended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public CompositeListIterator(ListIterator<E> iterator, E object) { - this(iterator, new SingleElementListIterator<E>(object)); - } - - /** - * Construct a list iterator with the specified list iterators. - */ - public CompositeListIterator(ListIterator<E>... iterators) { - this(new ArrayListIterator<ListIterator<E>>(iterators)); - } - - public void add(E o) { - this.checkNextIterator(); - this.nextIterator.add(o); - this.nextIndex++; - } - - public boolean hasNext() { - try { - this.loadNextIterator(); - } catch (NoSuchElementException ex) { - // this occurs if there are no iterators at all - return false; - } - return this.nextIterator.hasNext(); - } - - public boolean hasPrevious() { - try { - this.loadPreviousIterator(); - } catch (NoSuchElementException ex) { - // this occurs if there are no iterators at all - return false; - } - return this.nextIterator.hasPrevious(); - } - - public E next() { - this.loadNextIterator(); - E result = this.nextIterator.next(); - - // the statement above will throw a NoSuchElementException - // if the current iterator is at the end of the line; - // so if we get here, we can set the 'lastIteratorToReturnElement' - this.lastIteratorToReturnElement = this.nextIterator; - this.nextIndex++; - this.nextReturned = true; - - return result; - } - - public int nextIndex() { - return this.nextIndex; - } - - public E previous() { - this.loadPreviousIterator(); - E result = this.nextIterator.previous(); - - // the statement above will throw a NoSuchElementException - // if the current iterator is at the end of the line; - // so if we get here, we can set the 'lastIteratorToReturnElement' - this.lastIteratorToReturnElement = this.nextIterator; - this.nextIndex--; - this.nextReturned = false; - - return result; - } - - public int previousIndex() { - return this.nextIndex - 1; - } - - public void remove() { - if (this.lastIteratorToReturnElement == null) { - throw new IllegalStateException(); - } - this.lastIteratorToReturnElement.remove(); - if (this.nextReturned) { - // decrement the index because the "next" element has moved forward in the list - this.nextIndex--; - } - } - - public void set(E e) { - if (this.lastIteratorToReturnElement == null) { - throw new IllegalStateException(); - } - this.lastIteratorToReturnElement.set(e); - } - - /** - * Load 'nextIterator' with the first iterator that <code>hasNext()</code> - * or the final iterator if all the elements have already been retrieved. - */ - private void loadNextIterator() { - this.checkNextIterator(); - while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) { - this.nextIterator = this.iterators.next(); - } - } - - /** - * Load 'nextIterator' with the first iterator that <code>hasPrevious()</code> - * or the first iterator if all the elements have already been retrieved. - */ - private void loadPreviousIterator() { - this.checkNextIterator(); - while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) { - this.nextIterator = this.iterators.previous(); - } - } - - /** - * If 'nextIterator' is null, load it with the first iterator. - */ - private void checkNextIterator() { - if (this.nextIterator == null) { - this.nextIterator = this.iterators.next(); - } - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterators); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java deleted file mode 100644 index 1e7721a892..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Enumeration; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>NullEnumeration</code> is just that. - */ -public final class EmptyEnumeration<E> - implements Enumeration<E> -{ - - // singleton - @SuppressWarnings("unchecked") - private static final EmptyEnumeration INSTANCE = new EmptyEnumeration(); - - /** - * Return the singleton. - */ - @SuppressWarnings("unchecked") - public static <T> Enumeration<T> instance() { - return INSTANCE; - } - - /** - * Ensure single instance. - */ - private EmptyEnumeration() { - super(); - } - - public boolean hasMoreElements() { - return false; - } - - public E nextElement() { - throw new NoSuchElementException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java deleted file mode 100644 index aacac33339..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * An <code>EmptyIterator</code> is just that. - */ -public final class EmptyIterator<E> - implements Iterator<E> -{ - - // singleton - @SuppressWarnings("unchecked") - private static final EmptyIterator INSTANCE = new EmptyIterator(); - - /** - * Return the singleton. - */ - @SuppressWarnings("unchecked") - public static <T> Iterator<T> instance() { - return INSTANCE; - } - - /** - * Ensure single instance. - */ - private EmptyIterator() { - super(); - } - - public boolean hasNext() { - return false; - } - - public E next() { - throw new NoSuchElementException(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java deleted file mode 100644 index f3ab4a464f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.ListIterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * An <code>EmptyListIterator</code> is just that. - */ -public final class EmptyListIterator<E> - implements ListIterator<E> -{ - - // singleton - @SuppressWarnings("unchecked") - private static final EmptyListIterator INSTANCE = new EmptyListIterator(); - - /** - * Return the singleton. - */ - @SuppressWarnings("unchecked") - public static <T> ListIterator<T> instance() { - return INSTANCE; - } - - /** - * Ensure single instance. - */ - private EmptyListIterator() { - super(); - } - - public void add(E e) { - throw new UnsupportedOperationException(); - } - - public boolean hasNext() { - return false; - } - - public boolean hasPrevious() { - return false; - } - - public E next() { - throw new NoSuchElementException(); - } - - public int nextIndex() { - return 0; - } - - public E previous() { - throw new NoSuchElementException(); - } - - public int previousIndex() { - return -1; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void set(E e) { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EnumerationIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EnumerationIterator.java deleted file mode 100644 index a75710c4ef..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EnumerationIterator.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Enumeration; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * An <code>EnumerationIterator</code> wraps an - * <code>Enumeration</code> so that it can be treated like an - * <code>Iterator</code>. - */ -public class EnumerationIterator<E> - implements Iterator<E> -{ - private final Enumeration<? extends E> enumeration; - - /** - * Construct an iterator that wraps the specified enumeration. - */ - public EnumerationIterator(Enumeration<? extends E> enumeration) { - this.enumeration = enumeration; - } - - public boolean hasNext() { - return this.enumeration.hasMoreElements(); - } - - public E next() { - return this.enumeration.nextElement(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.enumeration); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java deleted file mode 100644 index fa22c65476..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>FilteringIterator</code> wraps another <code>Iterator</code> - * and uses a <code>Filter</code> to determine which elements in the - * nested iterator are to be returned by calls to <code>next()</code>. - * <p> - * As an alternative to building a <code>Filter</code>, a subclass - * of <code>FilteringIterator</code> can override the - * <code>accept(Object)</code> method. - * <p> - * One, possibly undesirable, side-effect of using this iterator is that - * the nested iterator's <code>next()</code> method will be invoked - * <em>before</em> the filtered iterator's <code>next()</code> - * method is invoked. This is because the "next" element must be - * checked for whether it is to be accepted before the filtered iterator - * can determine whether it has a "next" element (i.e. that the - * <code>hasNext()</code> method should return <code>true</code>). - * This also prevents a filtered iterator from supporting the optional - * <code>remove()</code> method. - */ -public class FilteringIterator<E1, E2> - implements Iterator<E2> -{ - private final Iterator<? extends E1> nestedIterator; - private final Filter<E1> filter; - private E2 next; - private boolean done; - - - /** - * Construct an iterator with the specified nested - * iterator and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> method instead of building - * a <code>Filter</code>. - */ - public FilteringIterator(Iterator<? extends E1> nestedIterator) { - this(nestedIterator, Filter.Disabled.<E1>instance()); - } - - /** - * Construct an iterator with the specified nested - * iterator and filter. - */ - public FilteringIterator(Iterator<? extends E1> nestedIterator, Filter<E1> filter) { - super(); - this.nestedIterator = nestedIterator; - this.filter = filter; - this.loadNext(); - } - - public boolean hasNext() { - return ! this.done; - } - - public E2 next() { - if (this.done) { - throw new NoSuchElementException(); - } - E2 result = this.next; - this.loadNext(); - return result; - } - - /** - * Because we need to pre-load the next element - * to be returned, we cannot support the <code>remove()</code> - * method. - */ - public void remove() { - throw new UnsupportedOperationException(); - } - - /** - * Load next with the next valid entry from the nested - * iterator. If there are none, next is set to <code>END</code>. - */ - private void loadNext() { - this.done = true; - while (this.nestedIterator.hasNext() && (this.done)) { - E1 temp = this.nestedIterator.next(); - if (this.accept(temp)) { - // assume that if the object was accepted it is of type E - this.next = this.cast(temp); - this.done = false; - } else { - this.next = null; - this.done = true; - } - } - } - - /** - * We have to assume the filter will only "accept" objects that can - * be cast to E2. - */ - @SuppressWarnings("unchecked") - private E2 cast(E1 o) { - return (E2) o; - } - - /** - * Return whether the <code>FilteringIterator</code> - * should return the specified next element from a call to the - * <code>next()</code> method. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Filter</code>. - */ - protected boolean accept(E1 o) { - return this.filter.accept(o); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GenericIteratorWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GenericIteratorWrapper.java deleted file mode 100644 index 01e5e0a93b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GenericIteratorWrapper.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * Wrap an iterator on elements of any sub-type of E, converting it into an - * iterator on elements of type E. This shouldn't be a problem since there - * is no way to add elements to the iterator. - */ -public class GenericIteratorWrapper<E> - implements Iterator<E> -{ - private final Iterator<? extends E> iterator; - - public GenericIteratorWrapper(Iterator<? extends E> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public E next() { - return this.iterator.next(); - } - - public void remove() { - this.iterator.remove(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java deleted file mode 100644 index c199e6ec4c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.NoSuchElementException; -import java.util.Set; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>GraphIterator</code> is similar to a <code>TreeIterator</code> - * except that it cannot be assumed that all nodes assume a strict tree - * structure. For instance, in a tree, a node cannot be a descendent of - * itself, but a graph may have a cyclical structure. - * - * A <code>GraphIterator</code> simplifies the traversal of a - * graph of objects, where the objects' protocol(s) provides - * a method for getting the next collection of nodes in the graph, - * (or *neighbors*), but does not provide a method for getting *all* - * of the nodes in the graph. - * (e.g. a neighbor can return his neighbors, and those neighbors - * can return their neighbors, which might also include the original - * neighbor, but you only want to visit the original neighbor once.) - * <p> - * If a neighbor has already been visited (determined by using - * <code>equals(Object)</code>), that neighbor is not visited again, - * nor are the neighbors of that object. - * <p> - * It is up to the user of this class to ensure a *complete* graph. - * <p> - * To use, supply:<ul> - * <li> either the initial node of the graph or an Iterator over an - * initial collection of graph nodes - * <li> a <code>MisterRogers</code> that tells who the neighbors are - * of each node - * (alternatively, subclass <code>GraphIterator</code> - * and override the <code>neighbors(Object)</code> method) - * </ul> - * <p> - * <code>remove()</code> is not supported. This method, if - * desired, must be implemented by the user of this class. - */ -public class GraphIterator<E> - implements Iterator<E> -{ - private final Collection<Iterator<? extends E>> iterators; - private final Set<E> visitedNeighbors; - private final MisterRogers<E> misterRogers; - - private Iterator<? extends E> currentIterator; - - private E nextNeighbor; - private boolean done; - - - /** - * Construct an iterator with the specified collection of roots - * and a disabled mister rogers. - * Use this constructor if you want to override the - * <code>children(Object)</code> method instead of building - * a <code>MisterRogers</code>. - */ - public GraphIterator(E... roots) { - this(new ArrayIterator<E>(roots)); - } - - /** - * Construct an iterator with the specified collection of roots - * and a disabled mister rogers. - * Use this constructor if you want to override the - * <code>children(Object)</code> method instead of building - * a <code>MisterRogers</code>. - */ - public GraphIterator(Iterator<? extends E> roots) { - this(roots, MisterRogers.Disabled.<E>instance()); - } - - /** - * Construct an iterator with the specified root - * and a disabled mister rogers. - * Use this constructor if you want to override the - * <code>children(Object)</code> method instead of building - * a <code>MisterRogers</code>. - */ - public GraphIterator(E root) { - this(root, MisterRogers.Disabled.<E>instance()); - } - - /** - * Construct an iterator with the specified root - * and mister rogers. - */ - public GraphIterator(E root, MisterRogers<E> misterRogers) { - this(new SingleElementIterator<E>(root), misterRogers); - } - - /** - * Construct an iterator with the specified roots - * and mister rogers. - */ - public GraphIterator(Iterator<? extends E> roots, MisterRogers<E> misterRogers) { - super(); - this.currentIterator = roots; - // use a LinkedList since we will be pulling off the front and adding to the end - this.iterators = new LinkedList<Iterator<? extends E>>(); - this.misterRogers = misterRogers; - this.visitedNeighbors = new HashSet<E>(); - this.loadNextNeighbor(); - } - - /** - * Load next neighbor with the next entry from the current iterator. - * If the current iterator has none, load the next iterator. - * If there are no more, the 'done' flag is set. - */ - private void loadNextNeighbor() { - if (this.currentIterator == EmptyIterator.instance()) { - this.done = true; - } - else if (this.currentIterator.hasNext()) { - E nextPossibleNeighbor = this.currentIterator.next(); - if (this.visitedNeighbors.contains(nextPossibleNeighbor)) { - this.loadNextNeighbor(); // recurse - } else { - this.nextNeighbor = nextPossibleNeighbor; - this.visitedNeighbors.add(nextPossibleNeighbor); - this.iterators.add(this.neighbors(nextPossibleNeighbor)); - } - } - else { - for (Iterator<? extends Iterator<? extends E>> stream = this.iterators.iterator(); ! this.currentIterator.hasNext() && stream.hasNext(); ) { - this.currentIterator = stream.next(); - stream.remove(); - } - if ( ! this.currentIterator.hasNext()) { - this.currentIterator = EmptyIterator.instance(); - } - this.loadNextNeighbor(); // recurse - } - } - - public boolean hasNext() { - return ! this.done; - } - - public E next() { - if (this.done) { - throw new NoSuchElementException(); - } - E next = this.nextNeighbor; - this.loadNextNeighbor(); - return next; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - /** - * Return the immediate neighbors of the specified object. - */ - protected Iterator<? extends E> neighbors(E next) { - return this.misterRogers.neighbors(next); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.currentIterator); - } - - - //********** inner classes ********** - - /** - * Used by <code>GraphIterator</code> to retrieve - * the immediate neighbors of a node in the graph. - * "These are the people in your neighborhood..." - */ - public interface MisterRogers<T> { - - /** - * Return the immediate neighbors of the specified object. - */ - Iterator<? extends T> neighbors(T next); - - - final class Null<S> implements MisterRogers<S> { - @SuppressWarnings("unchecked") - public static final MisterRogers INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R> MisterRogers<R> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // return no neighbors - public Iterator<S> neighbors(S next) { - return EmptyIterator.instance(); - } - @Override - public String toString() { - return "GraphIterator.MisterRogers.Null"; - } - } - - /** The mister rogers used when the #neighbors(Object) method is overridden. */ - final class Disabled<S> implements MisterRogers<S> { - @SuppressWarnings("unchecked") - public static final MisterRogers INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> MisterRogers<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public Iterator<S> neighbors(S next) { - throw new UnsupportedOperationException(); // GraphIterator.neighbors(Object) was not implemented - } - @Override - public String toString() { - return "GraphIterator.MisterRogers.Disabled"; - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/IteratorEnumeration.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/IteratorEnumeration.java deleted file mode 100644 index 55a4f08b70..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/IteratorEnumeration.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Enumeration; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * An <code>IteratorEnumeration</code> wraps an - * <code>Iterator</code> so that it can be treated like an - * <code>Enumeration</code>. - */ -public class IteratorEnumeration<E> - implements Enumeration<E> -{ - private final Iterator<? extends E> iterator; - - /** - * Construct an enumeration that wraps the specified iterator. - */ - public IteratorEnumeration(Iterator<? extends E> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasMoreElements() { - return this.iterator.hasNext(); - } - - public E nextElement() { - return this.iterator.next(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/PeekableIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/PeekableIterator.java deleted file mode 100644 index 316aedcf63..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/PeekableIterator.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>PeekableIterator</code> wraps another <code>Iterator</code> - * and allows a <code>peek()</code> at the next element to be - * returned by <code>next()</code>. - * <p> - * One, possibly undesirable, side-effect of using this iterator is that - * the nested iterator's <code>next()</code> method will be invoked - * <em>before</em> the peekable iterator's <code>next()</code> - * method is invoked. This is because the "next" element must be - * pre-loaded for the <code>peek()</code> method. - * This also prevents a peekable iterator from supporting the optional - * <code>remove()</code> method. - */ - -public class PeekableIterator<E> - implements Iterator<E> -{ - private final Iterator<? extends E> nestedIterator; - private E next; - private boolean done; - - - /** - * Construct a peekable iterator that wraps the specified nested - * iterator. - */ - public PeekableIterator(Iterator<? extends E> nestedIterator) { - super(); - this.nestedIterator = nestedIterator; - this.done = false; - this.loadNext(); - } - - public boolean hasNext() { - return ! this.done; - } - - public E next() { - if (this.done) { - throw new NoSuchElementException(); - } - E result = this.next; - this.loadNext(); - return result; - } - - /** - * Return the element that will be returned by the next call to the - * <code>next()</code> method, without advancing past it. - */ - public E peek() { - if (this.done) { - throw new NoSuchElementException(); - } - return this.next; - } - - /** - * Because we need to pre-load the next element - * to be returned, we cannot support the <code>remove()</code> - * method. - */ - public void remove() { - throw new UnsupportedOperationException(); - } - - /** - * Load next with the next entry from the nested - * iterator. If there are none, next is set to <code>END</code>. - */ - private void loadNext() { - if (this.nestedIterator.hasNext()) { - this.next = this.nestedIterator.next(); - } else { - this.next = null; - this.done = true; - } - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyCompositeListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyCompositeListIterator.java deleted file mode 100644 index 92d896c65c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyCompositeListIterator.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>ReadOnlyCompositeListIterator</code> wraps a list - * of <code>ListIterator</code>s and makes them appear to be a single - * read-only <code>ListIterator</code>. A read-only composite list - * iterator is more flexible than a normal composite when it comes to the element types of - * the nested iterators. - */ -public class ReadOnlyCompositeListIterator<E> - implements ListIterator<E> -{ - private final ListIterator<? extends ListIterator<? extends E>> iterators; - private ListIterator<? extends E> nextIterator; - private int nextIndex; - - - /** - * Construct a read-only list iterator with the specified list of - * list iterators. - */ - public ReadOnlyCompositeListIterator(List<? extends ListIterator<? extends E>> iterators) { - this(iterators.listIterator()); - } - - /** - * Construct a read-only list iterator with the specified list of - * list iterators. - */ - public ReadOnlyCompositeListIterator(ListIterator<? extends ListIterator<? extends E>> iterators) { - super(); - this.iterators = iterators; - this.nextIndex = 0; - } - - /** - * Construct a read-only list iterator with the specified object prepended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public ReadOnlyCompositeListIterator(E object, ListIterator<? extends E> iterator) { - this(new SingleElementListIterator<E>(object), iterator); - } - - /** - * Construct a read-only list iterator with the specified object appended - * to the specified iterator. - */ - @SuppressWarnings("unchecked") - public ReadOnlyCompositeListIterator(ListIterator<? extends E> iterator, E object) { - this(iterator, new SingleElementListIterator<E>(object)); - } - - /** - * Construct a read-only list iterator with the specified list iterators. - */ - public ReadOnlyCompositeListIterator(ListIterator<? extends E>... iterators) { - this(new ArrayListIterator<ListIterator<? extends E>>(iterators)); - } - - public boolean hasNext() { - try { - this.loadNextIterator(); - } catch (NoSuchElementException ex) { - // this occurs if there are no iterators at all - return false; - } - return this.nextIterator.hasNext(); - } - - public boolean hasPrevious() { - try { - this.loadPreviousIterator(); - } catch (NoSuchElementException ex) { - // this occurs if there are no iterators at all - return false; - } - return this.nextIterator.hasPrevious(); - } - - public E next() { - this.loadNextIterator(); - E result = this.nextIterator.next(); - - // the statement above will throw a NoSuchElementException - // if the current iterator is at the end of the line; - // so if we get here, we can increment 'nextIndex' - this.nextIndex++; - - return result; - } - - public int nextIndex() { - return this.nextIndex; - } - - public E previous() { - this.loadPreviousIterator(); - E result = this.nextIterator.previous(); - - // the statement above will throw a NoSuchElementException - // if the current iterator is at the end of the line; - // so if we get here, we can decrement 'nextIndex' - this.nextIndex--; - - return result; - } - - public int previousIndex() { - return this.nextIndex - 1; - } - - public void add(E o) { - // the list iterator is read-only - throw new UnsupportedOperationException(); - } - - public void remove() { - // the list iterator is read-only - throw new UnsupportedOperationException(); - } - - public void set(E e) { - // the list iterator is read-only - throw new UnsupportedOperationException(); - } - - /** - * Load nextIterator with the first iterator that <code>hasNext()</code> - * or the final iterator if all the elements have already been retrieved. - */ - private void loadNextIterator() { - this.checkNextIterator(); - while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) { - this.nextIterator = this.iterators.next(); - } - } - - /** - * Load nextIterator with the first iterator that <code>hasPrevious()</code> - * or the first iterator if all the elements have already been retrieved. - */ - private void loadPreviousIterator() { - this.checkNextIterator(); - while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) { - this.nextIterator = this.iterators.previous(); - } - } - - /** - * If 'nextIterator' is null, load it with the first iterator. - */ - private void checkNextIterator() { - if (this.nextIterator == null) { - this.nextIterator = this.iterators.next(); - } - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.iterators); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyIterator.java deleted file mode 100644 index df0a51333d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyIterator.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>ReadOnlyIterator</code> wraps another <code>Iterator</code> - * and removes support for #remove(). - */ -public class ReadOnlyIterator<E> - implements Iterator<E> -{ - private final Iterator<? extends E> nestedIterator; - - /** - * Construct an iterator on the specified collection that - * disallows removes. - */ - public ReadOnlyIterator(Collection<? extends E> c) { - this(c.iterator()); - } - - /** - * Construct an iterator with the specified nested iterator - * and disallow removes. - */ - public ReadOnlyIterator(Iterator<? extends E> nestedIterator) { - super(); - this.nestedIterator = nestedIterator; - } - - public boolean hasNext() { - // delegate to the nested iterator - return this.nestedIterator.hasNext(); - } - - public E next() { - // delegate to the nested iterator - return this.nestedIterator.next(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyListIterator.java deleted file mode 100644 index c3b2591f44..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ReadOnlyListIterator.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>ReadOnlyListIterator</code> wraps another - * <code>ListIterator</code> and removes support for: - * #remove() - * #set(Object) - * #add(Object) - */ -public class ReadOnlyListIterator<E> - implements ListIterator<E> -{ - private final ListIterator<? extends E> nestedListIterator; - - - /** - * Construct an iterator on the specified list that - * disallows removes, sets, and adds. - */ - public ReadOnlyListIterator(List<? extends E> list) { - this(list.listIterator()); - } - - /** - * Construct an iterator on the specified list iterator that - * disallows removes, sets, and adds. - */ - public ReadOnlyListIterator(ListIterator<? extends E> nestedListIterator) { - super(); - this.nestedListIterator = nestedListIterator; - } - - public boolean hasNext() { - // delegate to the nested iterator - return this.nestedListIterator.hasNext(); - } - - public E next() { - // delegate to the nested iterator - return this.nestedListIterator.next(); - } - - public boolean hasPrevious() { - // delegate to the nested iterator - return this.nestedListIterator.hasPrevious(); - } - - public E previous() { - // delegate to the nested iterator - return this.nestedListIterator.previous(); - } - - public int nextIndex() { - // delegate to the nested iterator - return this.nestedListIterator.nextIndex(); - } - - public int previousIndex() { - // delegate to the nested iterator - return this.nestedListIterator.previousIndex(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void set(E o) { - throw new UnsupportedOperationException(); - } - - public void add(E o) { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedListIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ResultSetIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ResultSetIterator.java deleted file mode 100644 index b5891c7dac..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ResultSetIterator.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>ResultSetIterator</code> wraps a <code>ResultSet</code> - * and transforms its rows for client consumption. Subclasses can override - * <code>#buildNext(ResultSet)</code> to build the expected object from - * the current row of the result set. - * <p> - * To use, supply:<ul> - * <li> a <code>ResultSet</code> - * <li> an <code>Adapter</code> that converts a row in the <code>ResultSet</code> - * into the desired object - * (alternatively, subclass <code>ResultSetIterator</code> - * and override the <code>buildNext(ResultSet)</code> method) - * </ul> - * <p> - */ -public class ResultSetIterator<E> - implements Iterator<E> -{ - private final ResultSet resultSet; - private final Adapter<E> adapter; - private E next; - private boolean done; - - - /** - * Construct an iterator on the specified result set that returns - * the objects produced by the specified adapter. - */ - public ResultSetIterator(ResultSet resultSet, Adapter<E> adapter) { - super(); - this.resultSet = resultSet; - this.adapter = adapter; - this.done = false; - this.next = this.buildNext(); - } - - /** - * Construct an iterator on the specified result set that returns - * the first object in each row of the result set. - */ - public ResultSetIterator(ResultSet resultSet) { - this(resultSet, Adapter.Default.<E>instance()); - } - - /** - * Build the next object for the iterator to return. - * Close the result set when we reach the end. - */ - private E buildNext() { - try { - if (this.resultSet.next()) { - return this.buildNext(this.resultSet); - } - this.resultSet.close(); - this.done = true; - return null; - } catch (SQLException ex) { - throw new RuntimeException(ex); - } - } - - /** - * By default, return the first object in the current row - * of the result set. Any <code>SQLException</code>s will - * be caught and wrapped in a <code>RuntimeException</code>. - */ - protected E buildNext(ResultSet rs) throws SQLException { - return this.adapter.buildNext(rs); - } - - public boolean hasNext() { - return ! this.done; - } - - public E next() { - if (this.done) { - throw new NoSuchElementException(); - } - E temp = this.next; - this.next = this.buildNext(); - return temp; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.resultSet); - } - - - // ********** interface ********** - - /** - * Used by <code>ResultSetIterator</code> to convert a - * <code>ResultSet</code>'s current row into the next object - * to be returned by the <code>Iterator</code>. - */ - public interface Adapter<T> { - - /** - * Return an object corresponding to the result set's - * "current" row. Any <code>SQLException</code>s will - * be caught and wrapped in a <code>RuntimeException</code>. - * @see java.sql.ResultSet - */ - T buildNext(ResultSet rs) throws SQLException; - - - final class Default<S> implements Adapter<S> { - @SuppressWarnings("unchecked") - public static final Adapter INSTANCE = new Default(); - @SuppressWarnings("unchecked") - public static <R> Adapter<R> instance() { - return INSTANCE; - } - // ensure single instance - private Default() { - super(); - } - // return the first object in the current row of the result set - @SuppressWarnings("unchecked") - public S buildNext(ResultSet rs) throws SQLException { - // result set columns are indexed starting with 1 - return (S) rs.getObject(1); - } - @Override - public String toString() { - return "ResultSetIterator.Adapter.Default"; //$NON-NLS-1$ - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementIterator.java deleted file mode 100644 index 75fd9d80fd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementIterator.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>SingleElementIterator</code> holds a single element - * and returns it with the first call to <code>next()</code>, at - * which point it will return <code>false</code> to any subsequent - * call to <code>hasNext()</code>. - * <p> - * A <code>SingleElementIterator</code> is equivalent to the - * <code>Iterator</code> returned by: - * <code>java.util.Collections.singleton(element).iterator()</code> - */ -public class SingleElementIterator<E> - implements Iterator<E> -{ - private final E element; - private boolean done; - - - /** - * Construct an iterator that returns only the specified element. - */ - public SingleElementIterator(E element) { - super(); - this.element = element; - this.done = false; - } - - public boolean hasNext() { - return ! this.done; - } - - public E next() { - if (this.done) { - throw new NoSuchElementException(); - } - this.done = true; - return this.element; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.element); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementListIterator.java deleted file mode 100644 index 799cb72aef..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SingleElementListIterator.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.ListIterator; -import java.util.NoSuchElementException; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>SingleElementListIterator</code> holds a single element - * and returns it with the first call to <code>next()</code>, at - * which point it will return <code>false</code> to any subsequent - * call to <code>hasNext()</code>. Likewise, it will return <code>false</code> - * to a call to <code>hasPrevious()</code> until a call to <code>next()</code>, - * at which point a call to <code>previous()</code> will return the - * single element. - * <p> - * A <code>SingleElementListIterator</code> is equivalent to the - * <code>Iterator</code> returned by: - * <code>java.util.Collections.singletonList(element).listIterator()</code> - */ -public class SingleElementListIterator<E> - implements ListIterator<E> -{ - private final E element; - private boolean hasNext; - - - /** - * Construct a list iterator that returns only the specified element. - */ - public SingleElementListIterator(E element) { - super(); - this.element = element; - this.hasNext = true; - } - - public boolean hasNext() { - return this.hasNext; - } - - public E next() { - if (this.hasNext) { - this.hasNext = false; - return this.element; - } - throw new NoSuchElementException(); - } - - public int nextIndex() { - return this.hasNext ? 0 : 1; - } - - public boolean hasPrevious() { - return ! this.hasNext; - } - - public E previous() { - if (this.hasNext) { - throw new NoSuchElementException(); - } - this.hasNext = true; - return this.element; - } - - public int previousIndex() { - return this.hasNext ? -1 : 0; - } - - public void add(E e) { - throw new UnsupportedOperationException(); - } - - public void set(E e) { - throw new UnsupportedOperationException(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.element); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationIterator.java deleted file mode 100644 index b970d28841..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationIterator.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.Transformer; - - -/** - * A <code>TransformationIterator</code> wraps another <code>Iterator</code> - * and transforms its results for client consumption. To use, supply a - * <code>Transformer</code> or subclass <code>TransformationIterator</code> - * and override the <code>transform(Object)</code> method. - * Objects of type E1 are transformed into objects of type E2; - * i.e. the iterator returns objects of type E2. - */ -public class TransformationIterator<E1, E2> - implements Iterator<E2> -{ - private final Iterator<? extends E1> nestedIterator; - private final Transformer<E1, ? extends E2> transformer; - - - /** - * Construct an iterator with the specified nested iterator - * and a disabled transformer. - * Use this constructor if you want to override the - * <code>transform(Object)</code> method instead of building - * a <code>Transformer</code>. - */ - public TransformationIterator(Iterator<? extends E1> nestedIterator) { - this(nestedIterator, Transformer.Disabled.<E1, E2>instance()); - } - - /** - * Construct an iterator with the specified nested iterator - * and transformer. - */ - public TransformationIterator(Iterator<? extends E1> nestedIterator, Transformer<E1, ? extends E2> transformer) { - super(); - this.nestedIterator = nestedIterator; - this.transformer = transformer; - } - - public boolean hasNext() { - // delegate to the nested iterator - return this.nestedIterator.hasNext(); - } - - public E2 next() { - // transform the object returned by the nested iterator before returning it - return this.transform(this.nestedIterator.next()); - } - - public void remove() { - // delegate to the nested iterator - this.nestedIterator.remove(); - } - - /** - * Transform the specified object and return the result. - */ - protected E2 transform(E1 next) { - return this.transformer.transform(next); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationListIterator.java deleted file mode 100644 index 087fc11046..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TransformationListIterator.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.Transformer; - -/** - * A <code>TransformationListIterator</code> wraps another <code>ListIterator</code> - * and transforms its results for client consumption. To use, supply a - * <code>Transformer</code> or subclass <code>TransformationIterator</code> - * and override the <code>transform(Object)</code> method. - * - * The methods <code>set(Object)</code> and <code>add(Object)</code> - * are left unsupported in this class. - */ -public class TransformationListIterator<E1, E2> - implements ListIterator<E2> -{ - private final ListIterator<? extends E1> nestedIterator; - private final Transformer<E1, ? extends E2> transformer; - - - /** - * Construct an iterator with the specified nested iterator - * and a disabled transformer. - * Use this constructor if you want to override the - * <code>transform(Object)</code> method instead of building - * a <code>Transformer</code>. - */ - public TransformationListIterator(ListIterator<? extends E1> nestedIterator) { - this(nestedIterator, Transformer.Disabled.<E1, E2>instance()); - } - - /** - * Construct an iterator with the specified nested iterator - * and transformer. - */ - public TransformationListIterator(ListIterator<? extends E1> nestedIterator, Transformer<E1, ? extends E2> transformer) { - super(); - this.nestedIterator = nestedIterator; - this.transformer = transformer; - } - - public boolean hasNext() { - // delegate to the nested iterator - return this.nestedIterator.hasNext(); - } - - public E2 next() { - // transform the object returned by the nested iterator before returning it - return this.transform(this.nestedIterator.next()); - } - - public int nextIndex() { - // delegate to the nested iterator - return this.nestedIterator.nextIndex(); - } - - public boolean hasPrevious() { - // delegate to the nested iterator - return this.nestedIterator.hasPrevious(); - } - - public E2 previous() { - // transform the object returned by the nested iterator before returning it - return this.transform(this.nestedIterator.previous()); - } - - public int previousIndex() { - // delegate to the nested iterator - return this.nestedIterator.previousIndex(); - } - - public void add(E2 o) { - throw new UnsupportedOperationException(); - } - - public void set(E2 o) { - throw new UnsupportedOperationException(); - } - - public void remove() { - // delegate to the nested iterator - this.nestedIterator.remove(); - } - - /** - * Transform the specified object and return the result. - */ - protected E2 transform(E1 next) { - return this.transformer.transform(next); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.nestedIterator); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TreeIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TreeIterator.java deleted file mode 100644 index 47074d7c7d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/TreeIterator.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.iterators; - -import java.util.Iterator; -import java.util.LinkedList; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * A <code>TreeIterator</code> simplifies the traversal of a - * tree of objects, where the objects' protocol(s) provides - * a method for getting the immediate children of the given - * node but does not provide a method for getting all the - * descendants (children, grandchildren, etc.) of the given node. - * <p> - * To use, supply:<ul> - * <li> either the root element of the tree or, if the tree has - * multiple roots, an <code>Iterator</code> over the set of roots - * <li> a <code>Midwife</code> that delivers the children - * of each child - * (alternatively, subclass <code>TreeIterator</code> - * and override the <code>children(Object)</code> method) - * </ul> - * <p> - */ -public class TreeIterator<E> - implements Iterator<E> -{ - private final LinkedList<Iterator<? extends E>> iterators; - private final Midwife<E> midwife; - private Iterator<? extends E> currentIterator; - - - /** - * Construct an iterator with the specified collection of roots - * and a disabled midwife. - * Use this constructor if you want to override the - * <code>children(Object)</code> method instead of building - * a <code>Midwife</code>. - */ - public TreeIterator(Iterator<? extends E> roots) { - this(roots, Midwife.Disabled.<E>instance()); - } - - /** - * Construct an iterator with the specified root - * and a disabled midwife. - * Use this constructor if you want to override the - * <code>children(Object)</code> method instead of building - * a <code>Midwife</code>. - */ - public TreeIterator(E root) { - this(root, Midwife.Disabled.<E>instance()); - } - - /** - * Construct an iterator with the specified root - * and midwife. - */ - public TreeIterator(E root, Midwife<E> midwife) { - this(new SingleElementIterator<E>(root), midwife); - } - - /** - * Construct an iterator with the specified roots - * and midwife. - */ - public TreeIterator(Iterator<? extends E> roots, Midwife<E> midwife) { - super(); - this.currentIterator = roots; - // use a LinkedList since we will be pulling off the front and adding to the end - this.iterators = new LinkedList<Iterator<? extends E>>(); - this.midwife = midwife; - } - - public boolean hasNext() { - if (this.currentIterator.hasNext()) { - return true; - } - for (Iterator<? extends E> iterator : this.iterators) { - if (iterator.hasNext()) { - return true; - } - } - return false; - } - - public E next() { - if (this.currentIterator.hasNext()) { - return this.nextInternal(); - } - for (Iterator<Iterator<? extends E>> stream = this.iterators.iterator(); stream.hasNext(); ) { - this.currentIterator = stream.next(); - if (this.currentIterator.hasNext()) { - break; - } - stream.remove(); - } - return this.nextInternal(); - } - - /** - * Fetch the children of the next node before returning it. - */ - private E nextInternal() { - E next = this.currentIterator.next(); - this.iterators.add(this.children(next)); - return next; - } - - public void remove() { - this.currentIterator.remove(); - } - - /** - * Return the immediate children of the specified object. - */ - protected Iterator<? extends E> children(E next) { - return this.midwife.children(next); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.currentIterator); - } - - - //********** inner classes ********** - - /** - * Used by <code>TreeIterator</code> to retrieve - * the immediate children of a node in the tree. - */ - public interface Midwife<T> { - - /** - * Return the immediate children of the specified object. - */ - Iterator<? extends T> children(T o); - - - final class Null<S> implements Midwife<S> { - @SuppressWarnings("unchecked") - public static final Midwife INSTANCE = new Null(); - @SuppressWarnings("unchecked") - public static <R> Midwife<R> instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - // return no neighbors - public Iterator<S> children(S next) { - return EmptyIterator.instance(); - } - @Override - public String toString() { - return "TreeIterator.Midwife.Null"; //$NON-NLS-1$ - } - } - - /** The midwife used when the #children(Object) method is overridden. */ - final class Disabled<S> implements Midwife<S> { - @SuppressWarnings("unchecked") - public static final Midwife INSTANCE = new Disabled(); - @SuppressWarnings("unchecked") - public static <R> Midwife<R> instance() { - return INSTANCE; - } - // ensure single instance - private Disabled() { - super(); - } - // throw an exception - public Iterator<S> children(S next) { - throw new UnsupportedOperationException(); // TreeIterator.children(Object) was not implemented - } - @Override - public String toString() { - return "TreeIterator.Midwife.Disabled"; //$NON-NLS-1$ - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java deleted file mode 100644 index e81db41721..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java +++ /dev/null @@ -1,996 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.HashBag; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Convenience implementation of Model protocol. - */ -public abstract class AbstractModel implements Model, Serializable { - /** - * Delegate state/property/collection/list/tree change support to this - * helper object. The change support object is "lazy-initialized". - */ - private ChangeSupport changeSupport; - - - // ********** constructors/initialization ********** - - /** - * Default constructor. - * This will call #initialize() on the newly-created instance. - */ - protected AbstractModel() { - super(); - } - - /** - * This accessor will build the change support when required. - */ - protected synchronized ChangeSupport getChangeSupport() { - if (this.changeSupport == null) { - this.changeSupport = this.buildChangeSupport(); - } - return this.changeSupport; - } - - /** - * Allow subclasses to tweak the change support used. - */ - protected ChangeSupport buildChangeSupport() { - return new ChangeSupport(this); - } - - - // ********** state change support ********** - - public synchronized void addStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().addStateChangeListener(listener); - } - - public synchronized void removeStateChangeListener(StateChangeListener listener) { - this.getChangeSupport().removeStateChangeListener(listener); - } - - protected final void fireStateChanged() { - this.getChangeSupport().fireStateChanged(); - } - - protected final void fireStateChanged(StateChangeEvent event) { - this.getChangeSupport().fireStateChanged(event); - } - - - // ********** property change support ********** - - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - this.getChangeSupport().addPropertyChangeListener(listener); - } - - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().addPropertyChangeListener(propertyName, listener); - } - - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - this.getChangeSupport().removePropertyChangeListener(listener); - } - - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.getChangeSupport().removePropertyChangeListener(propertyName, listener); - } - - protected final void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, int oldValue, int newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, oldValue, newValue); - } - - protected final void firePropertyChanged(String propertyName, Object newValue) { - this.getChangeSupport().firePropertyChanged(propertyName, null, newValue); - } - - protected final void firePropertyChanged(PropertyChangeEvent event) { - this.getChangeSupport().firePropertyChanged(event); - } - - - // ********** collection change support ********** - - public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - this.getChangeSupport().addCollectionChangeListener(listener); - } - - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().addCollectionChangeListener(collectionName, listener); - } - - public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { - this.getChangeSupport().removeCollectionChangeListener(listener); - } - - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.getChangeSupport().removeCollectionChangeListener(collectionName, listener); - } - - protected final void fireItemAdded(String collectionName, Object addedItem) { - this.getChangeSupport().fireItemAdded(collectionName, addedItem); - } - - protected final void fireItemsAdded(String collectionName, Collection<?> addedItems) { - this.getChangeSupport().fireItemsAdded(collectionName, addedItems); - } - - protected final void fireItemsAdded(CollectionChangeEvent event) { - this.getChangeSupport().fireItemsAdded(event); - } - - protected final void fireItemRemoved(String collectionName, Object removedItem) { - this.getChangeSupport().fireItemRemoved(collectionName, removedItem); - } - - protected final void fireItemsRemoved(String collectionName, Collection<?> removedItems) { - this.getChangeSupport().fireItemsRemoved(collectionName, removedItems); - } - - protected final void fireItemsRemoved(CollectionChangeEvent event) { - this.getChangeSupport().fireItemsRemoved(event); - } - - protected final void fireCollectionCleared(String collectionName) { - this.getChangeSupport().fireCollectionCleared(collectionName); - } - - protected final void fireCollectionCleared(CollectionChangeEvent event) { - this.getChangeSupport().fireCollectionCleared(event); - } - - protected final void fireCollectionChanged(String collectionName) { - this.getChangeSupport().fireCollectionChanged(collectionName); - } - - protected final void fireCollectionChanged(CollectionChangeEvent event) { - this.getChangeSupport().fireCollectionChanged(event); - } - - /** - * Convenience method. - * Add the specified item to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#add(Object) - */ - protected <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) { - if (collection.add(item)) { - this.fireItemAdded(collectionName, item); - return true; - } - return false; - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) { - return this.addItemsToCollection(new ArrayIterator<E>(items), collection, collectionName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) { - return this.addItemsToCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound collection - * and fire the appropriate event if necessary. - * Return whether collection changed. - * @see java.util.Collection#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) { - Collection<E> addedItems = null; - while (items.hasNext()) { - E item = items.next(); - if (collection.add(item)) { - if (addedItems == null) { - addedItems = new ArrayList<E>(); - } - addedItems.add(item); - } - } - if (addedItems != null) { - this.fireItemsAdded(collectionName, addedItems); - return true; - } - return false; - } - - /** - * Convenience method. - * Remove the specified item from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#remove(Object) - */ - protected boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) { - if (collection.remove(item)) { - this.fireItemRemoved(collectionName, item); - return true; - } - return false; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.removeItemsFromCollection(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.removeItemsFromCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - Collection<?> items2 = CollectionTools.collection(items); - items2.retainAll(collection); - boolean changed = collection.removeAll(items2); - - if ( ! items2.isEmpty()) { - this.fireItemsRemoved(collectionName, items2); - } - return changed; - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) { - return this.retainItemsInCollection(new ArrayIterator<Object>(items), collection, collectionName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) { - return this.retainItemsInCollection(items.iterator(), collection, collectionName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound collection - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.Collection#retainAll(java.util.Collection) - */ - protected boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) { - Collection<?> items2 = CollectionTools.collection(items); - Collection<?> removedItems = CollectionTools.collection(collection); - removedItems.removeAll(items2); - boolean changed = collection.retainAll(items2); - - if ( ! removedItems.isEmpty()) { - this.fireItemsRemoved(collectionName, removedItems); - } - return changed; - } - - /** - * Convenience method. - * Clear the entire collection - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see java.util.Collection#clear() - */ - protected boolean clearCollection(Collection<?> collection, String collectionName) { - if (collection.isEmpty()) { - return false; - } - collection.clear(); - this.fireCollectionCleared(collectionName); - return true; - } - - /** - * Convenience method. - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - protected <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) { - if (newCollection.isEmpty()) { - return this.clearCollection(collection, collectionName); - } - - if (collection.isEmpty()) { - return this.addItemsToCollection(newCollection, collection, collectionName); - } - - boolean changed = false; - Collection<E> removeItems = new HashBag<E>(collection); - removeItems.removeAll(newCollection); - changed |= this.removeItemsFromCollection(removeItems, collection, collectionName); - - Collection<E> addItems = new HashBag<E>(newCollection); - addItems.removeAll(collection); - changed |= this.addItemsToCollection(addItems, collection, collectionName); - - return changed; - } - - /** - * Convenience method. - * Synchronize the collection with the specified new collection, - * making a minimum number of removes and adds. - * Return whether the collection changed. - */ - protected <E> boolean synchronizeCollection(Iterator<E> newItems, Collection<E> collection, String collectionName) { - return this.synchronizeCollection(CollectionTools.collection(newItems), collection, collectionName); - } - - - // ********** list change support ********** - - public synchronized void addListChangeListener(ListChangeListener listener) { - this.getChangeSupport().addListChangeListener(listener); - } - - public synchronized void addListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().addListChangeListener(listName, listener); - } - - public synchronized void removeListChangeListener(ListChangeListener listener) { - this.getChangeSupport().removeListChangeListener(listener); - } - - public synchronized void removeListChangeListener(String listName, ListChangeListener listener) { - this.getChangeSupport().removeListChangeListener(listName, listener); - } - - protected final void fireItemAdded(String listName, int index, Object addedItem) { - this.getChangeSupport().fireItemAdded(listName, index, addedItem); - } - - protected final void fireItemsAdded(String listName, int index, List<?> addedItems) { - this.getChangeSupport().fireItemsAdded(listName, index, addedItems); - } - - protected final void fireItemsAdded(ListChangeEvent event) { - this.getChangeSupport().fireItemsAdded(event); - } - - protected final void fireItemRemoved(String listName, int index, Object removedItem) { - this.getChangeSupport().fireItemRemoved(listName, index, removedItem); - } - - protected final void fireItemsRemoved(String listName, int index, List<?> removedItems) { - this.getChangeSupport().fireItemsRemoved(listName, index, removedItems); - } - - protected final void fireItemsRemoved(ListChangeEvent event) { - this.getChangeSupport().fireItemsRemoved(event); - } - - protected final void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - this.getChangeSupport().fireItemReplaced(listName, index, newItem, replacedItem); - } - - protected final <E> void fireItemsReplaced(String listName, int index, List<? extends E> newItems, List<E> replacedItems) { - this.getChangeSupport().fireItemsReplaced(listName, index, newItems, replacedItems); - } - - protected final void fireItemsReplaced(ListChangeEvent event) { - this.getChangeSupport().fireItemsReplaced(event); - } - - protected final void fireItemMoved(String listName, int targetIndex, int sourceIndex) { - this.getChangeSupport().fireItemMoved(listName, targetIndex, sourceIndex); - } - - protected final <E> void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - this.getChangeSupport().fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - protected final void fireItemsMoved(ListChangeEvent event) { - this.getChangeSupport().fireItemsMoved(event); - } - - protected final void fireListCleared(String listName) { - this.getChangeSupport().fireListCleared(listName); - } - - protected final void fireListCleared(ListChangeEvent event) { - this.getChangeSupport().fireListCleared(event); - } - - protected final void fireListChanged(String listName) { - this.getChangeSupport().fireListChanged(listName); - } - - protected final void fireListChanged(ListChangeEvent event) { - this.getChangeSupport().fireListChanged(event); - } - - /** - * Convenience method. - * Add the specified item to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#add(int, Object) - */ - protected <E> void addItemToList(int index, E item, List<E> list, String listName) { - list.add(index, item); - this.fireItemAdded(listName, index, item); - } - - /** - * Convenience method. - * Add the specified item to the end of the specified bound list - * and fire the appropriate event if necessary. - * Return whether list changed. - * @see java.util.List#add(Object) - */ - protected <E> boolean addItemToList(E item, List<E> list, String listName) { - if (list.add(item)) { - this.fireItemAdded(listName, list.size() - 1, item); - return true; - } - return false; - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) { - return this.addItemsToList(index, new ArrayIterator<E>(items), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(index, items.iterator(), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(int, java.util.Collection) - */ - protected <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) { - List<E> items2 = CollectionTools.list(items); - if (list.addAll(index, items2)) { - this.fireItemsAdded(listName, index, items2); - return true; - } - return false; - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(E[] items, List<E> list, String listName) { - return this.addItemsToList(new ArrayIterator<E>(items), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) { - return this.addItemsToList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Add the specified items to the end of to the specified bound list - * and fire the appropriate event if necessary. - * @see java.util.List#addAll(java.util.Collection) - */ - protected <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) { - List<E> items2 = CollectionTools.list(items); - int index = list.size(); - if (list.addAll(items2)) { - this.fireItemsAdded(listName, index, items2); - return true; - } - return false; // empty list of items added - } - - /** - * Convenience method. - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed item. - * @see java.util.List#remove(int) - */ - protected <E> E removeItemFromList(int index, List<E> list, String listName) { - E item = list.remove(index); - this.fireItemRemoved(listName, index, item); - return item; - } - - /** - * Convenience method. - * Remove the specified item from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed item. - * @see java.util.List#remove(Object) - */ - protected boolean removeItemFromList(Object item, List<?> list, String listName) { - int index = list.indexOf(item); - if (index == -1) { - return false; - } - list.remove(index); - this.fireItemRemoved(listName, index, item); - return true; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#remove(int) - */ - protected <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) { - List<E> subList = list.subList(index, index + length); - List<E> removedItems = new ArrayList<E>(subList); - subList.clear(); - this.fireItemsRemoved(listName, index, removedItems); - return removedItems; - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Object[] items, List<?> list, String listName) { - return this.removeItemsFromList(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) { - return this.removeItemsFromList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Remove the specified items from the specified bound list - * and fire the appropriate event if necessary. - * Return the removed items. - * @see java.util.List#removeAll(java.util.Collection) - */ - protected boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) { - boolean changed = false; - while (items.hasNext()) { - changed |= this.removeItemFromList(items.next(), list, listName); - } - return changed; - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Object[] items, List<?> list, String listName) { - return this.retainItemsInList(new ArrayIterator<Object>(items), list, listName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) { - return this.retainItemsInList(items.iterator(), list, listName); - } - - /** - * Convenience method. - * Retain the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return whether the collection changed. - * @see java.util.List#retainAll(java.util.Collection) - */ - protected boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) { - Collection<?> items2 = CollectionTools.collection(items); - Collection<?> removedItems = CollectionTools.collection(list); - removedItems.removeAll(items2); - return this.removeItemsFromList(removedItems, list, listName); - } - - /** - * Convenience method. - * Set the specified item in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced item. - * @see java.util.List#set(int, Object) - */ - protected <E> E setItemInList(int index, E item, List<E> list, String listName) { - E replacedItem = list.set(index, item); - this.fireItemReplaced(listName, index, item, replacedItem); - return replacedItem; - } - - /** - * Convenience method. - * Replace the specified item in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced item. - * @see java.util.List#set(int, Object) - */ - protected <E> E replaceItemInList(E oldItem, E newItem, List<E> list, String listName) { - return this.setItemInList(list.indexOf(oldItem), newItem, list, listName); - } - - /** - * Convenience method. - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see java.util.List#set(int, Object) - */ - protected <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) { - return this.setItemsInList(index, Arrays.asList(items), list, listName); - } - - /** - * Convenience method. - * Set the specified items in the specified bound list - * and fire the appropriate event if necessary. - * Return the replaced items. - * @see java.util.List#set(int, Object) - */ - protected <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) { - List<E> subList = list.subList(index, index + items.size()); - List<E> replacedItems = new ArrayList<E>(subList); - for (int i = 0; i < items.size(); i++) { - subList.set(i, items.get(i)); - } - this.fireItemsReplaced(listName, index, items, replacedItems); - return replacedItems; - } - - /** - * Convenience method. - * Move items in the specified list from the specified source index to the - * specified target index for the specified length. - */ - protected <E> void moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) { - CollectionTools.move(list, targetIndex, sourceIndex, length); - this.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - /** - * Convenience method. - * Move an item in the specified list from the specified source index to the - * specified target index. - */ - protected <E> void moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) { - CollectionTools.move(list, targetIndex, sourceIndex); - this.fireItemMoved(listName, targetIndex, sourceIndex); - } - - /** - * Convenience method. - * Clear the entire list - * and fire the appropriate event if necessary. - * Return whether the list changed. - * @see java.util.List#clear() - */ - protected boolean clearList(List<?> list, String listName) { - if (list.isEmpty()) { - return false; - } - list.clear(); - this.fireListCleared(listName); - return true; - } - - - // ********** tree change support ********** - - public synchronized void addTreeChangeListener(TreeChangeListener listener) { - this.getChangeSupport().addTreeChangeListener(listener); - } - - public synchronized void addTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().addTreeChangeListener(treeName, listener); - } - - public synchronized void removeTreeChangeListener(TreeChangeListener listener) { - this.getChangeSupport().removeTreeChangeListener(listener); - } - - public synchronized void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.getChangeSupport().removeTreeChangeListener(treeName, listener); - } - - protected final void fireNodeAdded(String treeName, Object[] path) { - this.getChangeSupport().fireNodeAdded(treeName, path); - } - - protected final void fireNodeAdded(TreeChangeEvent event) { - this.getChangeSupport().fireNodeAdded(event); - } - - protected final void fireNodeRemoved(String treeName, Object[] path) { - this.getChangeSupport().fireNodeRemoved(treeName, path); - } - - protected final void fireNodeRemoved(TreeChangeEvent event) { - this.getChangeSupport().fireNodeRemoved(event); - } - - protected final void fireTreeCleared(String treeName) { - this.getChangeSupport().fireTreeCleared(treeName); - } - - protected final void fireTreeCleared(TreeChangeEvent event) { - this.getChangeSupport().fireTreeCleared(event); - } - - protected final void fireTreeChanged(String treeName) { - this.getChangeSupport().fireTreeChanged(treeName); - } - - protected final void fireTreeChanged(String treeName, Object[] path) { - this.getChangeSupport().fireTreeChanged(treeName, path); - } - - protected final void fireTreeChanged(TreeChangeEvent event) { - this.getChangeSupport().fireTreeChanged(event); - } - - - // ********** queries ********** - - /** - * Return whether there are any state change listeners. - */ - public boolean hasAnyStateChangeListeners() { - return this.getChangeSupport().hasAnyStateChangeListeners(); - } - - /** - * Return whether there are no state change listeners. - */ - public boolean hasNoStateChangeListeners() { - return ! this.hasAnyStateChangeListeners(); - } - - /** - * Return whether there are any property change listeners for a specific property. - */ - public boolean hasAnyPropertyChangeListeners(String propertyName) { - return this.getChangeSupport().hasAnyPropertyChangeListeners(propertyName); - } - - /** - * Return whether there are any property change listeners for a specific property. - */ - public boolean hasNoPropertyChangeListeners(String propertyName) { - return ! this.hasAnyPropertyChangeListeners(propertyName); - } - - /** - * Return whether there are any collection change listeners for a specific collection. - */ - public boolean hasAnyCollectionChangeListeners(String collectionName) { - return this.getChangeSupport().hasAnyCollectionChangeListeners(collectionName); - } - - /** - * Return whether there are any collection change listeners for a specific collection. - */ - public boolean hasNoCollectionChangeListeners(String collectionName) { - return ! this.hasAnyCollectionChangeListeners(collectionName); - } - - /** - * Return whether there are any list change listeners for a specific list. - */ - public boolean hasAnyListChangeListeners(String listName) { - return this.getChangeSupport().hasAnyListChangeListeners(listName); - } - - /** - * Return whether there are any list change listeners for a specific list. - */ - public boolean hasNoListChangeListeners(String listName) { - return ! this.hasAnyListChangeListeners(listName); - } - - /** - * Return whether there are any tree change listeners for a specific tree. - */ - public boolean hasAnyTreeChangeListeners(String treeName) { - return this.getChangeSupport().hasAnyTreeChangeListeners(treeName); - } - - /** - * Return whether there are any tree change listeners for a specific tree. - */ - public boolean hasNoTreeChangeListeners(String treeName) { - return ! this.hasAnyTreeChangeListeners(treeName); - } - - - // ********** convenience methods ********** - - /** - * Return whether the values are equal, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - * - * DO NOT use this to determine whether to fire a change notification, - * ChangeSupport already does that. - */ - protected final boolean valuesAreEqual(Object value1, Object value2) { - return this.getChangeSupport().valuesAreEqual(value1, value2); - } - protected final boolean attributeValueHasNotChanged(Object oldValue, Object newValue) { - return this.valuesAreEqual(oldValue, newValue); - } - - - /** - * Return whether the values are different, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - * - * DO NOT use this to determine whether to fire a change notification, - * ChangeSupport already does that. - * - * For example, after firing the change notification, you can use this method - * to decide if some other, related, piece of state needs to be synchronized - * with the state that just changed. - */ - protected final boolean valuesAreDifferent(Object value1, Object value2) { - return this.getChangeSupport().valuesAreDifferent(value1, value2); - } - protected final boolean attributeValueHasChanged(Object oldValue, Object newValue) { - return this.valuesAreDifferent(oldValue, newValue); - } - - - // ********** Object overrides ********** - - /** - * Although cloning models is usually not a Good Idea, - * we should at least support it properly. - */ - @Override - protected AbstractModel clone() throws CloneNotSupportedException { - AbstractModel clone = (AbstractModel) super.clone(); - clone.postClone(); - return clone; - } - - /** - * Perform any post-clone processing necessary to - * successfully disconnect the clone from the original. - * When this method is called on the clone, the clone - * is a "shallow" copy of the original (i.e. the clone - * shares all its instance variables with the original). - */ - protected void postClone() { - // clear out change support - models do not share listeners - this.changeSupport = null; - // when you override this method, don't forget to include: - // super.postClone(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - StringTools.buildSimpleToStringOn(this, sb); - sb.append(" ("); //$NON-NLS-1$ - this.toString(sb); - sb.append(')'); - return sb.toString(); - } - - /** - * make this public so one model can call a nested model's - * #toString(StringBuilder) - */ - public void toString(@SuppressWarnings("unused") StringBuilder sb) { - // subclasses should override this to do something a bit more helpful - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java deleted file mode 100644 index e85a27bbe1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/CallbackChangeSupport.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model; - -import org.eclipse.jpt.utility.model.Model; - -/** - * This change support class will notify the source when one of the source's - * aspects has changed. - */ -public class CallbackChangeSupport extends ChangeSupport { - private static final long serialVersionUID = 1L; - - public CallbackChangeSupport(Source source) { - super(source); - } - - protected Source source() { - return (Source) this.source; - } - - @Override - protected ChangeSupport buildChildChangeSupport() { - return new Child(this.source()); - } - - @Override - protected void sourceChanged(String aspectName) { - super.sourceChanged(aspectName); - this.source().aspectChanged(aspectName); - } - - - // ********** child change support ********** - - /** - * The aspect-specific change support class does not need to - * notify the source node of changes (the parent will take care of that); - * nor does it need to build "grandchildren" change support objects. - */ - protected static class Child extends ChangeSupport { - private static final long serialVersionUID = 1L; - - public Child(Source source) { - super(source); - } - - protected Source source() { - return (Source) this.source; - } - - @Override - protected ChangeSupport buildChildChangeSupport() { - // there are no grandchildren - throw new UnsupportedOperationException(); - } - - } - - - // ********** source interface ********** - - /** - * The callback change support source must implement this interface so it - * can be notified of any aspect changes. - */ - public interface Source extends Model { - - /** - * The specified aspect changed. - */ - void aspectChanged(String aspectName); - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java deleted file mode 100644 index 3150f612bc..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java +++ /dev/null @@ -1,2363 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Support object that can be used by implementors of the Model interface. - * It provides for state, property, collection, list, and tree change notifications to - * listeners. - * - * NB: There is lots of copy-n-paste code in this class. Nearly all of this duplication - * is an effort to prevent the unnecessary creation of new objects (typically event - * objects). Since many events are fired when there are no listeners, we postpone - * the creation of event objects until we know we have interested listeners. - * Most methods have the "non-duplicated" version of the method body commented - * out at the top of the current method body. - * The hope was that this class would prove to be fairly static and the duplicated - * code would not prove onerous; but that has not proven to be - * the case, as we have added support for "state" changes, "dirty" notification, - * and custom "notifiers", with more to come, I'm sure.... ~bjv - * - * NB2: This class will check to see if, during the firing of events, a listener - * on the original, cloned, list of listeners has been removed from the master - * list of listeners *before* it is notified. If the listener has been removed - * "concurrently" it will *not* be notified. (See the code that uses the - * 'stillListening' local boolean flag.) - * - * NB3: Any listener that is added during the firing of events will *not* be - * also notified. - * - * NB4: This class is serializable, but it will only write out listeners that - * are also serializable while silently leaving behind listeners that are not. - * - * TODO fire a state change event with *every* change? - * TODO use objects (IDs?) instead of strings to identify aspects? - */ -public class ChangeSupport - implements Serializable -{ - - /** The object to be provided as the "source" for any generated events. */ - protected final Model source; - - /** Associate a listener class to a collection of "generic" listeners for that class. */ - private transient GenericListenerList[] genericListeners = EMPTY_GENERIC_LISTENERS; - private static final GenericListenerList[] EMPTY_GENERIC_LISTENERS = new GenericListenerList[0]; - - /** Associate aspect names to child change support objects. */ - private AspectChild[] aspectChildren = EMPTY_ASPECT_CHILDREN; - private static final AspectChild[] EMPTY_ASPECT_CHILDREN = new AspectChild[0]; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - /** - * Construct support for the specified source of change events. - * The source cannot be null. - */ - public ChangeSupport(Model source) { - super(); - if (source == null) { - throw new NullPointerException(); - } - this.source = source; - } - - - // ********** internal behavior ********** - - /** - * Add a "generic" listener that listens to all events appropriate to that - * listener, regardless of the aspect name associated with that event. - * The listener cannot be null. - */ - protected <T extends ChangeListener> void addListener(Class<T> listenerClass, T listener) { - if (listener == null) { - throw new NullPointerException(); // better sooner than later - } - synchronized (this) { - GenericListenerList gll = this.genericListenerList(listenerClass); - if (gll == null) { - this.addGenericListenerList(listenerClass, listener); - } else { - gll.addListener(listener); - } - } - } - - /** - * Return the "generic" listener list for the specified listener class. - * Return null if the list is not present. - */ - protected GenericListenerList genericListenerList(Class<? extends ChangeListener> listenerClass) { - for (GenericListenerList gll : this.genericListeners) { - if (gll.listenerClass == listenerClass) { - return gll; - } - } - return null; - } - - /** - * Add the "generic" listener list for the specified listener class. - * Return the newly-built generic listener list. - */ - protected <T extends ChangeListener> GenericListenerList addGenericListenerList(Class<T> listenerClass, T listener) { - GenericListenerList gll = new GenericListenerList(listenerClass, listener); - this.genericListeners = CollectionTools.add(this.genericListeners, gll); - return gll; - } - - /** - * Adds a listener that listens to all events appropriate to that listener, - * and only to those events carrying the aspect name specified. - * The aspect name cannot be null and the listener cannot be null. - */ - protected <T extends ChangeListener> void addListener(String aspectName, Class<T> listenerClass, T listener) { - if ((aspectName == null) || (listener == null)) { - throw new NullPointerException(); // better sooner than later - } - synchronized (this) { - ChangeSupport child = this.child(aspectName); - if (child == null) { - child = this.addChild(aspectName); - } - child.addListener(listenerClass, listener); - } - } - - /** - * Return the child change support for the specified aspect name. - * Return null if the aspect name is null or the child is not present. - */ - protected ChangeSupport child(String aspectName) { - // put in a null check to simplify calling code - if (aspectName == null) { - return null; - } - for (AspectChild aspectChild : this.aspectChildren) { - if (aspectChild.aspectName == aspectName) { - return aspectChild.child; - } - } - return null; - } - - /** - * Add the child change support for the specified aspect name. - * Return the newly-built child change support. - */ - protected ChangeSupport addChild(String aspectName) { - ChangeSupport child = this.buildChildChangeSupport(); - this.aspectChildren = CollectionTools.add(this.aspectChildren, new AspectChild(aspectName, child)); - return child; - } - - /** - * Build and return a child change support to hold aspect-specific listeners. - */ - protected ChangeSupport buildChildChangeSupport() { - return new ChangeSupport(this.source); - } - - /** - * Removes a "generic" listener that has been registered for all events - * appropriate to that listener. - */ - protected <T extends ChangeListener> void removeListener(Class<T> listenerClass, T listener) { - synchronized (this) { - GenericListenerList gll = this.genericListenerList(listenerClass); - if (gll == null) { - throw new IllegalArgumentException("listener not registered"); //$NON-NLS-1$ - } - if ( ! gll.removeListener(listener)) { // leave the GLL, even if it is empty? - throw new IllegalArgumentException("listener not registered: " + listener); //$NON-NLS-1$ - } - } - } - - /** - * Removes a listener that has been registered for appropriate - * events carrying the specified aspect name. - */ - protected <T extends ChangeListener> void removeListener(String aspectName, Class<T> listenerClass, T listener) { - synchronized (this) { - ChangeSupport child = this.child(aspectName); - if (child == null) { - throw new IllegalArgumentException("listener not registered"); //$NON-NLS-1$ - } - child.removeListener(listenerClass, listener); // leave the child, even if it is empty? - } - } - - - // ********** internal queries ********** - - /** - * Return the "generic" listeners for the specified listener class. - * Return null if there are no listeners. - */ - protected ChangeListener[] listeners(Class<? extends ChangeListener> listenerClass) { - GenericListenerList gll = this.genericListenerList(listenerClass); - return (gll == null) ? null : gll.listeners; - } - - /** - * Return whether there are any "generic" listeners for the specified - * listener class. - */ - protected synchronized <T extends ChangeListener> boolean hasAnyListeners(Class<T> listenerClass) { - GenericListenerList gll = this.genericListenerList(listenerClass); - return (gll != null) && gll.hasListeners(); - } - - /** - * Return whether there are no "generic" listeners for the specified - * listener class. - */ - protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass) { - return ! this.hasAnyListeners(listenerClass); - } - - /** - * Return whether there are any listeners for the specified - * listener class and aspect name. - */ - protected synchronized boolean hasAnyListeners(Class<? extends ChangeListener> listenerClass, String aspectName) { - if (this.hasAnyListeners(listenerClass)) { - return true; // there's a "generic" listener - } - ChangeSupport child = this.child(aspectName); - return (child != null) && - child.hasAnyListeners(listenerClass); - } - - /** - * Return whether there are no "generic" listeners for the specified - * listener class and aspect name. - */ - protected <T extends ChangeListener> boolean hasNoListeners(Class<T> listenerClass, String aspectName) { - return ! this.hasAnyListeners(listenerClass, aspectName); - } - - - // ********** behavior ********** - - /** - * The specified aspect of the source has changed; - * override this method to perform things like setting a - * dirty flag or validating the source's state. - * The aspect ID will be null if a "state change" occurred. - */ - protected void sourceChanged(@SuppressWarnings("unused") String aspectName) { - // the default is to do nothing - } - - - // ********** state change support ********** - - protected static final Class<StateChangeListener> STATE_CHANGE_LISTENER_CLASS = StateChangeListener.class; - - /** - * Add a state change listener. - */ - public void addStateChangeListener(StateChangeListener listener) { - this.addListener(STATE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a state change listener. - */ - public void removeStateChangeListener(StateChangeListener listener) { - this.removeListener(STATE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any state change listeners. - */ - public boolean hasAnyStateChangeListeners() { - return this.hasAnyListeners(STATE_CHANGE_LISTENER_CLASS); - } - - private StateChangeListener[] stateChangeListeners() { - return (StateChangeListener[]) this.listeners(STATE_CHANGE_LISTENER_CLASS); - } - - /** - * Fire the specified state change event to any registered listeners. - */ - public void fireStateChanged(StateChangeEvent event) { - - StateChangeListener[] targets = null; - - synchronized (this) { - StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); - if (stateChangeListeners != null) { - targets = stateChangeListeners.clone(); - } - } - - if (targets != null) { - for (StateChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.stateChangeListeners(), target); - } - if (stillListening) { - target.stateChanged(event); - } - } - } - - this.sourceChanged(null); - } - - /** - * Report a generic state change event to any registered state change - * listeners. - */ - public void fireStateChanged() { -// this.fireStateChange(new StateChangeEvent(this.source)); - - StateChangeListener[] targets = null; - - synchronized (this) { - StateChangeListener[] stateChangeListeners = this.stateChangeListeners(); - if (stateChangeListeners != null) { - targets = stateChangeListeners.clone(); - } - } - - if (targets != null) { - StateChangeEvent event = null; - for (StateChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.stateChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new StateChangeEvent(this.source); - } - target.stateChanged(event); - } - } - } - - this.sourceChanged(null); - } - - - // ********** property change support ********** - - protected static final Class<PropertyChangeListener> PROPERTY_CHANGE_LISTENER_CLASS = PropertyChangeListener.class; - - /** - * Return whether the values are equal, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - */ - public boolean valuesAreEqual(Object value1, Object value2) { - if ((value1 == null) && (value2 == null)) { - return true; // both are null - } - if ((value1 == null) || (value2 == null)) { - return false; // one is null but the other is not - } - return value1.equals(value2); - } - - /** - * Return whether the values are different, with the appropriate null checks. - * Convenience method for checking whether an attribute value has changed. - */ - public boolean valuesAreDifferent(Object value1, Object value2) { - return ! this.valuesAreEqual(value1, value2); - } - - /** - * Add a property change listener that is registered for all properties. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - this.addListener(PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Add a property change listener for the specified property. The listener - * will be notified only for changes to the specified property. - */ - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.addListener(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a property change listener that was registered for all properties. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - this.removeListener(PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a property change listener that was registered for a specific property. - */ - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - this.removeListener(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any property change listeners that will - * be notified when the specified property has changed. - */ - public boolean hasAnyPropertyChangeListeners(String propertyName) { - return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - } - - /** - * Return whether there are any property change listeners that will - * be notified when any property has changed. - */ - public boolean hasAnyPropertyChangeListeners() { - return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS); - } - - private PropertyChangeListener[] propertyChangeListeners() { - return (PropertyChangeListener[]) this.listeners(PROPERTY_CHANGE_LISTENER_CLASS); - } - - /** - * Fire the specified property change event to any registered listeners. - * No event is fired if the given event's old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - */ - public void firePropertyChanged(PropertyChangeEvent event) { - if (this.valuesAreEqual(event.getOldValue(), event.getNewValue())) { - return; - } - - String propertyName = event.getPropertyName(); - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - target.propertyChanged(event); - } - } - } - if (child != null) { - child.firePropertyChanged(event); - } - - this.sourceChanged(propertyName); - } - - /** - * Report a bound property update to any registered property change listeners. - * No event is fired if the given old and new values are the same; - * this includes when both values are null. Use a state change event - * for general purpose notification of changes. - */ - public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { -// this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); - if (this.valuesAreEqual(oldValue, newValue)) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - /** - * Report an int bound property update to any registered listeners. - * No event is fired if old and new are equal. - * <p> - * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. - */ - public void firePropertyChanged(String propertyName, int oldValue, int newValue) { -// this.firePropertyChanged(propertyName, new Integer(oldValue), new Integer(newValue)); - if (oldValue == newValue) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, new Integer(oldValue), new Integer(newValue)); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - /** - * Report a boolean bound property update to any registered listeners. - * No event is fired if old and new are equal. - * <p> - * This is merely a convenience wrapper around the more general - * firePropertyChange method that takes Object values. - */ - public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { -// this.firePropertyChanged(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - if (oldValue == newValue) { - return; - } - - PropertyChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - PropertyChangeListener[] propertyChangeListeners = this.propertyChangeListeners(); - if (propertyChangeListeners != null) { - targets = propertyChangeListeners.clone(); - } - child = this.child(propertyName); - } - - PropertyChangeEvent event = null; - - if (targets != null) { - for (PropertyChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.propertyChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); - } - target.propertyChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.firePropertyChanged(propertyName, oldValue, newValue); - } else { - child.firePropertyChanged(event); - } - } - - this.sourceChanged(propertyName); - } - - - // ********** collection change support ********** - - protected static final Class<CollectionChangeListener> COLLECTION_CHANGE_LISTENER_CLASS = CollectionChangeListener.class; - - /** - * Add a collection change listener that is registered for all collections. - */ - public void addCollectionChangeListener(CollectionChangeListener listener) { - this.addListener(COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Add a collection change listener for the specified collection. The listener - * will be notified only for changes to the specified collection. - */ - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.addListener(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a collection change listener that was registered for all collections. - */ - public void removeCollectionChangeListener(CollectionChangeListener listener) { - this.removeListener(COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a collection change listener that was registered for a specific collection. - */ - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - this.removeListener(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any collection change listeners that will - * be notified when the specified collection has changed. - */ - public boolean hasAnyCollectionChangeListeners(String collectionName) { - return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - } - - /** - * Return whether there are any collection change listeners that will - * be notified when any collection has changed. - */ - public boolean hasAnyCollectionChangeListeners() { - return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS); - } - - private CollectionChangeListener[] collectionChangeListeners() { - return (CollectionChangeListener[]) this.listeners(COLLECTION_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsAdded(CollectionChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.itemsAdded(event); - } - } - } - if (child != null) { - child.fireItemsAdded(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsAdded(String collectionName, Collection<?> addedItems) { -// this.fireItemsAdded(new CollectionChangeEvent(this.source, collectionName, addedItems)); - if (addedItems.size() == 0) { - return; - } - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, addedItems); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsAdded(collectionName, addedItems); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemAdded(String collectionName, Object addedItem) { -// this.fireItemsAdded(collectionName, Collections.singleton(addedItem)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(addedItem)); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemAdded(collectionName, addedItem); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsRemoved(CollectionChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.itemsRemoved(event); - } - } - } - if (child != null) { - child.fireItemsRemoved(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemsRemoved(String collectionName, Collection<?> removedItems) { -// this.fireItemsRemoved(new CollectionChangeEvent(this.source, collectionName, removedItems)); - if (removedItems.size() == 0) { - return; - } - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, removedItems); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsRemoved(collectionName, removedItems); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireItemRemoved(String collectionName, Object removedItem) { -// this.fireItemsRemoved(collectionName, Collections.singleton(removedItem)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(removedItem)); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemRemoved(collectionName, removedItem); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(CollectionChangeEvent event) { - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.collectionCleared(event); - } - } - } - if (child != null) { - child.fireCollectionCleared(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionCleared(String collectionName) { -// this.fireCollectionCleared(new CollectionChangeEvent(this.source, collectionName)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName); - } - target.collectionCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireCollectionCleared(collectionName); - } else { - child.fireCollectionCleared(event); - } - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(CollectionChangeEvent event) { - String collectionName = event.getCollectionName(); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - target.collectionChanged(event); - } - } - } - if (child != null) { - child.fireCollectionChanged(event); - } - - this.sourceChanged(collectionName); - } - - /** - * Report a bound collection update to any registered listeners. - */ - public void fireCollectionChanged(String collectionName) { -// this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName)); - - CollectionChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - CollectionChangeListener[] collectionChangeListeners = this.collectionChangeListeners(); - if (collectionChangeListeners != null) { - targets = collectionChangeListeners.clone(); - } - child = this.child(collectionName); - } - - CollectionChangeEvent event = null; - - if (targets != null) { - for (CollectionChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.collectionChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new CollectionChangeEvent(this.source, collectionName); - } - target.collectionChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireCollectionChanged(collectionName); - } else { - child.fireCollectionChanged(event); - } - } - - this.sourceChanged(collectionName); - } - - - // ********** list change support ********** - - protected static final Class<ListChangeListener> LIST_CHANGE_LISTENER_CLASS = ListChangeListener.class; - - /** - * Add a list change listener that is registered for all lists. - */ - public void addListChangeListener(ListChangeListener listener) { - this.addListener(LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Add a list change listener for the specified list. The listener - * will be notified only for changes to the specified list. - */ - public void addListChangeListener(String listName, ListChangeListener listener) { - this.addListener(listName, LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a list change listener that was registered for all lists. - */ - public void removeListChangeListener(ListChangeListener listener) { - this.removeListener(LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a list change listener that was registered for a specific list. - */ - public void removeListChangeListener(String listName, ListChangeListener listener) { - this.removeListener(listName, LIST_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any list change listeners that will - * be notified when the specified list has changed. - */ - public boolean hasAnyListChangeListeners(String listName) { - return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS, listName); - } - - /** - * Return whether there are any list change listeners that will - * be notified when any list has changed. - */ - public boolean hasAnyListChangeListeners() { - return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS); - } - - private ListChangeListener[] listChangeListeners() { - return (ListChangeListener[]) this.listeners(LIST_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsAdded(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsAdded(event); - } - } - } - if (child != null) { - child.fireItemsAdded(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsAdded(String listName, int index, List<?> addedItems) { -// this.fireItemsAdded(new ListChangeEvent(this.source, listName, index, addedItems)); - if (addedItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, addedItems); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsAdded(listName, index, addedItems); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemAdded(String listName, int index, Object addedItem) { -// this.fireItemsAdded(listName, index, Collections.singletonList(addedItem)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(addedItem)); - } - target.itemsAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemAdded(listName, index, addedItem); - } else { - child.fireItemsAdded(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsRemoved(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsRemoved(event); - } - } - } - if (child != null) { - child.fireItemsRemoved(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsRemoved(String listName, int index, List<?> removedItems) { -// this.fireItemsRemoved(new ListChangeEvent(this.source, listName, index, removedItems)); - if (removedItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, removedItems); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsRemoved(listName, index, removedItems); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemRemoved(String listName, int index, Object removedItem) { -// this.fireItemsRemoved(listName, index, Collections.singletonList(removedItem)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(removedItem)); - } - target.itemsRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemRemoved(listName, index, removedItem); - } else { - child.fireItemsRemoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsReplaced(ListChangeEvent event) { - if (event.itemsSize() == 0) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsReplaced(event); - } - } - } - if (child != null) { - child.fireItemsReplaced(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) { -// this.fireItemsReplaced(new ListChangeEvent(this.source, listName, index, newItems, replacedItems)); - if (newItems.size() == 0) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, newItems, replacedItems); - } - target.itemsReplaced(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsReplaced(listName, index, newItems, replacedItems); - } else { - child.fireItemsReplaced(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { -// this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem)); - } - target.itemsReplaced(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemReplaced(listName, index, newItem, replacedItem); - } else { - child.fireItemsReplaced(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsMoved(ListChangeEvent event) { - if (event.getTargetIndex() == event.getSourceIndex()) { - return; - } - - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.itemsMoved(event); - } - } - } - if (child != null) { - child.fireItemsMoved(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { -// this.fireItemsMoved(new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length)); - if (targetIndex == sourceIndex) { - return; - } - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length); - } - target.itemsMoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } else { - child.fireItemsMoved(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireItemMoved(String listName, int targetIndex, int sourceIndex) { - this.fireItemsMoved(listName, targetIndex, sourceIndex, 1); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(ListChangeEvent event) { - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.listCleared(event); - } - } - } - if (child != null) { - child.fireListCleared(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListCleared(String listName) { -// this.fireListCleared(new ListChangeEvent(this.source, listName)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName); - } - target.listCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireListCleared(listName); - } else { - child.fireListCleared(event); - } - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(ListChangeEvent event) { - String listName = event.getListName(); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - target.listChanged(event); - } - } - } - if (child != null) { - child.fireListChanged(event); - } - - this.sourceChanged(listName); - } - - /** - * Report a bound list update to any registered listeners. - */ - public void fireListChanged(String listName) { -// this.fireListChanged(new ListChangeEvent(this.source, listName)); - - ListChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - ListChangeListener[] listChangeListeners = this.listChangeListeners(); - if (listChangeListeners != null) { - targets = listChangeListeners.clone(); - } - child = this.child(listName); - } - - ListChangeEvent event = null; - - if (targets != null) { - for (ListChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.listChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new ListChangeEvent(this.source, listName); - } - target.listChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireListChanged(listName); - } else { - child.fireListChanged(event); - } - } - - this.sourceChanged(listName); - } - - - // ********** tree change support ********** - - protected static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class; - private static final Object[] EMPTY_TREE_PATH = new Object[0]; - - /** - * Add a tree change listener that is registered for all trees. - */ - public void addTreeChangeListener(TreeChangeListener listener) { - this.addListener(TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Add a tree change listener for the specified tree. The listener - * will be notified only for changes to the specified tree. - */ - public void addTreeChangeListener(String treeName, TreeChangeListener listener) { - this.addListener(treeName, TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a tree change listener that was registered for all tree. - */ - public void removeTreeChangeListener(TreeChangeListener listener) { - this.removeListener(TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Remove a tree change listener that was registered for a specific tree. - */ - public void removeTreeChangeListener(String treeName, TreeChangeListener listener) { - this.removeListener(treeName, TREE_CHANGE_LISTENER_CLASS, listener); - } - - /** - * Return whether there are any tree change listeners that will - * be notified when the specified tree has changed. - */ - public boolean hasAnyTreeChangeListeners(String treeName) { - return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS, treeName); - } - - /** - * Return whether there are any tree change listeners that will - * be notified when any tree has changed. - */ - public boolean hasAnyTreeChangeListeners() { - return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS); - } - - private TreeChangeListener[] treeChangeListeners() { - return (TreeChangeListener[]) this.listeners(TREE_CHANGE_LISTENER_CLASS); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.nodeAdded(event); - } - } - } - if (child != null) { - child.fireNodeAdded(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeAdded(String treeName, Object[] path) { -// this.fireNodeAdded(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.nodeAdded(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireNodeAdded(treeName, path); - } else { - child.fireNodeAdded(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.nodeRemoved(event); - } - } - } - if (child != null) { - child.fireNodeRemoved(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireNodeRemoved(String treeName, Object[] path) { -// this.fireNodeRemoved(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.nodeRemoved(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireNodeRemoved(treeName, path); - } else { - child.fireNodeRemoved(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.treeCleared(event); - } - } - } - if (child != null) { - child.fireTreeCleared(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(String treeName, Object[] path) { -// this.fireTreeCleared(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.treeCleared(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireTreeCleared(treeName, path); - } else { - child.fireTreeCleared(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeCleared(String treeName) { - this.fireTreeCleared(treeName, EMPTY_TREE_PATH); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(TreeChangeEvent event) { - String treeName = event.getTreeName(); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - target.treeChanged(event); - } - } - } - if (child != null) { - child.fireTreeChanged(event); - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(String treeName, Object[] path) { -// this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, path)); - - TreeChangeListener[] targets = null; - ChangeSupport child = null; - - synchronized (this) { - TreeChangeListener[] treeChangeListeners = this.treeChangeListeners(); - if (treeChangeListeners != null) { - targets = treeChangeListeners.clone(); - } - child = this.child(treeName); - } - - TreeChangeEvent event = null; - - if (targets != null) { - for (TreeChangeListener target : targets) { - boolean stillListening; - synchronized (this) { - stillListening = CollectionTools.contains(this.treeChangeListeners(), target); - } - if (stillListening) { - if (event == null) { - // here's the reason for the duplicate code... - event = new TreeChangeEvent(this.source, treeName, path); - } - target.treeChanged(event); - } - } - } - if (child != null) { - if (event == null) { - child.fireTreeChanged(treeName, path); - } else { - child.fireTreeChanged(event); - } - } - - this.sourceChanged(treeName); - } - - /** - * Report a bound tree update to any registered listeners. - */ - public void fireTreeChanged(String treeName) { - this.fireTreeChanged(treeName, EMPTY_TREE_PATH); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.source); - } - - - // ********** serialization ********** - - private synchronized void writeObject(ObjectOutputStream s) throws IOException { - // write out the source, children, and any hidden stuff - s.defaultWriteObject(); - - // only write out Serializable listeners - int len = this.genericListeners.length; - for (int i = 0; i < len; i++) { - this.writeObject(s, this.genericListeners[i]); - } - s.writeObject(null); - } - - private void writeObject(ObjectOutputStream s, GenericListenerList gll) throws IOException { - boolean first = true; - int len = gll.listeners.length; - for (int i = 0; i < len; i++) { - ChangeListener listener = gll.listeners[i]; - if (listener instanceof Serializable) { - if (first) { - first = false; - s.writeObject(gll.listenerClass); - } - s.writeObject(listener); - } - } - if ( ! first) { - s.writeObject(null); - } - } - - private synchronized void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { - // read in the source, children, and any hidden stuff - s.defaultReadObject(); - - // read in generic listener lists - this.genericListeners = EMPTY_GENERIC_LISTENERS; - Object o; - while (null != (o = s.readObject())) { - @SuppressWarnings("unchecked") - Class<? extends ChangeListener> listenerClass = (Class<? extends ChangeListener>) o; - GenericListenerList gll = null; - while (null != (o = s.readObject())) { - if (gll == null) { - gll = this.addGenericListenerList_(listenerClass, (ChangeListener) o); - } else { - gll.addListener((ChangeListener) o); - } - } - } - } - - @SuppressWarnings("unchecked") - private <T extends ChangeListener> GenericListenerList addGenericListenerList_(Class<T> listenerClass, ChangeListener listener) { - return this.addGenericListenerList(listenerClass, (T) listener); - } - - - // ********** member classes ********** - - /** - * Pair a listener class with its "generic" listeners. - */ - private static class GenericListenerList { - final Class<? extends ChangeListener> listenerClass; - ChangeListener[] listeners; - - <T extends ChangeListener> GenericListenerList(Class<T> listenerClass, T listener) { - super(); - this.listenerClass = listenerClass; - this.listeners = (ChangeListener[]) Array.newInstance(listenerClass, 1); - this.listeners[0] = listener; - } - - void addListener(ChangeListener listener) { - this.listeners = CollectionTools.add(this.listeners, listener); - } - - boolean removeListener(ChangeListener listener) { - int len = this.listeners.length; - if (len == 0) { - return false; - } - try { - this.listeners = CollectionTools.remove(this.listeners, listener); - } catch (ArrayIndexOutOfBoundsException ex) { - return false; // listener not in the list - } - return (this.listeners.length + 1) == len; - } - - boolean hasListeners() { - return this.listeners.length > 0; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, ClassTools.shortNameFor(this.listenerClass)); - } - - } - - /** - * Pair an aspect name with the change support holding its associated - * listeners. - */ - private static class AspectChild implements Serializable { - final String aspectName; - final ChangeSupport child; - private static final long serialVersionUID = 1L; - - AspectChild(String aspectName, ChangeSupport child) { - super(); - this.aspectName = aspectName; - this.child = child; - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.aspectName); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java deleted file mode 100644 index 29852e2a0f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/SingleAspectChangeSupport.java +++ /dev/null @@ -1,331 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model; - -import java.util.Collection; -import java.util.List; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; - -/** - * This change support class changes the behavior of the standard - * ChangeSupport in several ways: - * - All events fired by the source must specify the single aspect. - * - Listeners are required to be either "generic" listeners or - * listeners of the single aspect. - */ -public class SingleAspectChangeSupport - extends ChangeSupport -{ - protected final Class<? extends ChangeListener> listenerClass; - protected final String aspectName; - - private static final long serialVersionUID = 1L; - - - // ********** constructor ********** - - public SingleAspectChangeSupport(Model source, Class<? extends ChangeListener> listenerClass, String aspectName) { - super(source); - this.listenerClass = listenerClass; - this.aspectName = aspectName; - } - - - // ********** internal behavior ********** - - private UnsupportedOperationException unsupportedOperationException() { - return new UnsupportedOperationException("This Model supports only changes for the listener type \"" + this.listenerClass.getName() - + "\" and the aspect \"" + this.aspectName + "\""); - } - - private void check(Class<? extends ChangeListener> lClass, String aName) { - if (lClass != this.listenerClass) { - throw new IllegalArgumentException("This Model supports only changes for the listener type \"" + this.listenerClass.getName() + "\" : \"" + lClass.getName() + "\""); - } - if (aName != this.aspectName) { - throw new IllegalArgumentException("This Model supports only changes for the aspect \"" + this.aspectName + "\" : \"" + aName + "\""); - } - } - - @Override - protected <T extends ChangeListener> void addListener(String aName, Class<T> lClass, T listener) { - this.check(lClass, aName); - super.addListener(aName, lClass, listener); - } - - @Override - protected <T extends ChangeListener> void removeListener(String aName, Class<T> lClass, T listener) { - this.check(lClass, aName); - super.removeListener(aName, lClass, listener); - } - - - // ********** internal queries ********** - - @Override - protected boolean hasAnyListeners(Class<? extends ChangeListener> lClass, String aName) { - this.check(lClass, aName); - return super.hasAnyListeners(lClass, aName); - } - - - // ********** state change support ********** - - @Override - public void fireStateChanged(StateChangeEvent event) { - throw this.unsupportedOperationException(); - } - - @Override - public void fireStateChanged() { - throw this.unsupportedOperationException(); - } - - - // ********** property change support ********** - - @Override - public void firePropertyChanged(PropertyChangeEvent event) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, event.getPropertyName()); - super.firePropertyChanged(event); - } - - @Override - public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public void firePropertyChanged(String propertyName, int oldValue, int newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - @Override - public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) { - this.check(PROPERTY_CHANGE_LISTENER_CLASS, propertyName); - super.firePropertyChanged(propertyName, oldValue, newValue); - } - - - // ********** collection change support ********** - - @Override - public void fireItemsAdded(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireItemsAdded(event); - } - - @Override - public void fireItemsAdded(String collectionName, Collection<?> addedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemsAdded(collectionName, addedItems); - } - - @Override - public void fireItemAdded(String collectionName, Object addedItem) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemAdded(collectionName, addedItem); - } - - @Override - public void fireItemsRemoved(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireItemsRemoved(event); - } - - @Override - public void fireItemsRemoved(String collectionName, Collection<?> removedItems) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemsRemoved(collectionName, removedItems); - } - - @Override - public void fireItemRemoved(String collectionName, Object removedItem) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireItemRemoved(collectionName, removedItem); - } - - @Override - public void fireCollectionCleared(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireCollectionCleared(event); - } - - @Override - public void fireCollectionCleared(String collectionName) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireCollectionCleared(collectionName); - } - - @Override - public void fireCollectionChanged(CollectionChangeEvent event) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, event.getCollectionName()); - super.fireCollectionChanged(event); - } - - @Override - public void fireCollectionChanged(String collectionName) { - this.check(COLLECTION_CHANGE_LISTENER_CLASS, collectionName); - super.fireCollectionChanged(collectionName); - } - - - // ********** list change support ********** - - @Override - public void fireItemsAdded(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsAdded(event); - } - - @Override - public void fireItemsAdded(String listName, int index, List<?> addedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsAdded(listName, index, addedItems); - } - - @Override - public void fireItemAdded(String listName, int index, Object addedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemAdded(listName, index, addedItem); - } - - @Override - public void fireItemsRemoved(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsRemoved(event); - } - - @Override - public void fireItemsRemoved(String listName, int index, List<?> removedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsRemoved(listName, index, removedItems); - } - - @Override - public void fireItemRemoved(String listName, int index, Object removedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemRemoved(listName, index, removedItem); - } - - @Override - public void fireItemsReplaced(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsReplaced(event); - } - - @Override - public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsReplaced(listName, index, newItems, replacedItems); - } - - @Override - public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemReplaced(listName, index, newItem, replacedItem); - } - - @Override - public void fireItemsMoved(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireItemsMoved(event); - } - - @Override - public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireItemsMoved(listName, targetIndex, sourceIndex, length); - } - - @Override - public void fireListCleared(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireListCleared(event); - } - - @Override - public void fireListCleared(String listName) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireListCleared(listName); - } - - @Override - public void fireListChanged(ListChangeEvent event) { - this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName()); - super.fireListChanged(event); - } - - @Override - public void fireListChanged(String listName) { - this.check(LIST_CHANGE_LISTENER_CLASS, listName); - super.fireListChanged(listName); - } - - - // ********** tree change support ********** - - @Override - public void fireNodeAdded(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeAdded(event); - } - - @Override - public void fireNodeAdded(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeAdded(treeName, path); - } - - @Override - public void fireNodeRemoved(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireNodeRemoved(event); - } - - @Override - public void fireNodeRemoved(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireNodeRemoved(treeName, path); - } - - @Override - public void fireTreeCleared(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeCleared(event); - } - - @Override - public void fireTreeCleared(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeCleared(treeName, path); - } - - @Override - public void fireTreeChanged(TreeChangeEvent event) { - this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName()); - super.fireTreeChanged(event); - } - - @Override - public void fireTreeChanged(String treeName, Object[] path) { - this.check(TREE_CHANGE_LISTENER_CLASS, treeName); - super.fireTreeChanged(treeName, path); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java deleted file mode 100644 index 4cab405723..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTCollectionChangeListenerWrapper.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.listener.awt; - -import java.awt.EventQueue; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; - -/** - * Wrap another collection change listener and forward events to it on the AWT - * event queue. - */ -public class AWTCollectionChangeListenerWrapper - implements CollectionChangeListener -{ - private final CollectionChangeListener listener; - - public AWTCollectionChangeListenerWrapper(CollectionChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void itemsAdded(CollectionChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(CollectionChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void collectionCleared(CollectionChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.collectionCleared_(event); - } else { - this.executeOnEventQueue(this.buildCollectionClearedRunnable(event)); - } - } - - public void collectionChanged(CollectionChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.collectionChanged_(event); - } else { - this.executeOnEventQueue(this.buildCollectionChangedRunnable(event)); - } - } - - private Runnable buildItemsAddedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added"; - } - }; - } - - private Runnable buildItemsRemovedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed"; - } - }; - } - - private Runnable buildCollectionClearedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionCleared_(event); - } - @Override - public String toString() { - return "collection cleared"; - } - }; - } - - private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) { - return new Runnable() { - public void run() { - AWTCollectionChangeListenerWrapper.this.collectionChanged_(event); - } - @Override - public String toString() { - return "collection changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #invokeAndWait(Runnable) can sometimes make things - * more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void itemsAdded_(CollectionChangeEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(CollectionChangeEvent event) { - this.listener.itemsRemoved(event); - } - - void collectionCleared_(CollectionChangeEvent event) { - this.listener.collectionCleared(event); - } - - void collectionChanged_(CollectionChangeEvent event) { - this.listener.collectionChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java deleted file mode 100644 index 7bed089ac8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTListChangeListenerWrapper.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.listener.awt; - -import java.awt.EventQueue; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; - -/** - * Wrap another list change listener and forward events to it on the AWT - * event queue. - */ -public class AWTListChangeListenerWrapper - implements ListChangeListener -{ - private final ListChangeListener listener; - - public AWTListChangeListenerWrapper(ListChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void itemsAdded(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsAdded_(event); - } else { - this.executeOnEventQueue(this.buildItemsAddedRunnable(event)); - } - } - - public void itemsRemoved(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsRemoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsRemovedRunnable(event)); - } - } - - public void itemsMoved(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsMoved_(event); - } else { - this.executeOnEventQueue(this.buildItemsMovedRunnable(event)); - } - } - - public void itemsReplaced(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.itemsReplaced_(event); - } else { - this.executeOnEventQueue(this.buildItemsReplacedRunnable(event)); - } - } - - public void listCleared(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.listCleared_(event); - } else { - this.executeOnEventQueue(this.buildListClearedRunnable(event)); - } - } - - public void listChanged(ListChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.listChanged_(event); - } else { - this.executeOnEventQueue(this.buildListChangedRunnable(event)); - } - } - - private Runnable buildItemsAddedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsAdded_(event); - } - @Override - public String toString() { - return "items added"; - } - }; - } - - private Runnable buildItemsRemovedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsRemoved_(event); - } - @Override - public String toString() { - return "items removed"; - } - }; - } - - private Runnable buildItemsMovedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsMoved_(event); - } - @Override - public String toString() { - return "items moved"; - } - }; - } - - private Runnable buildItemsReplacedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.itemsReplaced_(event); - } - @Override - public String toString() { - return "items replaced"; - } - }; - } - - private Runnable buildListClearedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listCleared_(event); - } - @Override - public String toString() { - return "list cleared"; - } - }; - } - - private Runnable buildListChangedRunnable(final ListChangeEvent event) { - return new Runnable() { - public void run() { - AWTListChangeListenerWrapper.this.listChanged_(event); - } - @Override - public String toString() { - return "list changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #invokeAndWait(Runnable) can sometimes make things - * more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void itemsAdded_(ListChangeEvent event) { - this.listener.itemsAdded(event); - } - - void itemsRemoved_(ListChangeEvent event) { - this.listener.itemsRemoved(event); - } - - void itemsMoved_(ListChangeEvent event) { - this.listener.itemsMoved(event); - } - - void itemsReplaced_(ListChangeEvent event) { - this.listener.itemsReplaced(event); - } - - void listCleared_(ListChangeEvent event) { - this.listener.listCleared(event); - } - - void listChanged_(ListChangeEvent event) { - this.listener.listChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java deleted file mode 100644 index bcc372ac02..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTPropertyChangeListenerWrapper.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.listener.awt; - -import java.awt.EventQueue; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; - -/** - * Wrap another property change listener and forward events to it on the AWT - * event queue. - */ -public class AWTPropertyChangeListenerWrapper - implements PropertyChangeListener -{ - private final PropertyChangeListener listener; - - - public AWTPropertyChangeListenerWrapper(PropertyChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void propertyChanged(PropertyChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.propertyChanged_(event); - } else { - this.executeOnEventQueue(this.buildRunnable(event)); - } - } - - private Runnable buildRunnable(final PropertyChangeEvent event) { - return new Runnable() { - public void run() { - AWTPropertyChangeListenerWrapper.this.propertyChanged_(event); - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #invokeAndWait(Runnable) can sometimes make things - * more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void propertyChanged_(PropertyChangeEvent event) { - this.listener.propertyChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java deleted file mode 100644 index f5f2988d04..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTStateChangeListenerWrapper.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.listener.awt; - -import java.awt.EventQueue; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; - -/** - * Wrap another state change listener and forward events to it on the AWT - * event queue. - */ -public class AWTStateChangeListenerWrapper - implements StateChangeListener -{ - private final StateChangeListener listener; - - public AWTStateChangeListenerWrapper(StateChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void stateChanged(StateChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.stateChanged_(event); - } else { - this.executeOnEventQueue(this.buildRunnable(event)); - } - } - - private Runnable buildRunnable(final StateChangeEvent event) { - return new Runnable() { - public void run() { - AWTStateChangeListenerWrapper.this.stateChanged_(event); - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #invokeAndWait(Runnable) can sometimes make things - * more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void stateChanged_(StateChangeEvent event) { - this.listener.stateChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java deleted file mode 100644 index be7cfb113a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/awt/AWTTreeChangeListenerWrapper.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.listener.awt; - -import java.awt.EventQueue; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Wrap another tree change listener and forward events to it on the AWT - * event queue. - */ -public class AWTTreeChangeListenerWrapper - implements TreeChangeListener -{ - private final TreeChangeListener listener; - - public AWTTreeChangeListenerWrapper(TreeChangeListener listener) { - super(); - if (listener == null) { - throw new NullPointerException(); - } - this.listener = listener; - } - - public void nodeAdded(TreeChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.nodeAdded_(event); - } else { - this.executeOnEventQueue(this.buildNodeAddedRunnable(event)); - } - } - - public void nodeRemoved(TreeChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.nodeRemoved_(event); - } else { - this.executeOnEventQueue(this.buildNodeRemovedRunnable(event)); - } - } - - public void treeCleared(TreeChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.treeCleared_(event); - } else { - this.executeOnEventQueue(this.buildTreeClearedRunnable(event)); - } - } - - public void treeChanged(TreeChangeEvent event) { - if (EventQueue.isDispatchThread()) { - this.treeChanged_(event); - } else { - this.executeOnEventQueue(this.buildTreeChangedRunnable(event)); - } - } - - private Runnable buildNodeAddedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeAdded_(event); - } - @Override - public String toString() { - return "node added"; - } - }; - } - - private Runnable buildNodeRemovedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.nodeRemoved_(event); - } - @Override - public String toString() { - return "node removed"; - } - }; - } - - private Runnable buildTreeClearedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeCleared_(event); - } - @Override - public String toString() { - return "tree cleared"; - } - }; - } - - private Runnable buildTreeChangedRunnable(final TreeChangeEvent event) { - return new Runnable() { - public void run() { - AWTTreeChangeListenerWrapper.this.treeChanged_(event); - } - @Override - public String toString() { - return "tree changed"; - } - }; - } - - /** - * EventQueue#invokeLater(Runnable) seems to work OK; - * but using #invokeAndWait(Runnable) can sometimes make things - * more predictable when debugging, at the risk of deadlocks. - */ - private void executeOnEventQueue(Runnable r) { - EventQueue.invokeLater(r); -// try { -// EventQueue.invokeAndWait(r); -// } catch (InterruptedException ex) { -// throw new RuntimeException(ex); -// } catch (java.lang.reflect.InvocationTargetException ex) { -// throw new RuntimeException(ex); -// } - } - - void nodeAdded_(TreeChangeEvent event) { - this.listener.nodeAdded(event); - } - - void nodeRemoved_(TreeChangeEvent event) { - this.listener.nodeRemoved(event); - } - - void treeCleared_(TreeChangeEvent event) { - this.listener.treeCleared(event); - } - - void treeChanged_(TreeChangeEvent event) { - this.listener.treeChanged(event); - } - - @Override - public String toString() { - return "AWT(" + this.listener.toString() + ")"; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java deleted file mode 100644 index 906c2e147c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AbstractTreeNodeValueModel.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import java.util.List; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ChainIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.TreeNodeValueModel; - -/** - * Subclasses need only implement the following methods: - * - * #value() - * return the user-determined "value" of the node, - * i.e. the object "wrapped" by the node - * - * #setValue(Object) - * set the user-determined "value" of the node, - * i.e. the object "wrapped" by the node; - * typically only overridden for nodes with "primitive" values - * - * #parent() - * return the parent of the node, which should be another - * TreeNodeValueModel - * - * #childrenModel() - * return a ListValueModel for the node's children - * - * #engageValue() and #disengageValue() - * override these methods to listen to the node's value if - * it can change in a way that should be reflected in the tree - */ -public abstract class AbstractTreeNodeValueModel<T> - extends AbstractModel - implements TreeNodeValueModel<T> -{ - - - // ********** constructors ********** - - /** - * Default constructor. - */ - protected AbstractTreeNodeValueModel() { - super(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - // this model fires *both* "value property change" and "state change" events... -// return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE); - return super.buildChangeSupport(); - } - - - // ********** extend AbstractModel implementation ********** - - /** - * Clients should be adding both "state change" and "value property change" - * listeners. - */ - @Override - public void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoStateChangeListeners()) { - this.engageValue(); - } - super.addStateChangeListener(listener); - } - - /** - * Begin listening to the node's value's state. If the state of the node changes - * in a way that should be reflected in the tree, fire a "state change" event. - */ - protected abstract void engageValue(); - - /** - * @see #addStateChangeListener(StateChangeListener) - */ - @Override - public void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoStateChangeListeners()) { - this.disengageValue(); - } - } - - /** - * Stop listening to the node's value. - * @see #engageValue() - */ - protected abstract void disengageValue(); - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - throw new UnsupportedOperationException(); - } - - - // ********** TreeNodeValueModel implementation ********** - - @SuppressWarnings("unchecked") - public TreeNodeValueModel<T>[] path() { - List<TreeNodeValueModel<T>> path = CollectionTools.reverseList(this.backPath()); - return path.toArray(new TreeNodeValueModel[path.size()]); - } - - /** - * Return an iterator that climbs up the node's path, - * starting with, and including, the node - * and up to, and including, the root node. - */ - protected Iterator<TreeNodeValueModel<T>> backPath() { - return new ChainIterator<TreeNodeValueModel<T>>(this) { - @Override - protected TreeNodeValueModel<T> nextLink(TreeNodeValueModel<T> currentLink) { - return currentLink.parent(); - } - }; - } - - public TreeNodeValueModel<T> child(int index) { - return this.childrenModel().get(index); - } - - public int childrenSize() { - return this.childrenModel().size(); - } - - public int indexOfChild(TreeNodeValueModel<T> child) { - ListValueModel<TreeNodeValueModel<T>> children = this.childrenModel(); - int size = children.size(); - for (int i = 0; i < size; i++) { - if (children.get(i) == child) { - return i; - } - } - return -1; - } - - public boolean isLeaf() { - return this.childrenModel().size() == 0; - } - - - // ********** standard methods ********** - - /** - * We implement #equals(Object) so that TreePaths containing these nodes - * will resolve properly when the nodes contain the same values. This is - * necessary because nodes are dropped and rebuilt willy-nilly when dealing - * with a sorted list of children; and this allows us to save and restore - * a tree's expanded paths. The nodes in the expanded paths that are - * saved before any modification (e.g. renaming a node) will be different - * from the nodes in the tree's paths after the modification, if the modification - * results in a possible change in the node sort order. ~bjv - */ - @Override - public boolean equals(Object o) { - if (o == null) { - return false; - } - if (o.getClass() != this.getClass()) { - return false; - } - @SuppressWarnings("unchecked") - AbstractTreeNodeValueModel<T> other = (AbstractTreeNodeValueModel<T>) o; - return this.getValue().equals(other.getValue()); - } - - @Override - public int hashCode() { - return this.getValue().hashCode(); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java deleted file mode 100644 index f7d33d56e3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectAdapter.java +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This abstract extension of AbstractModel provides a base for adding - * change listeners (PropertyChange, CollectionChange, ListChange, TreeChange) - * to a subject and converting the subject's change notifications into a single - * set of change notifications for a common aspect (e.g. VALUE). - * - * The adapter will only listen to the subject (and subject holder) when the - * adapter itself actually has listeners. This will allow the adapter to be - * garbage collected when appropriate - */ -public abstract class AspectAdapter<S> - extends AbstractModel -{ - /** - * The subject that holds the aspect and fires - * change notification when the aspect changes. - * We need to hold on to this directly so we can - * disengage it when it changes. - */ - protected S subject; - - /** - * A value model that holds the subject - * that holds the aspect and provides change notification. - * This is useful when there are a number of AspectAdapters - * that have the same subject and that subject can change. - * All the AspectAdapters should share the same subject holder. - * For now, this is can only be set upon construction and is - * immutable. - */ - protected final PropertyValueModel<? extends S> subjectHolder; - - /** A listener that keeps us in synch with the subjectHolder. */ - protected final PropertyChangeListener subjectChangeListener; - - - // ********** constructors ********** - - /** - * Construct an AspectAdapter for the specified subject. - */ - protected AspectAdapter(S subject) { - this(new StaticPropertyValueModel<S>(subject)); - } - - /** - * Construct an AspectAdapter for the specified subject holder. - * The subject holder cannot be null. - */ - protected AspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - super(); - if (subjectHolder == null) { - throw new NullPointerException(); - } - this.subjectHolder = subjectHolder; - this.subjectChangeListener = this.buildSubjectChangeListener(); - // the subject is null when we are not listening to it - // this will typically result in our value being null - this.subject = null; - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new LocalChangeSupport(this, this.getListenerClass(), this.getListenerAspectName()); - } - - /** - * The subject holder's value has changed, keep our subject in synch. - */ - protected PropertyChangeListener buildSubjectChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - AspectAdapter.this.subjectChanged(); - } - @Override - public String toString() { - return "subject change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * The subject has changed. Notify listeners that the value has changed. - */ - protected synchronized void subjectChanged() { - Object oldValue = this.getValue(); - boolean hasListeners = this.hasListeners(); - if (hasListeners) { - this.disengageSubject(); - } - this.subject = this.subjectHolder.getValue(); - if (hasListeners) { - this.engageSubject(); - this.fireAspectChange(oldValue, this.getValue()); - } - } - - /** - * Return the aspect's current value. - */ - protected abstract Object getValue(); - - /** - * Return the class of listener that is interested in the aspect adapter's - * changes. - */ - protected abstract Class<? extends ChangeListener> getListenerClass(); - - /** - * Return the name of the aspect adapter's aspect (e.g. VALUE). - * This is the name of the aspect adapter's single aspect, not the - * name of the subject's aspect the aspect adapter is adapting. - */ - protected abstract String getListenerAspectName(); - - /** - * Return whether there are any listeners for the aspect. - */ - protected abstract boolean hasListeners(); - - /** - * Return whether there are no listeners for the aspect. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * The aspect has changed, notify listeners appropriately. - */ - protected abstract void fireAspectChange(Object oldValue, Object newValue); - - protected void engageSubject() { - // check for nothing to listen to - if (this.subject != null) { - this.engageSubject_(); - } - } - - /** - * The subject is not null - add our listener. - */ - protected abstract void engageSubject_(); - - protected void disengageSubject() { - // check for nothing to listen to - if (this.subject != null) { - this.disengageSubject_(); - } - } - - /** - * The subject is not null - remove our listener. - */ - protected abstract void disengageSubject_(); - - protected void engageSubjectHolder() { - this.subjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener); - // synch our subject *after* we start listening to the subject holder, - // since its value might change when a listener is added - this.subject = this.subjectHolder.getValue(); - } - - protected void disengageSubjectHolder() { - this.subjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener); - // clear out the subject when we are not listening to its holder - this.subject = null; - } - - protected void engageModels() { - this.engageSubjectHolder(); - this.engageSubject(); - } - - protected void disengageModels() { - this.disengageSubject(); - this.disengageSubjectHolder(); - } - - - // ********** local change support ********** - - /** - * Extend change support to start listening to the aspect adapter's - * models (the subject holder and the subject itself) when the first - * relevant listener is added. - * Conversely, stop listening to the aspect adapter's models when the - * last relevant listener is removed. - * A relevant listener is a listener of the relevant type. - */ - protected class LocalChangeSupport extends SingleAspectChangeSupport { - private static final long serialVersionUID = 1L; - - public LocalChangeSupport(AspectAdapter<S> source, Class<? extends ChangeListener> listenerClass, String aspectName) { - super(source, listenerClass, aspectName); - } - - protected boolean listenerIsRelevant(Class<? extends ChangeListener> lClass) { - return lClass == this.listenerClass; - } - - protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> lClass) { - return this.listenerIsRelevant(lClass) - && this.hasNoListeners(lClass); - } - - protected boolean listenerIsRelevant(Class<? extends ChangeListener> lClass, String listenerAspectName) { - return this.listenerIsRelevant(lClass) - && (listenerAspectName == AspectAdapter.this.getListenerAspectName()); - } - - protected boolean hasNoRelevantListeners(Class<? extends ChangeListener> lClass, String listenerAspectName) { - return this.listenerIsRelevant(lClass, listenerAspectName) - && this.hasNoListeners(lClass, listenerAspectName); - } - - - // ********** overrides ********** - - @Override - protected <T extends ChangeListener> void addListener(Class<T> lClass, T listener) { - if (this.hasNoRelevantListeners(lClass)) { - AspectAdapter.this.engageModels(); - } - super.addListener(lClass, listener); - } - - @Override - protected <T extends ChangeListener> void addListener(String listenerAspectName, Class<T> lClass, T listener) { - if (this.hasNoRelevantListeners(lClass, listenerAspectName)) { - AspectAdapter.this.engageModels(); - } - super.addListener(listenerAspectName, lClass, listener); - } - - @Override - protected <T extends ChangeListener> void removeListener(Class<T> lClass, T listener) { - super.removeListener(lClass, listener); - if (this.hasNoRelevantListeners(lClass)) { - AspectAdapter.this.disengageModels(); - } - } - - @Override - protected <T extends ChangeListener> void removeListener(String listenerAspectName, Class<T> lClass, T listener) { - super.removeListener(listenerAspectName, lClass, listener); - if (this.hasNoRelevantListeners(lClass, listenerAspectName)) { - AspectAdapter.this.disengageModels(); - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java deleted file mode 100644 index 75853757ad..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/AspectPropertyValueModelAdapter.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current model value - * - */ -public abstract class AspectPropertyValueModelAdapter<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - /** - * Cache the current value so we can pass an "old value" when - * we fire a property change event. - * We need this because the value may be calculated and we may - * not able to derive the "old value" from the collection - * change event fired by the collection value model. - */ - protected T value; - - - // ********** constructor/initialization ********** - - protected AspectPropertyValueModelAdapter() { - super(); - // our value is null when we are not listening to the collection holder - this.value = null; - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, VALUE); - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the cached value. - */ - public T getValue() { - return this.value; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the wrapped collection if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addPropertyChangeListener(listener); - } - - /** - * Extend to start listening to the wrapped collection if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName == VALUE && this.hasNoListeners()) { - this.engageModel(); - } - super.addPropertyChangeListener(propertyName, listener); - } - - /** - * Extend to stop listening to the wrapped collection if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - super.removePropertyChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the wrapped collection if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName == VALUE && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether there are any listeners for the aspect. - */ - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - /** - * Return whether there are any listeners for the aspect. - */ - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - /** - * Start listening to the model and build the value. - */ - protected void engageModel() { - this.engageModel_(); - // synch our value *after* we start listening to the collection, - // since the collection's value might change when a listener is added - this.value = this.buildValue(); - } - - /** - * Start listening to the model. - */ - protected abstract void engageModel_(); - - /** - * Build and return the current value, as derived from the - * current state of the wrapped model. - */ - protected abstract T buildValue(); - - /** - * Stop listening to the model and clear the value. - */ - protected void disengageModel() { - this.disengageModel_(); - // clear out our value when we are not listening to the collection - this.value = null; - } - - /** - * Stop listening to the model. - */ - protected abstract void disengageModel_(); - - /** - * The wrapped model changed in some fashion. - * Recalculate the value and notify any listeners. - */ - protected void propertyChanged() { - Object old = this.value; - this.value = this.buildValue(); - this.firePropertyChanged(VALUE, old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java deleted file mode 100644 index 8781be4afd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/BufferedWritablePropertyValueModel.java +++ /dev/null @@ -1,345 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A BufferedPropertyValueModel is used to hold a temporary copy of the value - * in another property value model (the "wrapped" value holder). The application - * can modify this temporary copy, ad nauseam; but the temporary copy is only - * passed through to the "wrapped" value holder when the trigger "accepts" the - * buffered value. Alternatively, the application can "reset" the buffered value - * to the original, "wrapped" value. - * - * The trigger is another value model that holds a Boolean and the application - * changes the trigger's value to true on "accept", false on "reset". Typically, - * in a dialog: - * - pressing the OK button will trigger an "accept" and close the dialog - * - pressing the Cancel button will simply close the dialog, - * dropping the "buffered" values into the bit bucket - * - pressing the Apply button will trigger an "accept" and leave the dialog open - * - pressing the Restore button will trigger a "reset" and leave the dialog open - * - * A number of buffered property value models can wrap another set of - * property aspect adapters that adapt the various aspects of a single - * domain model. All the bufferd property value models can be hooked to the - * same trigger, and that trigger is controlled by the application, typically - * via the OK button in a dialog. - * - * @see PropertyAspectAdapter - */ -public class BufferedWritablePropertyValueModel<T> - extends PropertyValueModelWrapper<T> - implements WritablePropertyValueModel<T> -{ - - /** - * We cache the value here until it is accepted and passed - * through to the wrapped value holder. - */ - protected T bufferedValue; - - /** - * This is set to true when we are "accepting" the buffered value - * and passing it through to the wrapped value holder. This allows - * us to ignore the property change event fired by the wrapped - * value holder. - * (We can't stop listening to the wrapped value holder, because - * if we are the only listener that could "deactivate" the wrapped - * value holder.) - */ - protected boolean accepting; - - /** - * This is the trigger that indicates whether the buffered value - * should be accepted or reset. - */ - protected final PropertyValueModel<Boolean> triggerHolder; - - /** This listens to the trigger holder. */ - protected final PropertyChangeListener triggerChangeListener; - - /** - * This flag indicates whether our buffered value has been assigned - * a value and is possibly out of synch with the wrapped value. - */ - protected boolean buffering; - - - // ********** constructors ********** - - /** - * Construct a buffered property value model with the specified wrapped - * property value model and trigger holder. - */ - public BufferedWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, PropertyValueModel<Boolean> triggerHolder) { - super(valueHolder); - if (triggerHolder == null) { - throw new NullPointerException(); - } - this.triggerHolder = triggerHolder; - this.bufferedValue = null; - this.buffering = false; - this.accepting = false; - this.triggerChangeListener = this.buildTriggerChangeListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildTriggerChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - BufferedWritablePropertyValueModel.this.triggerChanged(event); - } - @Override - public String toString() { - return "trigger change listener"; - } - }; - } - - - // ********** ValueModel implementation ********** - - /** - * If we are currently "buffering" a value, return that; - * otherwise, return the wrapped value. - */ - public T getValue() { - return this.buffering ? this.bufferedValue : this.valueHolder.getValue(); - } - - /** - * Assign the new value to our "buffered" value. - * It will be forwarded to the wrapped value holder - * when the trigger is "accepted". - */ - public void setValue(T value) { - Object old = this.getValue(); - this.bufferedValue = value; - this.buffering = true; - this.firePropertyChanged(VALUE, old, this.bufferedValue); - } - - - // ********** PropertyValueModelWrapper extensions ********** - - /** - * extend to engage the trigger holder also - */ - @Override - protected void engageValueHolder() { - super.engageValueHolder(); - this.triggerHolder.addPropertyChangeListener(VALUE, this.triggerChangeListener); - } - - /** - * extend to disengage the trigger holder also - */ - @Override - protected void disengageValueHolder() { - this.triggerHolder.removePropertyChangeListener(VALUE, this.triggerChangeListener); - super.disengageValueHolder(); - } - - - // ********** behavior ********** - - /** - * If we do not yet have a "buffered" value, simply propagate the - * change notification with the buffered model as the source. - * If we do have a "buffered" value, do nothing. - */ - @Override - protected void valueChanged(PropertyChangeEvent event) { - if (this.accepting) { - // if we are currently "accepting" the value, ignore change notifications, - // since we caused them and our own listeners are already aware of the change - return; - } - if (this.buffering) { - this.handleChangeConflict(event); - } else { - this.firePropertyChanged(event.cloneWithSource(this)); - } - } - - /** - * By default, if we have a "buffered" value and the "wrapped" value changes, - * we simply ignore the new "wrapped" value and simply overlay it with the - * "buffered" value if it is "accepted". ("Last One In Wins" concurrency model) - * Subclasses can override this method to change that behavior with a - * different concurrency model. For example, you could drop the "buffered" value - * and replace it with the new "wrapped" value, or you could throw an - * exception. - */ - protected void handleChangeConflict(PropertyChangeEvent event) { - // the default is to do nothing - } - - /** - * The trigger changed: - * If it is now true, "accept" the buffered value and forward - * it to the wrapped value holder. - * If it is now false, "reset" the buffered value to its original value. - */ - protected void triggerChanged(PropertyChangeEvent event) { - if ( ! this.buffering) { - // if nothing has been "buffered", we don't need to do anything: - // nothing needs to be passed through; nothing needs to be reset; - return; - } - if (((Boolean) event.getNewValue()).booleanValue()) { - // set the accepting flag so we ignore any events - // fired by the wrapped value holder - this.accepting = true; - this.valueHolder().setValue(this.bufferedValue); - this.bufferedValue = null; - this.buffering = false; - // clear the flag once the "accept" is complete - this.accepting = false; - } else { - // notify our listeners that our value has been reset - Object old = this.bufferedValue; - this.bufferedValue = null; - this.buffering = false; - this.firePropertyChanged(VALUE, old, this.valueHolder.getValue()); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getValue()); - } - - - // ********** convenience methods ********** - - /** - * Return whether the buffered model is currently "buffering" - * a value. - */ - public boolean isBuffering() { - return this.buffering; - } - - /** - * Our constructor accepts only a WritablePropertyValueModel<T>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - - // ********** inner class ********** - - /** - * Trigger is a special property value model that only maintains its - * value (of true or false) during the change notification caused by - * the #setValue(Object) method. In other words, a Trigger object - * only has a valid value - */ - public static class Trigger extends SimplePropertyValueModel<Boolean> { - - - // ********** constructor ********** - - /** - * Construct a trigger with a null value. - */ - public Trigger() { - super(); - } - - - // ********** ValueModel implementation ********** - - /** - * Extend so that this method can only be invoked during - * change notification triggered by #setValue(Object). - */ - @Override - public Boolean getValue() { - if (this.value == null) { - throw new IllegalStateException("The method Trigger.value() may only be called during change notification."); - } - return this.value; - } - - /** - * Extend to reset the value to null once all the - * listeners have been notified. - */ - @Override - public void setValue(Boolean value) { - super.setValue(value); - this.value = null; - } - - - // ********** convenience methods ********** - - /** - * Set the trigger's value: - * - true indicates "accept" - * - false indicates "reset" - */ - public void setValue(boolean value) { - this.setValue(Boolean.valueOf(value)); - } - - /** - * Return the trigger's value: - * - true indicates "accept" - * - false indicates "reset" - */ - public boolean booleanValue() { - return this.getValue().booleanValue(); - } - - /** - * Accept the trigger (i.e. set its value to true). - */ - public void accept() { - this.setValue(true); - } - - /** - * Return whether the trigger has been accepted - * (i.e. its value was changed to true). - */ - public boolean isAccepted() { - return this.booleanValue(); - } - - /** - * Reset the trigger (i.e. set its value to false). - */ - public void reset() { - this.setValue(false); - } - - /** - * Return whether the trigger has been reset - * (i.e. its value was changed to false). - */ - public boolean isReset() { - return ! this.booleanValue(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationPropertyValueModel.java deleted file mode 100644 index a2d1e6157d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationPropertyValueModel.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A <code>CachingTransformationPropertyValueModel</code> wraps another - * <code>PropertyValueModel</code> and uses a <code>Transformer</code> - * to transform the wrapped value before it is returned by <code>getValue()</code>. - * The transformed value is calculated and cached during initialization and every - * time the wrapped value changes. This can be useful when the old value - * passed in to <code>valueChanged(PropertyChangeEvent)</code> can no longer - * be "transformed" because its state is no longer valid. - * This caching can also improve time performance in some situations. - * <p> - * As an alternative to building a <code>Transformer</code>, - * a subclass of <code>CachingTransformationPropertyValueModel</code> can - * either override the <code>transform_(Object)</code> method or, - * if something other than null should be returned when the wrapped value - * is null, override the <code>transform(Object)</code> method. - */ -public class CachingTransformationPropertyValueModel<T1, T2> - extends TransformationPropertyValueModel<T1, T2> -{ - - /** - * Cache the transformed value so that during property change event notification - * we do not have to transform the old value. The old value could no longer be valid in - * the model; as a result, transforming it would not be valid. - */ - protected T2 cachedValue; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified nested - * property value model and the default transformer. - * Use this constructor if you want to override the - * <code>transform_(Object)</code> or <code>transform(Object)</code> - * method instead of building a <code>Transformer</code>. - */ - public CachingTransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct an property value model with the specified nested - * property value model and transformer. - */ - public CachingTransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder, Transformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - - // ********** behavior ********** - - /** - * We have listeners, transform the nested value and cache the result. - */ - @Override - protected void engageValueHolder() { - super.engageValueHolder(); - this.cachedValue = this.transform(this.valueHolder.getValue()); - } - - /** - * We have no more listeners, clear the cached value. - */ - @Override - protected void disengageValueHolder() { - this.cachedValue = null; - super.disengageValueHolder(); - } - - /** - * No need to transform the nested value, simply return the cached value, - * which is already transformed. - */ - @Override - public T2 getValue() { - return this.cachedValue; - } - - /** - * Transform the specified new value, caching it before returning it. - */ - @Override - protected T2 transformNew(T1 value) { - this.cachedValue = super.transformNew(value); - return this.cachedValue; - } - - /** - * No need to transform the old value, simply return the cached value, - * which is already transformed. - */ - @Override - protected T2 transformOld(T1 value) { - return this.cachedValue; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java deleted file mode 100644 index 18b6ce0bdc..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CachingTransformationWritablePropertyValueModel.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.BidiTransformer; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>CachingTransformationWritablePropertyValueModel<code> augments the - * behavior of a <code>TransformationWritablePropertyValueModel<code> by caching - * the transformed value. - * The transformed value is calculated and cached during initialization and every - * time the wrapped value changes. This can be useful when the old value - * passed in to <code>valueChanged(PropertyChangeEvent)</code> can no longer - * be "transformed" because its state is no longer valid. - * This caching can also improve time performance in some situations. - */ -public class CachingTransformationWritablePropertyValueModel<T1, T2> - extends TransformationWritablePropertyValueModel<T1, T2> -{ - - /** - * Cache the transformed value so that during property change event notification - * we do not have to transform the old value. The old value could no longer be valid in - * the model; as a result, transforming it would not be valid. - */ - protected T2 cachedValue; - - - // ********** constructors/initialization ********** - - /** - * Construct a writable property value model with the specified nested - * writable property value model and the default bidi transformer. - * Use this constructor if you want to override the - * <code>transform_(Object)</code> and <code>reverseTransform_(Object)</code> - * (or <code>transform(Object)</code> and <code>reverseTransform(Object)</code>) - * methods instead of building a <code>BidiTransformer</code>. - */ - public CachingTransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct a writable property value model with the specified nested - * writable property value model and bidi transformer. - */ - public CachingTransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder, BidiTransformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - - // ********** behavior ********** - - /** - * We have listeners, transform the nested value and cache the result. - */ - @Override - protected void engageValueHolder() { - super.engageValueHolder(); - this.cachedValue = this.transform(this.valueHolder.getValue()); - } - - /** - * We have no more listeners, clear the cached value. - */ - @Override - protected void disengageValueHolder() { - this.cachedValue = null; - super.disengageValueHolder(); - } - - /** - * No need to transform the nested value, simply return the cached value, - * which is already transformed. - */ - @Override - public T2 getValue() { - return this.cachedValue; - } - - /** - * Transform the specified new value, caching it before returning it. - */ - @Override - protected T2 transformNew(T1 value) { - this.cachedValue = super.transformNew(value); - return this.cachedValue; - } - - /** - * No need to transform the old value, simply return the cached value, - * which is already transformed. - */ - @Override - protected T2 transformOld(T1 value) { - return this.cachedValue; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java deleted file mode 100644 index f55783e8a9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionAspectAdapter.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides CollectionChange support. - * This allows us to convert a set of one or more collections into - * a single collection, VALUES. - * - * The typical subclass will override the following methods: - * #iterator_() - * at the very minimum, override this method to return an iterator on the - * subject's collection aspect; it does not need to be overridden if - * #iterator() is overridden and its behavior changed - * #size_() - * override this method to improve performance; it does not need to be overridden if - * #size() is overridden and its behavior changed - * #iterator() - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - * #size() - * override this method only if returning a zero when the - * subject is null is unacceptable - */ -public abstract class CollectionAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements CollectionValueModel<E> -{ - /** - * The name of the subject's collections that we use for the value. - */ - protected final String[] collectionNames; - protected static final String[] EMPTY_COLLECTION_NAMES = new String[0]; - - /** A listener that listens to the subject's collection aspect. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructors ********** - - /** - * Construct a CollectionAspectAdapter for the specified subject - * and collection. - */ - protected CollectionAspectAdapter(String collectionName, S subject) { - this(new String[] {collectionName}, subject); - } - - /** - * Construct a CollectionAspectAdapter for the specified subject - * and collections. - */ - protected CollectionAspectAdapter(String[] collectionNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), collectionNames); - } - - /** - * Construct a CollectionAspectAdapter for the specified subject holder - * and collections. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... collectionNames) { - super(subjectHolder); - this.collectionNames = collectionNames; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - /** - * Construct a CollectionAspectAdapter for the specified subject holder - * and collections. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> collectionNames) { - this(subjectHolder, collectionNames.toArray(new String[collectionNames.size()])); - } - - /** - * Construct a CollectionAspectAdapter for an "unchanging" collection in - * the specified subject. This is useful for a collection aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new collection. - */ - protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_COLLECTION_NAMES); - } - - - // ********** initialization ********** - - /** - * The subject's collection aspect has changed, notify the listeners. - */ - protected CollectionChangeListener buildCollectionChangeListener() { - // transform the subject's collection change events into VALUE collection change events - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionAspectAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionAspectAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionAspectAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener: " + Arrays.asList(CollectionAspectAdapter.this.collectionNames); - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - /** - * Return the elements of the subject's collection aspect. - */ - public Iterator<E> iterator() { - return (this.subject == null) ? EmptyIterator.<E>instance() : this.iterator_(); - } - - /** - * Return the elements of the subject's collection aspect. - * At this point we can be sure that the subject is not null. - * @see #iterator() - */ - protected Iterator<E> iterator_() { - throw new UnsupportedOperationException(); - } - - /** - * Return the size of the subject's collection aspect. - */ - public int size() { - return (this.subject == null) ? 0 : this.size_(); - } - - /** - * Return the size of the subject's collection aspect. - * At this point we can be sure that the subject is not null. - * @see #size() - */ - protected int size_() { - return CollectionTools.size(this.iterator()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUES); - } - - @Override - protected void engageSubject_() { - for (String collectionName : this.collectionNames) { - ((Model) this.subject).addCollectionChangeListener(collectionName, this.collectionChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String collectionName : this.collectionNames) { - ((Model) this.subject).removeCollectionChangeListener(collectionName, this.collectionChangeListener); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.collectionNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.collectionNames[i]); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(CollectionChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, VALUES)); - } - - protected void itemsRemoved(CollectionChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, VALUES)); - } - - protected void collectionCleared(CollectionChangeEvent event) { - this.fireCollectionCleared(VALUES); // nothing from original event to forward - } - - protected void collectionChanged(CollectionChangeEvent event) { - this.fireCollectionChanged(VALUES); // nothing from original event to forward - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java deleted file mode 100644 index 6c236ab78f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionListValueModelAdapter.java +++ /dev/null @@ -1,296 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a CollectionValueModel behave like - * a read-only ListValueModel, sorta. - * - * To maintain a reasonably consistent appearance to client code, we - * keep an internal list somewhat in synch with the wrapped collection. - * - * NB: Since we only listen to the wrapped collection when we have - * listeners ourselves and we can only stay in synch with the wrapped - * collection while we are listening to it, results to various methods - * (e.g. #size(), getItem(int)) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - */ -public class CollectionListValueModelAdapter<E> - extends AbstractModel - implements ListValueModel<E> -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<? extends E> collectionHolder; - - /** A listener that forwards any events fired by the collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - /** - * Our internal list, which holds the same elements as - * the wrapped collection, but keeps them in order. - */ - // we declare this an ArrayList so we can use #clone() and #ensureCapacity(int) - protected final ArrayList<E> list; - - - // ********** constructors ********** - - /** - * Wrap the specified CollectionValueModel. - */ - public CollectionListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - super(); - if (collectionHolder == null) { - throw new NullPointerException(); - } - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - this.list = new ArrayList<E>(); - // postpone building the list and listening to the underlying collection - // until we have listeners ourselves... - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - /** - * The wrapped collection has changed, forward an equivalent - * list change event to our listeners. - */ - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionListValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.list); - } - - public E get(int index) { - return this.list.get(index); - } - - public int size() { - return this.list.size(); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the collection holder if necessary. - */ - @Override - public void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Override to start listening to the collection holder if necessary. - */ - @Override - public void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Override to stop listening to the collection holder if appropriate. - */ - @Override - public void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the collection holder if appropriate. - */ - @Override - public void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return the index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.list.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.list.get(i) == o) { - return i; - } - } - return -1; - } - - - // ********** behavior ********** - - protected void buildList() { - Iterator<? extends E> stream = this.collectionHolder.iterator(); - // if the new collection is empty, do nothing - if (stream.hasNext()) { - this.list.ensureCapacity(this.collectionHolder.size()); - while (stream.hasNext()) { - this.list.add(stream.next()); - } - this.postBuildList(); - } - } - - /** - * Allow subclasses to manipulate the internal list before - * sending out change notification. - */ - protected void postBuildList() { - // the default is to do nothing... - } - - protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - // synch our list *after* we start listening to the collection holder, - // since its value might change when a listener is added - this.buildList(); - } - - protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - // clear out the list when we are not listening to the collection holder - this.list.clear(); - } - - protected void itemsAdded(CollectionChangeEvent e) { - this.addItemsToList(this.indexToAddItems(), CollectionTools.list(this.items(e)), this.list, LIST_VALUES); - } - - protected int indexToAddItems() { - return this.list.size(); - } - - @SuppressWarnings("unchecked") - protected Iterator<E> items(CollectionChangeEvent e) { - return (Iterator<E>) e.items(); - } - - protected void itemsRemoved(CollectionChangeEvent e) { - // we have to remove the items individually, - // since they are probably not in sequence - for (Iterator<E> stream = this.items(e); stream.hasNext(); ) { - this.removeItemFromList(this.lastIdentityIndexOf(stream.next()), this.list, LIST_VALUES); - } - } - - protected void collectionCleared(CollectionChangeEvent e) { - this.clearList(this.list, LIST_VALUES); - } - - /** - * synchronize our internal list with the wrapped collection - * and fire the appropriate events - */ - protected void collectionChanged(CollectionChangeEvent e) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.list.isEmpty()) { - @SuppressWarnings("unchecked") - ArrayList<E> removedItems = (ArrayList<E>) this.list.clone(); - this.list.clear(); - this.fireItemsRemoved(LIST_VALUES, 0, removedItems); - } - - this.buildList(); - // put in empty check so we don't fire events unnecessarily - if ( ! this.list.isEmpty()) { - this.fireItemsAdded(LIST_VALUES, 0, this.list); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java deleted file mode 100644 index a28ff711db..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionPropertyValueModelAdapter.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a collection value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current collection value - * - * Subclasses might want to override: - * - #itemsAdded(CollectionChangeEvent event) - * - #itemsRemoved(CollectionChangeEvent event) - * - #collectionCleared(CollectionChangeEvent event) - * - #collectionChanged(CollectionChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class CollectionPropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<T> -{ - /** The wrapped collection value model. */ - protected final CollectionValueModel<?> collectionHolder; - - /** A listener that allows us to synch with changes to the wrapped collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * collection value model. - */ - protected CollectionPropertyValueModelAdapter(CollectionValueModel<?> collectionHolder) { - super(); - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionPropertyValueModelAdapter.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the collection holder. - */ - @Override - protected void engageModel_() { - this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - /** - * Stop listening to the collection holder. - */ - @Override - protected void disengageModel_() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were removed from the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected void itemsRemoved(CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped collection holder was cleared; - * propagate the change notification appropriately. - */ - protected void collectionCleared(CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The value of the wrapped collection holder has changed; - * propagate the change notification appropriately. - */ - protected void collectionChanged(CollectionChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java deleted file mode 100644 index 4190fe1d41..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CollectionValueModelWrapper.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another collection value model, "lazily" listen to it, and propagate - * its change notifications. - */ -public abstract class CollectionValueModelWrapper<E> - extends AbstractModel -{ - - /** The wrapped collection value model. */ - protected final CollectionValueModel<? extends E> collectionHolder; - - /** A listener that allows us to synch with changes to the wrapped collection holder. */ - protected final CollectionChangeListener collectionChangeListener; - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model. - */ - protected CollectionValueModelWrapper(CollectionValueModel<? extends E> collectionHolder) { - super(); - this.collectionHolder = collectionHolder; - this.collectionChangeListener = this.buildCollectionChangeListener(); - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, CollectionValueModel.VALUES); - } - - protected CollectionChangeListener buildCollectionChangeListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.itemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.collectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CollectionValueModelWrapper.this.collectionChanged(event); - } - @Override - public String toString() { - return "collection change listener"; - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == CollectionValueModel.VALUES && this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == CollectionValueModel.VALUES && this.hasNoCollectionChangeListeners(CollectionValueModel.VALUES)) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the collection holder. - */ - protected void engageModel() { - this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - /** - * Stop listening to the collection holder. - */ - protected void disengageModel() { - this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterator<E> items(CollectionChangeEvent event) { - return (Iterator<E>) event.items(); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collectionHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(CollectionChangeEvent event); - - /** - * Items were removed from the wrapped collection holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(CollectionChangeEvent event); - - /** - * The wrapped collection holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void collectionCleared(CollectionChangeEvent event); - - /** - * The value of the wrapped collection holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void collectionChanged(CollectionChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java deleted file mode 100644 index 815e48e54c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeCollectionValueModel.java +++ /dev/null @@ -1,406 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.NullList; -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>CompositeCollectionValueModel</code> wraps another - * <code>CollectionValueModel</code> and uses a <code>Transformer</code> - * to convert each item in the wrapped collection to yet another - * <code>CollectionValueModel</code>. This composite collection contains - * the combined items from all these component collections. - * - * NB: The wrapped collection must be an "identity set" that does not - * contain the same item twice or this class will throw an exception. - * - * Terminology: - * - sources - the items in the wrapped collection value model; these - * are converted into component CVMs by the transformer - * - component CVMs - the component collection value models that are combined - * by this composite collection value model - * - items - the items held by the component CVMs - */ -public class CompositeCollectionValueModel<E1, E2> - extends CollectionValueModelWrapper<E1> - implements CollectionValueModel<E2> -{ - /** - * This is the (optional) user-supplied object that transforms - * the items in the wrapped collection to collection value models. - */ - private final Transformer<E1, CollectionValueModel<E2>> transformer; - - /** - * Cache of the component collection value models that - * were generated by the transformer; keyed by the item - * in the wrapped collection that was passed to the transformer. - */ - private final IdentityHashMap<E1, CollectionValueModel<E2>> componentCVMs; - - /** - * Cache of the collections corresponding to the component - * collection value models above; keyed by the component - * collection value models. - * Use ArrayLists so we can use ArrayList-specific methods - * (e.g. #clone() and #ensureCapacity()). - */ - private final IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>> collections; - - /** Listener that listens to all the component collection value models. */ - private final CollectionChangeListener componentCVMListener; - - /** Cache the size of the composite collection. */ - private int size; - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model. Use this constructor if - * - the wrapped collection value model already contains other - * collection value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionHolder) { - this(collectionHolder, Transformer.Null.<E1, CollectionValueModel<E2>>instance()); - } - - /** - * Construct a collection value model with the specified wrapped - * collection value model and transformer. - */ - public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, CollectionValueModel<E2>> transformer) { - super(collectionHolder); - this.transformer = transformer; - this.componentCVMs = new IdentityHashMap<E1, CollectionValueModel<E2>>(); - this.collections = new IdentityHashMap<CollectionValueModel<E2>, ArrayList<E2>>(); - this.componentCVMListener = this.buildComponentListener(); - this.size = 0; - } - - /** - * Construct a collection value model with the specified wrapped - * list value model. Use this constructor if - * - the wrapped list value model already contains collection - * value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - public CompositeCollectionValueModel(ListValueModel<? extends E1> listHolder) { - this(new ListCollectionValueModelAdapter<E1>(listHolder)); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and transformer. - */ - public CompositeCollectionValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, CollectionValueModel<E2>> transformer) { - this(new ListCollectionValueModelAdapter<E1>(listHolder), transformer); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection. Use this constructor if - * - the wrapped collection already contains collection - * value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - public CompositeCollectionValueModel(Collection<? extends E1> collection) { - this(new StaticCollectionValueModel<E1>(collection)); - } - - /** - * Construct a collection value model with the specified, unchanging, wrapped - * collection and transformer. - */ - public CompositeCollectionValueModel(Collection<? extends E1> collection, Transformer<E1, CollectionValueModel<E2>> transformer) { - this(new StaticCollectionValueModel<E1>(collection), transformer); - } - - - // ********** initialization ********** - - protected CollectionChangeListener buildComponentListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentItemsRemoved(event); - } - public void collectionCleared(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentCollectionCleared(event); - } - public void collectionChanged(CollectionChangeEvent event) { - CompositeCollectionValueModel.this.componentCollectionChanged(event); - } - @Override - public String toString() { - return "component listener"; - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E2> iterator() { - return new CompositeIterator<E2>(this.buildCollectionsIterators()); - } - - protected Iterator<Iterator<E2>> buildCollectionsIterators() { - return new TransformationIterator<ArrayList<E2>, Iterator<E2>>(this.collections.values().iterator()) { - @Override - protected Iterator<E2> transform(ArrayList<E2> next) { - return next.iterator(); - } - }; - } - - public int size() { - return this.size; - } - - - // ********** CollectionValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the wrapped collection, - // since its value might change when a listener is added - this.addAllComponentSources(); - } - - /** - * Transform all the sources to collection value models - * and add their items to our cache, with no event notification. - */ - protected void addAllComponentSources() { - for (E1 source : this.collectionHolder) { - this.addComponentSource(source, NullList.<E2>instance()); - } - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // stop listening to the components... - for (CollectionValueModel<E2> componentCVM : this.componentCVMs.values()) { - componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener); - } - // ...and clear the cache - this.componentCVMs.clear(); - this.collections.clear(); - this.size = 0; - } - - /** - * Some component sources were added; - * add their corresponding items to our cache. - */ - @Override - protected void itemsAdded(CollectionChangeEvent event) { - ArrayList<E2> addedItems = new ArrayList<E2>(); - for (Iterator<E1> stream = this.items(event); stream.hasNext(); ) { - this.addComponentSource(stream.next(), addedItems); - } - this.fireItemsAdded(VALUES, addedItems); - } - - /** - * Transform the specified source to a collection value model - * and add its items to our cache and the "collecting parameter". - */ - protected void addComponentSource(E1 source, List<E2> addedItems) { - CollectionValueModel<E2> componentCVM = this.transform(source); - if (this.componentCVMs.put(source, componentCVM) != null) { - throw new IllegalStateException("duplicate component: " + source); - } - componentCVM.addCollectionChangeListener(VALUES, this.componentCVMListener); - ArrayList<E2> componentCollection = new ArrayList<E2>(componentCVM.size()); - if (this.collections.put(componentCVM, componentCollection) != null) { - throw new IllegalStateException("duplicate collection: " + source); - } - this.addComponentItems(componentCVM, componentCollection); - addedItems.addAll(componentCollection); - } - - /** - * Add the items in the specified component CVM to the specified component - * collection. - */ - protected void addComponentItems(CollectionValueModel<E2> componentCVM, ArrayList<E2> componentCollection) { - int itemsSize = componentCVM.size(); - this.size += itemsSize; - componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - CollectionTools.addAll(componentCollection, componentCVM); - } - - /** - * Some component sources were removed; - * remove their corresponding items from our cache. - */ - @Override - protected void itemsRemoved(CollectionChangeEvent event) { - ArrayList<E2> removedItems = new ArrayList<E2>(); - for (Iterator<E1> stream = this.items(event); stream.hasNext(); ) { - this.removeComponentSource(stream.next(), removedItems); - } - this.fireItemsRemoved(VALUES, removedItems); - } - - /** - * Remove the items corresponding to the specified source - * from our cache. - */ - protected void removeComponentSource(E1 source, List<E2> removedItems) { - CollectionValueModel<E2> componentCVM = this.componentCVMs.remove(source); - if (componentCVM == null) { - throw new IllegalStateException("missing component: " + source); - } - componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener); - ArrayList<E2> componentCollection = this.collections.remove(componentCVM); - if (componentCollection == null) { - throw new IllegalStateException("missing collection: " + source); - } - removedItems.addAll(componentCollection); - this.removeComponentItems(componentCollection); - } - - /** - * Update our size and collection cache. - */ - protected void removeComponentItems(ArrayList<E2> componentCollection) { - this.size -= componentCollection.size(); - componentCollection.clear(); - } - - /** - * The component sources cleared; - * clear our cache. - */ - @Override - protected void collectionCleared(CollectionChangeEvent event) { - this.removeAllComponentSources(); - this.fireCollectionCleared(VALUES); - } - - protected void removeAllComponentSources() { - // copy the keys so we don't eat our own tail - ArrayList<E1> copy = new ArrayList<E1>(this.componentCVMs.keySet()); - for (E1 source : copy) { - this.removeComponentSource(source, NullList.<E2>instance()); - } - } - - /** - * The component sources changed; - * rebuild our cache. - */ - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.removeAllComponentSources(); - this.addAllComponentSources(); - this.fireCollectionChanged(VALUES); - } - - - // ********** internal methods ********** - - /** - * Transform the specified object into a collection value model. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Transformer</code>. - */ - protected CollectionValueModel<E2> transform(E1 value) { - return this.transformer.transform(value); - } - - /** - * One of the component collections had items added; - * synchronize our caches. - */ - protected void componentItemsAdded(CollectionChangeEvent event) { - int itemsSize = event.itemsSize(); - this.size += itemsSize; - - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - componentCollection.ensureCapacity(componentCollection.size() + itemsSize); - - this.addItemsToCollection(this.componentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections had items removed; - * synchronize our caches. - */ - protected void componentItemsRemoved(CollectionChangeEvent event) { - this.size -= event.itemsSize(); - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - this.removeItemsFromCollection(this.componentItems(event), componentCollection, VALUES); - } - - /** - * One of the component collections was cleared; - * synchronize our caches by clearing out the appropriate - * collection. - */ - protected void componentCollectionCleared(CollectionChangeEvent event) { - ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event)); - ArrayList<E2> removedItems = new ArrayList<E2>(componentCollection); - this.removeComponentItems(componentCollection); - this.fireItemsRemoved(VALUES, removedItems); - } - - /** - * One of the component collections changed; - * synchronize our caches by clearing out the appropriate - * collection and then rebuilding it. - */ - protected void componentCollectionChanged(CollectionChangeEvent event) { - CollectionValueModel<E2> componentCVM = this.componentCVM(event); - ArrayList<E2> componentCollection = this.collections.get(componentCVM); - this.removeComponentItems(componentCollection); - this.addComponentItems(componentCVM, componentCollection); - this.fireCollectionChanged(VALUES); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected Iterator<E2> componentItems(CollectionChangeEvent event) { - return (Iterator<E2>) event.items(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected CollectionValueModel<E2> componentCVM(CollectionChangeEvent event) { - return (CollectionValueModel<E2>) event.getSource(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java deleted file mode 100644 index 3609d5a4dd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/CompositeListValueModel.java +++ /dev/null @@ -1,574 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>CompositeListValueModel</code> wraps another - * <code>ListValueModel</code> and uses a <code>Transformer</code> - * to convert each item in the wrapped list to yet another - * <code>ListValueModel</code>. This composite list contains - * the combined items from all these component lists. - * - * Terminology: - * - sources - the items in the wrapped list value model; these - * are converted into component LVMs by the transformer - * - componentLVMs - the component list value models that are combined - * by this composite list value model - * - items - the items held by the component LVMs - */ -public class CompositeListValueModel<E1, E2> - extends ListValueModelWrapper<E1> - implements ListValueModel<E2> -{ - /** - * This is the (optional) user-supplied object that transforms - * the items in the wrapped list to list value models. - */ - private final Transformer<E1, ListValueModel<E2>> transformer; - - /** - * Cache of the sources, component LVMs, lists. - */ - private final ArrayList<Info> infoList; - protected class Info { - // the object passed to the transformer - final E1 source; - // the list value model generated by the transformer - final ListValueModel<E2> componentLVM; - // cache of the items held by the component LVM - final ArrayList<E2> items; - // the component LVM's beginning index within the composite LVM - int begin; - Info(E1 source, ListValueModel<E2> componentLVM, ArrayList<E2> items, int begin) { - super(); - this.source = source; - this.componentLVM = componentLVM; - this.items = items; - this.begin = begin; - } - } - - /** Listener that listens to all the component list value models. */ - private final ListChangeListener componentLVMListener; - - /** Cache the size of the composite list. */ - private int size; - - - // ********** constructors ********** - - /** - * Construct a list value model with the specified wrapped - * list value model. Use this constructor if - * - the wrapped list value model already contains other - * list value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - public CompositeListValueModel(ListValueModel<? extends E1> listHolder) { - this(listHolder, Transformer.Null.<E1, ListValueModel<E2>>instance()); - } - - /** - * Construct a list value model with the specified wrapped - * list value model and transformer. - */ - public CompositeListValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, ListValueModel<E2>> transformer) { - super(listHolder); - this.transformer = transformer; - this.infoList = new ArrayList<Info>(); - this.componentLVMListener = this.buildComponentLVMListener(); - this.size = 0; - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list. Use this constructor if - * - the wrapped list already contains list value models or - * - you want to override the <code>transform(E1)</code> method - * instead of building a <code>Transformer</code> - */ - public CompositeListValueModel(List<? extends E1> list) { - this(new StaticListValueModel<E1>(list)); - } - - /** - * Construct a list value model with the specified, unchanging, wrapped - * list and transformer. - */ - public CompositeListValueModel(List<? extends E1> list, Transformer<E1, ListValueModel<E2>> transformer) { - this(new StaticListValueModel<E1>(list), transformer); - } - - - // ********** initialization ********** - - protected ListChangeListener buildComponentLVMListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - CompositeListValueModel.this.componentItemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - CompositeListValueModel.this.componentListCleared(event); - } - public void listChanged(ListChangeEvent event) { - CompositeListValueModel.this.componentListChanged(event); - } - @Override - public String toString() { - return "component LVM listener"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public E2 get(int index) { - if ((index < 0) || (index >= this.size)) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size); - } - // move backwards through the info list - for (int i = this.infoList.size(); i-- > 0; ) { - Info info = this.infoList.get(i); - if (index >= info.begin) { - return info.items.get(index - info.begin); - } - } - throw new IllegalStateException(); // something is wack - } - - public Iterator<E2> iterator() { - return this.listIterator(); - } - - public ListIterator<E2> listIterator() { - return new ReadOnlyCompositeListIterator<E2>(this.buildListsIterators()); - } - - protected ListIterator<ListIterator<E2>> buildListsIterators() { - return new TransformationListIterator<Info, ListIterator<E2>>(this.infoList.listIterator()) { - @Override - protected ListIterator<E2> transform(Info info) { - return info.items.listIterator(); - } - }; - } - - public int size() { - return this.size; - } - - public Object[] toArray() { - return CollectionTools.array(this.listIterator(), this.size); - } - - - // ********** ListValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the wrapped list, - // since its value might change when a listener is added - this.addComponentSources(0, this.listHolder.listIterator(), this.listHolder.size()); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // stop listening to the component LVMs... - for (Info info : this.infoList) { - info.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener); - } - // ...and clear the cache - this.infoList.clear(); - this.size = 0; - } - - /** - * Some component sources were added; update our cache. - */ - @Override - protected void itemsAdded(ListChangeEvent event) { - this.addComponentSources(event.getIndex(), this.items(event), event.itemsSize(), true); // true = fire event - } - - /** - * Do not fire an event. - */ - protected void addComponentSources(int addedSourcesIndex, ListIterator<? extends E1> addedSources, int addedSourcesSize) { - this.addComponentSources(addedSourcesIndex, addedSources, addedSourcesSize, false); // false = do not fire event - } - - /** - * Add infos corresponding to the specified sources to our cache. - * Fire the appropriate event if requested. - */ - protected void addComponentSources(int addedSourcesIndex, ListIterator<? extends E1> addedSources, int addedSourcesSize, boolean fireEvent) { - ArrayList<Info> newInfoList = new ArrayList<Info>(addedSourcesSize); - // the 'items' are either tacked on to the end or - // at the 'begin' index of the first 'info' that is being pushed back - int newItemsIndex = (addedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(addedSourcesIndex).begin; - - int begin = newItemsIndex; - while (addedSources.hasNext()) { - E1 source = addedSources.next(); - ListValueModel<E2> componentLVM = this.transform(source); - componentLVM.addListChangeListener(LIST_VALUES, this.componentLVMListener); - ArrayList<E2> items = new ArrayList<E2>(componentLVM.size()); - CollectionTools.addAll(items, componentLVM.listIterator()); - newInfoList.add(new Info(source, componentLVM, items, begin)); - begin += items.size(); - } - this.infoList.addAll(addedSourcesIndex, newInfoList); - int newItemsSize = begin - newItemsIndex; - this.size += newItemsSize; - - // bump the 'begin' index for all the infos that were pushed back by the insert - int movedInfosIndex = addedSourcesIndex + addedSourcesSize; - for (int i = movedInfosIndex; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - - if (fireEvent) { - ArrayList<E2> newItems = new ArrayList<E2>(newItemsSize); - for (int i = addedSourcesIndex; i < movedInfosIndex; i++) { - newItems.addAll(this.infoList.get(i).items); - } - this.fireItemsAdded(LIST_VALUES, newItemsIndex, newItems); - } - } - - /** - * Some component sources were removed; update our cache. - */ - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.removeComponentSources(event.getIndex(), event.itemsSize(), true); // true = fire event - } - - /** - * Do not fire an event. - */ - protected void removeComponentSources(int removedSourcesIndex, int removedSourcesSize) { - this.removeComponentSources(removedSourcesIndex, removedSourcesSize, false); // false = do not fire event - } - - /** - * Remove the infos corresponding to the specified sources from our cache. - */ - protected void removeComponentSources(int removedSourcesIndex, int removedSourcesSize, boolean fireEvent) { - int removedItemsIndex = this.infoList.get(removedSourcesIndex).begin; - int movedSourcesIndex = removedSourcesIndex + removedSourcesSize; - int movedItemsIndex = (movedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(movedSourcesIndex).begin; - int removedItemsSize = movedItemsIndex - removedItemsIndex; - this.size -= removedItemsSize; - - List<Info> subList = this.infoList.subList(removedSourcesIndex, removedSourcesIndex + removedSourcesSize); - ArrayList<Info> removedInfoList = new ArrayList<Info>(subList); // make a copy - subList.clear(); - - // decrement the 'begin' index for all the infos that were moved forward by the deletes - for (int i = removedSourcesIndex; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - - for (Info removedInfo : removedInfoList) { - removedInfo.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener); - } - - if (fireEvent) { - ArrayList<E2> removedItems = new ArrayList<E2>(removedItemsSize); - for (Info removedInfo : removedInfoList) { - removedItems.addAll(removedInfo.items); - } - this.fireItemsRemoved(LIST_VALUES, removedItemsIndex, removedItems); - } - } - - /** - * Some component sources were replaced; update our cache. - */ - @Override - protected void itemsReplaced(ListChangeEvent event) { - this.replaceComponentSources(event.getIndex(), this.items(event), event.itemsSize(), true); // true = fire event - } - - /** - * Replaced component sources will not (typically) map to a set of replaced - * items, so we remove and add the corresponding lists of items, resulting in - * two events. - */ - protected void replaceComponentSources(int replacedSourcesIndex, ListIterator<? extends E1> newSources, int replacedSourcesSize, boolean fireEvent) { - this.removeComponentSources(replacedSourcesIndex, replacedSourcesSize, fireEvent); - this.addComponentSources(replacedSourcesIndex, newSources, replacedSourcesSize, fireEvent); - } - - /** - * Some component sources were moved; update our cache. - */ - @Override - protected void itemsMoved(ListChangeEvent event) { - this.moveComponentSources(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength(), true); // true = fire event - } - - protected void moveComponentSources(int targetSourcesIndex, int sourceSourcesIndex, int movedSourcesLength, boolean fireEvent) { - int sourceItemsIndex = this.infoList.get(sourceSourcesIndex).begin; - - int nextSourceSourceIndex = sourceSourcesIndex + movedSourcesLength; - int nextSourceItemIndex = (nextSourceSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextSourceSourceIndex).begin; - int moveItemsLength = nextSourceItemIndex - sourceItemsIndex; - - int targetItemsIndex = -1; - if (sourceSourcesIndex > targetSourcesIndex) { - // move from high to low index - targetItemsIndex = this.infoList.get(targetSourcesIndex).begin; - } else { - // move from low to high index (higher items move down during move) - int nextTargetSourceIndex = targetSourcesIndex + movedSourcesLength; - targetItemsIndex = (nextTargetSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextTargetSourceIndex).begin; - targetItemsIndex = targetItemsIndex - moveItemsLength; - } - - CollectionTools.move(this.infoList, targetSourcesIndex, sourceSourcesIndex, movedSourcesLength); - - // update the 'begin' indexes of all the affected 'infos' - int min = Math.min(targetSourcesIndex, sourceSourcesIndex); - int max = Math.max(targetSourcesIndex, sourceSourcesIndex) + movedSourcesLength; - int begin = Math.min(targetItemsIndex, sourceItemsIndex); - for (int i = min; i < max; i++) { - Info info = this.infoList.get(i); - info.begin = begin; - begin += info.componentLVM.size(); - } - - if (fireEvent) { - this.fireItemsMoved(LIST_VALUES, targetItemsIndex, sourceItemsIndex, moveItemsLength); - } - } - - /** - * The component sources were cleared; clear our cache. - */ - @Override - protected void listCleared(ListChangeEvent event) { - this.removeComponentSources(0, this.infoList.size()); - this.fireListCleared(LIST_VALUES); - } - - /** - * The component sources changed; rebuild our cache. - */ - @Override - protected void listChanged(ListChangeEvent event) { - this.removeComponentSources(0, this.infoList.size()); - this.addComponentSources(0, this.listHolder.listIterator(), this.listHolder.size()); - this.fireListChanged(LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(CollectionTools.list(this.listIterator(), this.size)); - } - - - // ********** internal methods ********** - - /** - * Transform the specified object into a list value model. - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Transformer</code>. - */ - protected ListValueModel<E2> transform(E1 value) { - return this.transformer.transform(value); - } - - /** - * Return the index of the specified component LVM. - */ - protected int indexOf(ListValueModel<E2> componentLVM) { - for (int i = 0; i < this.infoList.size(); i++) { - if (this.infoList.get(i).componentLVM == componentLVM) { - return i; - } - } - throw new IllegalArgumentException("invalid component LVM: " + componentLVM); - } - - /** - * Return the index of the specified event's component LVM. - */ - protected int indexFor(ListChangeEvent event) { - return this.indexOf(this.componentLVM(event)); - } - - /** - * Items were added to one of the component lists; - * synchronize our cache. - */ - protected void componentItemsAdded(ListChangeEvent event) { - // update the affected 'begin' indices - int componentLVMIndex = this.indexFor(event); - int newItemsSize = event.itemsSize(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - this.size += newItemsSize; - - // synchronize the cached list - Info info = this.infoList.get(componentLVMIndex); - CollectionTools.addAll(info.items, event.getIndex(), this.componentItems(event), event.itemsSize()); - - // translate the event - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were removed from one of the component lists; - * synchronize our cache. - */ - protected void componentItemsRemoved(ListChangeEvent event) { - // update the affected 'begin' indices - int componentLVMIndex = this.indexFor(event); - int removedItemsSize = event.itemsSize(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - this.size -= removedItemsSize; - - // synchronize the cached list - Info info = this.infoList.get(componentLVMIndex); - int itemIndex = event.getIndex(); - info.items.subList(itemIndex, itemIndex + event.itemsSize()).clear(); - - // translate the event - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were replaced in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsReplaced(ListChangeEvent event) { - // no changes to the 'begin' indices or size - - // synchronize the cached list - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - int i = event.getIndex(); - for (Iterator<E2> stream = this.componentItems(event); stream.hasNext(); ) { - info.items.set(i++, stream.next()); - } - - // translate the event - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * Items were moved in one of the component lists; - * synchronize our cache. - */ - protected void componentItemsMoved(ListChangeEvent event) { - // no changes to the 'begin' indices or size - - // synchronize the cached list - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - CollectionTools.move(info.items, event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength()); - - // translate the event - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES, info.begin)); - } - - /** - * One of the component lists was cleared; - * synchronize our cache. - */ - protected void componentListCleared(ListChangeEvent event) { - int componentLVMIndex = this.indexFor(event); - this.clearComponentList(componentLVMIndex, this.infoList.get(componentLVMIndex)); - } - - protected void clearComponentList(int componentLVMIndex, Info info) { - // update the affected 'begin' indices - int removedItemsSize = info.items.size(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin -= removedItemsSize; - } - this.size -= removedItemsSize; - - // synchronize the cached list - ArrayList<E2> items = new ArrayList<E2>(info.items); - info.items.clear(); - - // translate the event - this.fireItemsRemoved(LIST_VALUES, info.begin, items); - } - - /** - * One of the component lists changed; - * synchronize our cache by clearing out the appropriate - * list and rebuilding it. - */ - protected void componentListChanged(ListChangeEvent event) { - int componentLVMIndex = this.indexFor(event); - Info info = this.infoList.get(componentLVMIndex); - this.clearComponentList(componentLVMIndex, info); - - // update the affected 'begin' indices - int newItemsSize = info.componentLVM.size(); - for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) { - this.infoList.get(i).begin += newItemsSize; - } - this.size += newItemsSize; - - // synchronize the cached list - CollectionTools.addAll(info.items, info.componentLVM.listIterator(), newItemsSize); - - // translate the event - this.fireItemsAdded(LIST_VALUES, info.begin, info.items); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E2> componentItems(ListChangeEvent event) { - return (ListIterator<E2>) event.items(); - } - - // minimize scope of suppressed warnings - @SuppressWarnings("unchecked") - protected ListValueModel<E2> componentLVM(ListChangeEvent event) { - return (ListValueModel<E2>) event.getSource(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java deleted file mode 100644 index 84650cf2b8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ExtendedListValueModelWrapper.java +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyCompositeListIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This wrapper extends a ListValueModel (or CollectionValueModel) - * with fixed collections of items on either end. - * <p> - * NB: Be careful using or wrapping this list value model, since the - * "extended" items may be unexpected by the client code or wrapper. - */ -public class ExtendedListValueModelWrapper<E> - extends ListValueModelWrapper<E> - implements ListValueModel<E> -{ - /** the items "prepended" to the wrapped list */ - protected List<E> prefix; - - /** the items "appended" to the wrapped list */ - protected List<E> suffix; - - - // ********** lots o' constructors ********** - - /** - * Extend the specified list with a prefix and suffix. - */ - public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder, List<? extends E> suffix) { - super(listHolder); - this.prefix = new ArrayList<E>(prefix); - this.suffix = new ArrayList<E>(suffix); - } - - /** - * Extend the specified list with a prefix and suffix. - */ - public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder, E suffix) { - super(listHolder); - this.prefix = Collections.singletonList(prefix); - this.suffix = Collections.singletonList(suffix); - } - - /** - * Extend the specified list with a prefix. - */ - public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = new ArrayList<E>(prefix); - this.suffix = Collections.emptyList(); - } - - /** - * Extend the specified list with a prefix. - */ - public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = Collections.singletonList(prefix); - this.suffix = Collections.emptyList(); - } - - /** - * Extend the specified list with a suffix. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, List<? extends E> suffix) { - super(listHolder); - this.prefix = Collections.emptyList(); - this.suffix = new ArrayList<E>(suffix); - } - - /** - * Extend the specified list with a suffix. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, E suffix) { - super(listHolder); - this.prefix = Collections.emptyList(); - this.suffix = Collections.singletonList(suffix); - } - - /** - * Extend the specified list with a prefix containing a single null item. - */ - public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder) { - super(listHolder); - this.prefix = Collections.singletonList(null); - this.suffix = Collections.emptyList(); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.listIterator_()); - } - - @SuppressWarnings("unchecked") - protected ListIterator<E> listIterator_() { - return new ReadOnlyCompositeListIterator<E>( - this.prefix.listIterator(), - this.listHolder.listIterator(), - this.suffix.listIterator() - ); - } - - public E get(int index) { - int prefixSize = this.prefix.size(); - if (index < prefixSize) { - return this.prefix.get(index); - } else if (index >= prefixSize + this.listHolder.size()) { - return this.suffix.get(index - (prefixSize + this.listHolder.size())); - } else { - return this.listHolder.get(index - prefixSize); - } - } - - public int size() { - return this.prefix.size() + this.listHolder.size() + this.suffix.size(); - } - - public Object[] toArray() { - ArrayList<E> list = new ArrayList<E>(this.size()); - list.addAll(this.prefix); - CollectionTools.addAll(list, this.listHolder.iterator()); - list.addAll(this.suffix); - return list.toArray(); - } - - - // ********** ListValueModelWrapper implementation/overrides ********** - - @Override - protected void itemsAdded(ListChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsReplaced(ListChangeEvent event) { - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void itemsMoved(ListChangeEvent event) { - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES, this.prefix.size())); - } - - @Override - protected void listCleared(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); // not "cleared" - } - - @Override - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.prefix); - sb.append(" "); - super.toString(sb); - sb.append(" "); - sb.append(this.suffix); - } - - - // ********** miscellaneous ********** - - public void setPrefix(List<E> prefix) { - this.prefix = prefix; - this.fireListChanged(LIST_VALUES); - } - - public void setSuffix(List<E> suffix) { - this.suffix = suffix; - this.fireListChanged(LIST_VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java deleted file mode 100644 index 8dc865a0f3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringCollectionValueModel.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * A <code>FilteringCollectionValueModel</code> wraps another - * <code>CollectionValueModel</code> and uses a <code>Filter</code> - * to determine which items in the collection are returned by calls - * to <code>#iterator()</code>. - * <p> - * The filter can be changed at any time; allowing the same - * adapter to be used with different filter criteria (e.g. when the user - * wants to view a list of .java files). - * <p> - * NB: If the objects in the "filtered" collection can change in such a way - * that they should be removed from the "filtered" collection, you will - * need to wrap the original collection in an ItemAspectListValueModelAdapter. - * For example, if the filter only "accepts" items whose names begin - * with "X" and the names of the items can change, you will need to - * wrap the original list of unfiltered items with an - * ItemPropertyListValueModelAdapter that listens for changes to each - * item's name and fires the appropriate event whenever an item's name - * changes. The event will cause this wrapper to re-filter the changed - * item and add or remove it from the "filtered" collection as appropriate. - */ -public class FilteringCollectionValueModel<E> - extends CollectionValueModelWrapper<E> - implements CollectionValueModel<E> -{ - /** This filters the items in the nested collection. */ - private Filter<E> filter; - - /** Cache the items that were accepted by the filter */ - private final Collection<E> filteredItems; - - - // ********** constructors ********** - - /** - * Construct a collection value model with the specified wrapped - * collection value model and a filter that simply accepts every object. - */ - public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionHolder) { - this(collectionHolder, Filter.Null.<E>instance()); - } - - /** - * Construct a collection value model with the specified wrapped - * collection value model and filter. - */ - public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionHolder, Filter<E> filter) { - super(collectionHolder); - this.filter = filter; - this.filteredItems = new ArrayList<E>(); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and a filter that simply accepts every object. - */ - public FilteringCollectionValueModel(ListValueModel<E> listHolder) { - this(new ListCollectionValueModelAdapter<E>(listHolder)); - } - - /** - * Construct a collection value model with the specified wrapped - * list value model and filter. - */ - public FilteringCollectionValueModel(ListValueModel<E> listHolder, Filter<E> filter) { - this(new ListCollectionValueModelAdapter<E>(listHolder), filter); - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.filteredItems); - } - - public int size() { - return this.filteredItems.size(); - } - - - // ********** CollectionValueModelWrapper overrides/implementation ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch our cache *after* we start listening to the nested collection, - // since its value might change when a listener is added - CollectionTools.addAll(this.filteredItems, this.filter(this.collectionHolder.iterator())); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the cache when we are not listening to the nested collection - this.filteredItems.clear(); - } - - @Override - protected void itemsAdded(CollectionChangeEvent event) { - // filter the values before propagating the change event - this.addItemsToCollection(this.filter(this.items(event)), this.filteredItems, VALUES); - } - - @Override - protected void itemsRemoved(CollectionChangeEvent event) { - // do *not* filter the values, because they may no longer be - // "accepted" and that might be why they were removed in the first place; - // anyway, any extraneous items are harmless - this.removeItemsFromCollection(event.items(), this.filteredItems, VALUES); - } - - @Override - protected void collectionCleared(CollectionChangeEvent event) { - this.clearCollection(this.filteredItems, VALUES); - } - - @Override - protected void collectionChanged(CollectionChangeEvent event) { - this.rebuildFilteredItems(); - } - - - // ********** miscellaneous ********** - - /** - * Change the filter and rebuild the collection. - */ - public void setFilter(Filter<E> filter) { - this.filter = filter; - this.rebuildFilteredItems(); - } - - /** - * Return an iterator that filters the specified iterator. - */ - protected Iterator<E> filter(Iterator<? extends E> items) { - return new FilteringIterator<E, E>(items, this.filter); - } - - /** - * Synchronize our cache with the wrapped collection. - */ - protected void rebuildFilteredItems() { - this.filteredItems.clear(); - CollectionTools.addAll(this.filteredItems, this.filter(this.collectionHolder.iterator())); - this.fireCollectionChanged(VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java deleted file mode 100644 index a56cc34c80..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringPropertyValueModel.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A <code>FilteringPropertyValueModel</code> wraps another - * <code>PropertyValueModel</code> and uses a <code>Filter</code> - * to determine when the wrapped value is to be returned by calls - * to <code>value()</code>. - * <p> - * As an alternative to building a <code>Filter</code>, a subclass - * of <code>FilteringPropertyValueModel</code> can override the - * <code>accept(Object)</code> method. - * <p> - * One, possibly undesirable, side-effect of using this value model is that - * it must return *something* as the value. The default behavior is - * to return <code>null</code> whenever the wrapped value is not "accepted", - * which can be configured and/or overridden. - */ -public class FilteringPropertyValueModel<T> - extends PropertyValueModelWrapper<T> - implements PropertyValueModel<T> -{ - protected final Filter<T> filter; - protected final T defaultValue; - - - // ********** constructors ********** - - /** - * Construct a property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> - * method instead of building a <code>Filter</code>. - * The default value will be <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder) { - this(valueHolder, Filter.Disabled.<T>instance(), null); - } - - /** - * Construct a property value model with the specified nested - * property value model, specified default value, and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> - * method instead of building a <code>Filter</code> - * <em>and</em> you need to specify - * a default value other than <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, T defaultValue) { - this(valueHolder, Filter.Disabled.<T>instance(), defaultValue); - } - - /** - * Construct an property value model with the specified nested - * property value model and filter. - * The default value will be <code>null</code>. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, Filter<T> filter) { - this(valueHolder, filter, null); - } - - /** - * Construct an property value model with the specified nested - * property value model, filter, and default value. - */ - public FilteringPropertyValueModel(PropertyValueModel<? extends T> valueHolder, Filter<T> filter, T defaultValue) { - super(valueHolder); - this.filter = filter; - this.defaultValue = defaultValue; - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.filterValue(this.valueHolder.getValue()); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - // filter the values before propagating the change event - @SuppressWarnings("unchecked") - Object oldValue = this.filterValue((T) event.getOldValue()); - @SuppressWarnings("unchecked") - Object newValue = this.filterValue((T) event.getNewValue()); - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - - // ********** queries ********** - - /** - * If the specified value is "accepted" simply return it, - * otherwise return the default value. - */ - protected T filterValue(T value) { - return this.accept(value) ? value : this.defaultValue(); - } - - /** - * Return whether the <code>FilteringPropertyValueModel</code> should - * return the specified value from a call to the - * <code>value()</code> method; the value came - * from the nested property value model - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>Filter</code>. - */ - protected boolean accept(T value) { - return this.filter.accept(value); - } - - /** - * Return the object that should be returned if - * the nested value was rejected by the filter. - * The default is <code>null</code>. - */ - protected T defaultValue() { - return this.defaultValue; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java deleted file mode 100644 index d7e20f4cb3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/FilteringWritablePropertyValueModel.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.BidiFilter; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>FilteringWritablePropertyValueModel</code> wraps another - * <code>WritabelPropertyValueModel</code> and uses a <code>BidiFilter</code> - * to determine when the wrapped value is to be returned by calls - * to <code>value()</code> and modified by calls to - * <code>setValue(Object)</code>. - * <p> - * As an alternative to building a <code>BidiFilter</code>, a subclass - * of <code>FilteringWritablePropertyValueModel</code> can override the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods. - * <p> - * One, possibly undesirable, side-effect of using this value model is that - * it must return *something* as the value. The default behavior is - * to return <code>null</code> whenever the wrapped value is not "accepted", - * which can be configured and/or overridden. - * <p> - * Similarly, if an incoming value is not "reverseAccepted", *nothing* will passed - * through to the wrapped value holder, not even <code>null</code>. - */ -public class FilteringWritablePropertyValueModel<T> - extends FilteringPropertyValueModel<T> - implements WritablePropertyValueModel<T> -{ - - - // ********** constructors ********** - - /** - * Construct a property value model with the specified nested - * property value model and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods instead of building a <code>BidiFilter</code>. - * The default value will be <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder) { - this(valueHolder, BidiFilter.Disabled.<T>instance(), null); - } - - /** - * Construct a property value model with the specified nested - * property value model, specified default value, and a disabled filter. - * Use this constructor if you want to override the - * <code>accept(Object)</code> and <code>reverseAccept(Object)</code> - * methods instead of building a <code>BidiFilter</code> - * <em>and</em> you need to specify - * a default value other than <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, T defaultValue) { - this(valueHolder, BidiFilter.Disabled.<T>instance(), defaultValue); - } - - /** - * Construct an property value model with the specified nested - * property value model and filter. - * The default value will be <code>null</code>. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, BidiFilter<T> filter) { - this(valueHolder, filter, null); - } - - /** - * Construct an property value model with the specified nested - * property value model, filter, and default value. - */ - public FilteringWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, BidiFilter<T> filter, T defaultValue) { - super(valueHolder, filter, defaultValue); - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - if (this.reverseAccept(value)) { - this.valueHolder().setValue(value); - } - } - - - // ********** queries ********** - - /** - * Return whether the <code>FilteringWritablePropertyValueModel</code> - * should pass through the specified value to the nested - * writable property value model in a call to the - * <code>setValue(Object)</code> method - * <p> - * This method can be overridden by a subclass as an - * alternative to building a <code>BidiFilter</code>. - */ - protected boolean reverseAccept(T value) { - return this.getFilter().reverseAccept(value); - } - - /** - * Our constructors accept only a WritablePropertyValueModel<T>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - - /** - * Our constructors accept only a bidirectional filter. - */ - protected BidiFilter<T> getFilter() { - return (BidiFilter<T>) this.filter; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java deleted file mode 100644 index 17538f93d3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemAspectListValueModelAdapter.java +++ /dev/null @@ -1,295 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.EventObject; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.Counter; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Abstract list value model that provides behavior for wrapping a list value - * model (or collection value model) and listening for changes to aspects of the - * *items* held by the list (or collection). Changes to the actual list - * (or collection) are also monitored. - * - * This is useful if you have a collection of items that can be modified by adding - * or removing items or the items themselves might change in a fashion that - * might change the collection's external appearance. - * - * Subclasses need to override two methods: - * - * #listenToItem(Model) - * begin listening to the appropriate aspect of the specified item and call - * #itemAspectChanged(Object) whenever the aspect changes - * - * #stopListeningToItem(Model) - * stop listening to the appropriate aspect of the specified item - */ -public abstract class ItemAspectListValueModelAdapter<E> - extends ListValueModelWrapper<E> - implements ListValueModel<E> -{ - - /** - * Maintain a counter for each of the items in the - * wrapped list holder we are listening to. - */ - protected final IdentityHashMap<E, Counter> counters; - - - // ********** constructors ********** - - /** - * Constructor - the list holder is required. - */ - protected ItemAspectListValueModelAdapter(ListValueModel<? extends E> listHolder) { - super(listHolder); - this.counters = new IdentityHashMap<E, Counter>(); - } - - /** - * Constructor - the collection holder is required. - */ - protected ItemAspectListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - this(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.listHolder.listIterator()); - } - - public E get(int index) { - return this.listHolder.get(index); - } - - public int size() { - return this.listHolder.size(); - } - - public Object[] toArray() { - return this.listHolder.toArray(); - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder and the items in the list. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.engageAllItems(); - } - - protected void engageAllItems() { - this.engageItems(this.listHolder.iterator()); - } - - protected void engageItems(Iterator<? extends E> stream) { - while (stream.hasNext()) { - this.engageItem(stream.next()); - } - } - - protected void engageItem(E item) { - // listen to an item only once - Counter counter = this.counters.get(item); - if (counter == null) { - counter = new Counter(); - this.counters.put(item, counter); - this.startListeningToItem((Model) item); - } - counter.increment(); - } - - /** - * Start listening to the specified item. - */ - protected abstract void startListeningToItem(Model item); - - /** - * Stop listening to the list holder and the items in the list. - */ - @Override - protected void disengageModel() { - this.disengageAllItems(); - super.disengageModel(); - } - - protected void disengageAllItems() { - this.disengageItems(this.listHolder.iterator()); - } - - protected void disengageItems(Iterator<? extends E> stream) { - while (stream.hasNext()) { - this.disengageItem(stream.next()); - } - } - - protected void disengageItem(E item) { - // stop listening to an item only once - Counter counter = this.counters.get(item); - if (counter == null) { - // something is wrong if this happens... ~bjv - throw new IllegalStateException("missing counter: " + item); - } - if (counter.decrement() == 0) { - this.counters.remove(item); - this.stopListeningToItem((Model) item); - } - } - - /** - * Stop listening to the specified item. - */ - protected abstract void stopListeningToItem(Model item); - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder. - * Forward the event and begin listening to the added items. - */ - @Override - protected void itemsAdded(ListChangeEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES)); - this.engageItems(this.items(event)); - } - - /** - * Items were removed from the wrapped list holder. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.disengageItems(this.items(event)); - // re-fire event with the wrapper as the source - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES)); - } - - /** - * Items were replaced in the wrapped list holder. - * Stop listening to the removed items, forward the event, - * and begin listening to the added items. - */ - @Override - protected void itemsReplaced(ListChangeEvent event) { - this.disengageItems(this.replacedItems(event)); - // re-fire event with the wrapper as the source - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES)); - this.engageItems(this.items(event)); - } - - /** - * Items were moved in the wrapped list holder. - * No need to change any listeners; just forward the event. - */ - @Override - protected void itemsMoved(ListChangeEvent event) { - // re-fire event with the wrapper as the source - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES)); - } - - /** - * The wrapped list holder was cleared. - * Stop listening to the removed items and forward the event. - */ - @Override - protected void listCleared(ListChangeEvent event) { - // we should only need to disengage each item once... - // make a copy to prevent a ConcurrentModificationException - Collection<E> keys = new ArrayList<E>(this.counters.keySet()); - this.disengageItems(keys.iterator()); - this.counters.clear(); - // re-fire event with the wrapper as the source - this.fireListCleared(LIST_VALUES); - } - - /** - * The wrapped list holder has changed in some dramatic fashion. - * Reconfigure our listeners and forward the event. - */ - @Override - protected void listChanged(ListChangeEvent event) { - // we should only need to disengage each item once... - // make a copy to prevent a ConcurrentModificationException - Collection<E> keys = new ArrayList<E>(this.counters.keySet()); - this.disengageItems(keys.iterator()); - this.counters.clear(); - // re-fire event with the wrapper as the source - this.fireListChanged(LIST_VALUES); - this.engageAllItems(); - } - - - // ********** item change support ********** - - /** - * The specified item has a bound property that has changed. - * Notify listeners of the change. - */ - protected void itemAspectChanged(EventObject event) { - Object item = event.getSource(); - int index = this.lastIdentityIndexOf(item); - while (index != -1) { - this.itemAspectChanged(index, item); - index = this.lastIdentityIndexOf(item, index); - } - } - - /** - * The specified item has a bound property that has changed. - * Notify listeners of the change. - */ - protected void itemAspectChanged(int index, Object item) { - this.fireItemReplaced(LIST_VALUES, index, item, item); // hmmm... - } - - /** - * Return the last index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.listHolder.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.listHolder.get(i) == o) { - return i; - } - } - return -1; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java deleted file mode 100644 index 151a90f6c3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemCollectionListValueModelAdapter.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend ItemAspectListValueModelAdapter to listen to one or more collection - * aspects of each item in the wrapped list model. - */ -public class ItemCollectionListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' collections that we listen to. */ - protected final String[] collectionNames; - - /** Listener that listens to all the items in the list. */ - protected final CollectionChangeListener itemCollectionListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item Collections. - */ - public ItemCollectionListValueModelAdapter(ListValueModel<E> listHolder, String... collectionNames) { - super(listHolder); - this.collectionNames = collectionNames; - this.itemCollectionListener = this.buildItemCollectionListener(); - } - - /** - * Construct an adapter for the specified item Collections. - */ - public ItemCollectionListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... collectionNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), collectionNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a Collection aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected CollectionChangeListener buildItemCollectionListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void collectionCleared(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - public void collectionChanged(CollectionChangeEvent event) { - ItemCollectionListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item collection listener: " + Arrays.asList(ItemCollectionListValueModelAdapter.this.collectionNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String collectionName : this.collectionNames) { - item.addCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String collectionName : this.collectionNames) { - item.removeCollectionChangeListener(collectionName, this.itemCollectionListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java deleted file mode 100644 index 5354c1bde5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemListListValueModelAdapter.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend ItemAspectListValueModelAdapter to listen to one or more list - * aspects of each item in the wrapped list model. - */ -public class ItemListListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the subject's lists that we listen to. */ - protected final String[] listNames; - - /** Listener that listens to all the items in the list. */ - protected final ListChangeListener itemListListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item List aspects. - */ - public ItemListListValueModelAdapter(ListValueModel<E> listHolder, String... listNames) { - super(listHolder); - this.listNames = listNames; - this.itemListListener = this.buildItemListListener(); - } - - /** - * Construct an adapter for the specified item List aspects. - */ - public ItemListListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... listNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), listNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that the List aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected ListChangeListener buildItemListListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsRemoved(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsReplaced(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void itemsMoved(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void listCleared(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - public void listChanged(ListChangeEvent event) { - ItemListListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item list listener: " + Arrays.asList(ItemListListValueModelAdapter.this.listNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String listName : this.listNames) { - item.addListChangeListener(listName, this.itemListListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String listName : this.listNames) { - item.removeListChangeListener(listName, this.itemListListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java deleted file mode 100644 index 48140a0c5b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemPropertyListValueModelAdapter.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend ItemAspectListValueModelAdapter to listen to one or more - * properties of each item in the wrapped list model. - */ -public class ItemPropertyListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' properties that we listen to. */ - protected final String[] propertyNames; - - /** Listener that listens to all the items in the list. */ - protected final PropertyChangeListener itemPropertyListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item properties. - */ - public ItemPropertyListValueModelAdapter(ListValueModel<E> listHolder, String... propertyNames) { - super(listHolder); - this.propertyNames = propertyNames; - this.itemPropertyListener = this.buildItemPropertyListener(); - } - - /** - * Construct an adapter for the specified item properties. - */ - public ItemPropertyListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... propertyNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), propertyNames); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildItemPropertyListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ItemPropertyListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item property listener: " + Arrays.asList(ItemPropertyListValueModelAdapter.this.propertyNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String propertyName : this.propertyNames) { - item.addPropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String propertyName : this.propertyNames) { - item.removePropertyChangeListener(propertyName, this.itemPropertyListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java deleted file mode 100644 index 46d7d863fb..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemStateListValueModelAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend ItemAspectListValueModelAdapter to listen to the - * "state" of each item in the wrapped list model. - */ -public class ItemStateListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - /** Listener that listens to all the items in the list. */ - protected final StateChangeListener itemStateListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the item state. - */ - public ItemStateListValueModelAdapter(ListValueModel<E> listHolder) { - super(listHolder); - this.itemStateListener = this.buildItemStateListener(); - } - - /** - * Construct an adapter for the item state. - */ - public ItemStateListValueModelAdapter(CollectionValueModel<E> collectionHolder) { - this(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** initialization ********** - - protected StateChangeListener buildItemStateListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ItemStateListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item state listener"; - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - item.addStateChangeListener(this.itemStateListener); - } - - @Override - protected void stopListeningToItem(Model item) { - item.removeStateChangeListener(this.itemStateListener); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java deleted file mode 100644 index 4e39f6ec34..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ItemTreeListValueModelAdapter.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Extend ItemAspectListValueModelAdapter to listen to one or more tree - * aspects of each item in the wrapped list model. - */ -public class ItemTreeListValueModelAdapter<E> - extends ItemAspectListValueModelAdapter<E> -{ - - /** The names of the items' tree that we listen to. */ - protected final String[] treeNames; - - /** Listener that listens to all the items in the list. */ - protected final TreeChangeListener itemTreeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified item trees. - */ - public ItemTreeListValueModelAdapter(ListValueModel<E> listHolder, String... treeNames) { - super(listHolder); - this.treeNames = treeNames; - this.itemTreeListener = this.buildItemTreeListener(); - } - - /** - * Construct an adapter for the specified item trees. - */ - public ItemTreeListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... treeNames) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), treeNames); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a tree aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected TreeChangeListener buildItemTreeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void nodeRemoved(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void treeCleared(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - public void treeChanged(TreeChangeEvent event) { - ItemTreeListValueModelAdapter.this.itemAspectChanged(event); - } - @Override - public String toString() { - return "item tree listener: " + Arrays.asList(ItemTreeListValueModelAdapter.this.treeNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void startListeningToItem(Model item) { - for (String treeName : this.treeNames) { - item.addTreeChangeListener(treeName, this.itemTreeListener); - } - } - - @Override - protected void stopListeningToItem(Model item) { - for (String treeName : this.treeNames) { - item.removeTreeChangeListener(treeName, this.itemTreeListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java deleted file mode 100644 index b8adaaa96f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListAspectAdapter.java +++ /dev/null @@ -1,287 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides ListChange support. - * This allows us to convert a set of one or more collections into - * a single collection, LIST_VALUES. - * - * The typical subclass will override the following methods: - * #listIterator_() - * at the very minimum, override this method to return a list iterator - * on the subject's list aspect; it does not need to be overridden if - * #listIterator() is overridden and its behavior changed - * #get(int) - * override this method to improve performance - * #size_() - * override this method to improve performance; it does not need to be overridden if - * #size() is overridden and its behavior changed - * #listIterator() - * override this method only if returning an empty list iterator when the - * subject is null is unacceptable - * #size() - * override this method only if returning a zero when the - * subject is null is unacceptable - */ -public abstract class ListAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements ListValueModel<E> -{ - /** - * The name of the subject's lists that we use for the value. - */ - protected final String[] listNames; - protected static final String[] EMPTY_LIST_NAMES = new String[0]; - - /** A listener that listens to the subject's list aspect. */ - protected final ListChangeListener listChangeListener; - - private static final Object[] EMPTY_ARRAY = new Object[0]; - - - // ********** constructors ********** - - /** - * Construct a ListAspectAdapter for the specified subject - * and list. - */ - protected ListAspectAdapter(String listName, S subject) { - this(new String[] {listName}, subject); - } - - /** - * Construct a ListAspectAdapter for the specified subject - * and lists. - */ - protected ListAspectAdapter(String[] listNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), listNames); - } - - /** - * Construct a ListAspectAdapter for the specified subject holder - * and lists. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... listNames) { - super(subjectHolder); - this.listNames = listNames; - this.listChangeListener = this.buildListChangeListener(); - } - - /** - * Construct a ListAspectAdapter for the specified subject holder - * and lists. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> listNames) { - this(subjectHolder, listNames.toArray(new String[listNames.size()])); - } - - /** - * Construct a ListAspectAdapter for an "unchanging" list in - * the specified subject. This is useful for a list aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new list. - */ - protected ListAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_LIST_NAMES); - } - - - // ********** initialization ********** - - /** - * The subject's list aspect has changed, notify the listeners. - */ - protected ListChangeListener buildListChangeListener() { - // transform the subject's list change events into VALUE list change events - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListAspectAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListAspectAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListAspectAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListAspectAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListAspectAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListAspectAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener: " + Arrays.asList(ListAspectAdapter.this.listNames); - } - }; - } - - - // ********** ListValueModel implementation ********** - - /** - * Return the elements of the subject's list aspect. - */ - public Iterator<E> iterator() { - return this.listIterator(); - } - - /** - * Return the elements of the subject's list aspect. - */ - public ListIterator<E> listIterator() { - return (this.subject == null) ? EmptyListIterator.<E>instance() : this.listIterator_(); - } - - /** - * Return the elements of the subject's list aspect. - * At this point we can be sure that the subject is not null. - * @see #listIterator() - */ - protected ListIterator<E> listIterator_() { - throw new UnsupportedOperationException(); - } - - /** - * Return the element at the specified index of the subject's list aspect. - */ - public E get(int index) { - return CollectionTools.get(this.listIterator(), index); - } - - /** - * Return the size of the subject's list aspect. - */ - public int size() { - return this.subject == null ? 0 : this.size_(); - } - - /** - * Return the size of the subject's list aspect. - * At this point we can be sure that the subject is not null. - * @see #size() - */ - protected int size_() { - return CollectionTools.size(this.listIterator()); - } - - /** - * Return an array manifestation of the subject's list aspect. - */ - public Object[] toArray() { - return this.subject == null ? EMPTY_ARRAY : this.toArray_(); - } - - /** - * Return an array manifestation of the subject's list aspect. - * At this point we can be sure that the subject is not null. - * @see #toArray() - */ - protected Object[] toArray_() { - return CollectionTools.array(this.listIterator(), this.size()); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return ListChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return LIST_VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireListChanged(LIST_VALUES); - } - - @Override - protected void engageSubject_() { - for (String listName : this.listNames) { - ((Model) this.subject).addListChangeListener(listName, this.listChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String listName : this.listNames) { - ((Model) this.subject).removeListChangeListener(listName, this.listChangeListener); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.listNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.listNames[i]); - } - } - - - // ********** behavior ********** - - protected void itemsAdded(ListChangeEvent event) { - this.fireItemsAdded(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsRemoved(ListChangeEvent event) { - this.fireItemsRemoved(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsReplaced(ListChangeEvent event) { - this.fireItemsReplaced(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void itemsMoved(ListChangeEvent event) { - this.fireItemsMoved(event.cloneWithSource(this, LIST_VALUES)); - } - - protected void listCleared(ListChangeEvent event) { - this.fireListCleared(LIST_VALUES); // nothing from original event to forward - } - - protected void listChanged(ListChangeEvent event) { - this.fireListChanged(LIST_VALUES); // nothing from original event to forward - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java deleted file mode 100644 index dc8a7aad40..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCollectionValueModelAdapter.java +++ /dev/null @@ -1,300 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a ListValueModel behave like - * a read-only CollectionValueModel, sorta. - * - * We keep an internal collection somewhat in synch with the wrapped list. - * - * NB: Since we only listen to the wrapped list when we have - * listeners ourselves and we can only stay in synch with the wrapped - * list while we are listening to it, results to various methods - * (e.g. #size(), value()) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - */ -public class ListCollectionValueModelAdapter<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - /** The wrapped list value model. */ - protected final ListValueModel<? extends E> listHolder; - - /** A listener that forwards any events fired by the list holder. */ - protected final ListChangeListener listChangeListener; - - /** - * Our internal collection, which holds the same elements as - * the wrapped list. - */ - // we declare this an ArrayList so we can use #clone() and #ensureCapacity(int) - protected final ArrayList<E> collection; - - - // ********** constructors/initialization ********** - - /** - * Wrap the specified ListValueModel. - */ - public ListCollectionValueModelAdapter(ListValueModel<? extends E> listHolder) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - this.collection = new ArrayList<E>(); - // postpone building the collection and listening to the underlying list - // until we have listeners ourselves... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - /** - * The wrapped list has changed, forward an equivalent - * collection change event to our listeners. - */ - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListCollectionValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - // try to prevent backdoor modification of the list - return new ReadOnlyIterator<E>(this.collection); - } - - public int size() { - return this.collection.size(); - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the list holder if necessary. - */ - @Override - public void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Override to start listening to the list holder if necessary. - */ - @Override - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Override to stop listening to the list holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the list holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - /** - * Return the index of the specified item, using object - * identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o) { - return this.lastIdentityIndexOf(o, this.collection.size()); - } - - /** - * Return the last index of the specified item, starting just before the - * the specified endpoint, and using object identity instead of equality. - */ - protected int lastIdentityIndexOf(Object o, int end) { - for (int i = end; i-- > 0; ) { - if (this.collection.get(i) == o) { - return i; - } - } - return -1; - } - - - // ********** behavior ********** - - protected void buildCollection() { - Iterator<? extends E> stream = this.listHolder.iterator(); - // if the new list is empty, do nothing - if (stream.hasNext()) { - this.collection.ensureCapacity(this.listHolder.size()); - while (stream.hasNext()) { - this.collection.add(stream.next()); - } - } - } - - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - // synch our collection *after* we start listening to the list holder, - // since its value might change when a listener is added - this.buildCollection(); - } - - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - // clear out the collection when we are not listening to the list holder - this.collection.clear(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> items(ListChangeEvent event) { - return (ListIterator<E>) event.items(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> replacedItems(ListChangeEvent event) { - return (ListIterator<E>) event.replacedItems(); - } - - protected void itemsAdded(ListChangeEvent event) { - this.addItemsToCollection(this.items(event), this.collection, VALUES); - } - - protected void removeInternalItems(Iterator<E> items) { - // we have to remove the items individually, - // since they are probably not in sequence - while (items.hasNext()) { - Object removedItem = items.next(); - int index = this.lastIdentityIndexOf(removedItem); - this.collection.remove(index); - this.fireItemRemoved(VALUES, removedItem); - } - } - - protected void itemsRemoved(ListChangeEvent event) { - this.removeInternalItems(this.items(event)); - } - - protected void itemsReplaced(ListChangeEvent event) { - this.removeInternalItems(this.replacedItems(event)); - this.addItemsToCollection(this.items(event), this.collection, VALUES); - } - - protected void itemsMoved(ListChangeEvent event) { - // do nothing? moving items in a list has no net effect on a collection... - } - - protected void listCleared(ListChangeEvent event) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - this.collection.clear(); - this.fireCollectionCleared(VALUES); - } - } - - /** - * synchronize our internal collection with the wrapped list - * and fire the appropriate events - */ - protected void listChanged(ListChangeEvent event) { - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - @SuppressWarnings("unchecked") - ArrayList<E> removedItems = (ArrayList<E>) this.collection.clone(); - this.collection.clear(); - this.fireItemsRemoved(VALUES, removedItems); - } - - this.buildCollection(); - // put in empty check so we don't fire events unnecessarily - if ( ! this.collection.isEmpty()) { - this.fireItemsAdded(VALUES, this.collection); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java deleted file mode 100644 index f04821ad82..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListCurator.java +++ /dev/null @@ -1,220 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This extension of AspectAdapter provides ListChange support - * by adapting a subject's state change events to a minimum set - * of list change events. - */ -public abstract class ListCurator<S extends Model, E> - extends AspectAdapter<S> - implements ListValueModel<E> -{ - /** How the list looked before the last state change */ - private final ArrayList<E> record; - - /** A listener that listens for the subject's state to change */ - private final StateChangeListener stateChangeListener; - - - // ********** constructors ********** - - /** - * Construct a Curator for the specified subject. - */ - protected ListCurator(S subject) { - this(new StaticPropertyValueModel<S>(subject)); - } - - /** - * Construct a curator for the specified subject holder. - * The subject holder cannot be null. - */ - protected ListCurator(PropertyValueModel<? extends S> subjectHolder) { - super(subjectHolder); - this.record = new ArrayList<E>(); - this.stateChangeListener = this.buildStateChangeListener(); - } - - - // ********** initialization ********** - - /** - * The subject's state has changed, do inventory and report to listeners. - */ - protected StateChangeListener buildStateChangeListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ListCurator.this.submitInventoryReport(); - } - @Override - public String toString() { - return "state change listener"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.record); - } - - /** - * Return the item at the specified index of the subject's list aspect. - */ - public E get(int index) { - return this.record.get(index); - } - - /** - * Return the size of the subject's list aspect. - */ - public int size() { - return this.record.size(); - } - - /** - * Return an array manifestation of the subject's list aspect. - */ - public Object[] toArray() { - return this.record.toArray(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return ListChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return LIST_VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - /** - * The aspect has changed, notify listeners appropriately. - */ - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireListChanged(LIST_VALUES); - } - - /** - * The subject is not null - add our listener. - */ - @Override - protected void engageSubject_() { - ((Model) this.subject).addStateChangeListener(this.stateChangeListener); - // synch our list *after* we start listening to the subject, - // since its value might change when a listener is added - CollectionTools.addAll(this.record, this.iteratorForRecord()); - } - - /** - * The subject is not null - remove our listener. - */ - @Override - protected void disengageSubject_() { - ((Model) this.subject).removeStateChangeListener(this.stateChangeListener); - // clear out the list when we are not listening to the subject - this.record.clear(); - } - - - // ********** ListCurator protocol ********** - - /** - * This is intended to be different from #ListValueModel.iterator(). - * It is intended to be used only when the subject changes or the - * subject's "state" changes (as signified by a state change event). - */ - protected abstract Iterator<E> iteratorForRecord(); - - - // ********** behavior ********** - - void submitInventoryReport() { - List<E> newRecord = CollectionTools.list(this.iteratorForRecord()); - int recordIndex = 0; - - // add items from the new record - for (E newItem : newRecord) { - this.inventoryNewItem(recordIndex, newItem); - recordIndex++; - } - - // clean out items that are no longer in the new record - for (recordIndex = 0; recordIndex < this.record.size(); ) { - E item = this.record.get(recordIndex); - - if (newRecord.contains(item)) { - recordIndex++; - } else { - this.removeItemFromInventory(recordIndex, item); - } - } - } - - private void inventoryNewItem(int recordIndex, E newItem) { - List<E> rec = new ArrayList<E>(this.record); - - if ((recordIndex < rec.size()) && rec.get(recordIndex).equals(newItem)) { - return; - } - if (rec.contains(newItem)) { - this.removeItemFromInventory(recordIndex, rec.get(recordIndex)); - this.inventoryNewItem(recordIndex, newItem); - } else { - this.addItemToInventory(recordIndex, newItem); - } - } - - private void addItemToInventory(int index, E item) { - this.addItemToList(index, item, this.record, LIST_VALUES); - } - - private void removeItemFromInventory(int index, E item) { - this.removeItemFromList(index, this.record, LIST_VALUES); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java deleted file mode 100644 index 6c78b4fd62..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListPropertyValueModelAdapter.java +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a list value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current list value - * - * Subclasses might want to override: - * - #itemsAdded(ListChangeEvent event) - * - #itemsRemoved(ListChangeEvent event) - * - #itemsReplaced(ListChangeEvent event) - * - #itemsMoved(ListChangeEvent event) - * - #listCleared(ListChangeEvent event) - * - #listChanged(ListChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class ListPropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<T> -{ - /** The wrapped list value model. */ - protected final ListValueModel<?> listHolder; - - /** A listener that allows us to synch with changes to the wrapped list holder. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * list value model. - */ - protected ListPropertyValueModelAdapter(ListValueModel<?> listHolder) { - super(); - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - } - - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListPropertyValueModelAdapter.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder. - */ - @Override - protected void engageModel_() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - /** - * Stop listening to the list holder. - */ - @Override - protected void disengageModel_() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - - - // ********** collection change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsAdded(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were removed from the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsRemoved(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were replaced in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsReplaced(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Items were moved in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected void itemsMoved(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped list holder was cleared; - * propagate the change notification appropriately. - */ - protected void listCleared(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The value of the wrapped list holder has changed; - * propagate the change notification appropriately. - */ - protected void listChanged(ListChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java deleted file mode 100644 index 06f5a072e5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ListValueModelWrapper.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another list value model, "lazily" listen to it, and propagate - * its change notifications. - */ -public abstract class ListValueModelWrapper<E> - extends AbstractModel -{ - - /** The wrapped list value model. */ - protected final ListValueModel<? extends E> listHolder; - - /** A listener that allows us to synch with changes to the wrapped list holder. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Construct a list value model with the specified wrapped - * list value model. - */ - protected ListValueModelWrapper(ListValueModel<? extends E> listHolder) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - } - - - // ********** initialization ********** - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES); - } - - protected ListChangeListener buildListChangeListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListValueModelWrapper.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListValueModelWrapper.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListValueModelWrapper.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListValueModelWrapper.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListValueModelWrapper.this.listCleared(event); - } - public void listChanged(ListChangeEvent event) { - ListValueModelWrapper.this.listChanged(event); - } - @Override - public String toString() { - return "list change listener"; - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == ListValueModel.LIST_VALUES && this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.disengageModel(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == ListValueModel.LIST_VALUES && this.hasNoListChangeListeners(ListValueModel.LIST_VALUES)) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the list holder. - */ - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - /** - * Stop listening to the list holder. - */ - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.listHolder); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> items(ListChangeEvent event) { - return (ListIterator<E>) event.items(); - } - - // minimize suppressed warnings - @SuppressWarnings("unchecked") - protected ListIterator<E> replacedItems(ListChangeEvent event) { - return (ListIterator<E>) event.replacedItems(); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsAdded(ListChangeEvent event); - - /** - * Items were removed from the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsRemoved(ListChangeEvent event); - - /** - * Items were replaced in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsReplaced(ListChangeEvent event); - - /** - * Items were moved in the wrapped list holder; - * propagate the change notification appropriately. - */ - protected abstract void itemsMoved(ListChangeEvent event); - - /** - * The wrapped list holder was cleared; - * propagate the change notification appropriately. - */ - protected abstract void listCleared(ListChangeEvent event); - - /** - * The value of the wrapped list holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void listChanged(ListChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java deleted file mode 100644 index db6447c94b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullCollectionValueModel.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * A read-only collection value model for when you - * don't need to support a collection. In particular, this - * is useful for the leaf nodes of a tree that never have - * children. - * - * We don't use a singleton because we hold on to listeners. - */ -public final class NullCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullCollectionValueModel() { - super(); - } - - - // ********** CollectionValueModel implementation ********** - - public int size() { - return 0; - } - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java deleted file mode 100644 index 7bdb3ab3a3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullListValueModel.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An empty list value model for when you don't - * need to support a list. - * - * We don't use a singleton because we hold on to listeners. - */ -public final class NullListValueModel<E> - extends AbstractModel - implements ListValueModel<E> -{ - private static final Object[] EMPTY_ARRAY = new Object[0]; - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullListValueModel() { - super(); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return EmptyIterator.instance(); - } - - public ListIterator<E> listIterator() { - return EmptyListIterator.instance(); - } - - public int size() { - return 0; - } - - public E get(int index) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); - } - - public Object[] toArray() { - return EMPTY_ARRAY; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java deleted file mode 100644 index 12c9b670e8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullPropertyValueModel.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A property value model for when you - * don't need to support a value. - * - * We don't use a singleton because we hold on to listeners. - */ -public class NullPropertyValueModel<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullPropertyValueModel() { - super(); - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return null; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java deleted file mode 100644 index b035c29811..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/NullTreeValueModel.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * A tree value model for when you - * don't need to support any nodes. - * - * We don't use a singleton because we hold on to listeners. - */ -public class NullTreeValueModel<E> - extends AbstractModel - implements TreeValueModel<E> -{ - private static final long serialVersionUID = 1L; - - /** - * Default constructor. - */ - public NullTreeValueModel() { - super(); - } - - - // ********** TreeValueModel implementation ********** - - public Iterator<E> nodes() { - return EmptyIterator.instance(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return ClassTools.shortClassNameForObject(this); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java deleted file mode 100644 index eb2b4f8b43..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyAspectAdapter.java +++ /dev/null @@ -1,255 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This AspectAdapter provides basic PropertyChange support. - * This allows us to convert a set of one or more properties into - * a single property, VALUE. - * - * The typical subclass will override the following methods: - * #buildValue_() - * at the very minimum, override this method to return the value of the - * subject's property (or "virtual" property); it does not need to be - * overridden if #buildValue() is overridden and its behavior changed - * #setValue_(Object) - * override this method if the client code needs to *set* the value of - * the subject's property; oftentimes, though, the client code (e.g. UI) - * will need only to *get* the value; it does not need to be - * overridden if #setValue(Object) is overridden and its behavior changed - * #buildValue() - * override this method only if returning a null value when the subject is null - * is unacceptable - * #setValue(Object) - * override this method only if something must be done when the subject - * is null (e.g. throw an exception) - */ -public abstract class PropertyAspectAdapter<S extends Model, T> - extends AspectAdapter<S> - implements WritablePropertyValueModel<T> -{ - /** - * Cache the current value of the aspect so we - * can pass an "old value" when we fire a property change event. - * We need this because the value may be calculated and may - * not be in the property change event fired by the subject, - * especially when dealing with multiple aspects. - */ - protected T value; - - /** The name of the subject's properties that we use for the value. */ - protected final String[] propertyNames; - protected static final String[] EMPTY_PROPERTY_NAMES = new String[0]; - - /** A listener that listens to the appropriate properties of the subject. */ - protected final PropertyChangeListener propertyChangeListener; - - - // ********** constructors ********** - - /** - * Construct a PropertyAspectAdapter for the specified subject - * and property. - */ - protected PropertyAspectAdapter(String propertyName, S subject) { - this(new String[] {propertyName}, subject); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject - * and properties. - */ - protected PropertyAspectAdapter(String[] propertyNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), propertyNames); - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... propertyNames) { - super(subjectHolder); - this.propertyNames = propertyNames; - this.propertyChangeListener = this.buildPropertyChangeListener(); - // our value is null when we are not listening to the subject - this.value = null; - } - - /** - * Construct a PropertyAspectAdapter for the specified subject holder - * and properties. - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> propertyNames) { - this(subjectHolder, propertyNames.toArray(new String[propertyNames.size()])); - } - - /** - * Construct a PropertyAspectAdapter for an "unchanging" property in - * the specified subject. This is useful for a property aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new property. (A TransformationPropertyValueModel could also be - * used in this situation.) - */ - protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_PROPERTY_NAMES); - } - - - // ********** initialization ********** - - /** - * The subject's property has changed, notify the listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - // transform the subject's property change events into VALUE property change events - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - PropertyAspectAdapter.this.propertyChanged(); - } - @Override - public String toString() { - return "property change listener: " + Arrays.asList(PropertyAspectAdapter.this.propertyNames); //$NON-NLS-1$ - } - }; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Return the value of the subject's property. - */ - @Override - public final T getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - /** - * Set the value of the subject's property. - */ - public void setValue(T value) { - if (this.subject != null) { - this.setValue_(value); - } - } - - /** - * Set the value of the subject's property. - * At this point we can be sure that the subject is not null. - * @see #setValue(Object) - */ - protected void setValue_(@SuppressWarnings("unused") T value) { - throw new UnsupportedOperationException(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - @Override - protected void engageSubject() { - super.engageSubject(); - // synch our value *after* we start listening to the subject, - // since its value might change when a listener is added - this.value = this.buildValue(); - } - - @Override - protected void engageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).addPropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - @Override - protected void disengageSubject() { - super.disengageSubject(); - // clear out our value when we are not listening to the subject - this.value = null; - } - - @Override - protected void disengageSubject_() { - for (String propertyName : this.propertyNames) { - ((Model) this.subject).removePropertyChangeListener(propertyName, this.propertyChangeListener); - } - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.propertyNames.length; i++) { - if (i != 0) { - sb.append(", "); //$NON-NLS-1$ - } - sb.append(this.propertyNames[i]); - } - } - - - // ********** behavior ********** - - /** - * Return the aspect's value. - * At this point the subject may be null. - */ - protected T buildValue() { - return (this.subject == null) ? null : this.buildValue_(); - } - - /** - * Return the value of the subject's property. - * At this point we can be sure that the subject is not null. - * @see #buildValue() - */ - protected T buildValue_() { - throw new UnsupportedOperationException(); - } - - protected void propertyChanged() { - T old = this.value; - this.value = this.buildValue(); - this.fireAspectChange(old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java deleted file mode 100644 index 5b09ad161e..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyCollectionValueModelAdapter.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a PropertyValueModel behave like - * a read-only, single-element CollectionValueModel, sorta. - * - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a collection with a null element). - */ -public class PropertyCollectionValueModelAdapter<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends E> valueHolder; - - /** A listener that forwards any events fired by the value holder. */ - protected final PropertyChangeListener propertyChangeListener; - - /** Cache the value. */ - protected E value; - - - // ********** constructors/initialization ********** - - /** - * Wrap the specified ListValueModel. - */ - public PropertyCollectionValueModelAdapter(PropertyValueModel<? extends E> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.propertyChangeListener = this.buildPropertyChangeListener(); - // postpone building the value and listening to the underlying value - // until we have listeners ourselves... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - /** - * The wrapped value has changed, forward an equivalent - * collection change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - PropertyCollectionValueModelAdapter.this.valueChanged((E) event.getNewValue()); - } - @Override - public String toString() { - return "property change listener"; - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return (this.value == null) ? - EmptyIterator.<E>instance() - : - new SingleElementIterator<E>(this.value); - } - - public int size() { - return (this.value == null) ? 0 : 1; - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addCollectionChangeListener(CollectionChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(listener); - } - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - if (collectionName == VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addCollectionChangeListener(collectionName, listener); - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(CollectionChangeListener listener) { - super.removeCollectionChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) { - super.removeCollectionChangeListener(collectionName, listener); - if (collectionName == VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - protected void engageModel() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // synch our value *after* we start listening to the value holder, - // since its value might change when a listener is added - this.value = this.valueHolder.getValue(); - } - - protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // clear out the value when we are not listening to the value holder - this.value = null; - } - - /** - * synchronize our internal value with the wrapped value - * and fire the appropriate events - */ - protected void valueChanged(E newValue) { - // put in "empty" check so we don't fire events unnecessarily - if (this.value != null) { - E oldValue = this.value; - this.value = null; - this.fireItemRemoved(VALUES, oldValue); - } - this.value = newValue; - // put in "empty" check so we don't fire events unnecessarily - if (this.value != null) { - this.fireItemAdded(VALUES, this.value); - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java deleted file mode 100644 index 96afe29e1f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyListValueModelAdapter.java +++ /dev/null @@ -1,219 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; -import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * An adapter that allows us to make a PropertyValueModel behave like - * a read-only, single-element ListValueModel, sorta. - * - * If the property's value is null, an empty iterator is returned - * (i.e. you can't have a list with a null element). - */ -public class PropertyListValueModelAdapter<E> - extends AbstractModel - implements ListValueModel<E> -{ - - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends E> valueHolder; - - /** A listener that forwards any events fired by the value holder. */ - protected final PropertyChangeListener propertyChangeListener; - - /** Cache the value. */ - protected E value; - - - // ********** constructors/initialization ********** - - /** - * Wrap the specified property value model. - */ - public PropertyListValueModelAdapter(PropertyValueModel<? extends E> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.propertyChangeListener = this.buildPropertyChangeListener(); - // postpone building the value and listening to the underlying value - // until we have listeners ourselves... - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - /** - * The wrapped value has changed, forward an equivalent - * list change event to our listeners. - */ - protected PropertyChangeListener buildPropertyChangeListener() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - PropertyListValueModelAdapter.this.valueChanged((E) event.getNewValue()); - } - @Override - public String toString() { - return "property change listener"; - } - }; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return this.listIterator(); - } - - public ListIterator<E> listIterator() { - return (this.value == null) ? - EmptyListIterator.<E>instance() - : - new SingleElementListIterator<E>(this.value); - } - - public int size() { - return (this.value == null) ? 0 : 1; - } - - public E get(int index) { - if (this.value == null) { - throw this.ioobe(index, 0); - } - if (index > 0) { - throw this.ioobe(index, 1); - } - return this.value; - } - - protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - public Object[] toArray() { - return (this.value == null) ? EMPTY_OBJECT_ARRAY : new Object[] {this.value}; - } - - - // ********** extend change support ********** - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addListChangeListener(ListChangeListener listener) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listener); - } - - /** - * Override to start listening to the value holder if necessary. - */ - @Override - public void addListChangeListener(String listName, ListChangeListener listener) { - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.engageModel(); - } - super.addListChangeListener(listName, listener); - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeListChangeListener(ListChangeListener listener) { - super.removeListChangeListener(listener); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Override to stop listening to the value holder if appropriate. - */ - @Override - public void removeListChangeListener(String listName, ListChangeListener listener) { - super.removeListChangeListener(listName, listener); - if (listName == LIST_VALUES && this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - protected boolean hasListeners() { - return this.hasAnyListChangeListeners(LIST_VALUES); - } - - protected boolean hasNoListeners() { - return ! this.hasListeners(); - } - - - // ********** behavior ********** - - protected IndexOutOfBoundsException ioobe(int index, int size) { - return new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - } - - protected void engageModel() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // synch our value *after* we start listening to the value holder, - // since its value might change when a listener is added - this.value = this.valueHolder.getValue(); - } - - protected void disengageModel() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener); - // clear out the value when we are not listening to the value holder - this.value = null; - } - - /** - * synchronize our internal value with the wrapped value - * and fire the appropriate events - */ - protected void valueChanged(E newValue) { - E oldValue = this.value; - this.value = newValue; - if (oldValue == null) { - this.fireItemAdded(LIST_VALUES, 0, newValue); - } else { - if (newValue == null) { - this.fireItemRemoved(LIST_VALUES, 0, oldValue); - } else { - this.fireItemReplaced(LIST_VALUES, 0, newValue, oldValue); - } - } - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java deleted file mode 100644 index c5195af061..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/PropertyValueModelWrapper.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * another property value model, "lazily" listen to it, and propagate - * its change notifications. - */ -public abstract class PropertyValueModelWrapper<T> - extends AbstractModel -{ - - /** The wrapped property value model. */ - protected final PropertyValueModel<? extends T> valueHolder; - - /** A listener that allows us to synch with changes to the wrapped value holder. */ - protected final PropertyChangeListener valueChangeListener; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * property value model. The value holder is required. - */ - protected PropertyValueModelWrapper(PropertyValueModel<? extends T> valueHolder) { - super(); - if (valueHolder == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.valueChangeListener = this.buildValueChangeListener(); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE); - } - - protected PropertyChangeListener buildValueChangeListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - PropertyValueModelWrapper.this.valueChanged(event); - } - @Override - public String toString() { - return "value change listener"; //$NON-NLS-1$ - } - }; - } - - - // ********** extend change support ********** - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.engageValueHolder(); - } - super.addPropertyChangeListener(listener); - } - - /** - * Extend to start listening to the nested model if necessary. - */ - @Override - public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - if (propertyName == PropertyValueModel.VALUE && this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.engageValueHolder(); - } - super.addPropertyChangeListener(propertyName, listener); - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - super.removePropertyChangeListener(listener); - if (this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.disengageValueHolder(); - } - } - - /** - * Extend to stop listening to the nested model if necessary. - */ - @Override - public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - super.removePropertyChangeListener(propertyName, listener); - if (propertyName == PropertyValueModel.VALUE && this.hasNoPropertyChangeListeners(PropertyValueModel.VALUE)) { - this.disengageValueHolder(); - } - } - - - // ********** behavior ********** - - /** - * Begin listening to the value holder. - */ - protected void engageValueHolder() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - /** - * Stop listening to the value holder. - */ - protected void disengageValueHolder() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.valueHolder); - } - - - // ********** property change support ********** - - /** - * The value of the wrapped value holder has changed; - * propagate the change notification appropriately. - */ - protected abstract void valueChanged(PropertyChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java deleted file mode 100644 index e61c51136d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleCollectionValueModel.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.HashBag; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * Implementation of CollectionValueModel and Collection that simply holds a - * collection and notifies listeners of any changes. - */ -public class SimpleCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E>, Collection<E> -{ - /** The collection. */ - protected Collection<E> collection; - - - // ********** constructors ********** - - /** - * Construct a CollectionValueModel for the specified collection. - */ - public SimpleCollectionValueModel(Collection<E> collection) { - super(); - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - } - - /** - * Construct a CollectionValueModel with an empty initial collection. - */ - public SimpleCollectionValueModel() { - this(new HashBag<E>()); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES); - } - - - // ********** CollectionValueModel implementation ********** - - public Iterator<E> iterator() { - return new LocalIterator<E>(this.collection.iterator()); - } - - public int size() { - return this.collection.size(); - } - - - // ********** Collection implementation ********** - - public boolean isEmpty() { - return this.collection.isEmpty(); - } - - public boolean contains(Object o) { - return this.collection.contains(o); - } - - public Object[] toArray() { - return this.collection.toArray(); - } - - public <T extends Object> T[] toArray(T[] a) { - return this.collection.toArray(a); - } - - public boolean add(E o) { - return this.addItemToCollection(o, this.collection, VALUES); - } - - public boolean remove(Object o) { - return this.removeItemFromCollection(o, this.collection, VALUES); - } - - public boolean containsAll(Collection<?> c) { - return this.collection.containsAll(c); - } - - public boolean addAll(Collection<? extends E> c) { - return this.addItemsToCollection(c, this.collection, VALUES); - } - - public boolean removeAll(Collection<?> c) { - return this.removeItemsFromCollection(c, this.collection, VALUES); - } - - public boolean retainAll(Collection<?> c) { - return this.retainItemsInCollection(c, this.collection, VALUES); - } - - public void clear() { - this.clearCollection(this.collection, VALUES); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ((o instanceof Collection) && (o instanceof CollectionValueModel)) { - Collection<E> c1 = CollectionTools.collection(this.collection); - @SuppressWarnings("unchecked") - Collection<E> c2 = CollectionTools.collection(((Collection<E>) o).iterator()); - return c1.equals(c2); - } - return false; - } - - @Override - public int hashCode() { - return CollectionTools.collection(this.collection).hashCode(); - } - - - // ********** additional behavior ********** - - /** - * Allow the collection to be replaced. - */ - public void setCollection(Collection<E> collection) { - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - this.fireCollectionChanged(VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.collection); - } - - - // ********** iterator ********** - - private class LocalIterator<T> implements Iterator<T> { - private final Iterator<T> iterator; - private T next; - - LocalIterator(Iterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - return this.next = this.iterator.next(); - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleCollectionValueModel.this.fireItemRemoved(VALUES, this.next); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java deleted file mode 100644 index e6aca61c50..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimpleListValueModel.java +++ /dev/null @@ -1,316 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Implementation of ListValueModel and List that simply holds a - * collection and notifies listeners of any changes. - */ -public class SimpleListValueModel<E> - extends AbstractModel - implements ListValueModel<E>, List<E> -{ - /** The list. */ - protected List<E> list; - - - // ********** constructors ********** - - /** - * Construct a ListValueModel for the specified list. - */ - public SimpleListValueModel(List<E> list) { - super(); - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - } - - /** - * Construct a ListValueModel with an empty initial list. - */ - public SimpleListValueModel() { - this(new ArrayList<E>()); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return new LocalIterator<E>(this.list.iterator()); - } - - public ListIterator<E> listIterator() { - return new LocalListIterator<E>(this.list.listIterator()); - } - - public int size() { - return this.list.size(); - } - - public E get(int index) { - return this.list.get(index); - } - - - // ********** List implementation ********** - - public boolean isEmpty() { - return this.list.isEmpty(); - } - - public boolean contains(Object o) { - return this.list.contains(o); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - public <T extends Object> T[] toArray(T[] a) { - return this.list.toArray(a); - } - - public boolean add(E o) { - return this.addItemToList(o, this.list, LIST_VALUES); - } - - public boolean remove(Object o) { - return this.removeItemFromList(o, this.list, LIST_VALUES); - } - - public boolean containsAll(Collection<?> c) { - return this.list.containsAll(c); - } - - public boolean addAll(Collection<? extends E> c) { - return this.addItemsToList(c, this.list, LIST_VALUES); - } - - public boolean addAll(int index, Collection<? extends E> c) { - return this.addItemsToList(index, c, this.list, LIST_VALUES); - } - - public boolean removeAll(Collection<?> c) { - return this.removeItemsFromList(c, this.list, LIST_VALUES); - } - - public boolean retainAll(Collection<?> c) { - return this.retainItemsInList(c, this.list, LIST_VALUES); - } - - public void clear() { - this.clearList(this.list, LIST_VALUES); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ((o instanceof List) && (o instanceof ListValueModel)) { - List<E> l1 = CollectionTools.list(this.list); - @SuppressWarnings("unchecked") - List<E> l2 = CollectionTools.list(((List<E>) o).iterator()); - return l1.equals(l2); - } - return false; - } - - @Override - public int hashCode() { - return this.list.hashCode(); - } - - public E set(int index, E element) { - return this.setItemInList(index, element, this.list, LIST_VALUES); - } - - public void add(int index, E element) { - this.addItemToList(index, element, this.list, LIST_VALUES); - } - - public E remove(int index) { - return this.removeItemFromList(index, this.list, LIST_VALUES); - } - - public int indexOf(Object o) { - return this.list.indexOf(o); - } - - public int lastIndexOf(Object o) { - return this.list.lastIndexOf(o); - } - - public ListIterator<E> listIterator(int index) { - return new LocalListIterator<E>(this.list.listIterator(index)); - } - - public List<E> subList(int fromIndex, int toIndex) { - // TODO hmmm ~bjv - throw new UnsupportedOperationException(); - } - - - // ********** additional behavior ********** - - /** - * Allow the list to be replaced. - */ - public void setList(List<E> list) { - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - this.fireListChanged(LIST_VALUES); - } - - /** - * Move a single element. - */ - public void move(int targetIndex, int sourceIndex) { - this.moveItemInList(targetIndex, sourceIndex, this.list, LIST_VALUES); - } - - /** - * Move a sub-list of elements. - */ - public void move(int targetIndex, int sourceIndex, int length) { - this.moveItemsInList(targetIndex, sourceIndex, length, this.list, LIST_VALUES); - } - - /** - * Remove a range of elements. - */ - public void remove(int index, int length) { - this.removeItemsFromList(index, length, this.list, LIST_VALUES); - } - - /** - * Set a range of elements. - */ - public void set(int index, List<E> elements) { - this.setItemsInList(index, elements, this.list, LIST_VALUES); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.list); - } - - - // ********** iterators ********** - - private class LocalIterator<T> implements Iterator<T> { - private final Iterator<T> iterator; - private int index = -1; - private T next; - - LocalIterator(Iterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - this.next = this.iterator.next(); - this.index++; - return this.next; - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.index, this.next); - } - - } - - private class LocalListIterator<T> implements ListIterator<T> { - private final ListIterator<T> iterator; - private int last = -1; - private int next = 0; - private T current; - - LocalListIterator(ListIterator<T> iterator) { - super(); - this.iterator = iterator; - } - - public boolean hasNext() { - return this.iterator.hasNext(); - } - - public T next() { - this.current = this.iterator.next(); - this.last = this.next++; - return this.current; - } - - public int nextIndex() { - return this.iterator.nextIndex(); - } - - public boolean hasPrevious() { - return this.iterator.hasPrevious(); - } - - public T previous() { - this.current = this.iterator.previous(); - this.last = --this.next; - return this.current; - } - - public int previousIndex() { - return this.iterator.previousIndex(); - } - - @SuppressWarnings("synthetic-access") - public void set(T o) { - this.iterator.set(o); - SimpleListValueModel.this.fireItemReplaced(LIST_VALUES, this.last, o, this.current); - } - - @SuppressWarnings("synthetic-access") - public void add(T o) { - this.iterator.add(o); - SimpleListValueModel.this.fireItemAdded(LIST_VALUES, this.next, o); - } - - @SuppressWarnings("synthetic-access") - public void remove() { - this.iterator.remove(); - SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.last, this.current); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java deleted file mode 100644 index e7248e65c5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SimplePropertyValueModel.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.internal.model.SingleAspectChangeSupport; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Implementation of WritablePropertyValueModel that simply holds on to an - * object and uses it as the value. - */ -public class SimplePropertyValueModel<T> - extends AbstractModel - implements WritablePropertyValueModel<T> -{ - /** The value. */ - protected T value; - - - /** - * Construct a PropertyValueModel for the specified value. - */ - public SimplePropertyValueModel(T value) { - super(); - this.value = value; - } - - /** - * Construct a PropertyValueModel with a starting value of null. - */ - public SimplePropertyValueModel() { - this(null); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new SingleAspectChangeSupport(this, PropertyChangeListener.class, VALUE); - } - - - public T getValue() { - return this.value; - } - - public void setValue(T value) { - T old = this.value; - this.value = value; - this.firePropertyChanged(VALUE, old, value); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java deleted file mode 100644 index 2194ba4cb2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/SortedListValueModelAdapter.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.Range; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to make a <code>CollectionValueModel</code> - * (or <code>ListValueModel</code>) behave like a <code>ListValueModel</code> - * that keeps its contents sorted and notifies listeners appropriately. - * <p> - * The comparator can be changed at any time; allowing the same - * adapter to be used with different sort criteria (e.g. when the user - * wants to sort a list of files first by name, then by date, then by size). - * <p> - * NB: Since we only listen to the wrapped collection when we have - * listeners ourselves and we can only stay in synch with the wrapped - * collection while we are listening to it, results to various methods - * (e.g. <code>#size()</code>, <code>#getItem(int)</code>) will be - * unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - */ -public class SortedListValueModelAdapter<E> - extends CollectionListValueModelAdapter<E> -{ - /** - * A comparator used for sorting the elements; - * if it is null, we use "natural ordering". - */ - protected Comparator<E> comparator; - - - // ********** constructors ********** - - /** - * Wrap the specified collection value model and sort its contents - * using the specified comparator. - */ - public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder, Comparator<E> comparator) { - super(collectionHolder); - this.comparator = comparator; - } - - /** - * Wrap the specified collection value model and sort its contents - * based on the elements' "natural ordering". - */ - public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) { - this(collectionHolder, null); - } - - /** - * Wrap the specified list value model and sort its contents - * using the specified comparator. - */ - public SortedListValueModelAdapter(ListValueModel<? extends E> listHolder, Comparator<E> comparator) { - this(new ListCollectionValueModelAdapter<E>(listHolder), comparator); - } - - /** - * Wrap the specified list value model and sort its contents - * based on the elements' "natural ordering". - */ - public SortedListValueModelAdapter(ListValueModel<? extends E> listHolder) { - this(listHolder, null); - } - - - // ********** accessors ********** - - public void setComparator(Comparator<E> comparator) { - this.comparator = comparator; - this.sortList(); - } - - - // ********** behavior ********** - - /** - * Sort the internal list before - * sending out change notification. - */ - @Override - protected void postBuildList() { - super.postBuildList(); - Collections.sort(this.list, this.comparator); - } - - /** - * the list will need to be sorted after the item is added - */ - @Override - protected void itemsAdded(CollectionChangeEvent event) { - // first add the items and notify our listeners... - super.itemsAdded(event); - // ...then sort the list - this.sortList(); - } - - /** - * sort the list and notify our listeners, if necessary; - */ - protected void sortList() { - // save the unsorted state of the sorted list so we can minimize the number of "replaced" items - @SuppressWarnings("unchecked") - ArrayList<E> unsortedList = (ArrayList<E>) this.list.clone(); - Collections.sort(this.list, this.comparator); - Range diffRange = CollectionTools.identityDiffRange(unsortedList, this.list); - if (diffRange.size > 0) { - List<E> unsortedItems = unsortedList.subList(diffRange.start, diffRange.end + 1); - List<E> sortedItems = this.list.subList(diffRange.start, diffRange.end + 1); - this.fireItemsReplaced(LIST_VALUES, diffRange.start, sortedItems, unsortedItems); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java deleted file mode 100644 index db6c0c916f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StatePropertyValueModelAdapter.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; - -/** - * This abstract class provides the infrastructure needed to wrap - * a model, "lazily" listen to it, and convert - * its state change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current model - * - * Subclasses might want to override: - * - #stateChanged(StateChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class StatePropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<T> -{ - /** The wrapped model. */ - protected final Model model; - - /** A listener that allows us to synch with changes to the wrapped model. */ - protected final StateChangeListener stateChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped model. - */ - protected StatePropertyValueModelAdapter(Model model) { - super(); - this.model = model; - this.stateChangeListener = this.buildStateChangeListener(); - } - - protected StateChangeListener buildStateChangeListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - StatePropertyValueModelAdapter.this.stateChanged(event); - } - @Override - public String toString() { - return "state change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the model. - */ - @Override - protected void engageModel_() { - this.model.addStateChangeListener(this.stateChangeListener); - } - - /** - * Stop listening to the model. - */ - @Override - protected void disengageModel_() { - this.model.removeStateChangeListener(this.stateChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.model); - } - - - // ********** state change support ********** - - /** - * The model's state changed; - * propagate the change notification appropriately. - */ - protected void stateChanged(StateChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java deleted file mode 100644 index 4cbcba4527..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticCollectionValueModel.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; - -/** - * Implementation of CollectionValueModel that can be used for - * returning an iterator on a static collection, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticCollectionValueModel<E> - extends AbstractModel - implements CollectionValueModel<E> -{ - /** The collection. */ - protected final Collection<? extends E> collection; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static CollectionValueModel for the specified collection. - */ - public StaticCollectionValueModel(Collection<? extends E> collection) { - super(); - if (collection == null) { - throw new NullPointerException(); - } - this.collection = collection; - } - - // ********** CollectionValueModel implementation ********** - - public int size() { - return this.collection.size(); - } - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.collection.iterator()); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.collection); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java deleted file mode 100644 index 3ddae7920d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticListValueModel.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * Implementation of ListValueModel that can be used for - * returning a list iterator on a static list, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticListValueModel<E> - extends AbstractModel - implements ListValueModel<E> -{ - /** The value. */ - protected final List<? extends E> list; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static ListValueModel for the specified list. - */ - public StaticListValueModel(List<? extends E> list) { - super(); - if (list == null) { - throw new NullPointerException(); - } - this.list = list; - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E> iterator() { - return new ReadOnlyIterator<E>(this.list.iterator()); - } - - public ListIterator<E> listIterator() { - return new ReadOnlyListIterator<E>(this.list.listIterator()); - } - - public int size() { - return this.list.size(); - } - - public E get(int index) { - return this.list.get(index); - } - - public Object[] toArray() { - return this.list.toArray(); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.list); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java deleted file mode 100644 index e5eccf3ae2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticPropertyValueModel.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * Implementation of PropertyValueModel that can be used for - * returning a static value, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticPropertyValueModel<T> - extends AbstractModel - implements PropertyValueModel<T> -{ - /** The value. */ - protected final T value; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a static PropertyValueModel for the specified value. - */ - public StaticPropertyValueModel(T value) { - super(); - this.value = value; - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.value; - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java deleted file mode 100644 index 6c435a3238..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/StaticTreeValueModel.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * Implementation of TreeValueModel that can be used for - * returning an iterator on a static tree, but still allows listeners to be added. - * Listeners will NEVER be notified of any changes, because there should be none. - */ -public class StaticTreeValueModel<E> - extends AbstractModel - implements TreeValueModel<E> -{ - /** The tree's nodes. */ - protected final Iterable<? extends E> nodes; - - private static final long serialVersionUID = 1L; - - - /** - * Construct a read-only TreeValueModel for the specified nodes. - */ - public StaticTreeValueModel(Iterable<? extends E> nodes) { - super(); - if (nodes == null) { - throw new NullPointerException(); - } - this.nodes = nodes; - } - - // ********** TreeValueModel implementation ********** - - public Iterator<E> nodes() { - return new ReadOnlyIterator<E>(this.nodes.iterator()); - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, CollectionTools.collection(this.nodes())); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java deleted file mode 100644 index f1a7c1f877..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationListValueModelAdapter.java +++ /dev/null @@ -1,241 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * An adapter that allows us to transform a ListValueModel - * (or CollectionValueModel) into a read-only ListValueModel - * whose items are tranformations of the items in the wrapped - * ListValueModel. It will keep its contents in synch with - * the contents of the wrapped ListValueModel and notifies its - * listeners of any changes. - * <p> - * The transformer can be changed at any time; allowing the same - * adapter to be used with different transformations. - * <p> - * NB: Since we only listen to the wrapped list when we have - * listeners ourselves and we can only stay in synch with the wrapped - * list while we are listening to it, results to various methods - * (e.g. #size(), #getItem(int)) will be unpredictable whenever - * we do not have any listeners. This should not be too painful since, - * most likely, client objects will also be listeners. - */ -public class TransformationListValueModelAdapter<E1, E2> - extends ListValueModelWrapper<E1> - implements ListValueModel<E2> -{ - - /** This transforms the items, unless the subclass overrides #transformItem(Object). */ - protected Transformer<E1, E2> transformer; - - /** The list of transformed items. */ - protected final List<E2> transformedList; - - - // ********** constructors ********** - - /** - * Constructor - the list holder is required. - */ - public TransformationListValueModelAdapter(ListValueModel<? extends E1> listHolder, Transformer<E1, E2> transformer) { - super(listHolder); - this.transformer = transformer; - this.transformedList = new ArrayList<E2>(); - } - - /** - * Constructor - the list holder is required. - */ - public TransformationListValueModelAdapter(ListValueModel<? extends E1> listHolder) { - this(listHolder, Transformer.Null.<E1, E2>instance()); - } - - /** - * Constructor - the collection holder is required. - */ - public TransformationListValueModelAdapter(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, E2> transformer) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder), transformer); - } - - /** - * Constructor - the collection holder is required. - */ - public TransformationListValueModelAdapter(CollectionValueModel<? extends E1> collectionHolder) { - this(new CollectionListValueModelAdapter<E1>(collectionHolder)); - } - - - // ********** ListValueModel implementation ********** - - public Iterator<E2> iterator() { - return this.listIterator(); - } - - public ListIterator<E2> listIterator() { - return new ReadOnlyListIterator<E2>(this.transformedList); - } - - public E2 get(int index) { - return this.transformedList.get(index); - } - - public int size() { - return this.transformedList.size(); - } - - public Object[] toArray() { - return this.transformedList.toArray(); - } - - // ********** behavior ********** - - @Override - protected void engageModel() { - super.engageModel(); - // synch the transformed list *after* we start listening to the list holder, - // since its value might change when a listener is added - this.transformedList.addAll(this.transformItems(this.listHolder)); - } - - @Override - protected void disengageModel() { - super.disengageModel(); - // clear out the list when we are not listening to the collection holder - this.transformedList.clear(); - } - - /** - * Transform the items associated with the specified event. - */ - protected List<E2> transformItems(ListChangeEvent event) { - return this.transformItems(this.items(event), event.itemsSize()); - } - - /** - * Transform the items in the specified list value model. - */ - protected List<E2> transformItems(ListValueModel<? extends E1> lvm) { - return this.transformItems(lvm.listIterator(), lvm.size()); - } - - /** - * Transform the replaced items associated with the specified event. - */ - protected List<E2> transformReplacedItems(ListChangeEvent event) { - return this.transformItems(this.replacedItems(event), event.itemsSize()); - } - - /** - * Transform the specified items. - */ - protected List<E2> transformItems(ListIterator<? extends E1> items, int size) { - List<E2> result = new ArrayList<E2>(size); - while (items.hasNext()) { - result.add(this.transformItem(items.next())); - } - return result; - } - - /** - * Transform the specified item. - */ - protected E2 transformItem(E1 item) { - return this.transformer.transform(item); - } - - /** - * Change the transformer and rebuild the collection. - */ - public void setTransformer(Transformer<E1, E2> transformer) { - this.transformer = transformer; - this.rebuildTransformedList(); - } - - /** - * Synchronize our cache with the wrapped collection. - */ - protected void rebuildTransformedList() { - this.transformedList.clear(); - this.transformedList.addAll(this.transformItems(this.listHolder)); - this.fireListChanged(LIST_VALUES); - } - - - // ********** list change support ********** - - /** - * Items were added to the wrapped list holder. - * Transform them, add them to our transformation list, - * and notify our listeners. - */ - @Override - protected void itemsAdded(ListChangeEvent event) { - this.addItemsToList(event.getIndex(), this.transformItems(event), this.transformedList, LIST_VALUES); - } - - /** - * Items were removed from the wrapped list holder. - * Remove the corresponding items from our transformation list - * and notify our listeners. - */ - @Override - protected void itemsRemoved(ListChangeEvent event) { - this.removeItemsFromList(event.getIndex(), event.itemsSize(), this.transformedList, LIST_VALUES); - } - - /** - * Items were replaced in the wrapped list holder. - * Replace the corresponding items in our transformation list - * and notify our listeners. - */ - @Override - protected void itemsReplaced(ListChangeEvent event) { - this.setItemsInList(event.getIndex(), this.transformItems(event), this.transformedList, LIST_VALUES); - } - - /** - * Items were moved in the wrapped list holder. - * Move the corresponding items in our transformation list - * and notify our listeners. - */ - @Override - protected void itemsMoved(ListChangeEvent event) { - this.moveItemsInList(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength(), this.transformedList, LIST_VALUES); - } - - /** - * The wrapped list holder was cleared. - * Clear our transformation list and notify our listeners. - */ - @Override - protected void listCleared(ListChangeEvent event) { - this.clearList(this.transformedList, LIST_VALUES); - } - - /** - * The wrapped list holder has changed in some dramatic fashion. - * Rebuild our transformation list and notify our listeners. - */ - @Override - protected void listChanged(ListChangeEvent event) { - this.rebuildTransformedList(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java deleted file mode 100644 index ba878e5c19..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationPropertyValueModel.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.Transformer; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * A <code>TransformationPropertyValueModel</code> wraps another - * <code>PropertyValueModel</code> and uses a <code>Transformer</code> - * to transform the wrapped value before it is returned by <code>value()</code>. - * <p> - * As an alternative to building a <code>Transformer</code>, - * a subclass of <code>TransformationPropertyValueModel</code> can - * either override the <code>transform_(Object)</code> method or, - * if something other than null should be returned when the wrapped value - * is null, override the <code>transform(Object)</code> method. - */ -public class TransformationPropertyValueModel<T1, T2> - extends PropertyValueModelWrapper<T1> - implements PropertyValueModel<T2> -{ - protected final Transformer<T1, T2> transformer; - - - // ********** constructors/initialization ********** - - /** - * Construct a property value model with the specified nested - * property value model and the default transformer. - * Use this constructor if you want to override the - * <code>transform_(Object)</code> or <code>transform(Object)</code> - * method instead of building a <code>Transformer</code>. - */ - public TransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder) { - super(valueHolder); - this.transformer = this.buildTransformer(); - } - - /** - * Construct an property value model with the specified nested - * property value model and transformer. - */ - public TransformationPropertyValueModel(PropertyValueModel<? extends T1> valueHolder, Transformer<T1, T2> transformer) { - super(valueHolder); - this.transformer = transformer; - } - - protected Transformer<T1, T2> buildTransformer() { - return new DefaultTransformer(); - } - - - // ********** PropertyValueModel implementation ********** - - public T2 getValue() { - // transform the object returned by the nested value model before returning it - return this.transform(this.valueHolder.getValue()); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - // transform the values before propagating the change event - @SuppressWarnings("unchecked") - Object oldValue = this.transformOld((T1) event.getOldValue()); - @SuppressWarnings("unchecked") - Object newValue = this.transformNew((T1) event.getNewValue()); - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - - // ********** behavior ********** - - /** - * Transform the specified value and return the result. - * This is called by #value() and #valueChanged(PropertyChangeEvent). - */ - protected T2 transform(T1 value) { - return this.transformer.transform(value); - } - - /** - * Transform the specified, non-null, value and return the result. - */ - protected T2 transform_(@SuppressWarnings("unused") T1 value) { - throw new UnsupportedOperationException(); - } - - /** - * Transform the specified old value and return the result. - * By default, call {@link #transform(Object)}. - * This is called by {@link #valueChanged(PropertyChangeEvent)}. - */ - protected T2 transformOld(T1 value) { - return this.transform(value); - } - - /** - * Transform the specified new value and return the result. - * By default, call {@link #transform(Object)}. - * This is called by {@link #valueChanged(PropertyChangeEvent)}. - */ - protected T2 transformNew(T1 value) { - return this.transform(value); - } - - // ********** default transformer ********** - - /** - * The default transformer will return null if the wrapped value is null. - * If the wrapped value is not null, it is transformed by a subclass - * implementation of #transform_(Object). - */ - protected class DefaultTransformer implements Transformer<T1, T2> { - public T2 transform(T1 value) { - return (value == null) ? null : TransformationPropertyValueModel.this.transform_(value); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java deleted file mode 100644 index 1299097bf7..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TransformationWritablePropertyValueModel.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.BidiTransformer; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * A <code>TransformationWritablePropertyValueModel</code> wraps another - * <code>WritablePropertyValueModel</code> and uses a <code>BidiTransformer</code> - * to:<ul> - * <li>transform the wrapped value before it is returned by <code>value()</code> - * <li>"reverse-transform" the new value that comes in via - * <code>setValue(Object)</code> - * </ul> - * As an alternative to building a <code>BidiTransformer</code>, - * a subclass of <code>TransformationWritablePropertyValueModel</code> can - * override the <code>transform_(Object)</code> and - * <code>reverseTransform_(Object)</code> methods; or, - * if something other than null should be returned when the wrapped value - * is null or the new value is null, override the <code>transform(Object)</code> - * and <code>reverseTransform(Object)</code> methods. - */ -public class TransformationWritablePropertyValueModel<T1, T2> - extends TransformationPropertyValueModel<T1, T2> - implements WritablePropertyValueModel<T2> -{ - - // ********** constructors/initialization ********** - - /** - * Construct a writable property value model with the specified nested - * writable property value model and the default bidi transformer. - * Use this constructor if you want to override the - * <code>transform_(Object)</code> and <code>reverseTransform_(Object)</code> - * (or <code>transform(Object)</code> and <code>reverseTransform(Object)</code>) - * methods instead of building a <code>BidiTransformer</code>. - */ - public TransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder) { - super(valueHolder); - } - - /** - * Construct a writable property value model with the specified nested - * writable property value model and bidi transformer. - */ - public TransformationWritablePropertyValueModel(WritablePropertyValueModel<T1> valueHolder, BidiTransformer<T1, T2> transformer) { - super(valueHolder, transformer); - } - - @Override - protected BidiTransformer<T1, T2> buildTransformer() { - return new DefaultBidiTransformer(); - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T2 value) { - // "reverse-transform" the object before passing it to the the nested value model - this.valueHolder().setValue(this.reverseTransform(value)); - } - - - // ********** behavior ********** - - /** - * "Reverse-transform" the specified value and return the result. - * This is called by #setValue(Object). - */ - protected T1 reverseTransform(T2 value) { - return this.transformer().reverseTransform(value); - } - - /** - * "Reverse-transform" the specified, non-null, value and return the result. - */ - protected T1 reverseTransform_(@SuppressWarnings("unused") T2 value) { - throw new UnsupportedOperationException(); - } - - - // ********** queries ********** - - /** - * Our constructors accept only a WritablePropertyValueModel<T1>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T1> valueHolder() { - return (WritablePropertyValueModel<T1>) this.valueHolder; - } - - /** - * Our constructors accept only a bidirectional transformer. - */ - protected BidiTransformer<T1, T2> transformer() { - return (BidiTransformer<T1, T2>) this.transformer; - } - - - // ********** default bidi transformer ********** - - /** - * The default bidi transformer will return null if the wrapped value is null. - * If the wrapped value is not null, it is transformed by a subclass - * implementation of #transform_(Object). - * The default bidi transformer will also return null if the new value is null. - * If the new value is not null, it is reverse-transformed by a subclass - * implementation of #reverseTransform_(Object). - */ - protected class DefaultBidiTransformer - extends DefaultTransformer - implements BidiTransformer<T1, T2> - { - public T1 reverseTransform(T2 value) { - return (value == null) ? null : TransformationWritablePropertyValueModel.this.reverseTransform_(value); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java deleted file mode 100644 index 739bb97012..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreeAspectAdapter.java +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * This extension of PropertyAdapter provides TreeChange support. - * This allows us to convert a set of one or more trees into - * a single tree, NODES. - * - * The typical subclass will override the following methods: - * #nodes_() - * at the very minimum, override this method to return an iterator - * on the subject's tree aspect; it does not need to be overridden if - * #nodes() is overridden and its behavior changed - * #nodes() - * override this method only if returning an empty iterator when the - * subject is null is unacceptable - */ -public abstract class TreeAspectAdapter<S extends Model, E> - extends AspectAdapter<S> - implements TreeValueModel<E> -{ - /** - * The name of the subject's trees that we use for the value. - */ - protected final String[] treeNames; - protected static final String[] EMPTY_TREE_NAMES = new String[0]; - - /** A listener that listens to the subject's tree aspect. */ - protected final TreeChangeListener treeChangeListener; - - - // ********** constructors ********** - - /** - * Construct a TreeAspectAdapter for the specified subject - * and tree. - */ - protected TreeAspectAdapter(String treeName, S subject) { - this(new String[] {treeName}, subject); - } - - /** - * Construct a TreeAspectAdapter for the specified subject - * and trees. - */ - protected TreeAspectAdapter(String[] treeNames, S subject) { - this(new StaticPropertyValueModel<S>(subject), treeNames); - } - - /** - * Construct a TreeAspectAdapter for the specified subject holder - * and trees. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder, String... treeNames) { - super(subjectHolder); - this.treeNames = treeNames; - this.treeChangeListener = this.buildTreeChangeListener(); - } - - /** - * Construct a TreeAspectAdapter for the specified subject holder - * and trees. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder, Collection<String> treeNames) { - this(subjectHolder, treeNames.toArray(new String[treeNames.size()])); - } - - /** - * Construct a TreeAspectAdapter for an "unchanging" tree in - * the specified subject. This is useful for a tree aspect that does not - * change for a particular subject; but the subject will change, resulting in - * a new tree. - */ - protected TreeAspectAdapter(PropertyValueModel<? extends S> subjectHolder) { - this(subjectHolder, EMPTY_TREE_NAMES); - } - - - // ********** initialization ********** - - /** - * The subject's tree aspect has changed, notify the listeners. - */ - protected TreeChangeListener buildTreeChangeListener() { - // transform the subject's tree change events into VALUE tree change events - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - TreeAspectAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeChangeEvent event) { - TreeAspectAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeChangeEvent event) { - TreeAspectAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - TreeAspectAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "tree change listener: " + Arrays.asList(TreeAspectAdapter.this.treeNames); - } - }; - } - - - // ********** TreeValueModel implementation ********** - - /** - * Return the nodes of the subject's tree aspect. - */ - public Iterator<E> nodes() { - return (this.subject == null) ? EmptyIterator.<E>instance() : this.nodes_(); - } - - /** - * Return the nodes of the subject's tree aspect. - * At this point we can be sure that the subject is not null. - * @see #nodes() - */ - protected Iterator<E> nodes_() { - throw new UnsupportedOperationException(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.nodes(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return TreeChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return NODES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyTreeChangeListeners(NODES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireTreeChanged(NODES); - } - - @Override - protected void engageSubject_() { - for (String treeName : this.treeNames) { - ((Model) this.subject).addTreeChangeListener(treeName, this.treeChangeListener); - } - } - - @Override - protected void disengageSubject_() { - for (String treeName : this.treeNames) { - ((Model) this.subject).removeTreeChangeListener(treeName, this.treeChangeListener); - } - } - - @Override - public void toString(StringBuilder sb) { - for (int i = 0; i < this.treeNames.length; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(this.treeNames[i]); - } - } - - - // ********** behavior ********** - - protected void nodeAdded(TreeChangeEvent event) { - this.fireNodeAdded(NODES, event.getPath()); - } - - protected void nodeRemoved(TreeChangeEvent event) { - this.fireNodeRemoved(NODES, event.getPath()); - } - - protected void treeCleared(TreeChangeEvent event) { - this.fireTreeCleared(NODES); - } - - protected void treeChanged(TreeChangeEvent event) { - this.fireTreeChanged(NODES, event.getPath()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java deleted file mode 100644 index 11b6f1a2b9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/TreePropertyValueModelAdapter.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.TreeValueModel; - -/** - * This abstract class provides the infrastructure needed to wrap - * a tree value model, "lazily" listen to it, and convert - * its change notifications into property value model change - * notifications. - * - * Subclasses must override: - * - #buildValue() - * to return the current property value, as derived from the - * current collection value - * - * Subclasses might want to override: - * - #stateChanged(StateChangeEvent event) - * to improve performance (by not recalculating the value, if possible) - */ -public abstract class TreePropertyValueModelAdapter<T> - extends AspectPropertyValueModelAdapter<T> -{ - /** The wrapped tree value model. */ - protected final TreeValueModel<?> treeHolder; - - /** A listener that allows us to synch with changes to the wrapped tree holder. */ - protected final TreeChangeListener treeChangeListener; - - - // ********** constructor/initialization ********** - - /** - * Construct a property value model with the specified wrapped - * tree value model. - */ - protected TreePropertyValueModelAdapter(TreeValueModel<?> treeHolder) { - super(); - this.treeHolder = treeHolder; - this.treeChangeListener = this.buildTreeChangeListener(); - } - - protected TreeChangeListener buildTreeChangeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.nodeAdded(event); - } - public void nodeRemoved(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.nodeRemoved(event); - } - public void treeCleared(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.treeCleared(event); - } - public void treeChanged(TreeChangeEvent event) { - TreePropertyValueModelAdapter.this.treeChanged(event); - } - @Override - public String toString() { - return "tree change listener"; - } - }; - } - - - // ********** behavior ********** - - /** - * Start listening to the tree holder. - */ - @Override - protected void engageModel_() { - this.treeHolder.addTreeChangeListener(this.treeChangeListener); - } - - /** - * Stop listening to the tree holder. - */ - @Override - protected void disengageModel_() { - this.treeHolder.removeTreeChangeListener(this.treeChangeListener); - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.treeHolder); - } - - - // ********** state change support ********** - - /** - * Nodes were added to the wrapped tree holder; - * propagate the change notification appropriately. - */ - protected void nodeAdded(TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * Nodes were removed from the wrapped tree holder; - * propagate the change notification appropriately. - */ - protected void nodeRemoved(TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped tree holder was cleared; - * propagate the change notification appropriately. - */ - protected void treeCleared(TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - - /** - * The wrapped tree holder changed; - * propagate the change notification appropriately. - */ - protected void treeChanged(TreeChangeEvent event) { - // by default, simply recalculate the value and fire an event - this.propertyChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java deleted file mode 100644 index 6fea2e865f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueAspectAdapter.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.internal.model.ChangeSupport; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Abstract model that provides behavior for wrapping a property - * value model and listening for changes to aspects of the *value* contained - * by the property value model. Changes to the actual value are also monitored. - * - * This is useful if you have a value that may change, but whose aspects can also - * change in a fashion that might be of interest to the client. - * - * NB: Clients will need to listen for two different change notifications: a property - * change event will be be fired when the value changes; a state change event - * will be fired when an aspect of the value changes. - * - * Subclasses need to override two methods: - * - * #engageValue_() - * begin listening to the appropriate aspect of the value and call - * #valueAspectChanged(Object) whenever the aspect changes - * - * #disengageValue_() - * stop listening to the appropriate aspect of the value - */ -public abstract class ValueAspectAdapter<T> - extends PropertyValueModelWrapper<T> - implements WritablePropertyValueModel<T> -{ - /** Cache the value so we can disengage. Null until we have a listener*/ - protected T value; - - - // ********** constructors/initialization ********** - - /** - * Constructor - the value holder is required. - */ - protected ValueAspectAdapter(WritablePropertyValueModel<T> valueHolder) { - super(valueHolder); - } - - /** - * Override to allow both property value model change and state change - * listeners. - */ - @Override - protected ChangeSupport buildChangeSupport() { - return new ChangeSupport(this); - } - - - // ********** PropertyValueModel implementation ********** - - public T getValue() { - return this.value; - } - - - // ********** WritablePropertyValueModel implementation ********** - - public void setValue(T value) { - this.valueHolder().setValue(value); - } - - - // ********** PropertyValueModelWrapper implementation ********** - - @Override - protected void valueChanged(PropertyChangeEvent event) { - this.disengageValue(); - this.engageValue(); - this.firePropertyChanged(event.cloneWithSource(this)); - } - - - // ********** extend change support ********** - - @Override - public synchronized void addStateChangeListener(StateChangeListener listener) { - if (this.hasNoStateChangeListeners()) { - this.engageValue(); - } - super.addStateChangeListener(listener); - } - - @Override - public synchronized void removeStateChangeListener(StateChangeListener listener) { - super.removeStateChangeListener(listener); - if (this.hasNoStateChangeListeners()) { - this.disengageValue(); - } - } - - - // ********** behavior ********** - - /** - * Start listening to the current value. - */ - protected void engageValue() { - this.value = this.valueHolder.getValue(); - if (this.value != null) { - this.engageValue_(); - } - } - - /** - * Start listening to the current value. - * At this point we can be sure that the value is not null. - */ - protected abstract void engageValue_(); - - /** - * Stop listening to the current value. - */ - protected void disengageValue() { - if (this.value != null) { - this.disengageValue_(); - this.value = null; - } - } - - /** - * Stop listening to the current value. - * At this point we can be sure that the value is not null. - */ - protected abstract void disengageValue_(); - - /** - * Subclasses should call this method whenever the value's aspect changes. - */ - protected void valueAspectChanged() { - this.fireStateChanged(); - } - - /** - * Our constructors accept only a WritablePropertyValueModel<T1>. - */ - @SuppressWarnings("unchecked") - protected WritablePropertyValueModel<T> valueHolder() { - return (WritablePropertyValueModel<T>) this.valueHolder; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java deleted file mode 100644 index 069fc0e2e0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueCollectionAdapter.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more collection - * aspects of the value in the wrapped value model. - */ -public class ValueCollectionAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - - /** The names of the value's collections that we listen to. */ - protected final String[] collectionNames; - - /** Listener that listens to the value. */ - protected final CollectionChangeListener valueCollectionListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value collections. - */ - public ValueCollectionAdapter(WritablePropertyValueModel<T> valueHolder, String... collectionNames) { - super(valueHolder); - this.collectionNames = collectionNames; - this.valueCollectionListener = this.buildValueCollectionListener(); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a Collection aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected CollectionChangeListener buildValueCollectionListener() { - return new CollectionChangeListener() { - public void itemsAdded(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void itemsRemoved(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void collectionCleared(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - public void collectionChanged(CollectionChangeEvent event) { - ValueCollectionAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value collection listener: " + Arrays.asList(ValueCollectionAdapter.this.collectionNames); - } - }; - } - - @Override - protected void engageValue_() { - for (String collectionName : this.collectionNames) { - this.value.addCollectionChangeListener(collectionName, this.valueCollectionListener); - } - } - - @Override - protected void disengageValue_() { - for (String collectionName : this.collectionNames) { - this.value.removeCollectionChangeListener(collectionName, this.valueCollectionListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java deleted file mode 100644 index 85cb429f8f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueListAdapter.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more list - * aspects of the value in the wrapped value model. - */ -public class ValueListAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - - /** The names of the value's lists that we listen to. */ - protected final String[] listNames; - - /** Listener that listens to the value. */ - protected final ListChangeListener valueListListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value lists. - */ - public ValueListAdapter(WritablePropertyValueModel<T> valueHolder, String... listNames) { - super(valueHolder); - this.listNames = listNames; - this.valueListListener = this.buildValueListListener(); - } - - - // ********** initialization ********** - - /** - * All we really care about is the fact that a List aspect has - * changed. Do the same thing no matter which event occurs. - */ - protected ListChangeListener buildValueListListener() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsRemoved(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsReplaced(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void itemsMoved(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void listCleared(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - public void listChanged(ListChangeEvent event) { - ValueListAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value list listener: " + Arrays.asList(ValueListAdapter.this.listNames); - } - }; - } - - @Override - protected void engageValue_() { - for (String listName : this.listNames) { - this.value.addListChangeListener(listName, this.valueListListener); - } - } - - @Override - protected void disengageValue_() { - for (String listName : this.listNames) { - this.value.removeListChangeListener(listName, this.valueListListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java deleted file mode 100644 index a3d7e01731..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValuePropertyAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more - * properties of the value in the wrapped value model. - */ -public class ValuePropertyAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** The names of the value's properties that we listen to. */ - protected final String[] propertyNames; - - /** Listener that listens to the value. */ - protected final PropertyChangeListener valuePropertyListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value properties. - */ - public ValuePropertyAdapter(WritablePropertyValueModel<T> valueHolder, String... propertyNames) { - super(valueHolder); - this.propertyNames = propertyNames; - this.valuePropertyListener = this.buildValuePropertyListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValuePropertyListener() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ValuePropertyAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value property listener: " + Arrays.asList(ValuePropertyAdapter.this.propertyNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageValue_() { - for (String propertyName : this.propertyNames) { - this.value.addPropertyChangeListener(propertyName, this.valuePropertyListener); - } - } - - @Override - protected void disengageValue_() { - for (String propertyName : this.propertyNames) { - this.value.removePropertyChangeListener(propertyName, this.valuePropertyListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java deleted file mode 100644 index d516fdbf1b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueStateAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to the - * "state" of the value in the wrapped value model. - */ -public class ValueStateAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** Listener that listens to value. */ - protected final StateChangeListener valueStateListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the value state. - */ - public ValueStateAdapter(WritablePropertyValueModel<T> valueHolder) { - super(valueHolder); - this.valueStateListener = this.buildValueStateListener(); - } - - - // ********** initialization ********** - - protected StateChangeListener buildValueStateListener() { - return new StateChangeListener() { - public void stateChanged(StateChangeEvent event) { - ValueStateAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value state listener"; - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageValue_() { - this.value.addStateChangeListener(this.valueStateListener); - } - - @Override - protected void disengageValue_() { - this.value.removeStateChangeListener(this.valueStateListener); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java deleted file mode 100644 index 41361ed37a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/ValueTreeAdapter.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value; - -import java.util.Arrays; -import org.eclipse.jpt.utility.model.Model; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * Extend ValueAspectAdapter to listen to one or more - * tree aspects of the value in the wrapped value model. - */ -public class ValueTreeAdapter<T extends Model> - extends ValueAspectAdapter<T> -{ - /** The names of the value's trees that we listen to. */ - protected final String[] treeNames; - - /** Listener that listens to the value. */ - protected final TreeChangeListener valueTreeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified value trees. - */ - public ValueTreeAdapter(WritablePropertyValueModel<T> valueHolder, String... treeNames) { - super(valueHolder); - this.treeNames = treeNames; - this.valueTreeListener = this.buildValueTreeListener(); - } - - - // ********** initialization ********** - - protected TreeChangeListener buildValueTreeListener() { - return new TreeChangeListener() { - public void nodeAdded(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void nodeRemoved(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void treeCleared(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - public void treeChanged(TreeChangeEvent event) { - ValueTreeAdapter.this.valueAspectChanged(); - } - @Override - public String toString() { - return "value tree listener: " + Arrays.asList(ValueTreeAdapter.this.treeNames); - } - }; - } - - - // ********** behavior ********** - - @Override - protected void engageValue_() { - for (String treeName : this.treeNames) { - this.value.addTreeChangeListener(treeName, this.valueTreeListener); - } - } - - @Override - protected void disengageValue_() { - for (String treeName : this.treeNames) { - this.value.removeTreeChangeListener(treeName, this.valueTreeListener); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java deleted file mode 100644 index 44a9d56e11..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java +++ /dev/null @@ -1,345 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.prefs; - -import java.util.prefs.PreferenceChangeEvent; -import java.util.prefs.PreferenceChangeListener; -import java.util.prefs.Preferences; -import org.eclipse.jpt.utility.internal.BidiStringConverter; -import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This adapter wraps a Preference and converts it into a PropertyValueModel. - * It listens for the appropriate "preference" changes and converts them into - * VALUE property changes. It also allows the specification of a default value - * for the Preference, which, by default, is null (and is probably *not* a very - * good default). - * - * You can configure whether the preference's value is returned, - * unchanged, as a string or as some other object (e.g. an Integer) by - * setting the adapter's converter. Internally, the preference's value - * is stored as the converted object; and the conversions take place - * when reading or writing from the preferences node or retrieving the - * value from an event fired by the preferences node. - * - * This adapter is a bit different from most other adapters because the - * change events fired off by a Preferences node are asynchronous from - * the change itself. (AbstractPreferences uses an event dispatch daemon.) - * As a result, a client can set our value with #setValue(Object) and we - * will return from that method before we ever receive notification from - * the Preferences node that *it* has changed. This means we cannot - * rely on that event to keep our internally cached value in synch. - */ -public class PreferencePropertyValueModel<P> - extends AspectAdapter<Preferences> - implements WritablePropertyValueModel<P> -{ - /** The key to the preference we use for the value. */ - protected final String key; - - /** - * Cache the current (object) value of the preference so we - * can pass an "old value" when we fire a property change event. - */ - protected P value; - - /** - * The default (object) value returned if there is no value - * associated with the preference. - */ - protected final P defaultValue; - - /** - * This converter is used to convert the preference's - * string value to and from an object. - */ - protected final BidiStringConverter<P> converter; - - /** A listener that listens to the appropriate preference. */ - protected final PreferenceChangeListener preferenceChangeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified preference. - * The default value of the preference will be null. - */ - public PreferencePropertyValueModel(Preferences preferences, String key) { - this(preferences, key, null); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(Preferences preferences, String key, P defaultValue) { - this(preferences, key, defaultValue, BidiStringConverter.Default.<P>instance()); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(Preferences preferences, String key, P defaultValue, BidiStringConverter<P> converter) { - this(new StaticPropertyValueModel<Preferences>(preferences), key, defaultValue, converter); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public static PreferencePropertyValueModel<Boolean> forBoolean(Preferences preferences, String key, boolean defaultValue) { - return new PreferencePropertyValueModel<Boolean>( - preferences, - key, - defaultValue ? Boolean.TRUE : Boolean.FALSE, - BidiStringConverter.BooleanConverter.instance() - ); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public static PreferencePropertyValueModel<Integer> forInteger(Preferences preferences, String key, int defaultValue) { - return new PreferencePropertyValueModel<Integer>( - preferences, - key, - new Integer(defaultValue), - BidiStringConverter.IntegerConverter.instance() - ); - } - - /** - * Construct an adapter for the specified preference. - * The default value of the preference will be null. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key) { - this(preferencesHolder, key, null); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key, P defaultValue) { - this(preferencesHolder, key, defaultValue, BidiStringConverter.Default.<P>instance()); - } - - /** - * Construct an adapter for the specified preference with - * the specified default value for the preference. - */ - public PreferencePropertyValueModel(PropertyValueModel<? extends Preferences> preferencesHolder, String key, P defaultValue, BidiStringConverter<P> converter) { - super(preferencesHolder); - this.key = key; - this.defaultValue = defaultValue; - this.converter = converter; - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - // our value is null when we are not listening to the preference - this.value = null; - } - - - // ********** initialization ********** - - /** - * A preference has changed, notify the listeners if necessary. - */ - protected PreferenceChangeListener buildPreferenceChangeListener() { - // transform the preference change events into VALUE property change events - return new PreferenceChangeListener() { - public void preferenceChange(PreferenceChangeEvent event) { - PreferencePropertyValueModel.this.preferenceChanged(event.getKey(), event.getNewValue()); - } - @Override - public String toString() { - return "preference change listener"; - } - }; - } - - - // ********** ValueModel implementation ********** - - /** - * Return the cached (converted) value. - */ - @Override - public synchronized P getValue() { - return this.value; - } - - - // ********** PropertyValueModel implementation ********** - - /** - * Set the cached value, then set the appropriate preference value. - */ - public synchronized void setValue(P value) { - if (this.hasNoListeners()) { - return; // no changes allowed when we have no listeners - } - - Object old = this.value; - this.value = value; - this.fireAspectChange(old, value); - - if ((this.subject != null) && this.shouldSetPreference(old, value)) { - this.setValue_(value); - } - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return PropertyChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUE; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyPropertyChangeListeners(VALUE); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.firePropertyChanged(VALUE, oldValue, newValue); - } - - @Override - protected void engageSubject_() { - this.subject.addPreferenceChangeListener(this.preferenceChangeListener); - this.value = this.buildValue(); - } - - @Override - protected void disengageSubject_() { - try { - this.subject.removePreferenceChangeListener(this.preferenceChangeListener); - } catch (IllegalStateException ex) { - // for some odd reason, we are not allowed to remove a listener from a "dead" - // preferences node; so handle the exception that gets thrown here - if ( ! ex.getMessage().equals("Node has been removed.")) { - // if it is not the expected exception, re-throw it - throw ex; - } - } - this.value = null; - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.key); - sb.append(" => "); - sb.append(this.value); - } - - - // ********** public API ********** - - /** - * Return the preference's key. - */ - public String getKey() { - return this.key; - } - - - // ********** internal methods ********** - - /** - * Return the preference's value. - * At this point the subject may be null. - */ - protected P buildValue() { - return (this.subject == null) ? null : this.buildValue_(); - } - - /** - * Return the appropriate preference, converted to the appropriate object. - * At this point we can be sure that the subject is not null. - */ - protected P buildValue_() { - return this.convertToObject(this.subject.get(this.key, this.convertToString(this.defaultValue))); - } - - /** - * Set the appropriate preference after converting the value to a string. - * At this point we can be sure that the subject is not null. - */ - protected void setValue_(P value) { - this.subject.put(this.key, this.convertToString(value)); - } - - /** - * Return whether the specified new value should be passed - * through to the preference. By default, only if the value has changed, - * will it be passed through to the preference. This also has the - * effect of not creating new preferences in the "backing store" - * if the new value is the same as the default value. - * - * Subclasses can override this method to return true if they - * would like to ALWAYS pass through the new value to the preference. - */ - protected boolean shouldSetPreference(Object oldValue, Object newValue) { - return this.attributeValueHasChanged(oldValue, newValue); - } - - /** - * Convert the specified object to a string that can be stored as - * the value of the preference. - */ - protected String convertToString(P o) { - return this.converter.convertToString(o); - } - - /** - * Convert the specified preference value string to an - * appropriately-typed object to be returned to the client. - */ - protected P convertToObject(String s) { - return this.converter.convertToObject(s); - } - - protected void preferenceChanged(String prefKey, String newValue) { - if (prefKey.equals(this.key)) { - this.preferenceChanged(); - } - } - - /** - * The underlying preference changed; either because we changed it - * in #setValue_(Object) or a third-party changed it. - * If this is called because of our own change, the event will be - * swallowed because the old and new values are the same. - */ - protected synchronized void preferenceChanged() { - Object old = this.value; - this.value = this.buildValue(); - this.fireAspectChange(old, this.value); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java deleted file mode 100644 index 546a6686d2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.prefs; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.prefs.BackingStoreException; -import java.util.prefs.PreferenceChangeEvent; -import java.util.prefs.PreferenceChangeListener; -import java.util.prefs.Preferences; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.internal.model.value.AspectAdapter; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.listener.ChangeListener; -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; - -/** - * This adapter wraps a Preferences node and converts its preferences into a - * CollectionValueModel of PreferencePropertyValueModels. It listens for - * "preference" changes and converts them into VALUE collection changes. - */ -public class PreferencesCollectionValueModel<P> - extends AspectAdapter<Preferences> - implements CollectionValueModel<PreferencePropertyValueModel<P>> -{ - - /** Cache the current preferences, stored in models and keyed by name. */ - protected final HashMap<String, PreferencePropertyValueModel<P>> preferences; - - /** A listener that listens to the preferences node for added or removed preferences. */ - protected final PreferenceChangeListener preferenceChangeListener; - - - // ********** constructors ********** - - /** - * Construct an adapter for the specified preferences node. - */ - public PreferencesCollectionValueModel(Preferences preferences) { - this(new StaticPropertyValueModel<Preferences>(preferences)); - } - - /** - * Construct an adapter for the specified preferences node. - */ - public PreferencesCollectionValueModel(PropertyValueModel<? extends Preferences> preferencesHolder) { - super(preferencesHolder); - this.preferences = new HashMap<String, PreferencePropertyValueModel<P>>(); - this.preferenceChangeListener = this.buildPreferenceChangeListener(); - } - - - // ********** initialization ********** - - /** - * A preferences have changed, notify the listeners. - */ - protected PreferenceChangeListener buildPreferenceChangeListener() { - // transform the preference change events into VALUE collection change events - return new PreferenceChangeListener() { - public void preferenceChange(PreferenceChangeEvent event) { - PreferencesCollectionValueModel.this.preferenceChanged(event.getKey(), event.getNewValue()); - } - @Override - public String toString() { - return "preference change listener"; - } - }; - } - - - // ********** CollectionValueModel implementation ********** - - /** - * Return an iterator on the preference models. - */ - public synchronized Iterator<PreferencePropertyValueModel<P>> iterator() { - return this.preferences.values().iterator(); - } - - public synchronized int size() { - return this.preferences.size(); - } - - - // ********** AspectAdapter implementation ********** - - @Override - protected Object getValue() { - return this.iterator(); - } - - @Override - protected Class<? extends ChangeListener> getListenerClass() { - return CollectionChangeListener.class; - } - - @Override - protected String getListenerAspectName() { - return VALUES; - } - - @Override - protected boolean hasListeners() { - return this.hasAnyCollectionChangeListeners(VALUES); - } - - @Override - protected void fireAspectChange(Object oldValue, Object newValue) { - this.fireCollectionChanged(VALUES); - } - - @Override - protected void engageSubject_() { - this.subject.addPreferenceChangeListener(this.preferenceChangeListener); - for (Iterator<PreferencePropertyValueModel<P>> stream = this.preferenceModels(); stream.hasNext(); ) { - PreferencePropertyValueModel<P> preferenceModel = stream.next(); - this.preferences.put(preferenceModel.getKey(), preferenceModel); - } - } - - @Override - protected void disengageSubject_() { - try { - this.subject.removePreferenceChangeListener(this.preferenceChangeListener); - } catch (IllegalStateException ex) { - // for some odd reason, we are not allowed to remove a listener from a "dead" - // preferences node; so handle the exception that gets thrown here - if ( ! ex.getMessage().equals("Node has been removed.")) { - // if it is not the expected exception, re-throw it - throw ex; - } - } - this.preferences.clear(); - } - - - // ********** AbstractModel implementation ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.subject); - } - - - // ********** internal methods ********** - - /** - * Return an iterator on the preference models. - * At this point we can be sure that the subject is not null. - */ - protected Iterator<PreferencePropertyValueModel<P>> preferenceModels() { - String[] keys; - try { - keys = this.subject.keys(); - } catch (BackingStoreException ex) { - throw new RuntimeException(ex); - } - return new TransformationIterator<String, PreferencePropertyValueModel<P>>(new ArrayIterator<String>(keys)) { - @Override - protected PreferencePropertyValueModel<P> transform(String key) { - return PreferencesCollectionValueModel.this.buildPreferenceModel(key); - } - }; - } - - /** - * Override this method to tweak the model used to wrap the - * specified preference (e.g. to customize the model's converter). - */ - protected PreferencePropertyValueModel<P> buildPreferenceModel(String key) { - return new PreferencePropertyValueModel<P>(this.subjectHolder, key); - } - - protected synchronized void preferenceChanged(String key, String newValue) { - if (newValue == null) { - // a preference was removed - PreferencePropertyValueModel<P> preferenceModel = this.preferences.remove(key); - this.fireItemRemoved(VALUES, preferenceModel); - } else if ( ! this.preferences.containsKey(key)) { - // a preference was added - PreferencePropertyValueModel<P> preferenceModel = this.buildPreferenceModel(key); - this.preferences.put(key, preferenceModel); - this.fireItemAdded(VALUES, preferenceModel); - } else { - // a preference's value changed - do nothing - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java deleted file mode 100644 index 302a83f1dd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/AbstractTreeModel.java +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.io.Serializable; -import javax.swing.event.EventListenerList; -import javax.swing.event.TreeModelEvent; -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreeModel; - -/** - * Abstract class that should have been provided by the JDK - * (à la javax.swing.AbstractListModel). This class provides: - * - support for a collection of listeners - * - a number of convenience methods for firing events for those listeners - */ -public abstract class AbstractTreeModel - implements TreeModel, Serializable -{ - /** Our listeners. */ - protected final EventListenerList listenerList; - - - // ********** constructors/initialization ********** - - protected AbstractTreeModel() { - super(); - this.listenerList = new EventListenerList(); - } - - - // ********** partial TreeModel implementation ********** - - public void addTreeModelListener(TreeModelListener l) { - this.listenerList.add(TreeModelListener.class, l); - } - - public void removeTreeModelListener(TreeModelListener l) { - this.listenerList.remove(TreeModelListener.class, l); - } - - - // ********** queries ********** - - /** - * Return the model's current collection of listeners. - * (There seems to be a pattern of making this type of method public; - * although it should probably be protected....) - */ - public TreeModelListener[] treeModelListeners() { - return this.listenerList.getListeners(TreeModelListener.class); - } - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoTreeModelListeners() { - return this.listenerList.getListenerCount(TreeModelListener.class) == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasTreeModelListeners() { - return ! this.hasNoTreeModelListeners(); - } - - - // ********** behavior ********** - - /** - * Notify listeners of a model change. - * A significant property of the nodes changed, but the nodes themselves - * are still the same objects. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesChanged(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesChanged(event); - } - } - } - - - /** - * Notify listeners of a model change. - * A significant property of the node changed, but the node itself is the same object. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeChanged(Object[] path, int childIndex, Object child) { - this.fireTreeNodesChanged(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * A significant property of the root changed, but the root itself is the same object. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeRootChanged(Object root) { - this.fireTreeNodesChanged(new Object[] {root}, null, null); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesInserted(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesInserted(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeInserted(Object[] path, int childIndex, Object child) { - this.fireTreeNodesInserted(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodesRemoved(Object[] path, int[] childIndices, Object[] children) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path, childIndices, children); - } - ((TreeModelListener) listeners[i+1]).treeNodesRemoved(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeNodeRemoved(Object[] path, int childIndex, Object child) { - this.fireTreeNodesRemoved(path, new int[] {childIndex}, new Object[] {child}); - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeStructureChanged(Object[] path) { - // guaranteed to return a non-null array - Object[] listeners = this.listenerList.getListenerList(); - TreeModelEvent event = null; - // process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // lazily create the event - if (event == null) { - event = new TreeModelEvent(this, path); - } - ((TreeModelListener) listeners[i+1]).treeStructureChanged(event); - } - } - } - - /** - * Notify listeners of a model change. - * @see javax.swing.event.TreeModelEvent - * @see javax.swing.event.TreeModelListener - */ - protected void fireTreeRootReplaced(Object newRoot) { - this.fireTreeStructureChanged(new Object[] {newRoot}); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/CheckBoxModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/CheckBoxModelAdapter.java deleted file mode 100644 index 126cbfa561..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/CheckBoxModelAdapter.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JCheckBox) in synch with a PropertyValueModel that - * holds a boolean. - * - * Maybe not the richest class in our toolbox, but it was the - * victim of refactoring.... ~bjv - */ -public class CheckBoxModelAdapter - extends ToggleButtonModelAdapter -{ - - // ********** constructors ********** - - /** - * Constructor - the boolean holder is required. - */ - public CheckBoxModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) { - super(booleanHolder, defaultValue); - } - - /** - * Constructor - the boolean holder is required. - * The default value will be false. - */ - public CheckBoxModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder) { - super(booleanHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ColumnAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ColumnAdapter.java deleted file mode 100644 index 482b5d2468..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ColumnAdapter.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - - -/** - * This adapter is used by the table model adapter to - * convert a model object into the models used for each of - * the cells for the object's corresponding row in the table. - */ -public interface ColumnAdapter { - /** - * Return the number of columns in the table. - * Typically this is static. - */ - int columnCount(); - - /** - * Return the name of the specified column. - */ - String columnName(int index); - - /** - * Return the class of the specified column. - */ - Class<?> columnClass(int index); - - /** - * Return whether the specified column is editable. - * Typically this is the same for every row. - */ - boolean columnIsEditable(int index); - - /** - * Return the cell models for the specified subject - * that corresponds to a single row in the table. - */ - WritablePropertyValueModel<Object>[] cellModels(Object subject); - -}
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java deleted file mode 100644 index b3e0c9269c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ComboBoxModelAdapter.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import javax.swing.ComboBoxModel; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ComboBoxModel can be used to keep a ListDataListener - * (e.g. a JComboBox) in synch with a ListValueModel (or a CollectionValueModel). - * For combo boxes, the model object that holds the current selection is - * typically a different model object than the one that holds the collection - * of choices. - * - * For example, a MWReference (the selectionOwner) has an attribute - * "sourceTable" (the collectionOwner) - * which holds on to a collection of MWDatabaseFields. When the selection - * is changed this model will keep the listeners aware of the changes. - * The inherited list model will keep its listeners aware of changes to the - * collection model - * - * In addition to the collection holder required by the superclass, - * an instance of this ComboBoxModel must be supplied with a - * selection holder, which is a PropertyValueModel that provides access - * to the selection (typically a PropertyAspectAdapter). - */ -public class ComboBoxModelAdapter - extends ListModelAdapter - implements ComboBoxModel -{ - protected final WritablePropertyValueModel<Object> selectionHolder; - protected final PropertyChangeListener selectionListener; - - - // ********** constructors ********** - - /** - * Constructor - the list holder and selection holder are required; - */ - public ComboBoxModelAdapter(ListValueModel<?> listHolder, WritablePropertyValueModel<Object> selectionHolder) { - super(listHolder); - if (selectionHolder == null) { - throw new NullPointerException(); - } - this.selectionHolder = selectionHolder; - this.selectionListener = this.buildSelectionListener(); - } - - /** - * Constructor - the collection holder and selection holder are required; - */ - public ComboBoxModelAdapter(CollectionValueModel<?> collectionHolder, WritablePropertyValueModel<Object> selectionHolder) { - super(collectionHolder); - if (selectionHolder == null) { - throw new NullPointerException(); - } - this.selectionHolder = selectionHolder; - this.selectionListener = this.buildSelectionListener(); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildSelectionListener() { - return new AWTPropertyChangeListenerWrapper(this.buildSelectionListener_()); - } - - protected PropertyChangeListener buildSelectionListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - // notify listeners that the selection has changed - ComboBoxModelAdapter.this.fireSelectionChanged(); - } - @Override - public String toString() { - return "selection listener"; - } - }; - } - - - // ********** ComboBoxModel implementation ********** - - public Object getSelectedItem() { - return this.selectionHolder.getValue(); - } - - public void setSelectedItem(Object selectedItem) { - this.selectionHolder.setValue(selectedItem); - } - - - // ********** behavior ********** - - /** - * Extend to engage the selection holder. - */ - @Override - protected void engageModel() { - super.engageModel(); - this.selectionHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener); - } - - /** - * Extend to disengage the selection holder. - */ - @Override - protected void disengageModel() { - this.selectionHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener); - super.disengageModel(); - } - - /** - * Notify the listeners that the selection has changed. - */ - protected void fireSelectionChanged() { - // I guess this will work... - this.fireContentsChanged(this, -1, -1); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.selectionHolder + ":" + this.listHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java deleted file mode 100644 index 66d09d23ca..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DateSpinnerModelAdapter.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.Calendar; -import java.util.Date; -import javax.swing.SpinnerDateModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerDateModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a date. - * - * This class must be a sub-class of SpinnerDateModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see ListSpinnerModelAdapter - * @see NumberSpinnerModelAdapter - */ -public class DateSpinnerModelAdapter - extends SpinnerDateModel -{ - - /** - * The default spinner value; used when the underlying model date value is null. - * The default is the current date. - */ - private final Date defaultValue; - - /** A value model on the underlying date. */ - private final WritablePropertyValueModel<Object> dateHolder; - - /** A listener that allows us to synchronize with changes made to the underlying date. */ - private final PropertyChangeListener dateChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the date holder is required. - * The default spinner value is the current date. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder) { - this(dateHolder, new Date()); - } - - /** - * Constructor - the date holder and default value are required. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Date defaultValue) { - this(dateHolder, null, null, Calendar.DAY_OF_MONTH, defaultValue); - } - - /** - * Constructor - the date holder is required. - * The default spinner value is the current date. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField) { - this(dateHolder, start, end, calendarField, new Date()); - } - - /** - * Constructor - the date holder is required. - */ - public DateSpinnerModelAdapter(WritablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField, Date defaultValue) { - super(dateHolder.getValue() == null ? defaultValue : (Date) dateHolder.getValue(), start, end, calendarField); - this.dateHolder = dateHolder; - this.dateChangeListener = this.buildDateChangeListener(); - // postpone listening to the underlying date - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildDateChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildDateChangeListener_()); - } - - protected PropertyChangeListener buildDateChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - DateSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "date listener"; - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.dateHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying date directly. - * The resulting event will be ignored: @see #synchronize(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.dateHolder.setValue(value); - } - - /** - * Extend to start listening to the underlying date if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.dateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener); - this.synchronize(this.dateHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying date if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.dateHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener); - } - } - - - // ********** queries ********** - - protected Date getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the spinner date has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.dateHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java deleted file mode 100644 index eeb65b4965..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/DocumentAdapter.java +++ /dev/null @@ -1,362 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.io.Serializable; -import java.util.EventObject; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.EventListenerList; -import javax.swing.event.UndoableEditEvent; -import javax.swing.event.UndoableEditListener; -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.PlainDocument; -import javax.swing.text.Position; -import javax.swing.text.Segment; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.text.Document can be used to keep a DocumentListener - * (e.g. a JTextField) in synch with a PropertyValueModel that holds a string. - * - * NB: This model should only be used for "small" documents; - * i.e. documents used by text fields, not text panes. - * @see #synchronizeDelegate(String) - */ -public class DocumentAdapter - implements Document, Serializable -{ - - /** The delegate document whose behavior we "enhance". */ - protected final Document delegate; - - /** A listener that allows us to forward any changes made to the delegate document. */ - protected final CombinedListener delegateListener; - - /** A value model on the underlying model string. */ - protected final WritablePropertyValueModel<String> stringHolder; - - /** A listener that allows us to synchronize with changes made to the underlying model string. */ - protected final PropertyChangeListener stringListener; - - /** The event listener list for the document. */ - protected final EventListenerList listenerList = new EventListenerList(); - - - // ********** constructors ********** - - /** - * Constructor - the string holder is required. - * Wrap the specified document. - */ - public DocumentAdapter(WritablePropertyValueModel<String> stringHolder, Document delegate) { - super(); - if (stringHolder == null || delegate == null) { - throw new NullPointerException(); - } - this.stringHolder = stringHolder; - // postpone listening to the underlying model string - // until we have listeners ourselves... - this.delegate = delegate; - this.stringListener = this.buildStringListener(); - this.delegateListener = this.buildDelegateListener(); - } - - /** - * Constructor - the string holder is required. - * Wrap a plain document. - */ - public DocumentAdapter(WritablePropertyValueModel<String> stringHolder) { - this(stringHolder, new PlainDocument()); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildStringListener() { - return new AWTPropertyChangeListenerWrapper(this.buildStringListener_()); - } - - protected PropertyChangeListener buildStringListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - DocumentAdapter.this.stringChanged(event); - } - @Override - public String toString() { - return "string listener"; - } - }; - } - - protected CombinedListener buildDelegateListener() { - return new InternalListener(); - } - - - // ********** Document implementation ********** - - public int getLength() { - return this.delegate.getLength(); - } - - /** - * Extend to start listening to the underlying models if necessary. - */ - public void addDocumentListener(DocumentListener listener) { - if (this.listenerList.getListenerCount(DocumentListener.class) == 0) { - this.delegate.addDocumentListener(this.delegateListener); - this.engageStringHolder(); - } - this.listenerList.add(DocumentListener.class, listener); - } - - /** - * Extend to stop listening to the underlying models if appropriate. - */ - public void removeDocumentListener(DocumentListener listener) { - this.listenerList.remove(DocumentListener.class, listener); - if (this.listenerList.getListenerCount(DocumentListener.class) == 0) { - this.disengageStringHolder(); - this.delegate.removeDocumentListener(this.delegateListener); - } - } - - /** - * Extend to start listening to the delegate document if necessary. - */ - public void addUndoableEditListener(UndoableEditListener listener) { - if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) { - this.delegate.addUndoableEditListener(this.delegateListener); - } - this.listenerList.add(UndoableEditListener.class, listener); - } - - /** - * Extend to stop listening to the delegate document if appropriate. - */ - public void removeUndoableEditListener(UndoableEditListener listener) { - this.listenerList.remove(UndoableEditListener.class, listener); - if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) { - this.delegate.removeUndoableEditListener(this.delegateListener); - } - } - - public Object getProperty(Object key) { - return this.delegate.getProperty(key); - } - - public void putProperty(Object key, Object value) { - this.delegate.putProperty(key, value); - } - - /** - * Extend to update the underlying model string directly. - * The resulting event will be ignored: @see #synchronizeDelegate(String). - */ - public void remove(int offset, int len) throws BadLocationException { - this.delegate.remove(offset, len); - this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength())); - } - - /** - * Extend to update the underlying model string directly. - * The resulting event will be ignored: @see #synchronizeDelegate(String). - */ - public void insertString(int offset, String insertedString, AttributeSet a) throws BadLocationException { - this.delegate.insertString(offset, insertedString, a); - this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength())); - } - - public String getText(int offset, int length) throws BadLocationException { - return this.delegate.getText(offset, length); - } - - public void getText(int offset, int length, Segment txt) throws BadLocationException { - this.delegate.getText(offset, length, txt); - } - - public Position getStartPosition() { - return this.delegate.getStartPosition(); - } - - public Position getEndPosition() { - return this.delegate.getEndPosition(); - } - - public Position createPosition(int offs) throws BadLocationException { - return this.delegate.createPosition(offs); - } - - public Element[] getRootElements() { - return this.delegate.getRootElements(); - } - - public Element getDefaultRootElement() { - return this.delegate.getDefaultRootElement(); - } - - public void render(Runnable r) { - this.delegate.render(r); - } - - - // ********** queries ********** - - public DocumentListener[] documentListeners() { - return this.listenerList.getListeners(DocumentListener.class); - } - - public UndoableEditListener[] undoableEditListeners() { - return this.listenerList.getListeners(UndoableEditListener.class); - } - - - // ********** behavior ********** - - /** - * A third party has modified the underlying model string. - * Synchronize the delegate document accordingly. - */ - protected void stringChanged(PropertyChangeEvent event) { - this.synchronizeDelegate((String) event.getNewValue()); - } - - /** - * Replace the document's entire text string with the new string. - */ - protected void synchronizeDelegate(String s) { - try { - int len = this.delegate.getLength(); - // check to see whether the delegate has already been synchronized - // (via #insertString() or #remove()) - if ( ! this.delegate.getText(0, len).equals(s)) { - this.delegate.remove(0, len); - this.delegate.insertString(0, s, null); - } - } catch (BadLocationException ex) { - throw new IllegalStateException(ex.getMessage()); // this should not happen... - } - } - - protected void engageStringHolder() { - this.stringHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringListener); - this.synchronizeDelegate(this.stringHolder.getValue()); - } - - protected void disengageStringHolder() { - this.stringHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.stringListener); - } - - protected void delegateChangedUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].changedUpdate(ee); - } - } - - protected void delegateInsertUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].insertUpdate(ee); - } - } - - protected void delegateRemoveUpdate(DocumentEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - DocumentEvent ee = new InternalDocumentEvent(this, event); - DocumentListener[] listeners = this.documentListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].removeUpdate(ee); - } - } - - protected void delegateUndoableEditHappened(UndoableEditEvent event) { - // no need to lazy-initialize the event; - // we wouldn't get here if we did not have listeners... - UndoableEditEvent ee = new UndoableEditEvent(this, event.getEdit()); - UndoableEditListener[] listeners = this.undoableEditListeners(); - for (int i = listeners.length; i-- > 0; ) { - listeners[i].undoableEditHappened(ee); - } - } - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.stringHolder); - } - - -// ********** inner class ********** - - protected interface CombinedListener extends DocumentListener, UndoableEditListener { - // just consolidate the two interfaces - } - - protected class InternalListener implements CombinedListener { - public void changedUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateChangedUpdate(event); - } - public void insertUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateInsertUpdate(event); - } - public void removeUpdate(DocumentEvent event) { - DocumentAdapter.this.delegateRemoveUpdate(event); - } - public void undoableEditHappened(UndoableEditEvent event) { - DocumentAdapter.this.delegateUndoableEditHappened(event); - } - } - - protected static class InternalDocumentEvent - extends EventObject - implements DocumentEvent - { - protected DocumentEvent delegate; - - protected InternalDocumentEvent(Document document, DocumentEvent delegate) { - super(document); - this.delegate = delegate; - } - public ElementChange getChange(Element elem) { - return this.delegate.getChange(elem); - } - public Document getDocument() { - return (Document) this.source; - } - public int getLength() { - return this.delegate.getLength(); - } - public int getOffset() { - return this.delegate.getOffset(); - } - public EventType getType() { - return this.delegate.getType(); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java deleted file mode 100644 index 42e952f6b0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListModelAdapter.java +++ /dev/null @@ -1,286 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import javax.swing.AbstractListModel; -import javax.swing.event.ListDataListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This javax.swing.ListModel can be used to keep a ListDataListener - * (e.g. a JList) in synch with a ListValueModel (or a CollectionValueModel). - * - * An instance of this ListModel *must* be supplied with a value model, - * which is a ListValueModel on the bound list or a CollectionValueModel - * on the bound collection. This is required - the list (or collection) - * itself can be null, but the value model that holds it cannot. - */ -public class ListModelAdapter - extends AbstractListModel -{ - /** A value model on the underlying model list. */ - protected ListValueModel<?> listHolder; - - /** - * Cache the size of the list for "dramatic" changes. - * @see #listChanged(ListChangeEvent) - */ - protected int listSize; - - /** A listener that allows us to forward changes made to the underlying model list. */ - protected final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Default constructor - initialize stuff. - */ - private ListModelAdapter() { - super(); - this.listSize = 0; - this.listChangeListener = this.buildListChangeListener(); - } - - /** - * Constructor - the list holder is required. - */ - public ListModelAdapter(ListValueModel<?> listHolder) { - this(); - this.setModel(listHolder); - } - - /** - * Constructor - the collection holder is required. - */ - public ListModelAdapter(CollectionValueModel<?> collectionHolder) { - this(); - this.setModel(collectionHolder); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - ListModelAdapter.this.itemsAdded(event); - } - public void itemsRemoved(ListChangeEvent event) { - ListModelAdapter.this.itemsRemoved(event); - } - public void itemsReplaced(ListChangeEvent event) { - ListModelAdapter.this.itemsReplaced(event); - } - public void itemsMoved(ListChangeEvent event) { - ListModelAdapter.this.itemsMoved(event); - } - public void listCleared(ListChangeEvent event) { - ListModelAdapter.this.listCleared(); - } - public void listChanged(ListChangeEvent event) { - ListModelAdapter.this.listChanged(); - } - @Override - public String toString() { - return "list listener"; - } - }; - } - - - // ********** ListModel implementation ********** - - public int getSize() { - return this.listHolder.size(); - } - - public Object getElementAt(int index) { - return this.listHolder.get(index); - } - - /** - * Extend to start listening to the underlying model list if necessary. - */ - @Override - public void addListDataListener(ListDataListener l) { - if (this.hasNoListDataListeners()) { - this.engageModel(); - this.listSize = this.listHolder.size(); - } - super.addListDataListener(l); - } - - /** - * Extend to stop listening to the underlying model list if appropriate. - */ - @Override - public void removeListDataListener(ListDataListener l) { - super.removeListDataListener(l); - if (this.hasNoListDataListeners()) { - this.disengageModel(); - this.listSize = 0; - } - } - - - // ********** public API ********** - - /** - * Return the underlying list model. - */ - public ListValueModel<?> model() { - return this.listHolder; - } - - /** - * Set the underlying list model. - */ - public void setModel(ListValueModel<?> listHolder) { - if (listHolder == null) { - throw new NullPointerException(); - } - boolean hasListeners = this.hasListDataListeners(); - if (hasListeners) { - this.disengageModel(); - } - this.listHolder = listHolder; - if (hasListeners) { - this.engageModel(); - this.listChanged(); - } - } - - /** - * Set the underlying collection model. - */ - @SuppressWarnings("unchecked") - public void setModel(CollectionValueModel<?> collectionHolder) { - this.setModel(new CollectionListValueModelAdapter(collectionHolder)); - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoListDataListeners() { - return this.getListDataListeners().length == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasListDataListeners() { - return ! this.hasNoListDataListeners(); - } - - - // ********** behavior ********** - - protected void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - protected void disengageModel() { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - - - // ********** list change support ********** - - /** - * Items were added to the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsAdded(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireIntervalAdded(this, start, end); - this.listSize += event.itemsSize(); - } - - /** - * Items were removed from the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsRemoved(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireIntervalRemoved(this, start, end); - this.listSize -= event.itemsSize(); - } - - /** - * Items were replaced in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsReplaced(ListChangeEvent event) { - int start = event.getIndex(); - int end = start + event.itemsSize() - 1; - this.fireContentsChanged(this, start, end); - } - - /** - * Items were moved in the underlying model list. - * Notify listeners of the changes. - */ - protected void itemsMoved(ListChangeEvent event) { - int start = Math.min(event.getSourceIndex(), event.getTargetIndex()); - int end = Math.max(event.getSourceIndex(), event.getTargetIndex()) + event.getMoveLength() - 1; - this.fireContentsChanged(this, start, end); - } - - /** - * The underlying model list was cleared. - * Notify listeners of the changes. - */ - protected void listCleared() { - if (this.listSize != 0) { - this.fireIntervalRemoved(this, 0, this.listSize - 1); - this.listSize = 0; - } - } - - /** - * The underlying model list has changed "dramatically". - * Notify listeners of the changes. - */ - protected void listChanged() { - if (this.listSize != 0) { - this.fireIntervalRemoved(this, 0, this.listSize - 1); - } - this.listSize = this.listHolder.size(); - if (this.listSize != 0) { - this.fireIntervalAdded(this, 0, this.listSize - 1); - } - } - - - // ********** Object overrides ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.listHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java deleted file mode 100644 index 527120367b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ListSpinnerModelAdapter.java +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.Arrays; -import java.util.List; -import javax.swing.SpinnerListModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerListModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value - * in the list. - * - * This class must be a sub-class of SpinnerListModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * NB: This model should only be used for values that have a reasonably - * inexpensive #equals() implementation. - * @see #synchronize(Object) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see DateSpinnerModelAdapter - * @see NumberSpinnerModelAdapter - */ -public class ListSpinnerModelAdapter - extends SpinnerListModel -{ - - /** - * The default spinner value; used when the underlying model value is null. - * The default is the first item on the list. - */ - private final Object defaultValue; - - /** A value model on the underlying value. */ - private final WritablePropertyValueModel<Object> valueHolder; - - /** A listener that allows us to synchronize with changes made to the underlying value. */ - private final PropertyChangeListener valueChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the value holder is required. - * Use the model value itself as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder) { - this(valueHolder, valueHolder.getValue()); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object defaultValue) { - this(valueHolder, new Object[] {defaultValue}, defaultValue); - } - - /** - * Constructor - the value holder is required. - * Use the first item in the list of values as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object[] values) { - this(valueHolder, values, values[0]); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object[] values, Object defaultValue) { - this(valueHolder, Arrays.asList(values), defaultValue); - } - - /** - * Constructor - the value holder is required. - * Use the first item in the list of values as the default spinner value. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, List<Object> values) { - this(valueHolder, values, values.get(0)); - } - - /** - * Constructor - the value holder is required. - */ - public ListSpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, List<Object> values, Object defaultValue) { - super(values); - this.valueHolder = valueHolder; - this.valueChangeListener = this.buildValueChangeListener(); - // postpone listening to the underlying value - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValueChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildValueChangeListener_()); - } - - protected PropertyChangeListener buildValueChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ListSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "value listener"; - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.valueHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying value directly. - * The resulting event will be ignored: @see #synchronize(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.valueHolder.setValue(value); - } - - /** - * Extend to start listening to the underlying value if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - this.synchronize(this.valueHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying value if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener); - } - } - - - // ********** queries ********** - - protected Object getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the spinner value has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java deleted file mode 100644 index 484ff33c3a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/NumberSpinnerModelAdapter.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerNumberModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a number. - * - * This class must be a sub-class of SpinnerNumberModel because of some - * crappy jdk code.... ~bjv - * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel) - * - * If this class needs to be modified, it would behoove us to review the - * other, similar classes: - * @see DateSpinnerModelAdapter - * @see ListSpinnerModelAdapter - */ -public class NumberSpinnerModelAdapter - extends SpinnerNumberModel -{ - - /** - * The default spinner value; used when the - * underlying model number value is null. - */ - private final Number defaultValue; - - /** A value model on the underlying number. */ - private final WritablePropertyValueModel<Number> numberHolder; - - /** - * A listener that allows us to synchronize with - * changes made to the underlying number. - */ - private final PropertyChangeListener numberChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the number holder is required. - * The default spinner value is zero. - * The step size is one. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder) { - this(numberHolder, 0); - } - - /** - * Constructor - the number holder is required. - * The step size is one. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int defaultValue) { - this(numberHolder, null, null, new Integer(1), new Integer(defaultValue)); - } - - /** - * Constructor - the number holder is required. - * Use the minimum value as the default spinner value. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize) { - this(numberHolder, minimum, maximum, stepSize, minimum); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize, int defaultValue) { - this(numberHolder, new Integer(minimum), new Integer(maximum), new Integer(stepSize), new Integer(defaultValue)); - } - - /** - * Constructor - the number holder is required. - * Use the minimum value as the default spinner value. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double value, double minimum, double maximum, double stepSize) { - this(numberHolder, value, minimum, maximum, stepSize, minimum); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, double value, double minimum, double maximum, double stepSize, double defaultValue) { - this(numberHolder, new Double(minimum), new Double(maximum), new Double(stepSize), new Double(defaultValue)); - } - - /** - * Constructor - the number holder is required. - */ - public NumberSpinnerModelAdapter(WritablePropertyValueModel<Number> numberHolder, Comparable<?> minimum, Comparable<?> maximum, Number stepSize, Number defaultValue) { - super(numberHolder.getValue() == null ? defaultValue : (Number) numberHolder.getValue(), minimum, maximum, stepSize); - this.numberHolder = numberHolder; - this.numberChangeListener = this.buildNumberChangeListener(); - // postpone listening to the underlying number - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildNumberChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildNumberChangeListener_()); - } - - protected PropertyChangeListener buildNumberChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - NumberSpinnerModelAdapter.this.synchronize(event.getNewValue()); - } - @Override - public String toString() { - return "number listener"; - } - }; - } - - - // ********** SpinnerModel implementation ********** - - /** - * Extend to check whether this method is being called before we - * have any listeners. - * This is necessary because some crappy jdk code gets the value - * from the model *before* listening to the model. ~bjv - * @see javax.swing.JSpinner.DefaultEditor(javax.swing.JSpinner) - */ - @Override - public Object getValue() { - if (this.getChangeListeners().length == 0) { - // sorry about this "lateral" call to super ~bjv - super.setValue(this.spinnerValueOf(this.numberHolder.getValue())); - } - return super.getValue(); - } - - /** - * Extend to update the underlying number directly. - * The resulting event will be ignored: @see #synchronizeDelegate(Object). - */ - @Override - public void setValue(Object value) { - super.setValue(value); - this.numberHolder.setValue((Number) value); - } - - /** - * Extend to start listening to the underlying number if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.getChangeListeners().length == 0) { - this.numberHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener); - this.synchronize(this.numberHolder.getValue()); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying number if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.getChangeListeners().length == 0) { - this.numberHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener); - } - } - - - // ********** queries ********** - - protected Number getDefaultValue() { - return this.defaultValue; - } - - /** - * Convert to a non-null value. - */ - protected Object spinnerValueOf(Object value) { - return (value == null) ? this.getDefaultValue() : value; - } - - - // ********** behavior ********** - - /** - * Set the spinner value if it has changed. - */ - void synchronize(Object value) { - Object newValue = this.spinnerValueOf(value); - // check to see whether the date has already been synchronized - // (via #setValue()) - if ( ! this.getValue().equals(newValue)) { - this.setValue(newValue); - } - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.numberHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java deleted file mode 100644 index 61d2e3701f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ObjectListSelectionModel.java +++ /dev/null @@ -1,427 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import javax.swing.DefaultListSelectionModel; -import javax.swing.ListModel; -import javax.swing.event.ListDataEvent; -import javax.swing.event.ListDataListener; -import javax.swing.event.ListSelectionListener; -import org.eclipse.jpt.utility.internal.CollectionTools; - -/** - * This ListSelectionModel is aware of the ListModel and - * provides convenience methods to access and set the - * selected *objects*, as opposed to the selected *indexes*. - */ -public class ObjectListSelectionModel - extends DefaultListSelectionModel -{ - /** The list model referenced by the list selection model. */ - private final ListModel listModel; - - /** A listener that allows us to clear the selection when the list model has changed. */ - private final ListDataListener listDataListener; - - - // ********** constructors ********** - - /** - * Construct a list selection model for the specified list model. - */ - public ObjectListSelectionModel(ListModel listModel) { - super(); - this.listModel = listModel; - this.listDataListener = this.buildListDataListener(); - } - - - // ********** initialization ********** - - private ListDataListener buildListDataListener() { - return new ListDataListener() { - public void intervalAdded(ListDataEvent event) { - // this does not affect the selection - } - public void intervalRemoved(ListDataEvent event) { - // this does not affect the selection - } - public void contentsChanged(ListDataEvent event) { - ObjectListSelectionModel.this.listModelContentsChanged(event); - } - @Override - public String toString() { - return "list data listener"; - } - }; - } - - /** - * Typically, the selection does not need to be cleared when the - * contents of the list have changed. Most of the time this just - * means an item has changed in a way that affects its display string - * or icon. We typically only use the class for edits involving - * single selection. - * A subclass can override this method if the selection - * should be cleared because a change could mean the selection is invalid. - */ - protected void listModelContentsChanged(ListDataEvent event) { - /**this.clearSelection();*/ - } - - - // ********** ListSelectionModel implementation ********** - - @Override - public void addListSelectionListener(ListSelectionListener l) { - if (this.hasNoListSelectionListeners()) { - this.listModel.addListDataListener(this.listDataListener); - } - super.addListSelectionListener(l); - } - - @Override - public void removeListSelectionListener(ListSelectionListener l) { - super.removeListSelectionListener(l); - if (this.hasNoListSelectionListeners()) { - this.listModel.removeListDataListener(this.listDataListener); - } - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoListSelectionListeners() { // private-protected - return this.getListSelectionListeners().length == 0; - } - - /** - * Return the list model referenced by the list selection model. - */ - public ListModel getListModel() { - return this.listModel; - } - - public int selectedValuesSize() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return 0; - } - - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - n++; - } - } - return n; - } - - /** - * Return the first selected value. - * Return null if the selection is empty. - */ - public Object selectedValue() { - int index = this.getMinSelectionIndex(); - if (index == -1) { - return null; - } - if (this.getListModel().getSize() <= index) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * Return an array of the selected values. - */ - public Object[] selectedValues() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return new Object[0]; - } - - int maxSize = (max - min) + 1; - Object[] temp = new Object[maxSize]; - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - temp[n++] = this.getListModel().getElementAt(i); - } - } - if (n == maxSize) { - // all the elements in the range were selected - return temp; - } - // only some of the elements in the range were selected - Object[] result = new Object[n]; - System.arraycopy(temp, 0, result, 0, n); - return result; - } - - /** - * Return an array of the selected indices in order. - */ - public int[] selectedIndices() { - int min = this.getMinSelectionIndex(); - int max = this.getMaxSelectionIndex(); - - if ((min < 0) || (max < 0)) { - return new int[0]; - } - - int maxSize = (max - min) + 1; - int[] temp = new int[maxSize]; - int n = 0; - int count = this.getListModel().getSize(); - for (int i = min; i <= max; i++) { - if (this.isSelectedIndex(i) && (i < count)) { - temp[n++] = i; - } - } - if (n == maxSize) { - // all the elements in the range were selected - Arrays.sort(temp); - return temp; - } - // only some of the elements in the range were selected - int[] result = new int[n]; - System.arraycopy(temp, 0, result, 0, n); - Arrays.sort(result); - return result; - } - - /** - * Set the selected value. - */ - public void setSelectedValue(Object object) { - this.setSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - this.clearSelection(); - this.addSelectedValuesInternal(objects); - this.setValueIsAdjusting(false); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Collection<?> objects) { - this.setSelectedValues(objects.iterator()); - } - - /** - * Set the current set of selected objects to the specified objects. - * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int) - */ - public void setSelectedValues(Object[] objects) { - this.setSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * Add the specified object to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValue(Object object) { - this.addSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - this.addSelectedValuesInternal(objects); - this.setValueIsAdjusting(false); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Collection<?> objects) { - this.addSelectedValues(objects.iterator()); - } - - /** - * Add the specified objects to the current set of selected objects. - * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int) - */ - public void addSelectedValues(Object[] objects) { - this.addSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * Remove the specified object from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValue(Object object) { - this.removeSelectedValues(CollectionTools.singletonIterator(object)); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Iterator<?> objects) { - this.setValueIsAdjusting(true); - ListModel lm = this.getListModel(); - int lmSize = lm.getSize(); - while (objects.hasNext()) { - int index = this.indexOf(objects.next(), lm, lmSize); - this.removeSelectionInterval(index, index); - } - this.setValueIsAdjusting(false); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Collection<?> objects) { - this.removeSelectedValues(objects.iterator()); - } - - /** - * Remove the specified objects from the current set of selected objects. - * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int) - */ - public void removeSelectedValues(Object[] objects) { - this.removeSelectedValues(CollectionTools.iterator(objects)); - } - - /** - * @see javax.swing.ListSelectionModel#getAnchorSelectionIndex() - * Return null if the anchor selection is empty. - */ - public Object getAnchorSelectedValue() { - int index = this.getAnchorSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#setAnchorSelectionIndex(int) - */ - public void setAnchorSelectedValue(Object object) { - this.setAnchorSelectionIndex(this.indexOf(object)); - } - - /** - * @see javax.swing.ListSelectionModel#getLeadSelectionIndex() - * Return null if the lead selection is empty. - */ - public Object getLeadSelectedValue() { - int index = this.getLeadSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#setLeadSelectionIndex(int) - */ - public void setLeadSelectedValue(Object object) { - this.setLeadSelectionIndex(this.indexOf(object)); - } - - /** - * @see javax.swing.ListSelectionModel#getMaxSelectionIndex() - * Return null if the max selection is empty. - */ - public Object getMaxSelectedValue() { - int index = this.getMaxSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#getMinSelectionIndex() - * Return null if the min selection is empty. - */ - public Object getMinSelectedValue() { - int index = this.getMinSelectionIndex(); - if (index == -1) { - return null; - } - return this.getListModel().getElementAt(index); - } - - /** - * @see javax.swing.ListSelectionModel#isSelectedIndex(int) - */ - public boolean valueIsSelected(Object object) { - return this.isSelectedIndex(this.indexOf(object)); - } - - /** - * Add the specified objects to the current set of selected objects, - * without wrapping the actions in "adjusting" events. - */ - private void addSelectedValuesInternal(Iterator<?> objects) { - ListModel lm = this.getListModel(); - int listModelSize = lm.getSize(); - while (objects.hasNext()) { - int index = this.indexOf(objects.next(), lm, listModelSize); - this.addSelectionInterval(index, index); - } - } - - /** - * Return the index in the list model of the specified object. - * Return -1 if the object is not in the list model. - */ - private int indexOf(Object object) { - ListModel lm = this.getListModel(); - return this.indexOf(object, lm, lm.getSize()); - } - - /** - * Return the index in the list model of the specified object. - * Return -1 if the object is not in the list model. - */ - // we're just jerking around with performance optimizations here - // (in memory of Phil...); - // call this method inside loops that do not modify the listModel - private int indexOf(Object object, ListModel lm, int listModelSize) { - for (int i = listModelSize; i-- > 0; ) { - if (lm.getElementAt(i) == object) { - return i; - } - } - return -1; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java deleted file mode 100644 index 2bc8a17734..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/PrimitiveListTreeModel.java +++ /dev/null @@ -1,233 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; -import javax.swing.event.TreeModelListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; - -/** - * This TreeModel implementation provides a tree with a "null" root that - * has a set of "primitive" children. These "primitive" children do not have - * children themselves, making the tree a maximum of 2 levels deep. - * This model automatically synchronizes the root's children with a - * ListValueModel that holds a collection of primitive (non-model) objects - * (e.g. Strings). - * - * This is useful for providing an "editable" list of primitives. Since the JDK - * does not provide us with an editable listbox, we must use an editable tree. - * We wrap everything in DefaultMutableTreeNodes. - * - * Subclasses must implement #primitiveChanged(int, Object) and update - * the model appropriately. This method is called when the user edits the - * list directly and presses <Enter>. - * - * The JTree using this model must be configured as "editable": - * tree.setEditable(true); - */ -// TODO convert to use an adapter instead of requiring subclass -public abstract class PrimitiveListTreeModel - extends DefaultTreeModel -{ - /** a model on the list of primitives */ - private final ListValueModel<?> listHolder; - - /** a listener that handles the adding, removing, and replacing of the primitives */ - private final ListChangeListener listChangeListener; - - - // ********** constructors ********** - - /** - * Public constructor - the list holder is required - */ - public PrimitiveListTreeModel(ListValueModel<?> listHolder) { - super(new DefaultMutableTreeNode(null, true)); // true = the root can have children - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.listChangeListener = this.buildListChangeListener(); - // postpone listening to the model until we have listeners ourselves - } - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new PrimitiveListChangeListener(); - } - - - // ********** behavior ********** - - /** - * Subclasses should override this method to update the - * model appropriately. The primitive at the specified index was - * edited directly by the user and the new value is as specified. - * Convert the value appropriately and place it in the model. - */ - protected abstract void primitiveChanged(int index, Object newValue); - - - // ********** TreeModel implementation ********** - - /** - * Override to change the underlying model instead of changing the node directly. - */ - @Override - public void valueForPathChanged(TreePath path, Object newValue) { - TreeNode node = (TreeNode) path.getLastPathComponent(); - int index = ((TreeNode) this.getRoot()).getIndex(node); - this.primitiveChanged(index, newValue); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTreeModelListener(TreeModelListener l) { - if (this.getTreeModelListeners().length == 0) { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - this.synchronizeList(); - } - super.addTreeModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeTreeModelListener(TreeModelListener l) { - super.removeTreeModelListener(l); - if (this.getTreeModelListeners().length == 0) { - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - } - - - // ********** behavior ********** - - /** - * Synchronize our list of nodes with the list of primitives - */ - void synchronizeList() { - this.clearList(); - this.buildList(); - } - - void clearList() { - int childcount = this.root.getChildCount(); - for (int i = childcount - 1; i >= 0; i--) { - this.removeNodeFromParent((MutableTreeNode)this.root.getChildAt(i)); - } - } - - private void buildList() { - for (Iterator<?> stream = this.listHolder.iterator(); stream.hasNext(); ) { - this.addPrimitive(stream.next()); - } - } - - /** - * Add the specified primitive to the end of the list. - */ - private void addPrimitive(Object primitive) { - this.insertPrimitive(this.root.getChildCount(), primitive); - } - - /** - * Create a node for the specified primitive - * and insert it as a child of the root. - */ - void insertPrimitive(int index, Object primitive) { - DefaultMutableTreeNode node = new DefaultMutableTreeNode(primitive, false); // don't allow children on the child node - this.insertNodeInto(node, (MutableTreeNode) this.root, index); - } - - /** - * Remove node at the specified index. - */ - MutableTreeNode removeNode(int index) { - MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index); - this.removeNodeFromParent(node); - return node; - } - - /** - * Replace the user object of the node at childIndex. - */ - void replacePrimitive(int index, Object primitive) { - MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index); - node.setUserObject(primitive); - this.nodeChanged(node); - } - - - // ********** inner class ********** - - private class PrimitiveListChangeListener implements ListChangeListener { - PrimitiveListChangeListener() { - super(); - } - - public void itemsAdded(ListChangeEvent event) { - int i = event.getIndex(); - for (ListIterator<?> stream = event.items(); stream.hasNext(); ) { - PrimitiveListTreeModel.this.insertPrimitive(i++, stream.next()); - } - } - - public void itemsRemoved(ListChangeEvent event) { - for (int i = 0; i < event.itemsSize(); i++) { - PrimitiveListTreeModel.this.removeNode(event.getIndex()); - } - } - - public void itemsReplaced(ListChangeEvent event) { - int i = event.getIndex(); - for (ListIterator<?> stream = event.items(); stream.hasNext(); ) { - PrimitiveListTreeModel.this.replacePrimitive(i++, stream.next()); - } - } - - public void itemsMoved(ListChangeEvent event) { - ArrayList<MutableTreeNode> temp = new ArrayList<MutableTreeNode>(event.getMoveLength()); - for (int i = 0; i < event.getMoveLength(); i++) { - temp.add(PrimitiveListTreeModel.this.removeNode(event.getSourceIndex())); - } - int i = event.getTargetIndex(); - for (MutableTreeNode node : temp) { - PrimitiveListTreeModel.this.insertPrimitive(i++, node); - } - } - - public void listCleared(ListChangeEvent event) { - PrimitiveListTreeModel.this.clearList(); - } - - public void listChanged(ListChangeEvent event) { - PrimitiveListTreeModel.this.synchronizeList(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java deleted file mode 100644 index 1caee488c8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/RadioButtonModelAdapter.java +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import org.eclipse.jpt.utility.internal.BidiFilter; -import org.eclipse.jpt.utility.internal.BidiTransformer; -import org.eclipse.jpt.utility.internal.model.value.FilteringWritablePropertyValueModel; -import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JRadioButton) in synch with a (typically shared) - * PropertyValueModel that holds one value out of a set of values. - * - * NOTE: Do *not* use this model with a ButtonGroup, since the - * shared value holder and the wrappers built by this adapter will - * keep the appropriate radio button checked. Also, this allows - * us to uncheck all the radio buttons in a group when the shared - * value is null. - */ -public class RadioButtonModelAdapter - extends ToggleButtonModelAdapter -{ - - // ********** constructors ********** - - /** - * Constructor - the value holder is required. - */ - public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue, boolean defaultValue) { - super(buildBooleanHolder(valueHolder, buttonValue), defaultValue); - } - - /** - * Constructor - the value holder is required. - * The default value will be false. - */ - public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) { - super(buildBooleanHolder(valueHolder, buttonValue)); - } - - - // ********** static methods ********** - - /** - * Build up a set of wrappers that will convert the - * specified value holder and button value to/from a boolean. - * - * If the value holder's value matches the button value, - * the wrapper will return true. Likewise, if the value holder's - * value is set to true, the wrapper will set the value holder's - * value to the button value. - */ - public static WritablePropertyValueModel<Boolean> buildBooleanHolder(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) { - WritablePropertyValueModel<Object> filteringPVM = new FilteringWritablePropertyValueModel<Object>(valueHolder, new RadioButtonFilter(buttonValue)); - return new TransformationWritablePropertyValueModel<Object, Boolean>(filteringPVM, new RadioButtonTransformer(buttonValue)); - } - - - // ********** overrides ********** - - /** - * The user cannot de-select a radio button - the user - * can only *select* a radio button. Only the model can - * cause a radio button to be de-selected. We use the - * ARMED flag to indicate whether we are being de-selected - * by the user. - */ - @Override - public void setSelected(boolean b) { - // do not allow the user to de-select a radio button - // radio buttons can - if ((b == false) && this.isArmed()) { - return; - } - super.setSelected(b); - } - - - // ********** inner classes ********** - - /** - * This filter will only pass through a new value to the wrapped - * value holder when it matches the configured button value. - */ - public static class RadioButtonFilter implements BidiFilter<Object> { - private Object buttonValue; - - public RadioButtonFilter(Object buttonValue) { - super(); - this.buttonValue = buttonValue; - } - - /** - * always return the wrapped value - */ - public boolean accept(Object value) { - return true; - } - - /** - * pass through the value to the wrapped property value model - * *only* when it matches our button value - */ - public boolean reverseAccept(Object value) { - return value == this.buttonValue; - } - - } - - /** - * This transformer will convert the wrapped value to Boolean.TRUE - * when it matches the configured button value. - */ - public static class RadioButtonTransformer implements BidiTransformer<Object, Boolean> { - private Object buttonValue; - - public RadioButtonTransformer(Object buttonValue) { - super(); - this.buttonValue = buttonValue; - } - - /** - * if the wrapped value matches our button value return true, - * if it is some other value return false; - * but if it is null simply pass it through because it will cause the - * button model's default value to be used - */ - public Boolean transform(Object value) { - return (value == null) ? null : Boolean.valueOf(value == this.buttonValue); - } - - /** - * if the new value is true, pass through the our button value; - * otherwise pass through null - */ - public Object reverseTransform(Boolean value) { - return (value.booleanValue()) ? this.buttonValue : null; - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java deleted file mode 100644 index c26f18fc90..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/SpinnerModelAdapter.java +++ /dev/null @@ -1,207 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import javax.swing.AbstractSpinnerModel; -import javax.swing.SpinnerModel; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.SpinnerModel can be used to keep a ChangeListener - * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value. - * - * Note: it is likely you want to use one of the following classes instead of - * this one: - * DateSpinnerModelAdapter - * NumberSpinnerModelAdapter - * ListSpinnerModelAdapter - * - * NB: This model should only be used for values that have a fairly - * inexpensive #equals() implementation. - * @see #synchronizeDelegate(Object) - */ -public class SpinnerModelAdapter - extends AbstractSpinnerModel -{ - /** The delegate spinner model whose behavior we "enhance". */ - protected final SpinnerModel delegate; - - /** A listener that allows us to forward any changes made to the delegate spinner model. */ - protected final ChangeListener delegateListener; - - /** A value model on the underlying value. */ - protected final WritablePropertyValueModel<Object> valueHolder; - - /** A listener that allows us to synchronize with changes made to the underlying value. */ - protected final PropertyChangeListener valueListener; - - - // ********** constructors ********** - - /** - * Constructor - the value holder and delegate are required. - */ - public SpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder, SpinnerModel delegate) { - super(); - if (valueHolder == null || delegate == null) { - throw new NullPointerException(); - } - this.valueHolder = valueHolder; - this.delegate = delegate; - // postpone listening to the underlying value - // until we have listeners ourselves... - this.valueListener = this.buildValueListener(); - this.delegateListener = this.buildDelegateListener(); - } - - /** - * Constructor - the value holder is required. - * This will wrap a simple number spinner model. - */ - public SpinnerModelAdapter(WritablePropertyValueModel<Object> valueHolder) { - this(valueHolder, new SpinnerNumberModel()); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildValueListener() { - return new AWTPropertyChangeListenerWrapper(this.buildValueListener_()); - } - - protected PropertyChangeListener buildValueListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - SpinnerModelAdapter.this.valueChanged(event); - } - @Override - public String toString() { - return "value listener"; - } - }; - } - - /** - * expand access a bit for inner class - */ - @Override - protected void fireStateChanged() { - super.fireStateChanged(); - } - - protected ChangeListener buildDelegateListener() { - return new ChangeListener() { - public void stateChanged(ChangeEvent event) { - // forward the event, with this as the source - SpinnerModelAdapter.this.fireStateChanged(); - } - @Override - public String toString() { - return "delegate listener"; - } - }; - } - - - // ********** SpinnerModel implementation ********** - - public Object getValue() { - return this.delegate.getValue(); - } - - /** - * Extend to update the underlying value directly. - * The resulting event will be ignored: @see #synchronizeDelegate(Object). - */ - public void setValue(Object value) { - this.delegate.setValue(value); - this.valueHolder.setValue(value); - } - - public Object getNextValue() { - return this.delegate.getNextValue(); - } - - public Object getPreviousValue() { - return this.delegate.getPreviousValue(); - } - - /** - * Extend to start listening to the underlying value if necessary. - */ - @Override - public void addChangeListener(ChangeListener listener) { - if (this.listenerList.getListenerCount(ChangeListener.class) == 0) { - this.delegate.addChangeListener(this.delegateListener); - this.engageValueHolder(); - } - super.addChangeListener(listener); - } - - /** - * Extend to stop listening to the underlying value if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener listener) { - super.removeChangeListener(listener); - if (this.listenerList.getListenerCount(ChangeListener.class) == 0) { - this.disengageValueHolder(); - this.delegate.removeChangeListener(this.delegateListener); - } - } - - - // ********** behavior ********** - - /** - * A third party has modified the underlying value. - * Synchronize the delegate model accordingly. - */ - protected void valueChanged(PropertyChangeEvent event) { - this.synchronizeDelegate(event.getNewValue()); - } - - /** - * Set the delegate's value if it has changed. - */ - protected void synchronizeDelegate(Object value) { - // check to see whether the delegate has already been synchronized - // (via #setValue()) - if ( ! this.delegate.getValue().equals(value)) { - this.delegate.setValue(value); - } - } - - protected void engageValueHolder() { - this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueListener); - this.synchronizeDelegate(this.valueHolder.getValue()); - } - - protected void disengageValueHolder() { - this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueListener); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.valueHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java deleted file mode 100644 index 5e039e270b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TableModelAdapter.java +++ /dev/null @@ -1,410 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import javax.swing.event.TableModelListener; -import javax.swing.table.AbstractTableModel; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.CollectionValueModel; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This TableModel can be used to keep a TableModelListener (e.g. a JTable) - * in synch with a ListValueModel that holds a collection of model objects, - * each of which corresponds to a row in the table. - * Typically, each column of the table will be bound to a different aspect - * of the contained model objects. - * - * For example, a MWTable has an attribute 'databaseFields' that holds - * a collection of MWDatabaseFields that would correspond to the rows of - * a JTable; and each MWDatabaseField has a number - * of attributes (e.g. name, type, size) that can be bound to the columns of - * a row in the JTable. As these database fields are added, removed, and - * changed, this model will keep the listeners aware of the changes. - * - * An instance of this TableModel must be supplied with a - * list holder (e.g. the 'databaseFields'), which is a value - * model on the bound collection This is required - the - * collection itself can be null, but the list value model that - * holds it is required. Typically this list will be sorted (@see - * SortedListValueModelAdapter). - * - * This TableModel must also be supplied with a ColumnAdapter that - * will be used to configure the headers, renderers, editors, and contents - * of the various columns. - * - * Design decision: - * Cell listener options (from low space/high time to high space/low time): - * - 1 cell listener listening to every cell (this is the current implementation) - * - 1 cell listener per row - * - 1 cell listener per cell - */ -public class TableModelAdapter<E> - extends AbstractTableModel -{ - /** - * a list of user objects that are converted to - * rows via the column adapter - */ - private ListValueModel<? extends E> listHolder; - private final ListChangeListener listChangeListener; - - /** - * each row is an array of cell models - */ - // declare as ArrayList so we can use #ensureCapacity(int) - private final ArrayList<WritablePropertyValueModel<Object>[]> rows; - - /** - * client-supplied adapter that provides with the various column - * settings and converts the objects in the LVM - * into an array of cell models - */ - private final ColumnAdapter columnAdapter; - - /** - * the single listener that listens to every cell's model - */ - private final PropertyChangeListener cellListener; - - - // ********** constructors ********** - - /** - * Construct a table model adapter for the specified objects - * and adapter. - */ - public TableModelAdapter(ListValueModel<? extends E> listHolder, ColumnAdapter columnAdapter) { - super(); - if (listHolder == null) { - throw new NullPointerException(); - } - this.listHolder = listHolder; - this.columnAdapter = columnAdapter; - this.listChangeListener = this.buildListChangeListener(); - this.rows = new ArrayList<WritablePropertyValueModel<Object>[]>(); - this.cellListener = this.buildCellListener(); - } - - /** - * Construct a table model adapter for the specified objects - * and adapter. - */ - public TableModelAdapter(CollectionValueModel<? extends E> collectionHolder, ColumnAdapter columnAdapter) { - this(new CollectionListValueModelAdapter<E>(collectionHolder), columnAdapter); - } - - - // ********** initialization ********** - - protected ListChangeListener buildListChangeListener() { - return new AWTListChangeListenerWrapper(this.buildListChangeListener_()); - } - - protected ListChangeListener buildListChangeListener_() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - TableModelAdapter.this.addRows(event.getIndex(), event.itemsSize(), this.items(event)); - } - public void itemsRemoved(ListChangeEvent event) { - TableModelAdapter.this.removeRows(event.getIndex(), event.itemsSize()); - } - public void itemsReplaced(ListChangeEvent event) { - TableModelAdapter.this.replaceRows(event.getIndex(), this.items(event)); - } - public void itemsMoved(ListChangeEvent event) { - TableModelAdapter.this.moveRows(event.getTargetIndex(), event.getSourceIndex(), event.getMoveLength()); - } - public void listCleared(ListChangeEvent event) { - TableModelAdapter.this.clearTable(); - } - public void listChanged(ListChangeEvent event) { - TableModelAdapter.this.rebuildTable(); - } - /** - * minimize scope of suppressed warnings - */ - @SuppressWarnings("unchecked") - protected Iterator<Object> items(ListChangeEvent event) { - return (Iterator<Object>) event.items(); - } - @Override - public String toString() { - return "list listener"; - } - }; - } - - - protected PropertyChangeListener buildCellListener() { - return new AWTPropertyChangeListenerWrapper(this.buildCellListener_()); - } - - protected PropertyChangeListener buildCellListener_() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - TableModelAdapter.this.cellChanged((WritablePropertyValueModel<Object>) event.getSource()); - } - @Override - public String toString() { - return "cell listener"; - } - }; - } - - - // ********** TableModel implementation ********** - - public int getColumnCount() { - return this.columnAdapter.columnCount(); - } - - public int getRowCount() { - return this.rows.size(); - } - - @Override - public String getColumnName(int column) { - return this.columnAdapter.columnName(column); - } - - @Override - public Class<?> getColumnClass(int columnIndex) { - return this.columnAdapter.columnClass(columnIndex); - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return this.columnAdapter.columnIsEditable(columnIndex); - } - - public Object getValueAt(int rowIndex, int columnIndex) { - WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex); - return row[columnIndex].getValue(); - } - - @Override - public void setValueAt(Object value, int rowIndex, int columnIndex) { - WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex); - row[columnIndex].setValue(value); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTableModelListener(TableModelListener l) { - if (this.hasNoTableModelListeners()) { - this.engageModel(); - } - super.addTableModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if necessary. - */ - @Override - public void removeTableModelListener(TableModelListener l) { - super.removeTableModelListener(l); - if (this.hasNoTableModelListeners()) { - this.disengageModel(); - } - } - - - // ********** public API ********** - - /** - * Return the underlying list model. - */ - public ListValueModel<? extends E> getModel() { - return this.listHolder; - } - - /** - * Set the underlying list model. - */ - public void setModel(ListValueModel<E> listHolder) { - if (listHolder == null) { - throw new NullPointerException(); - } - boolean hasListeners = this.hasTableModelListeners(); - if (hasListeners) { - this.disengageModel(); - } - this.listHolder = listHolder; - if (hasListeners) { - this.engageModel(); - this.fireTableDataChanged(); - } - } - - /** - * Set the underlying collection model. - */ - public void setModel(CollectionValueModel<E> collectionHolder) { - this.setModel(new CollectionListValueModelAdapter<E>(collectionHolder)); - } - - - // ********** queries ********** - - /** - * Return whether this model has no listeners. - */ - protected boolean hasNoTableModelListeners() { - return this.listenerList.getListenerCount(TableModelListener.class) == 0; - } - - /** - * Return whether this model has any listeners. - */ - protected boolean hasTableModelListeners() { - return ! this.hasNoTableModelListeners(); - } - - - // ********** behavior ********** - - /** - * Start listening to the list of objects and the various aspects - * of the objects that make up the rows. - */ - private void engageModel() { - this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - this.engageAllCells(); - } - - /** - * Convert the objects into rows and listen to the cells. - */ - private void engageAllCells() { - this.rows.ensureCapacity(this.listHolder.size()); - for (Iterator<? extends E> stream = this.listHolder.iterator(); stream.hasNext(); ) { - WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(stream.next()); - this.engageRow(row); - this.rows.add(row); - } - } - - /** - * Listen to the cells in the specified row. - */ - private void engageRow(WritablePropertyValueModel<Object>[] row) { - for (int i = row.length; i-- > 0; ) { - row[i].addPropertyChangeListener(PropertyValueModel.VALUE, this.cellListener); - } - } - - /** - * Stop listening. - */ - private void disengageModel() { - this.disengageAllCells(); - this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener); - } - - private void disengageAllCells() { - for (WritablePropertyValueModel<Object>[] row : this.rows) { - this.disengageRow(row); - } - this.rows.clear(); - } - - private void disengageRow(WritablePropertyValueModel<Object>[] row) { - for (int i = row.length; i-- > 0; ) { - row[i].removePropertyChangeListener(PropertyValueModel.VALUE, this.cellListener); - } - } - - /** - * brute-force search for the cell(s) that changed... - */ - void cellChanged(WritablePropertyValueModel<Object> cellHolder) { - for (int i = this.rows.size(); i-- > 0; ) { - WritablePropertyValueModel<Object>[] row = this.rows.get(i); - for (int j = row.length; j-- > 0; ) { - if (row[j] == cellHolder) { - this.fireTableCellUpdated(i, j); - } - } - } - } - - /** - * convert the items to rows - */ - void addRows(int index, int size, Iterator<Object> items) { - List<WritablePropertyValueModel<Object>[]> newRows = new ArrayList<WritablePropertyValueModel<Object>[]>(size); - while (items.hasNext()) { - WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(items.next()); - this.engageRow(row); - newRows.add(row); - } - this.rows.addAll(index, newRows); - this.fireTableRowsInserted(index, index + size - 1); - } - - void removeRows(int index, int size) { - for (int i = 0; i < size; i++) { - this.disengageRow(this.rows.remove(index)); - } - this.fireTableRowsDeleted(index, index + size - 1); - } - - void replaceRows(int index, Iterator<Object> items) { - int i = index; - while (items.hasNext()) { - WritablePropertyValueModel<Object>[] row = this.rows.get(i); - this.disengageRow(row); - row = this.columnAdapter.cellModels(items.next()); - this.engageRow(row); - this.rows.set(i, row); - i++; - } - this.fireTableRowsUpdated(index, i - 1); - } - - void moveRows(int targetIndex, int sourceIndex, int length) { - ArrayList<WritablePropertyValueModel<Object>[]> temp = new ArrayList<WritablePropertyValueModel<Object>[]>(length); - for (int i = 0; i < length; i++) { - temp.add(this.rows.remove(sourceIndex)); - } - this.rows.addAll(targetIndex, temp); - - int start = Math.min(targetIndex, sourceIndex); - int end = Math.max(targetIndex, sourceIndex) + length - 1; - this.fireTableRowsUpdated(start, end); - } - - void clearTable() { - this.disengageAllCells(); - this.fireTableDataChanged(); - } - - void rebuildTable() { - this.disengageAllCells(); - this.engageAllCells(); - this.fireTableDataChanged(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java deleted file mode 100644 index 7c0e742f33..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/ToggleButtonModelAdapter.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.awt.event.ActionListener; -import java.awt.event.ItemListener; -import javax.swing.JToggleButton.ToggleButtonModel; -import javax.swing.event.ChangeListener; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; - -/** - * This javax.swing.ButtonModel can be used to keep a listener - * (e.g. a JCheckBox or a JRadioButton) in synch with a PropertyValueModel - * on a boolean. - */ -public class ToggleButtonModelAdapter - extends ToggleButtonModel -{ - /** - * The default setting for the toggle button; for when the underlying model is null. - * The default [default value] is false (i.e. the toggle button is unchecked/empty). - */ - protected final boolean defaultValue; - - /** A value model on the underlying model boolean. */ - protected final WritablePropertyValueModel<Boolean> booleanHolder; - - /** - * A listener that allows us to synchronize with - * changes made to the underlying model boolean. - */ - protected final PropertyChangeListener booleanChangeListener; - - - // ********** constructors ********** - - /** - * Constructor - the boolean holder is required. - */ - public ToggleButtonModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) { - super(); - if (booleanHolder == null) { - throw new NullPointerException(); - } - this.booleanHolder = booleanHolder; - this.booleanChangeListener = this.buildBooleanChangeListener(); - // postpone listening to the underlying model - // until we have listeners ourselves... - this.defaultValue = defaultValue; - } - - /** - * Constructor - the boolean holder is required. - * The default value will be false. - */ - public ToggleButtonModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder) { - this(booleanHolder, false); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildBooleanChangeListener() { - return new AWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_()); - } - - protected PropertyChangeListener buildBooleanChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - ToggleButtonModelAdapter.this.booleanChanged(event); - } - @Override - public String toString() { - return "boolean listener"; - } - }; - } - - - // ********** ButtonModel implementation ********** - - /** - * Extend to update the underlying model if necessary. - */ - @Override - public void setSelected(boolean b) { - if (this.isSelected() != b) { // stop the recursion! - super.setSelected(b);//put the super call first, otherwise the following gets called twice - this.booleanHolder.setValue(Boolean.valueOf(b)); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addActionListener(ActionListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addActionListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeActionListener(ActionListener l) { - super.removeActionListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addItemListener(ItemListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addItemListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeItemListener(ItemListener l) { - super.removeItemListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addChangeListener(ChangeListener l) { - if (this.hasNoListeners()) { - this.engageModel(); - } - super.addChangeListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeChangeListener(ChangeListener l) { - super.removeChangeListener(l); - if (this.hasNoListeners()) { - this.disengageModel(); - } - } - - - // ********** queries ********** - - /** - * Return whether we have no listeners at all. - */ - protected boolean hasNoListeners() { - return this.listenerList.getListenerCount() == 0; - } - - protected boolean getDefaultValue() { - return this.defaultValue; - } - - - // ********** behavior ********** - - /** - * Synchronize with the specified value. - * If it is null, use the default value (which is typically false). - */ - protected void setSelected(Boolean value) { - if (value == null) { - this.setSelected(this.getDefaultValue()); - } else { - this.setSelected(value.booleanValue()); - } - } - - /** - * The underlying model has changed - synchronize accordingly. - */ - protected void booleanChanged(PropertyChangeEvent event) { - this.setSelected((Boolean) event.getNewValue()); - } - - protected void engageModel() { - this.booleanHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener); - this.setSelected(this.booleanHolder.getValue()); - } - - protected void disengageModel() { - this.booleanHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.booleanHolder); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java deleted file mode 100644 index f94a723025..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/swing/TreeModelAdapter.java +++ /dev/null @@ -1,722 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.model.value.swing; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreePath; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTListChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.listener.awt.AWTStateChangeListenerWrapper; -import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.value.ListValueModel; -import org.eclipse.jpt.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.utility.model.value.TreeNodeValueModel; - -/** - * This javax.swing.tree.TreeModel can be used to keep a TreeModelListener - * (e.g. a JTree) in synch with a tree of TreeNodeValueModel objects. Unlike - * javax.swing.tree.DefaultTreeModel, you do not add and remove nodes with - * methods implemented here. You can add and remove nodes by adding and - * removing them directly to/from the nodes (or, more typically, the domain - * objects the nodes are wrapping and listening to). - * - * Due to limitations in JTree, the root of the tree can never be null, - * which, typically, should not be a problem. (If you want to display an empty - * tree you can set the JTree's treeModel to null.) - */ -public class TreeModelAdapter<T> - extends AbstractTreeModel -{ - /** - * A value model on the underlying tree's root node and its - * corresponding listener. This allows clients to swap out - * the entire tree. Due to limitations in JTree, the root should - * never be set to null while we have listeners. - */ - private final PropertyValueModel<TreeNodeValueModel<T>> rootHolder; - private final PropertyChangeListener rootListener; - - /** - * A listener that notifies us when a node's internal - * "state" changes (as opposed to the node's value or list of - * children), allowing us to forward notification to our listeners. - */ - private final StateChangeListener nodeStateListener; - - /** - * A listener that notifies us when a node's "value" - * changes (as opposed to the node's state or list of - * children), allowing us to forward notification to our listeners. - * Typically, this will only happen with nodes that hold - * primitive data. - */ - private final PropertyChangeListener nodeValueListener; - - /** - * A listener that notifies us when an underlying node's - * "list" of children changes, allowing us to keep our - * internal tree in synch with the underlying tree model. - */ - private final ListChangeListener childrenListener; - - /* these attributes make up our internal tree */ - /** - * The root cannot be null while we have listeners, which is - * most of the time. The root is cached so we can disengage - * from it when it has been swapped out. - */ - private TreeNodeValueModel<T> root; - - /** - * Map the nodes to their lists of children. - * We cache these so we can swap out the entire list of children - * when we receive a #listChanged() event (which does not include - * the items that were affected). - * @see EventChangePolicy#rebuildChildren() - */ - final IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>> childrenLists; - - /** - * Map the children models to their parents. - * We cache these so we can figure out the "real" source of the - * list change events (the parent). - * @see EventChangePolicy#parent() - */ - final IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>> parents; - - - // ********** constructors ********** - - /** - * Construct a tree model for the specified root. - */ - public TreeModelAdapter(PropertyValueModel<TreeNodeValueModel<T>> rootHolder) { - super(); - if (rootHolder == null) { - throw new NullPointerException(); - } - this.rootHolder = rootHolder; - this.rootListener = this.buildRootListener(); - this.nodeStateListener = this.buildNodeStateListener(); - this.nodeValueListener = this.buildNodeValueListener(); - this.childrenListener = this.buildChildrenListener(); - this.childrenLists = new IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>>(); - this.parents = new IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>>(); - } - - /** - * Construct a tree model for the specified root. - */ - public TreeModelAdapter(TreeNodeValueModel<T> root) { - this(new StaticPropertyValueModel<TreeNodeValueModel<T>>(root)); - } - - - // ********** initialization ********** - - protected PropertyChangeListener buildRootListener() { - return new AWTPropertyChangeListenerWrapper(this.buildRootListener_()); - } - - protected PropertyChangeListener buildRootListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent event) { - TreeModelAdapter.this.rootChanged(); - } - @Override - public String toString() { - return "root listener"; - } - }; - } - - protected PropertyChangeListener buildNodeValueListener() { - return new AWTPropertyChangeListenerWrapper(this.buildNodeValueListener_()); - } - - protected PropertyChangeListener buildNodeValueListener_() { - return new PropertyChangeListener() { - @SuppressWarnings("unchecked") - public void propertyChanged(PropertyChangeEvent event) { - TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource()); - } - @Override - public String toString() { - return "node value listener"; - } - }; - } - - protected StateChangeListener buildNodeStateListener() { - return new AWTStateChangeListenerWrapper(this.buildNodeStateListener_()); - } - - protected StateChangeListener buildNodeStateListener_() { - return new StateChangeListener() { - @SuppressWarnings("unchecked") - public void stateChanged(StateChangeEvent event) { - TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource()); - } - @Override - public String toString() { - return "node state listener"; - } - }; - } - - protected ListChangeListener buildChildrenListener() { - return new AWTListChangeListenerWrapper(this.buildChildrenListener_()); - } - - protected ListChangeListener buildChildrenListener_() { - return new ListChangeListener() { - public void itemsAdded(ListChangeEvent event) { - new EventChangePolicy(event).addChildren(); - } - public void itemsRemoved(ListChangeEvent event) { - new EventChangePolicy(event).removeChildren(); - } - public void itemsReplaced(ListChangeEvent event) { - new EventChangePolicy(event).replaceChildren(); - } - public void itemsMoved(ListChangeEvent event) { - new EventChangePolicy(event).moveChildren(); - } - public void listCleared(ListChangeEvent event) { - new EventChangePolicy(event).clearChildren(); - } - public void listChanged(ListChangeEvent event) { - new EventChangePolicy(event).rebuildChildren(); - } - @Override - public String toString() { - return "children listener"; - } - }; - } - - - // ********** TreeModel implementation ********** - - public Object getRoot() { - return this.root; - } - - @SuppressWarnings("unchecked") - public Object getChild(Object parent, int index) { - return ((TreeNodeValueModel<T>) parent).child(index); - } - - @SuppressWarnings("unchecked") - public int getChildCount(Object parent) { - return ((TreeNodeValueModel<T>) parent).childrenSize(); - } - - @SuppressWarnings("unchecked") - public boolean isLeaf(Object node) { - return ((TreeNodeValueModel<T>) node).isLeaf(); - } - - @SuppressWarnings("unchecked") - public void valueForPathChanged(TreePath path, Object newValue) { - ((TreeNodeValueModel<T>) path.getLastPathComponent()).setValue((T) newValue); - } - - @SuppressWarnings("unchecked") - public int getIndexOfChild(Object parent, Object child) { - return ((TreeNodeValueModel<T>) parent).indexOfChild((TreeNodeValueModel<T>) child); - } - - /** - * Extend to start listening to the underlying model if necessary. - */ - @Override - public void addTreeModelListener(TreeModelListener l) { - if (this.hasNoTreeModelListeners()) { - this.engageModel(); - } - super.addTreeModelListener(l); - } - - /** - * Extend to stop listening to the underlying model if appropriate. - */ - @Override - public void removeTreeModelListener(TreeModelListener l) { - super.removeTreeModelListener(l); - if (this.hasNoTreeModelListeners()) { - this.disengageModel(); - } - } - - - // ********** behavior ********** - - /** - * Listen to the root and all the other nodes - * in the underlying tree model. - */ - private void engageModel() { - this.rootHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.rootListener); - this.root = this.rootHolder.getValue(); - if (this.root == null) { - throw new NullPointerException(); // the root cannot be null while we have listeners - } - this.engageNode(this.root); - this.addRoot(); - } - - /** - * Add the root and all of the nodes to the underlying tree. - */ - private void addRoot() { - this.addNode(0, this.root); - } - - /** - * Stop listening to the root and all the other - * nodes in the underlying tree model. - */ - private void disengageModel() { - this.removeRoot(); - this.disengageNode(this.root); - this.root = null; - this.rootHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.rootListener); - } - - /** - * Remove the root and all of the nodes from the underlying tree. - */ - private void removeRoot() { - this.removeNode(0, this.root); - } - - /** - * The root has been swapped. - * This method is a bit gnarly because the API for notifying listeners - * that the root has changed is a bit inconsistent with that used for - * non-root nodes. - */ - void rootChanged() { - TreeNodeValueModel<T> newRoot = this.rootHolder.getValue(); - if (newRoot == null) { - throw new NullPointerException(); // the root cannot be null while we have listeners - } - // remove all the current root's children from the tree - // and remove the it from the internal tree - this.removeRoot(); - - // save the old root and swap in the new root - TreeNodeValueModel<T> oldRoot = this.root; - this.root = newRoot; - - // we must be listening to both the old and new roots when we fire the event - // because their values can be affected by whether they have listeners - this.engageNode(this.root); - this.fireTreeRootReplaced(this.root); - // now we can stop listening to the old root - this.disengageNode(oldRoot); - - // add the new root to the internal tree and - // add all its children to the tree also - this.addRoot(); - } - - /** - * Either the "value" or the "state" of the specified node has changed, - * forward notification to our listeners. - */ - void nodeChanged(TreeNodeValueModel<T> node) { - TreeNodeValueModel<T> parent = node.parent(); - if (parent == null) { - this.fireTreeRootChanged(node); - } else { - this.fireTreeNodeChanged(parent.path(), parent.indexOfChild(node), node); - } - } - - /** - * Listen to the nodes, notify our listeners that the nodes were added, - * and then add the nodes to our internal tree. - * We must listen to the nodes before notifying anybody, because - * adding a listener can change the value of a node. - */ - void addChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) { - int len = childIndices.length; - for (int i = 0; i < len; i++) { - this.engageNode(children[i]); - } - this.fireTreeNodesInserted(path, childIndices, children); - for (int i = 0; i < len; i++) { - this.addNode(childIndices[i], children[i]); - } - } - - /** - * Listen to the node and its children model. - */ - private void engageNode(TreeNodeValueModel<T> node) { - node.addStateChangeListener(this.nodeStateListener); - node.addPropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener); - node.childrenModel().addListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener); - } - - /** - * Add the node to our internal tree; - * then recurse down through the node's children, - * adding them to the internal tree also. - */ - private void addNode(int index, TreeNodeValueModel<T> node) { - this.addNodeToInternalTree(node.parent(), index, node, node.childrenModel()); - new NodeChangePolicy(node).addChildren(); - } - - /** - * Add the specified node to our internal tree. - */ - private void addNodeToInternalTree(TreeNodeValueModel<T> parent, int index, TreeNodeValueModel<T> node, ListValueModel<TreeNodeValueModel<T>> childrenModel) { - List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent); - if (siblings == null) { - siblings = new ArrayList<TreeNodeValueModel<T>>(); - this.childrenLists.put(parent, siblings); - } - siblings.add(index, node); - - this.parents.put(childrenModel, node); - } - - /** - * Remove nodes from our internal tree, notify our listeners that the - * nodes were removed, then stop listening to the nodes. - * We must listen to the nodes until after notifying anybody, because - * removing a listener can change the value of a node. - */ - void removeChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) { - int len = childIndices.length; - for (int i = 0; i < len; i++) { - // the indices slide down a notch each time we remove a child - this.removeNode(childIndices[i] - i, children[i]); - } - this.fireTreeNodesRemoved(path, childIndices, children); - for (int i = 0; i < len; i++) { - this.disengageNode(children[i]); - } - } - - /** - * First, recurse down through the node's children, - * removing them from our internal tree; - * then remove the node itself from our internal tree. - */ - private void removeNode(int index, TreeNodeValueModel<T> node) { - new NodeChangePolicy(node).removeChildren(); - this.removeNodeFromInternalTree(node.parent(), index, node, node.childrenModel()); - } - - /** - * Remove the specified node from our internal tree. - */ - private void removeNodeFromInternalTree(TreeNodeValueModel<T> parent, int index, TreeNodeValueModel<T> node, ListValueModel<TreeNodeValueModel<T>> childrenModel) { - this.parents.remove(childrenModel); - - List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent); - siblings.remove(index); - if (siblings.isEmpty()) { - this.childrenLists.remove(parent); - } - } - - /** - * Stop listening to the node and its children model. - */ - private void disengageNode(TreeNodeValueModel<T> node) { - node.childrenModel().removeListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener); - node.removePropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener); - node.removeStateChangeListener(this.nodeStateListener); - } - - void moveChildren(TreeNodeValueModel<T> parent, int targetIndex, int sourceIndex, int length) { - List<TreeNodeValueModel<T>> childrenList = this.childrenLists.get(parent); - ArrayList<TreeNodeValueModel<T>> temp = new ArrayList<TreeNodeValueModel<T>>(length); - for (int i = 0; i < length; i++) { - temp.add(childrenList.remove(sourceIndex)); - } - childrenList.addAll(targetIndex, temp); - - this.fireTreeStructureChanged(parent.path()); - } - - - // ********** standard methods ********** - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.root); - } - - - // ********** inner classes ********** - - /** - * Coalesce some of the common change policy behavior. - */ - private abstract class ChangePolicy { - - ChangePolicy() { - super(); - } - - /** - * Add the current set of children. - */ - void addChildren() { - TreeModelAdapter.this.addChildren(this.parent().path(), this.childIndices(), this.childArray()); - } - - /** - * Remove the current set of children. - */ - void removeChildren() { - TreeModelAdapter.this.removeChildren(this.parent().path(), this.childIndices(), this.childArray()); - } - - /** - * Return an array of the indices of the current set of children, - * which should be contiguous. - */ - int[] childIndices() { - return this.buildIndices(this.childrenStartIndex(), this.childrenSize()); - } - - /** - * Return an array of the current set of children. - */ - TreeNodeValueModel<T>[] childArray() { - return this.buildArray(this.children(), this.childrenSize()); - } - - /** - * Build an array to hold the elements in the specified iterator. - * If they are different sizes, something is screwed up... - */ - TreeNodeValueModel<T>[] buildArray(Iterator<TreeNodeValueModel<T>> stream, int size) { - @SuppressWarnings("unchecked") - TreeNodeValueModel<T>[] array = new TreeNodeValueModel[size]; - for (int i = 0; stream.hasNext(); i++) { - array[i] = stream.next(); - } - return array; - } - - /** - * Return a set of indices, starting at zero and - * continuing for the specified size. - */ - int[] buildIndices(int size) { - return buildIndices(0, size); - } - - /** - * Return a set of indices, starting at the specified index and - * continuing for the specified size. - */ - int[] buildIndices(int start, int size) { - int[] indices = new int[size]; - int index = start; - for (int i = 0; i < size; i++) { - indices[i] = index++; - } - return indices; - } - - /** - * Return the parent of the current set of children. - */ - abstract TreeNodeValueModel<T> parent(); - - /** - * Return the starting index for the current set of children. - */ - abstract int childrenStartIndex(); - - /** - * Return the size of the current set of children. - */ - abstract int childrenSize(); - - /** - * Return an interator on the current set of children. - */ - abstract Iterator<TreeNodeValueModel<T>> children(); - - } - - - /** - * Wraps a ListChangeEvent for adding, removing, replacing, - * and changing children. - */ - private class EventChangePolicy extends ChangePolicy { - private ListChangeEvent event; - - EventChangePolicy(ListChangeEvent event) { - this.event = event; - } - - /** - * Map the ListChangeEvent's source to the corresponding parent. - */ - @Override - TreeNodeValueModel<T> parent() { - return TreeModelAdapter.this.parents.get(this.event.getSource()); - } - - /** - * The ListChangeEvent's item index is the children start index. - */ - @Override - int childrenStartIndex() { - return this.event.getIndex(); - } - - /** - * The ListChangeEvent's size is the children size. - */ - @Override - int childrenSize() { - return this.event.itemsSize(); - } - - /** - * The ListChangeEvent's items are the children. - */ - @Override - @SuppressWarnings("unchecked") - Iterator<TreeNodeValueModel<T>> children() { - return (Iterator<TreeNodeValueModel<T>>) this.event.items(); - } - - /** - * Remove the old nodes and add the new ones. - */ - void replaceChildren() { - TreeNodeValueModel<T>[] parentPath = this.parent().path(); - int[] childIndices = this.childIndices(); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, this.replacedChildren()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, this.childArray()); - } - - /** - * Remove the old nodes and add the new ones. - */ - void moveChildren() { - TreeModelAdapter.this.moveChildren(this.parent(), this.event.getTargetIndex(), this.event.getSourceIndex(), this.event.getMoveLength()); - } - - /** - * Clear all the nodes. - */ - void clearChildren() { - TreeNodeValueModel<T> parent = this.parent(); - TreeNodeValueModel<T>[] parentPath = parent.path(); - List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent); - int[] childIndices = this.buildIndices(childrenList.size()); - TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList.iterator(), childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - } - - /** - * Remove all the old nodes and add all the new nodes. - */ - void rebuildChildren() { - TreeNodeValueModel<T> parent = this.parent(); - TreeNodeValueModel<T>[] parentPath = parent.path(); - List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent); - int[] childIndices = this.buildIndices(childrenList.size()); - TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList.iterator(), childrenList.size()); - TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray); - - childIndices = this.buildIndices(parent.childrenModel().size()); - childArray = this.buildArray(parent.childrenModel().iterator(), parent.childrenSize()); - TreeModelAdapter.this.addChildren(parentPath, childIndices, childArray); - } - - /** - * The ListChangeEvent's replaced items are the replaced children. - */ - @SuppressWarnings("unchecked") - TreeNodeValueModel<T>[] replacedChildren() { - return this.buildArray((Iterator<TreeNodeValueModel<T>>) this.event.replacedItems(), this.event.itemsSize()); - } - - } - - - /** - * Wraps a TreeNodeValueModel for adding and removing its children. - */ - private class NodeChangePolicy extends ChangePolicy { - private TreeNodeValueModel<T> node; - - NodeChangePolicy(TreeNodeValueModel<T> node) { - this.node = node; - } - - /** - * The node itself is the parent. - */ - @Override - TreeNodeValueModel<T> parent() { - return this.node; - } - - /** - * Since we will always be dealing with all of the node's - * children, the children start index is always zero. - */ - @Override - int childrenStartIndex() { - return 0; - } - - /** - * Since we will always be dealing with all of the node's - * children, the children size is always equal to the size - * of the children model. - */ - @Override - int childrenSize() { - return this.node.childrenModel().size(); - } - - /** - * Since we will always be dealing with all of the node's - * children, the children are all the objects held by - * the children model. - */ - @Override - Iterator<TreeNodeValueModel<T>> children() { - return this.node.childrenModel().iterator(); - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNode.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNode.java deleted file mode 100644 index a7fab12bdb..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNode.java +++ /dev/null @@ -1,939 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Set; -import java.util.Vector; -import org.eclipse.jpt.utility.internal.iterators.CloneIterator; -import org.eclipse.jpt.utility.internal.iterators.CloneListIterator; -import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.model.AbstractModel; -import org.eclipse.jpt.utility.internal.model.CallbackChangeSupport; -import org.eclipse.jpt.utility.internal.model.ChangeSupport; - -/** - * Base class for Node classes. - * Provides support for the following: - * initialization - * enforced object identity wrt #equals()/#hashCode() - * containment hierarchy (parent/child) - * user comment - * dirty flag - * problems - * sorting - * - * Typically, subclasses should consider implementing the following methods: - * the appropriate constructors - * (with the appropriately-restrictive type declaration for parent) - * #initialize() - * #initialize(Node parentNode) - * #checkParent(Node parentNode) - * #addChildrenTo(List list) - * #nodeRemoved(Node) - * #validator() - * #transientAspectNames() or - * #addTransientAspectNamesTo(Set transientAspectNames) - * #addProblemsTo(List currentProblems) - * #nonValidatedAspectNames() - * #addNonValidatedAspectNamesTo(Set nonValidatedAspectNames) - * #displayString() - * #toString(StringBuilder sb) - */ -public abstract class AbstractNode - extends AbstractModel - implements Node, CallbackChangeSupport.Source -{ - - /** Containment hierarchy. */ - private Node parent; // pseudo-final - - /** Track whether the node has changed. */ - private volatile boolean dirty; - private volatile boolean dirtyBranch; - - /** - * The node's problems, as calculated during validation. - * This list should only be modified via a ProblemSynchronizer, - * allowing for asynchronous modification from another thread. - */ - private Vector<Problem> problems; // pseudo-final - private static final Object[] EMPTY_PROBLEM_MESSAGE_ARGUMENTS = new Object[0]; - - /** - * Cache the node's "branch" problems, as calculated during validation. - * This list should only be modified via a ProblemSynchronizer, - * allowing for asynchronous modification from another thread. - * This must be recalculated every time this node or one of its - * descendants changes it problems. - */ - private Vector<Problem> branchProblems; // pseudo-final - - /** User comment. */ - private volatile String comment; - - - // ********** static fields ********** - - /** - * Sets of transient aspect names, keyed by class. - * This is built up lazily, as the objects are modified. - */ - private static final HashMap<Class<? extends AbstractNode>, HashSet<String>> transientAspectNameSets = new HashMap<Class<? extends AbstractNode>, HashSet<String>>(); - - /** - * Sets of non-validated aspect names, keyed by class. - * This is built up lazily, as the objects are modified. - */ - private static final HashMap<Class<? extends AbstractNode>, HashSet<String>> nonValidatedAspectNameSets = new HashMap<Class<? extends AbstractNode>, HashSet<String>>(); - - - // ********** constructors ********** - - /** - * Most objects must have a parent. - * Use this constructor to create a new node. - * @see #initialize(Node) - */ - protected AbstractNode(Node parent) { - super(); - this.initialize(); - this.initialize(parent); - } - - - // ********** initialization ********** - - /** - * Initialize a newly-created instance. - * @see #initialize(Node) - */ - protected void initialize() { - this.comment = ""; //$NON-NLS-1$ - - // a new object is dirty, by definition - this.dirty = true; - this.dirtyBranch = true; - - this.problems = new Vector<Problem>(); - this.branchProblems = new Vector<Problem>(); - - // when you override this method, don't forget to include: - // super.initialize(); - } - - /** - * Initialize a newly-created instance. - * @see #initialize() - */ - protected void initialize(Node parentNode) { - this.checkParent(parentNode); - this.parent = parentNode; - // when you override this method, don't forget to include: - // super.initialize(parentNode); - } - - @Override - protected ChangeSupport buildChangeSupport() { - return new CallbackChangeSupport(this); - } - - - // ********** equality ********** - - /** - * Enforce object identity - do not allow objects to be equal unless - * they are the same object. - * Do NOT override this method - we rely on object identity extensively. - */ - @Override - public final boolean equals(Object o) { - return this == o; - } - - /** - * Enforce object identity - do not allow objects to be equal unless - * they are the same object. - * Do NOT override this method - we rely on object identity extensively. - */ - @Override - public final int hashCode() { - return super.hashCode(); - } - - - // ********** containment hierarchy (parent/children) ********** - - /** - * INTRA-TREE API? - * Return the node's parent in the containment hierarchy. - * Most nodes must have a parent. - * @see #children() - */ - public Node getParent() { - return this.parent; - } - - /** - * Throw an IllegalArgumentException if the parent is not valid - * for the node. - * By default require a non-null parent. Override if other restrictions exist - * or the parent should be null. - * NB: Root node model implementations will need to override this method. - */ - protected void checkParent(Node parentNode) { - if (parentNode == null) { - throw new IllegalArgumentException("The parent node cannot be null"); - } - } - - /** - * INTRA-TREE API? - * Return the node's children, which are also nodes. - * Do NOT override this method. - * Override #addChildrenTo(List). - * @see #getParent() - * @see #addChildrenTo(java.util.List) - */ - public final Iterator<Node> children() { - List<Node> children = new ArrayList<Node>(); - this.addChildrenTo(children); - return children.iterator(); - } - - /** - * Subclasses should override this method to add their children - * to the specified list. - * @see #children() - */ - protected void addChildrenTo(List<Node> list) { - // this class has no children, subclasses will... - // when you override this method, don't forget to include: - // super.addChildrenTo(list); - } - - /** - * INTRA-TREE API? - * Return the containment hierarchy's root node. - * Most nodes must have a root. - * @see #getParent() - * NB: Assume the root has no parent. - */ - public Node root() { - Node p = this.parent; - return (p == null) ? this : p.root(); - } - - /** - * Return whether the node is a descendant of the specified node. - * By definition, a node is a descendant of itself. - */ - public boolean isDescendantOf(Node node) { - return (this == node) || this.parentIsDescendantOf(node); - } - - protected boolean parentIsDescendantOf(Node node) { - return (this.parent != null) && this.parent.isDescendantOf(node); - } - - /** - * Return a collection holding all the node's "references", and all - * the node's descendants' "references". "References" are - * objects that are "referenced" by another object, as opposed - * to "owned" by another object. - */ - public Iterator<Node.Reference> branchReferences() { - Collection<Node.Reference> branchReferences = new ArrayList<Node.Reference>(1000); // start big - this.addBranchReferencesTo(branchReferences); - return branchReferences.iterator(); - } - - /** - * INTRA-TREE API - * Add the node's "references", and all the node's descendants' - * "references", to the specified collection. "References" are - * objects that are "referenced" by another object, as opposed - * to "owned" by another object. - * This method is of particular concern to Handles, since most - * (hopefully all) "references" are held by Handles. - * @see Reference - * @see #children() - */ - public void addBranchReferencesTo(Collection<Node.Reference> branchReferences) { - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.addBranchReferencesTo(branchReferences); - } - } - - /** - * Return all the nodes in the object's branch of the tree, - * including the node itself. The nodes will probably returned - * in "depth-first" order. - * Only really used for testing and debugging. - */ - public Iterator<Node> allNodes() { - Collection<Node> nodes = new ArrayList<Node>(1000); // start big - this.addAllNodesTo(nodes); - return nodes.iterator(); - } - - /** - * INTRA-TREE API? - * Add all the nodes in the object's branch of the tree, - * including the node itself, to the specified collection. - * Only really used for testing and debugging. - */ - public void addAllNodesTo(Collection<Node> nodes) { - nodes.add(this); - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.addAllNodesTo(nodes); - } - } - - - // ********** model synchronization support ********** - - /** - * INTRA-TREE API - * This is a general notification that the specified node has been - * removed from the tree. The node receiving this notification - * should perform any necessary updates to remain in synch - * with the tree (e.g. clearing out or replacing any references - * to the removed node or any of the removed node's descendants). - * @see #isDescendantOf(Node) - */ - public void nodeRemoved(Node node) { - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.nodeRemoved(node); - } - // when you override this method, don't forget to include: - // super.nodeRemoved(node); - } - - /** - * convenience method - * return whether node1 is a descendant of node2; - * node1 can be null - */ - protected boolean nodeIsDescendantOf(Node node1, Node node2) { - return (node1 != null) && node1.isDescendantOf(node2); - } - - /** - * INTRA-TREE API - * This is a general notification that the specified node has been - * renamed. The node receiving this notification should mark its - * branch dirty if necessary (i.e. it references the renamed node - * or one of its descendants). This method is of particular concern - * to Handles. - * @see #isDescendantOf(Node) - */ - public void nodeRenamed(Node node) { - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.nodeRenamed(node); - } - // when you override this method, don't forget to include: - // super.nodeRenamed(node); - } - - - // ********** user comment ********** - - /** - * Return the object's user comment. - */ - public final String comment() { - return this.comment; - } - - /** - * Set the object's user comment. - */ - public final void setComment(String comment) { - Object old = this.comment; - this.comment = comment; - this.firePropertyChanged(COMMENT_PROPERTY, old, comment); - } - - - // ********** change support ********** - - /** - * An aspect of the node has changed: - * - if it is a persistent aspect, mark the object dirty - * - if it is a significant aspect, validate the object - */ - public void aspectChanged(String aspectName) { - if (this.aspectIsPersistent(aspectName)) { - // System.out.println(Thread.currentThread() + " dirty change: " + this + ": " + aspectName); - this.markDirty(); - } - if (this.aspectChangeRequiresValidation(aspectName)) { - // System.out.println(Thread.currentThread() + " validation change: " + this + ": " + aspectName); - this.validate(); - } - } - - protected void validate() { - this.getValidator().validate(); - } - - /** - * INTRA-TREE API - * Return a validator that will be invoked whenever a - * "validated" aspect of the node tree changes. - * Typically only the root node directly holds a validator. - * NB: Root node model implementations will need to override this method. - */ - public Node.Validator getValidator() { - if (this.parent == null) { - throw new IllegalStateException("This node should not be firing change events during its construction."); - } - return this.parent.getValidator(); - } - - /** - * Set a validator that will be invoked whenever a - * "validated" aspect of the node tree changes. - * Typically only the root node directly holds a validator. - * NB: Root node model implementations will need to override this method. - */ - public void setValidator(Node.Validator validator) { - if (this.parent == null) { - throw new IllegalStateException("This root node should implement #setValidator(Node.Validator)."); - } - throw new UnsupportedOperationException("Only root nodes implement #setValidator(Node.Validator)."); - } - - - // ********** dirty flag support ********** - - /** - * Return whether any persistent aspects of the object - * have changed since the object was last read or saved. - * This does NOT include changes to the object's descendants. - */ - public final boolean isDirty() { - return this.dirty; - } - - /** - * Return whether any persistent aspects of the object, - * or any of its descendants, have changed since the object and - * its descendants were last read or saved. - */ - public final boolean isDirtyBranch() { - return this.dirtyBranch; - } - - /** - * Return whether the object is unmodified - * since it was last read or saved. - * This does NOT include changes to the object's descendants. - */ - public final boolean isClean() { - return ! this.dirty; - } - - /** - * Return whether the object and all of its descendants - * are unmodified since the object and - * its descendants were last read or saved. - */ - public final boolean isCleanBranch() { - return ! this.dirtyBranch; - } - - /** - * Set the dirty branch flag setting. This is set to true - * when either the object or one of its descendants becomes dirty. - */ - private void setIsDirtyBranch(boolean dirtyBranch) { - boolean old = this.dirtyBranch; - this.dirtyBranch = dirtyBranch; - this.firePropertyChanged(DIRTY_BRANCH_PROPERTY, old, dirtyBranch); - } - - /** - * Mark the object as dirty and as a dirty branch. - * An object is marked dirty when either a "persistent" attribute - * has changed or its save location has changed. - */ - private void markDirty() { - this.dirty = true; - this.markBranchDirty(); - } - - /** - * INTRA-TREE API - * Mark the node and its parent as dirty branches. - * This message is propagated up the containment - * tree when a particular node becomes dirty. - */ - public void markBranchDirty() { - // short-circuit any unnecessary propagation - if (this.dirtyBranch) { - // if this is already a dirty branch, the parent must be also - return; - } - - this.setIsDirtyBranch(true); - this.markParentBranchDirty(); - } - - protected void markParentBranchDirty() { - if (this.parent != null) { - this.parent.markBranchDirty(); - } - } - - /** - * Mark the object and all its descendants as dirty. - * This is used when the save location of some - * top-level object is changed and the entire - * containment tree must be marked dirty so it - * will be written out. - */ - public final void markEntireBranchDirty() { - this.markDirty(); - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.markEntireBranchDirty(); - } - } - - /** - * Mark the object and all its descendants as clean. - * Then notify the object's parent that it (the parent) - * might now be a clean branch also. - * Typically used when the object has just been - * read in or written out. - */ - public final void markEntireBranchClean() { - this.cascadeMarkEntireBranchClean(); - this.markParentBranchCleanIfPossible(); - } - - protected void markParentBranchCleanIfPossible() { - if (this.parent != null) { - this.parent.markBranchCleanIfPossible(); - } - } - - /** - * INTRA-TREE API - * Mark the node and all its descendants as clean. - * Typically used when the node has just been - * read in or written out. - * This method is for internal use only; it is not for - * client use. - * Not the best of method names.... :-( - */ - public final void cascadeMarkEntireBranchClean() { - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.cascadeMarkEntireBranchClean(); - } - this.dirty = false; - this.setIsDirtyBranch(false); - } - - /** - * INTRA-TREE API - * A child node's branch has been marked clean. If the node - * itself is clean and if all of its children are also clean, the - * node's branch can be marked clean. Then, if the node's - * branch is clean, the node will notify its parent that it might - * be clean also. This message is propagated up the containment - * tree when a particular node becomes clean. - */ - public final void markBranchCleanIfPossible() { - // short-circuit any unnecessary propagation - if (this.dirty) { - // if the object is "locally" dirty, it is still a dirty branch - return; - } - - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - if (child.isDirtyBranch()) { - return; - } - } - - this.setIsDirtyBranch(false); - this.markParentBranchCleanIfPossible(); - } - - private boolean aspectIsPersistent(String aspectName) { - return ! this.aspectIsTransient(aspectName); - } - - private boolean aspectIsTransient(String aspectName) { - return this.transientAspectNames().contains(aspectName); - } - - /** - * Return a set of the object's transient aspect names. - * These are the aspects that, when they change, will NOT cause the - * object to be marked dirty. - * If you need instance-based calculation of your transient aspects, - * override this method. If class-based calculation is sufficient, - * override #addTransientAspectNamesTo(Set). - */ - protected final Set<String> transientAspectNames() { - synchronized (transientAspectNameSets) { - HashSet<String> transientAspectNames = transientAspectNameSets.get(this.getClass()); - if (transientAspectNames == null) { - transientAspectNames = new HashSet<String>(); - this.addTransientAspectNamesTo(transientAspectNames); - transientAspectNameSets.put(this.getClass(), transientAspectNames); - } - return transientAspectNames; - } - } - - /** - * Add the object's transient aspect names to the specified set. - * These are the aspects that, when they change, will NOT cause the - * object to be marked dirty. - * If class-based calculation of your transient aspects is sufficient, - * override this method. If you need instance-based calculation, - * override #transientAspectNames(). - */ - protected void addTransientAspectNamesTo(Set<String> transientAspectNames) { - transientAspectNames.add(DIRTY_BRANCH_PROPERTY); - transientAspectNames.add(BRANCH_PROBLEMS_LIST); - transientAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY); - // when you override this method, don't forget to include: - // super.addTransientAspectNamesTo(transientAspectNames); - } - - /** - * Return the dirty nodes in the object's branch of the tree, - * including the node itself (if appropriate). - * Only really used for testing and debugging. - */ - public final Iterator<Node> allDirtyNodes() { - return new FilteringIterator<Node, Node>(this.allNodes()) { - @Override - protected boolean accept(Node node) { - return (node instanceof AbstractNode) && ((AbstractNode) node).isDirty(); - } - }; - } - - - // ********** problems ********** - - /** - * Return the node's problems. - * This does NOT include the problems of the node's descendants. - * @see #branchProblems() - */ - public final Iterator<Problem> problems() { - return new CloneIterator<Problem>(this.problems); // removes are not allowed - } - - /** - * Return the size of the node's problems. - * This does NOT include the problems of the node's descendants. - * @see #branchProblemsSize() - */ - public final int problemsSize() { - return this.problems.size(); - } - - /** - * Return whether the node has problems - * This does NOT include the problems of the node's descendants. - * @see #hasBranchProblems() - */ - public final boolean hasProblems() { - return ! this.problems.isEmpty(); - } - - /** - * Return all the node's problems along with all the - * node's descendants' problems. - */ - public final ListIterator<Problem> branchProblems() { - return new CloneListIterator<Problem>(this.branchProblems); // removes are not allowed - } - - /** - * Return the size of all the node's problems along with all the - * node's descendants' problems. - */ - public final int branchProblemsSize() { - return this.branchProblems.size(); - } - - /** - * Return whether the node or any of its descendants have problems. - */ - public final boolean hasBranchProblems() { - return ! this.branchProblems.isEmpty(); - } - - public final boolean containsBranchProblem(Problem problem) { - return this.branchProblems.contains(problem); - } - - protected final Problem buildProblem(String messageKey, Object... messageArguments) { - return new DefaultProblem(this, messageKey, messageArguments); - } - - protected final Problem buildProblem(String messageKey) { - return this.buildProblem(messageKey, EMPTY_PROBLEM_MESSAGE_ARGUMENTS); - } - - /** - * Validate the node and all of its descendants, - * and update their sets of "branch" problems. - * If the node's "branch" problems have changed, - * notify the node's parent. - */ - public void validateBranch() { - if (this.validateBranchInternal()) { - // if our "branch" problems have changed, then - // our parent must rebuild its "branch" problems also - this.rebuildParentBranchProblems(); - } - } - - protected void rebuildParentBranchProblems() { - if (this.parent != null) { - this.parent.rebuildBranchProblems(); - } - } - - /** - * INTRA-TREE API - * Validate the node and all of its descendants, - * and update their sets of "branch" problems. - * Return true if the collection of "branch" problems has changed. - * This method is for internal use only; it is not for - * client use. - */ - public boolean validateBranchInternal() { - // rebuild "branch" problems in children first - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - // ignore the return value because we are going to rebuild our "branch" - // problems no matter what, to see if they have changed - child.validateBranchInternal(); - } - - this.problems.clear(); - this.addProblemsTo(this.problems); - - return this.checkBranchProblems(); - } - - /** - * Check for any problems and add them to the specified list. - * This method should ONLY add problems for this particular node; - * it should NOT add problems for any of this node's descendants - * or ancestors. (Although there will be times when it is debatable - * as to which node a problem "belongs" to....) - * - * NB: This method should NOT modify ANY part of the node's state! - * It is a READ-ONLY behavior. ONLY the list of current problems - * passed in to the method should be modified. - */ - protected void addProblemsTo(List<Problem> currentProblems) { - // The default is to do nothing. - // When you override this method, don't forget to include: - // super.addProblemsTo(currentProblems); - } - - /** - * Rebuild the "branch" problems and return whether they have - * changed. - * NB: The entire collection of "branch" problems must be re-calculated - * with EVERY "significant" change - we cannot keep it in synch via - * change notifications because if a descendant with problems is - * removed or replaced we will not receive notification that its - * problems were removed from our "branch" problems. - */ - private boolean checkBranchProblems() { - Vector<Problem> oldBranchProblems = new Vector<Problem>(this.branchProblems); - int oldSize = this.branchProblems.size(); - - this.branchProblems.clear(); - this.branchProblems.addAll(this.problems); - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - child.addBranchProblemsTo(this.branchProblems); - } - - // if the size has changed to or from zero, our virtual flag has changed - int newSize = this.branchProblems.size(); - if ((oldSize == 0) && (newSize != 0)) { - this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, false, true); - } else if ((oldSize != 0) && (newSize == 0)) { - this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false); - } - - if (oldBranchProblems.equals(this.branchProblems)) { - return false; // our "branch" problems did not change - } - // our "branch" problems changed - this.fireListChanged(BRANCH_PROBLEMS_LIST); - return true; - } - - /** - * INTRA-TREE API - * Add all the problems of the node and all - * the problems of its descendants to the - * specified collection. - */ - public final void addBranchProblemsTo(List<Problem> list) { - list.addAll(this.branchProblems); - } - - /** - * INTRA-TREE API - * A child node's "branch" problems changed; - * therefore the node's "branch" problems have changed also and - * must be rebuilt. - */ - public final void rebuildBranchProblems() { - if ( ! this.checkBranchProblems()) { - throw new IllegalStateException("we should not get here unless our \"branch\" problems have changed"); - } - this.rebuildParentBranchProblems(); - } - - /** - * Clear the node's "branch" problems and the "branch" - * problems of all of its descendants. - * If the node's "branch" problems have changed, - * notify the node's parent. - */ - public final void clearAllBranchProblems() { - if (this.clearAllBranchProblemsInternal()) { - // if our "branch" problems have changed, then - // our parent must rebuild its "branch" problems also - this.rebuildParentBranchProblems(); - } - } - - /** - * INTRA-TREE API - * Clear the node's "branch" problems and the "branch" - * problems of all of its descendants. - * Return true if the collection of "branch" problems has changed. - * This method is for internal use only; it is not for - * client use. - */ - public final boolean clearAllBranchProblemsInternal() { - if (this.branchProblems.isEmpty()) { - return false; - } - for (Iterator<Node> stream = this.children(); stream.hasNext(); ) { - Node child = stream.next(); // pull out the child to ease debugging - // ignore the return value because we are going to clear our "branch" - // problems no matter what - child.clearAllBranchProblemsInternal(); - } - this.problems.clear(); - this.branchProblems.clear(); - this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false); - this.fireListChanged(BRANCH_PROBLEMS_LIST); - return true; - } - - /** - * Return whether a change to specified aspect requires a re-validation - * of the node's tree. - */ - private boolean aspectChangeRequiresValidation(String aspectName) { - return ! this.aspectChangeDoesNotRequireValidation(aspectName); - } - - private boolean aspectChangeDoesNotRequireValidation(String aspectName) { - return this.nonValidatedAspectNames().contains(aspectName); - } - - /** - * Return a set of the object's "non-validated" aspect names. - * These are the aspects that, when they change, will NOT cause the - * object (or its containing tree) to be validated, i.e. checked for problems. - * If you need instance-based calculation of your "non-validated" aspects, - * override this method. If class-based calculation is sufficient, - * override #addNonValidatedAspectNamesTo(Set). - */ - protected final Set<String> nonValidatedAspectNames() { - synchronized (nonValidatedAspectNameSets) { - HashSet<String> nonValidatedAspectNames = nonValidatedAspectNameSets.get(this.getClass()); - if (nonValidatedAspectNames == null) { - nonValidatedAspectNames = new HashSet<String>(); - this.addNonValidatedAspectNamesTo(nonValidatedAspectNames); - nonValidatedAspectNameSets.put(this.getClass(), nonValidatedAspectNames); - } - return nonValidatedAspectNames; - } - } - - /** - * Add the object's "non-validated" aspect names to the specified set. - * These are the aspects that, when they change, will NOT cause the - * object (or its containing tree) to be validated, i.e. checked for problems. - * If class-based calculation of your "non-validated" aspects is sufficient, - * override this method. If you need instance-based calculation, - * override #nonValidatedAspectNames(). - */ - protected void addNonValidatedAspectNamesTo(Set<String> nonValidatedAspectNames) { - nonValidatedAspectNames.add(COMMENT_PROPERTY); - nonValidatedAspectNames.add(DIRTY_BRANCH_PROPERTY); - nonValidatedAspectNames.add(BRANCH_PROBLEMS_LIST); - nonValidatedAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY); - // when you override this method, don't forget to include: - // super.addNonValidatedAspectNamesTo(nonValidatedAspectNames); - } - - - // ********** display methods ********** - - /** - * Compare display strings. - */ - public int compareTo(Node node) { - return DEFAULT_COMPARATOR.compare(this, node); - } - - /** - * Return a developer-friendly String. If you want something useful for - * displaying in a user interface, use #displayString(). - * If you want to give more information in your #toString(), - * override #toString(StringBuilder sb). - * Whatever you add to that string buffer will show up between the parentheses. - * @see AbstractModel#toString(StringBuilder sb) - * @see #displayString() - */ - @Override - public final String toString() { - return super.toString(); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java deleted file mode 100644 index fd2059cc8c..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.SynchronizedBoolean; - -/** - * This implementation of the PluggableValidator.Delegate interface - * simply sets a shared "validate" flag to true. This should trigger a - * separate "validation" thread to begin validating the appropriate - * branch of nodes. - */ -public class AsynchronousValidator - implements PluggableValidator.Delegate -{ - private SynchronizedBoolean validateFlag; - - /** - * Construct a validator delegate with the specified shared - * "validate" flag. This flag should be shared with - * another thread that will perform the actual validation. - */ - public AsynchronousValidator(SynchronizedBoolean validateFlag) { - super(); - this.validateFlag = validateFlag; - } - - /** - * Set the shared "validate" flag to true, triggering - * an asynchronous validation of the appropriate - * branch of nodes. - */ - public void validate() { - this.validateFlag.setTrue(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.validateFlag); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java deleted file mode 100644 index 9d3898c59d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import java.util.Arrays; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * This class is a straightforward implementation of the Problem interface. - */ -public class DefaultProblem - implements Problem -{ - private final Node source; - private final String messageKey; - private final Object[] messageArguments; - - - DefaultProblem(Node source, String messageKey, Object[] messageArguments) { - super(); - this.source = source; - this.messageKey = messageKey; - this.messageArguments = messageArguments; - } - - - // ********** Problem implementation ********** - - public Node source() { - return this.source; - } - - public String messageKey() { - return this.messageKey; - } - - public Object[] messageArguments() { - return this.messageArguments; - } - - - // ********** Object overrides ********** - - /** - * We implement #equals(Object) because problems are repeatedly - * re-calculated and the resulting problems merged with the existing - * set of problems; and we want to keep the original problems and - * ignore any freshly-generated duplicates. - * Also, problems are not saved to disk.... - */ - @Override - public boolean equals(Object o) { - if ( ! (o instanceof Problem)) { - return false; - } - Problem other = (Problem) o; - return this.source == other.source() - && this.messageKey.equals(other.messageKey()) - && Arrays.equals(this.messageArguments, other.messageArguments()); - } - - @Override - public int hashCode() { - return this.source.hashCode() ^ this.messageKey.hashCode(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.messageKey); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java deleted file mode 100644 index 2936883fce..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java +++ /dev/null @@ -1,419 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import java.text.Collator; -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.model.Model; - -/** - * This interface defines the methods that must be implemented - * by any class whose instances are to be part of a containment hierarchy - * that supports a "dirty" state and validation "problems". - * - * Note: Methods marked "INTRA-TREE API" are typically only used by - * the nodes themselves, as opposed to clients of the nodes. These - * methods are called by a node on either its parent or its children. - */ -public interface Node extends Model, Comparable<Node> { - - - // ********** containment hierarchy (parent/children) ********** - - /** - * INTRA-TREE API? - * Return the node's parent in the containment hierarchy. - * Most nodes must have a parent. The parent is immutable. - * @see #children() - */ - Node getParent(); - - /** - * INTRA-TREE API? - * Return the node's children, which are also nodes. - * @see #getParent() - */ - Iterator<Node> children(); - - /** - * INTRA-TREE API? - * Return the containment hierarchy's root node. - * Most nodes must have a root. - * @see #getParent() - */ - Node root(); - - /** - * Return whether the node is a descendant of the specified node. - * By definition, a node is a descendant of itself. - */ - boolean isDescendantOf(Node node); - - /** - * INTRA-TREE API - * Add the node's "references", and all the node's descendants' - * "references", to the specified collection. "References" are - * objects that are "referenced" by another object, as opposed - * to "owned" by another object. - * This method is of particular concern to Handles, since most - * (hopefully all) "references" are held by Handles. - * @see Reference - * @see #children() - */ - void addBranchReferencesTo(Collection<Node.Reference> branchReferences); - - /** - * INTRA-TREE API? - * Add all the nodes in the object's branch of the tree, - * including the node itself, to the specified collection. - * Only really used for testing and debugging. - */ - void addAllNodesTo(Collection<Node> nodes); - - - // ********** model synchronization support ********** - - /** - * INTRA-TREE API - * This is a general notification that the specified node has been - * removed from the tree. The node receiving this notification - * should perform any necessary updates to remain in synch - * with the tree (e.g. clearing out or replacing any references - * to the removed node or any of the removed node's descendants). - * @see #isDescendantOf(Node) - */ - void nodeRemoved(Node node); - - /** - * INTRA-TREE API - * This is a general notification that the specified node has been - * renamed. The node receiving this notification should mark its - * branch dirty if necessary (i.e. it references the renamed node - * or one of its descendants). This method is of particular concern - * to Handles. - * @see #isDescendantOf(Node) - */ - void nodeRenamed(Node node); - - - // ********** dirty flag support ********** - - /** - * Return whether any persistent aspects of the node, - * or any of its descendants, have changed since the node and - * its descendants were last read or saved. - */ - boolean isDirtyBranch(); - String DIRTY_BRANCH_PROPERTY = "dirtyBranch"; - - /** - * INTRA-TREE API - * Mark the node and its parent as dirty branches. - * This message is propagated up the containment - * tree when a particular node becomes dirty. - */ - void markBranchDirty(); - - /** - * Mark the node and all its descendants as dirty. - * This is used when the save location of some - * top-level node is changed and the entire - * containment tree must be marked dirty so it - * will be written out. - */ - void markEntireBranchDirty(); - - /** - * INTRA-TREE API - * A child node's branch has been marked clean. If the node - * itself is clean and if all of its children are also clean, the - * node's branch can be marked clean. Then, if the node's - * branch is clean, the node will notify its parent that it might - * be clean also. This message is propagated up the containment - * tree when a particular node becomes clean. - */ - void markBranchCleanIfPossible(); - - /** - * INTRA-TREE API - * Mark the node and all its descendants as clean. - * Typically used when the node has just been - * read in or written out. - * This method is for internal use only; it is not for - * client use. - * Not the best of method names.... :-( - */ - void cascadeMarkEntireBranchClean(); - - - // ********** problems ********** - - /** - * INTRA-TREE API - * Return a validator that will be invoked whenever a - * "validated" aspect of the node tree changes. - * Typically only the root node directly holds a validator. - */ - Validator getValidator(); - - /** - * Set a validator that will be invoked whenever a - * "validated" aspect of the node tree changes. - * Typically only the root node directly holds a validator. - */ - void setValidator(Validator validator); - - /** - * Validate the node and its descendants. - * This is an explicit request invoked by a client; and it will - * typically be followed by a call to one of the following methods: - * #branchProblems() - * #hasBranchProblems() - * Whether the node maintains its problems on the fly - * or waits until this method is called is determined by the - * implementation. - * @see Problem - */ - void validateBranch(); - - /** - * INTRA-TREE API - * Validate the node and all of its descendants, - * and update their sets of "branch" problems. - * Return true if the collection of "branch" problems has changed. - * This method is for internal use only; it is not for - * client use. - */ - boolean validateBranchInternal(); - - /** - * Return all the node's problems along with all the - * node's descendants' problems. - */ - ListIterator<Problem> branchProblems(); - String BRANCH_PROBLEMS_LIST = "branchProblems"; - - /** - * Return the size of all the node's problems along with all the - * node's descendants' problems. - */ - int branchProblemsSize(); - - /** - * Return whether the node or any of its descendants have problems. - */ - boolean hasBranchProblems(); - String HAS_BRANCH_PROBLEMS_PROPERTY = "hasBranchProblems"; - - /** - * Return whether the node contains the specified branch problem. - */ - boolean containsBranchProblem(Problem problem); - - /** - * INTRA-TREE API - * Something changed, rebuild the node's collection of branch problems. - */ - void rebuildBranchProblems(); - - /** - * INTRA-TREE API - * Add the node's problems, and all the node's descendants' - * problems, to the specified list. - * A call to this method should be immediately preceded by a call to - * #validateBranch() or all of the problems might not be - * added to the list. - * @see Problem - */ - void addBranchProblemsTo(List<Problem> branchProblems); - - /** - * Clear the node's "branch" problems and the "branch" - * problems of all of its descendants. - */ - void clearAllBranchProblems(); - - /** - * INTRA-TREE API - * Clear the node's "branch" problems and the "branch" - * problems of all of its descendants. - * Return true if the collection of "branch" problems has changed. - * This method is for internal use only; it is not for - * client use. - */ - boolean clearAllBranchProblemsInternal(); - - - // ********** comment ********** - - /** - * Return the user comment concerning the node. - */ - String comment(); - String COMMENT_PROPERTY = "comment"; - - /** - * Set the user comment concerning the node. - */ - void setComment(String comment); - - - // ********** displaying/sorting ********** - - /** - * Return a string representation of the model, suitable for sorting. - */ - String displayString(); - - - // ********** sub-interfaces ********** - - /** - * Simple interface defining a "reference" between two nodes. - * @see Node#addBranchReferencesTo(java.util.Collection) - */ - interface Reference { - - /** - * Return the "source" node of the reference, i.e. the node that - * references the "target" node. - */ - Node source(); - - /** - * Return the "target" node of the reference, i.e. the node that - * is referenced by the "source" node. - */ - Node target(); - - } - - - /** - * A validator will validate a node as appropriate. - * Typically the validation will - * - occur whenever a node has changed - * - encompass the entire tree containing the node - * - execute asynchronously - */ - interface Validator { - - /** - * A "significant" aspect has changed; - * validate the node as appropriate - */ - void validate(); - - /** - * Stop all validation of the node until #resume() is called. - * This can be used to improve the performance of any long-running - * action that triggers numerous changes to the node. Be sure to - * match a call to this method with a corresponding call to - * #resume(). - */ - void pause(); - - /** - * Resume validation of the node. This method can only be - * called after a matching call to #pause(). - */ - void resume(); - - } - - - // ********** helper implementations ********** - - /** - * Straightforward implementation of the Reference interface - * defined above. - */ - public class SimpleReference implements Reference { - private Node source; - private Node target; - public SimpleReference(Node source, Node target) { - super(); - if (source == null || target == null) { - throw new NullPointerException(); - } - this.source = source; - this.target = target; - } - public Node source() { - return this.source; - } - public Node target() { - return this.target; - } - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.source + " => " + this.target); - } - } - - /** - * Typical comparator that can be used to sort a collection of nodes. - * Sort based on display string: - * - identical objects are equal (which means that cannot - * co-exist in a SortedSet) - * - use the default collator (which typically interleaves - * lower- and upper-case letters) - * - allow duplicate display strings (from different objects) - * - try to return consistent results for same object pairs - */ - Comparator<Node> DEFAULT_COMPARATOR = - new Comparator<Node>() { - public int compare(Node node1, Node node2) { - // disallow duplicates based on object identity - if (node1 == node2) { - return 0; - } - - // first compare display strings using the default collator - int result = Collator.getInstance().compare(node1.displayString(), node2.displayString()); - if (result != 0) { - return result; - } - - // then compare using object-id - result = System.identityHashCode(node1) - System.identityHashCode(node2); - if (result != 0) { - return result; - } - - // It's unlikely that we get to this point; but, just in case, we will return -1. - // Unfortunately, this introduces some mild unpredictability to the sort order - // (unless the objects are always passed into this method in the same order). - return -1; // if all else fails, indicate that o1 < o2 - } - @Override - public String toString() { - return "Node.DEFAULT_COMPARATOR"; - } - }; - - - /** - * This validator does nothing to validate the node. - */ - Validator NULL_VALIDATOR = - new PluggableValidator(PluggableValidator.Delegate.Null.instance()) { - @Override - public String toString() { - return "Node.NULL_VALIDATOR"; - } - }; - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java deleted file mode 100644 index c44f8aab43..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.internal.SynchronizedBoolean; - -/** - * This implementation of the Validator interface implements the - * pause/resume portion of the protocol, but delegates the actual - * validation to a "pluggable" delegate. - */ -public class PluggableValidator - implements Node.Validator -{ - private boolean pause; - private boolean validateOnResume; - private final Delegate delegate; - - - /** - * Convenience factory method. - */ - public static Node.Validator buildAsynchronousValidator(SynchronizedBoolean validateFlag) { - return new PluggableValidator(new AsynchronousValidator(validateFlag)); - } - - /** - * Convenience factory method. - */ - public static Node.Validator buildSynchronousValidator(Node node) { - return new PluggableValidator(new SynchronousValidator(node)); - } - - /** - * Construct a validator with the specified delegate. - */ - public PluggableValidator(Delegate delegate) { - super(); - this.pause = false; - this.validateOnResume = false; - this.delegate = delegate; - } - - public synchronized void validate() { - if (this.pause) { - this.validateOnResume = true; - } else { - this.delegate.validate(); - } - } - - public synchronized void pause() { - if (this.pause) { - throw new IllegalStateException("already paused"); - } - this.pause = true; - } - - public synchronized void resume() { - if ( ! this.pause) { - throw new IllegalStateException("not paused"); - } - this.pause = false; - // validate any changes that occurred while the validation was paused - if (this.validateOnResume) { - this.validateOnResume = false; - this.delegate.validate(); - } - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.delegate); - } - - - // ********** member interface ********** - - /** - * Interface implemented by any delegates of a pluggable validator. - */ - public interface Delegate { - - /** - * The validator is not "paused" - perform the appropriate validation. - */ - void validate(); - - - /** - * This delegate does nothing. - */ - final class Null implements Delegate { - public static final Delegate INSTANCE = new Null(); - public static Delegate instance() { - return INSTANCE; - } - // ensure single instance - private Null() { - super(); - } - public void validate() { - // do nothing - } - @Override - public String toString() { - return "PluggableValidator.Delegate.Null"; - } - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java deleted file mode 100644 index 4f8e730362..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -/** - * Define an interface describing the problems associated with a node. - */ -public interface Problem { - - /** - * Return the node most closely associated with the problem. - */ - Node source(); - - /** - * Return a key that can be used to uniquely identify the problem's message. - */ - String messageKey(); - - /** - * Return the arguments associate with the problem's message. - */ - Object[] messageArguments(); - - /** - * Return whether the problem is equal to the specified object. - * It is equal if the specified object is a implementation of the - * Problem interface and its source, message key, and message - * arguments are all equal to this problem's. - */ - boolean equals(Object o); - - /** - * Return the problem's hash code, which should calculated as an - * XOR of the source's hash code and the message key's hash code. - */ - int hashCode(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java deleted file mode 100644 index 367d57a028..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; -import org.eclipse.jpt.utility.internal.SynchronizedBoolean; - -/** - * This implementation of Runnable will asynchronously validate - * a branch of nodes. It will wait until a shared "validate" flag is - * set to validate the branch. Once the the branch is validated, - * the thread will quiesce until the flag is set again. - * - * There are two ways to stop this thread: - * - Thread.interrupt() - * - set the "continue" flag to false - * For now, these two are equivalent; but in the future we might - * pass the "continue" flag to the Node.validateBranch() - * method so we can short-circuit the validation instead of waiting - * until the entire branch is validated. - */ -public class RunnableValidation - implements Runnable -{ - /** The node whose branch this thread will validate. */ - private final Node node; - - /** When this flag is set to true, we kick off the validation routine. */ - private final SynchronizedBoolean validateFlag; - - /** When this flag is set to false, we allow this thread to die. */ - private final SynchronizedBoolean continueFlag; - - /** Log any exceptions encountered during validation with the following settings. */ - private final Logger exceptionLogger; - private final Level exceptionLevel; - private final String exceptionMessage; - - - /** - * Construct a validation thread. - */ - public RunnableValidation( - Node node, - SynchronizedBoolean validateFlag, - SynchronizedBoolean continueFlag, - Logger exceptionLogger, - Level exceptionLevel, - String exceptionMessage - ) { - super(); - this.node = node; - this.validateFlag = validateFlag; - this.continueFlag = continueFlag; - this.exceptionLogger = exceptionLogger; - this.exceptionLevel = exceptionLevel; - this.exceptionMessage = exceptionMessage; - } - - - // ********** Runnable Implementation ********** - - /** - * Loop while the "continue" flag is true and the thread - * has not been interrupted by another thread. - * In each loop: Wait until the "validate" flag is set to true, - * then set it back to false and validate the branch of nodes. - */ - public void run() { - while (this.continueFlag.isTrue()) { - try { - this.validateFlag.waitToSetFalse(); - } catch (InterruptedException ex) { - // we were interrupted while waiting, must be quittin' time - return; - } - this.validateNode(); - } - } - - /** - * Validate the node, logging any exceptions. - * If an exception occurs, we terminate the validation until the - * "validation" flag is set again. Some exceptions occur because - * of concurrent changes to the model that occur *after* validation - * starts but before it completes an entire pass over the model. If that - * is the case, things should be OK; because the exception will be - * caught and the "validation" flag will have been set again *during* the - * initial validation pass. So when we return from catching the exception - * we will simply re-start the validation, hopefully with the model in - * a consistent state that will prevent another exception from - * occurring. Of course, if we have any exceptions that are *not* - * the result of the model being in an inconsistent state, we will - * probably fill the log; and those exceptions are bugs that need - * to be fixed. (!) Hopefully the user will notice the enormous log and - * contact support.... ~bjv - */ - private void validateNode() { - try { - this.node.validateBranch(); - } catch (Throwable ex) { - this.logException(ex); - } - } - - /** - * We need to do all this because Logger#log(LogRecord) does not pass through - * Logger#doLog(LogRecord) like all the other Logger#log(...) methods. - */ - private void logException(Throwable ex) { - LogRecord logRecord = new LogRecord(this.exceptionLevel, this.exceptionMessage); - logRecord.setParameters(new Object[] { this.node.displayString() }); - logRecord.setThrown(ex); - logRecord.setLoggerName(this.exceptionLogger.getName()); - logRecord.setResourceBundle(this.exceptionLogger.getResourceBundle()); - this.exceptionLogger.log(logRecord); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java deleted file mode 100644 index ede6b8b8f0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.node; - -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * This implementation of the PluggableValidator.Delegate interface - * will validate the node immediately. - * - * This is useful for debugging in a single thread or generating - * problem reports. - */ -public class SynchronousValidator - implements PluggableValidator.Delegate -{ - private final Node node; - - /** - * Construct a validator that will immediately validate the - * specified node. - */ - public SynchronousValidator(Node node) { - super(); - this.node = node; - } - - public void validate() { - this.node.validateBranch(); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.node); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CachingComboBoxModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CachingComboBoxModel.java deleted file mode 100644 index 8ebe2617e6..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CachingComboBoxModel.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import javax.swing.ComboBoxModel; - -/** - * This interface allows a client to better control the performance of - * a combo box model by allowing the client to specify when it is - * acceptable for the model to "cache" and "uncache" its list of elements. - * The model may ignore these hints if appropriate. - */ -public interface CachingComboBoxModel extends ComboBoxModel { - - /** - * Cache the comboBoxModel List. If you call this, you - * must make sure to call uncacheList() as well. Otherwise - * stale data will be in the ComboBox until cacheList() is - * called again or uncacheList() is called. - */ - void cacheList(); - - /** - * Clear the cached list. Next time the list is needed it will - * be built when it is not cached. - */ - void uncacheList(); - - /** - * Check to see if the list is already cached. This can be used for - * MouseEvents, since they are not terribly predictable. - */ - boolean isCached(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CheckBoxTableCellRenderer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CheckBoxTableCellRenderer.java deleted file mode 100644 index 45ec6be9e2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/CheckBoxTableCellRenderer.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Color; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JCheckBox; -import javax.swing.JTable; -import javax.swing.SwingConstants; -import javax.swing.UIManager; -import javax.swing.border.Border; -import org.eclipse.jpt.utility.internal.swing.TableCellEditorAdapter.ImmediateEditListener; - -/** - * Make the cell look like a check box. - */ -public class CheckBoxTableCellRenderer implements TableCellEditorAdapter.Renderer { - - /** the component used to paint the cell */ - private final JCheckBox checkBox; - - /** the listener to be notified on an immediate edit */ - protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener; - - /** "normal" border - assume the default table "focus" border is 1 pixel thick */ - private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); - - - // ********** constructors/initialization ********** - - /** - * Construct a cell renderer with no label or icon. - */ - public CheckBoxTableCellRenderer() { - super(); - this.checkBox = this.buildCheckBox(); - // by default, check boxes do not paint their borders - this.checkBox.setBorderPainted(true); - // this setting is recommended for check boxes inside of trees and tables - this.checkBox.setBorderPaintedFlat(true); - } - - /** - * Construct a cell renderer with the specified text and icon, - * either of which may be null. - */ - public CheckBoxTableCellRenderer(String text, Icon icon) { - this(); - this.setText(text); - this.setIcon(icon); - } - - /** - * Construct a cell renderer with the specified text. - */ - public CheckBoxTableCellRenderer(String text) { - this(text, null); - } - - /** - * Construct a cell renderer with the specified icon. - */ - public CheckBoxTableCellRenderer(Icon icon) { - this(null, icon); - } - - protected JCheckBox buildCheckBox() { - JCheckBox cb = new JCheckBox(); - cb.addActionListener(this.buildActionListener()); - return cb; - } - - private ActionListener buildActionListener() { - return new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (CheckBoxTableCellRenderer.this.immediateEditListener != null) { - CheckBoxTableCellRenderer.this.immediateEditListener.immediateEdit(); - } - } - }; - } - - - // ********** TableCellRenderer implementation ********** - - public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - this.checkBox.setHorizontalAlignment(SwingConstants.CENTER); - this.checkBox.setComponentOrientation(table.getComponentOrientation()); - this.checkBox.setFont(table.getFont()); - this.checkBox.setEnabled(table.isEnabled()); - - this.checkBox.setForeground(this.foregroundColor(table, value, selected, hasFocus, row, column)); - this.checkBox.setBackground(this.backgroundColor(table, value, selected, hasFocus, row, column)); - // once the colors are set, calculate opaque setting - this.checkBox.setOpaque(this.cellIsOpaqueIn(table, value, selected, hasFocus, row, column)); - this.checkBox.setBorder(this.border(table, value, selected, hasFocus, row, column)); - - this.setValue(value); - return this.checkBox; - } - - /** - * Return the cell's foreground color. - */ - protected Color foregroundColor(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return UIManager.getColor("Table.focusCellForeground"); - } - return table.getSelectionForeground(); - } - return table.getForeground(); - } - - /** - * Return the cell's background color. - */ - protected Color backgroundColor(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return UIManager.getColor("Table.focusCellBackground"); - } - return table.getSelectionBackground(); - } - return table.getBackground(); - } - - /** - * Return the cell's border. - */ - protected Border border(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - return hasFocus ? UIManager.getBorder("Table.focusCellHighlightBorder") : NO_FOCUS_BORDER; - } - - /** - * Return whether the cell should be opaque in the table. - * If the cell's background is the same as the table's background - * and table is opaque, we don't need to paint the background - - * the table will do it. - */ - protected boolean cellIsOpaqueIn(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - Color cellBackground = this.checkBox.getBackground(); - Color tableBackground = table.getBackground(); - return ! (table.isOpaque() && cellBackground.equals(tableBackground)); - } - - /** - * Set the check box's value. - */ - protected void setValue(Object value) { - // CR#3999318 - This null check needs to be removed once JDK bug is fixed - if (value == null) { - value = Boolean.FALSE; - } - this.checkBox.setSelected(((Boolean) value).booleanValue()); - } - - - // ********** TableCellEditorAdapter.Renderer implementation ********** - - public Object getValue() { - return Boolean.valueOf(this.checkBox.isSelected()); - } - - public void setImmediateEditListener(ImmediateEditListener listener) { - this.immediateEditListener = listener; - } - - // ********** public API ********** - - /** - * Set the check box's text; which by default is blank. - */ - public void setText(String text) { - this.checkBox.setText(text); - } - - /** - * Set the check box's icon; which by default is not present. - */ - public void setIcon(Icon icon) { - this.checkBox.setIcon(icon); - } - - /** - * Return the renderer's preferred height. This allows you - * to set the table's row height to something the check box - * will look good in.... - */ - public int preferredHeight() { - // add in space for the border top and bottom - return (int) this.checkBox.getPreferredSize().getHeight() + 2; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ComboBoxTableCellRenderer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ComboBoxTableCellRenderer.java deleted file mode 100644 index 55d8d1f9a0..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ComboBoxTableCellRenderer.java +++ /dev/null @@ -1,328 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.BorderFactory; -import javax.swing.ComboBoxModel; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JTable; -import javax.swing.ListCellRenderer; -import javax.swing.SwingConstants; -import javax.swing.UIManager; -import javax.swing.border.Border; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; -import org.eclipse.jpt.utility.internal.ClassTools; - -/** - * Make the cell look like a combo-box. - */ -public class ComboBoxTableCellRenderer implements TableCellEditorAdapter.Renderer { - - /* caching the combo box because we are caching the comboBoxModel. - * Everytime we rebuilt the comboBox we would set the model on it and not - * remove the model from the old combo box. This meant that new listeners - * kept being added to the comboBoxModel for every comboBox build. - * Not sure if there is a way to clear out the old combo box, or why - * we were buildig a new combo box every time so I went with caching it. - */ - private JComboBox comboBox; - - /** the items used to populate the combo box */ - private CachingComboBoxModel model; - private ListCellRenderer renderer; - Object value; - private static int height = -1; - boolean fakeFocusFlag; - - /** the listener to be notified on an immediate edit */ - protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener; - - /** hold the original colors of the combo-box */ - private static Color defaultForeground; - private static Color defaultBackground; - - /** "normal" border - assume the default table "focus" border is 1 pixel thick */ - private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); - - - // ********** constructors/initialization ********** - - /** - * Default constructor. - */ - private ComboBoxTableCellRenderer() { - super(); - initialize(); - } - - /** - * Construct a cell renderer that uses the specified combo-box model. - */ - public ComboBoxTableCellRenderer(ComboBoxModel model) { - this(new NonCachingComboBoxModel(model)); - } - - /** - * Construct a cell renderer that uses the specified caching combo-box model. - */ - public ComboBoxTableCellRenderer(CachingComboBoxModel model) { - this(); - this.model = model; - } - - /** - * Construct a cell renderer that uses the specified - * combo-box model and renderer. - */ - public ComboBoxTableCellRenderer(ComboBoxModel model, ListCellRenderer renderer) { - this(new NonCachingComboBoxModel(model), renderer); - } - - /** - * Construct a cell renderer that uses the specified - * caching combo-box model and renderer. - */ - public ComboBoxTableCellRenderer(CachingComboBoxModel model, ListCellRenderer renderer) { - this(model); - this.renderer = renderer; - } - - protected void initialize() { - // save the original colors of the combo-box, so we - // can use them to paint non-selected cells - if (height == -1) { - JComboBox cb = new JComboBox(); - cb.addItem("m"); - - // add in space for the border top and bottom - height = cb.getPreferredSize().height + 2; - - defaultForeground = cb.getForeground(); - defaultBackground = cb.getBackground(); - } - } - - static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(16), SwingConstants.LEADING); - - protected JComboBox buildComboBox() { - - final JComboBox result = new JComboBox() { - private boolean fakeFocus; - @Override - public boolean hasFocus() { - return fakeFocus || super.hasFocus(); - } - @Override - public void paint(Graphics g) { - fakeFocus = ComboBoxTableCellRenderer.this.fakeFocusFlag; - super.paint(g); - fakeFocus = false; - } - //wrap the renderer to deal with the prototypeDisplayValue - @Override - public void setRenderer(final ListCellRenderer aRenderer) { - super.setRenderer(new ListCellRenderer(){ - public Component getListCellRendererComponent(JList list, Object v, int index, boolean isSelected, boolean cellHasFocus) { - if (v == prototypeLabel) { - return prototypeLabel; - } - return aRenderer.getListCellRendererComponent(list, v, index, isSelected, cellHasFocus); - } - }); - } - @Override - public int getSelectedIndex() { - boolean listNotCached = !listIsCached(); - if (listNotCached) { - cacheList(); - } - - int index = super.getSelectedIndex(); - - if (listNotCached) { - uncacheList(); - } - return index; - } - - }; - // stole this code from javax.swing.DefaultCellEditor - result.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); - result.addActionListener(this.buildActionListener()); - result.addPopupMenuListener(this.buildPopupMenuListener()); - - //These are used to workaround problems with Swing trying to - //determine the size of a comboBox with a large model - result.setPrototypeDisplayValue(prototypeLabel); - getListBox(result).setPrototypeCellValue(prototypeLabel); - - return result; - } - - - private JList getListBox(JComboBox result) { - return (JList) ClassTools.fieldValue(result.getUI(), "listBox"); - } - - - private ActionListener buildActionListener() { - return new ActionListener() { - public void actionPerformed(ActionEvent e) { - JComboBox cb = (JComboBox) e.getSource(); - Object selectedItem = cb.getSelectedItem(); - - // Only update the selected item and invoke immediateEdit() if the - // selected item actually changed, during the initialization of the - // editing, the model changes and causes this method to be invoked, - // it causes CR#3963675 to occur because immediateEdit() stop the - // editing, which is done at the wrong time - if (ComboBoxTableCellRenderer.this.value != selectedItem) { - ComboBoxTableCellRenderer.this.value = cb.getSelectedItem(); - ComboBoxTableCellRenderer.this.immediateEdit(); - } - } - }; - } - - void immediateEdit() { - if (this.immediateEditListener != null) { - this.immediateEditListener.immediateEdit(); - } - } - - private PopupMenuListener buildPopupMenuListener() { - return new PopupMenuListener() { - - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - if (listIsCached()) { - uncacheList(); - } - cacheList(); - } - - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - if (listIsCached()) { - uncacheList(); - } - - } - - public void popupMenuCanceled(PopupMenuEvent e) { - if (listIsCached()) { - uncacheList(); - } - } - }; - } - - - void cacheList() { - this.model.cacheList(); - } - - void uncacheList() { - this.model.uncacheList(); - } - - boolean listIsCached() { - return this.model.isCached(); - } - // ********** TableCellRenderer implementation ********** - - public Component getTableCellRendererComponent(JTable table, Object val, boolean selected, boolean hasFocus, int row, int column) { - this.fakeFocusFlag = selected || hasFocus; - if (this.comboBox == null) { - this.comboBox = this.buildComboBox(); - - this.comboBox.setComponentOrientation(table.getComponentOrientation()); - this.comboBox.setModel(this.model); - if (this.renderer != null) { - this.comboBox.setRenderer(this.renderer); - } - this.comboBox.setFont(table.getFont()); - this.comboBox.setEnabled(table.isEnabled()); - this.comboBox.setBorder(this.border(table, val, selected, hasFocus, row, column)); - } - - // We need to go through the model since JComboBox might prevent us from - // selecting the value. This can happen when the value is not contained - // in the model, see CR#3950044 for an example - this.model.setSelectedItem(val); - - return this.comboBox; - } - - /** - * Return the cell's foreground color. - */ - protected Color foregroundColor(JTable table, Object val, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return defaultForeground; - } - return table.getSelectionForeground(); - } - return defaultForeground; - } - - /** - * Return the cell's background color. - */ - protected Color backgroundColor(JTable table, Object val, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return defaultBackground; - } - return table.getSelectionBackground(); - } - return defaultBackground; - } - - /** - * Return the cell's border. - */ - protected Border border(JTable table, Object val, boolean selected, boolean hasFocus, int row, int column) { - return hasFocus ? - UIManager.getBorder("Table.focusCellHighlightBorder") - : - NO_FOCUS_BORDER; - } - - - // ********** TableCellEditorAdapter.Renderer implementation ********** - - public Object getValue() { - return this.value; - } - - public void setImmediateEditListener(TableCellEditorAdapter.ImmediateEditListener listener) { - this.immediateEditListener = listener; - } - - - // ********** public API ********** - - /** - * Return the renderer's preferred height. This allows you - * to set the row height to something the combo-box will look good in.... - */ - public int preferredHeight() { - return height; - } - -}
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/Displayable.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/Displayable.java deleted file mode 100644 index f5149cfb78..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/Displayable.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.text.Collator; -import java.util.Comparator; -import javax.swing.Icon; -import org.eclipse.jpt.utility.model.Model; - -/** - * Used by general-purpose UI models and renderers to cast - * application model objects to something displayable. - */ -public interface Displayable - extends Model, Comparable<Displayable> -{ - - /** - * Return a string that can be used to identify the model - * in a textual UI setting (typically the object's name). - * When the display string changes, the model should fire - * the appropriate change notification: - * this.firePropertyChanged(DISPLAY_STRING_PROPERTY, oldDisplayString, this.displayString()); - */ - String displayString(); - String DISPLAY_STRING_PROPERTY = "displayString"; - - /** - * Return an icon that can be used to identify the model - * in a UI component that supports icons (the icon can be null). - * When the icon changes, the model should fire - * the appropriate change notification: - * this.firePropertyChanged(ICON_PROPERTY, oldIcon, this.icon()); - */ - Icon icon(); - String ICON_PROPERTY = "icon"; - - - // ********** helper implementations ********** - - Collator DEFAULT_COLLATOR = Collator.getInstance(); - - /** - * Since all displayable objects must be comparable, provide a - * typical comparator that can be used to sort a collection of - * displayable objects. - * Sort based on display string: - * - identical objects are equal (which means they cannot - * co-exist in a SortedSet) - * - use the default collator (which typically interleaves - * lower- and upper-case letters) - * - allow duplicate display strings (from different objects) - * - try to return consistent results for same object pairs - */ - Comparator<Displayable> DEFAULT_COMPARATOR = - new Comparator<Displayable>() { - public int compare(Displayable d1, Displayable d2) { - // disallow duplicates based on object identity - if (d1 == d2) { - return 0; - } - - // first compare display strings using the default collator - int result = DEFAULT_COLLATOR.compare(d1.displayString(), d2.displayString()); - if (result != 0) { - return result; - } - - // then compare using object-id - result = System.identityHashCode(d1) - System.identityHashCode(d2); - if (result != 0) { - return result; - } - - // It's unlikely that we get to this point; but, just in case, we will return -1. - // Unfortunately, this introduces some mild unpredictability to the sort order - // (unless the objects are always passed into this method in the same order). - return -1; // if all else fails, indicate that o1 < o2 - } - @Override - public String toString() { - return "Displayable.DEFAULT_COMPARATOR"; - } - }; - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/EmptyIcon.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/EmptyIcon.java deleted file mode 100644 index 148308eaa9..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/EmptyIcon.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Component; -import java.awt.Graphics; -import javax.swing.Icon; - -/** - * Implement the Icon interface with an icon that has a size but - * does not paint anything on the graphics context. - */ -public class EmptyIcon - implements Icon -{ - private final int width; - private final int height; - - public static final EmptyIcon NULL_INSTANCE = new EmptyIcon(0); - - - public EmptyIcon(int width, int height) { - super(); - this.width = width; - this.height = height; - } - - public EmptyIcon(int size) { - this(size, size); - } - - - // ********** Icon implementation ********** - - public void paintIcon(Component c, Graphics g, int x, int y) { - // don't paint anything for an empty icon - } - - public int getIconWidth() { - return this.width; - } - - public int getIconHeight() { - return this.height; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListBrowser.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListBrowser.java deleted file mode 100644 index d59f3e04d3..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListBrowser.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import javax.swing.Icon; -import javax.swing.JComboBox; -import javax.swing.JOptionPane; -import javax.swing.ListModel; - -/** - * This implementation of LongListComponent.Browser uses a - * JOptionPane to prompt the user for the selection. The JOPtionPane - * is passed a FilteringListPanel to assist the user in making - * a selection. - */ -public class FilteringListBrowser<T> - implements ListChooser.ListBrowser -{ - private FilteringListPanel<T> panel; - - /** - * Default constructor. - */ - public FilteringListBrowser() { - super(); - this.panel = this.buildPanel(); - } - - protected FilteringListPanel<T> buildPanel() { - return new LocalFilteringListPanel<T>(); - } - - /** - * Prompt the user using a JOptionPane with a filtering - * list panel. - */ - public void browse(ListChooser chooser) { - this.initializeCellRenderer(chooser); - - int option = - JOptionPane.showOptionDialog( - chooser, - this.message(chooser), - this.title(chooser), - this.optionType(chooser), - this.messageType(chooser), - this.icon(chooser), - this.selectionValues(chooser), - this.initialSelectionValue(chooser) - ); - - if (option == JOptionPane.OK_OPTION) { - chooser.getModel().setSelectedItem(this.panel.selection()); - } - - // clear the text field so the list box is re-filtered - this.panel.textField().setText(""); - } - - protected void initializeCellRenderer(JComboBox comboBox) { - // default behavior should be to use the cell renderer from the combobox. - this.panel.listBox().setCellRenderer(comboBox.getRenderer()); - } - - /** - * the message can be anything - here we build a component - */ - protected Object message(JComboBox comboBox) { - this.panel.setCompleteList(this.convertToArray(comboBox.getModel())); - this.panel.setSelection(comboBox.getModel().getSelectedItem()); - return this.panel; - } - - protected String title(JComboBox comboBox) { - return null; - } - - protected int optionType(JComboBox comboBox) { - return JOptionPane.OK_CANCEL_OPTION; - } - - protected int messageType(JComboBox comboBox) { - return JOptionPane.QUESTION_MESSAGE; - } - - protected Icon icon(JComboBox comboBox) { - return null; - } - - protected Object[] selectionValues(JComboBox comboBox) { - return null; - } - - protected Object initialSelectionValue(JComboBox comboBox) { - return null; - } - - /** - * Convert the list of objects in the specified list model - * into an array. - */ - protected Object[] convertToArray(ListModel model) { - int size = model.getSize(); - Object[] result = new Object[size]; - for (int i = 0; i < size; i++) { - result[i] = model.getElementAt(i); - } - return result; - } - - - // ********** custom panel ********** - - protected static class LocalFilteringListPanel<S> extends FilteringListPanel<S> { - protected static final Object[] EMPTY_ARRAY = new Object[0]; - - protected LocalFilteringListPanel() { - super(EMPTY_ARRAY, null); - } - - /** - * Disable the performance tweak because JOptionPane - * will try open wide enough to disable the horizontal scroll bar; - * and it looks a bit clumsy. - */ - @Override - protected String prototypeCellValue() { - return null; - } - - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListPanel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListPanel.java deleted file mode 100644 index ff17df3305..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/FilteringListPanel.java +++ /dev/null @@ -1,455 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.BorderLayout; -import java.awt.Font; -import javax.swing.AbstractListModel; -import javax.swing.BorderFactory; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; -import javax.swing.ListCellRenderer; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; -import javax.swing.border.Border; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import org.eclipse.jpt.utility.internal.SimpleStringMatcher; -import org.eclipse.jpt.utility.internal.StringConverter; -import org.eclipse.jpt.utility.internal.StringMatcher; - -/** - * This panel presents an entry field and a list box of choices that - * allows the user to filter the entries in the list box by entering - * a pattern in the entry field. - * - * By default, two wildcards are allowed in the pattern: - * '*' will match any set of zero or more characters - * '?' will match any single character - * - * The panel consists of 4 components that can be customized: - * - 1 text field - * - 1 list box - * - 2 labels, one for each of the above - * - * Other aspects of the panel's behavior can be changed: - * - the string converter determines how the objects in the - * list are converted to strings and compared to the pattern - * entered in the text field; by default the converter simply - * uses the result of the object's #toString() method - * (if you replace the string converter, you will probably - * want to replace the list box's cell renderer also) - * - the string matcher can also be changed if you would - * like different pattern matching behavior than that - * described above - * - you can specify the maximum size of the list - this may - * force the user to enter a pattern restrictive enough - * to result in a list smaller than the maximum size; the - * default is -1, which disables the restriction - * - * This panel is not a typical panel, in the sense that it does not share - * its model with clients via value models. Instead, this panel's model - * is set and queried directly because it is designed to be used in a - * dialog that directs the user's behavior (as opposed to a "normal" - * window). - */ -public class FilteringListPanel<T> extends JPanel { - - /** - * The complete list of available choices - * (as opposed to the partial list held by the list box). - */ - private Object[] completeList; - - /** - * An adapter used to convert the objects in the list - * to strings so they can be run through the matcher - * and displayed in the text field. - */ - StringConverter<T> stringConverter; - - /** The text field. */ - private JTextField textField; - private JLabel textFieldLabel; - private DocumentListener textFieldListener; - - /** The list box. */ - private JList listBox; - private JLabel listBoxLabel; - - /** The maximum number of entries displayed in the list box. */ - private int maxListSize; - - /** - * The matcher used to filter the list against - * the pattern entered in the text field. By default, - * this allows the two wildcard characters described in - * the class comment. - */ - private StringMatcher stringMatcher; - - /** - * Performance tweak: We use this buffer instead of - * a temporary variable during filtering so we don't have - * to keep re-allocating it. - */ - private Object[] buffer; - - private static final Border TEXT_FIELD_LABEL_BORDER = BorderFactory.createEmptyBorder(0, 0, 5, 0); - private static final Border LIST_BOX_LABEL_BORDER = BorderFactory.createEmptyBorder(5, 0, 5, 0); - - - // ********** constructors ********** - - /** - * Construct a FilteringListPanel with the specified list of choices - * and initial selection. Use the default string converter to convert the - * choices and selection to strings (which simply calls #toString() on - * the objects). - */ - public FilteringListPanel(Object[] completeList, Object initialSelection) { - this(completeList, initialSelection, StringConverter.Default.<T>instance()); - } - - /** - * Construct a FilteringListPanel with the specified list of choices - * and initial selection. Use the specified string converter to convert the - * choices and selection to strings. - */ - public FilteringListPanel(Object[] completeList, Object initialSelection, StringConverter<T> stringConverter) { - super(new BorderLayout()); - this.completeList = completeList; - this.stringConverter = stringConverter; - this.initialize(initialSelection); - } - - - // ********** initialization ********** - - private void initialize(Object initialSelection) { - this.maxListSize = this.defaultMaxListSize(); - this.buffer = this.buildBuffer(); - - this.textFieldListener = this.buildTextFieldListener(); - - this.stringMatcher = this.buildStringMatcher(); - - this.initializeLayout(initialSelection); - } - - private Object[] buildBuffer() { - return new Object[this.max()]; - } - - /** - * Return the current max number of entries allowed in the list box. - */ - private int max() { - if (this.maxListSize == -1) { - return this.completeList.length; - } - return Math.min(this.maxListSize, this.completeList.length); - } - - /** - * Build a listener that will listen to changes in the text field - * and filter the list appropriately. - */ - private DocumentListener buildTextFieldListener() { - return new DocumentListener() { - public void insertUpdate(DocumentEvent e) { - FilteringListPanel.this.filterList(); - } - public void changedUpdate(DocumentEvent e) { - FilteringListPanel.this.filterList(); - } - public void removeUpdate(DocumentEvent e) { - FilteringListPanel.this.filterList(); - } - @Override - public String toString() { - return "text field listener"; - } - }; - } - - private int defaultMaxListSize() { - return -1; - } - - private StringMatcher buildStringMatcher() { - return new SimpleStringMatcher<T>(); - } - - private void initializeLayout(Object initialSelection) { - // text field - JPanel textFieldPanel = new JPanel(new BorderLayout()); - this.textFieldLabel = new JLabel(); - this.textFieldLabel.setBorder(TEXT_FIELD_LABEL_BORDER); - textFieldPanel.add(this.textFieldLabel, BorderLayout.NORTH); - - this.textField = new JTextField(); - this.textField.getDocument().addDocumentListener(this.textFieldListener); - this.textFieldLabel.setLabelFor(this.textField); - textFieldPanel.add(this.textField, BorderLayout.CENTER); - - this.add(textFieldPanel, BorderLayout.NORTH); - - // list box - JPanel listBoxPanel = new JPanel(new BorderLayout()); - this.listBoxLabel = new JLabel(); - this.listBoxLabel.setBorder(LIST_BOX_LABEL_BORDER); - listBoxPanel.add(this.listBoxLabel, BorderLayout.NORTH); - - this.listBox = new JList(); - this.listBox.setDoubleBuffered(true); - this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.max())); - this.listBox.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - // performance tweak(?) - this.listBox.setPrototypeCellValue(this.prototypeCellValue()); - this.listBox.setPrototypeCellValue(null); - this.listBox.setCellRenderer(this.buildDefaultCellRenderer()); - this.listBoxLabel.setLabelFor(this.listBox); - // bug 2777802 - scroll bars shouldn't be on the tab sequence - JScrollPane listBoxScrollPane = new JScrollPane(this.listBox); - listBoxScrollPane.getHorizontalScrollBar().setFocusable(false); - listBoxScrollPane.getVerticalScrollBar().setFocusable(false); - listBoxPanel.add(listBoxScrollPane, BorderLayout.CENTER); - - // initialize the widgets - this.listBox.setSelectedValue(initialSelection, true); - this.textField.select(0, this.textField.getText().length()); - - this.add(listBoxPanel, BorderLayout.CENTER); - } - - - // ********** public API ********** - - public Object selection() { - return this.listBox.getSelectedValue(); - } - - public void setSelection(Object selection) { - this.listBox.setSelectedValue(selection, true); - } - - public Object[] completeList() { - return this.completeList; - } - - /** - * rebuild the filtering buffer and re-apply the filter - * to the new list - */ - public void setCompleteList(Object[] completeList) { - this.completeList = completeList; - if (this.buffer.length < this.max()) { - // the buffer will never shrink - might want to re-consider... ~bjv - this.buffer = this.buildBuffer(); - } - this.filterList(); - } - - public int maxListSize() { - return this.maxListSize; - } - - public void setMaxListSize(int maxListSize) { - this.maxListSize = maxListSize; - if (this.buffer.length < this.max()) { - // the buffer will never shrink - might want to re-consider... ~bjv - this.buffer = this.buildBuffer(); - } - this.filterList(); - } - - public StringConverter<T> stringConverter() { - return this.stringConverter; - } - - /** - * apply the new filter to the list - */ - public void setStringConverter(StringConverter<T> stringConverter) { - this.stringConverter = stringConverter; - this.filterList(); - } - - /** - * allow client code to access the text field - * (so we can set the focus) - */ - public JTextField textField() { - return this.textField; - } - - /** - * allow client code to access the text field label - */ - public JLabel textFieldLabel() { - return this.textFieldLabel; - } - - /** - * convenience method - */ - public void setTextFieldLabelText(String text) { - this.textFieldLabel.setText(text); - } - - /** - * allow client code to access the list box - * (so we can add mouse listeners for double-clicking) - */ - public JList listBox() { - return this.listBox; - } - - /** - * convenience method - */ - public void setListBoxCellRenderer(ListCellRenderer renderer) { - this.listBox.setCellRenderer(renderer); - } - - /** - * allow client code to access the list box label - */ - public JLabel listBoxLabel() { - return this.listBoxLabel; - } - - /** - * convenience method - */ - public void setListBoxLabelText(String text) { - this.listBoxLabel.setText(text); - } - - /** - * convenience method - */ - public void setComponentsFont(Font font) { - this.textFieldLabel.setFont(font); - this.textField.setFont(font); - this.listBoxLabel.setFont(font); - this.listBox.setFont(font); - } - - public StringMatcher stringMatcher() { - return this.stringMatcher; - } - - /** - * re-apply the filter to the list - */ - public void setStringMatcher(StringMatcher stringMatcher) { - this.stringMatcher = stringMatcher; - this.filterList(); - } - - - // ********** internal methods ********** - - /** - * Allow subclasses to disable performance tweak - * by returning null here. - */ - protected String prototypeCellValue() { - return "==========> A_STRING_THAT_IS_DEFINITELY_LONGER_THAN_EVERY_STRING_IN_THE_LIST <=========="; - } - - /** - * By default, use the string converter to build the text - * used by the list box's cell renderer. - */ - protected ListCellRenderer buildDefaultCellRenderer() { - return new SimpleListCellRenderer() { - @Override - @SuppressWarnings("unchecked") - protected String buildText(Object value) { - return FilteringListPanel.this.stringConverter.convertToString((T) value); - } - }; - } - - /** - * Something has changed that requires us to filter the list. - * - * This method is synchronized because a fast typist can - * generate events quicker than we can filter the list. (? ~bjv) - */ - synchronized void filterList() { - // temporarily stop listening to the list box selection, since we will - // be changing the selection during the filtering and don't want - // that to affect the text field - this.filterList(this.textField.getText()); - } - - /** - * Filter the contents of the list box to match the - * specified pattern. - */ - private void filterList(String pattern) { - if (pattern.length() == 0) { - this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.max())); - } else { - this.stringMatcher.setPatternString(pattern); - int j = 0; - int len = this.completeList.length; - int max = this.max(); - for (int i = 0; i < len; i++) { - if (this.stringMatcher.matches(this.stringConverter.convertToString(this.entry(i)))) { - this.buffer[j++] = this.completeList[i]; - } - if (j == max) { - break; - } - } - this.listBox.setModel(this.buildPartialArrayListModel(this.buffer, j)); - } - - // after filtering the list, determine the appropriate selection - if (this.listBox.getModel().getSize() == 0) { - this.listBox.getSelectionModel().clearSelection(); - } else { - this.listBox.getSelectionModel().setAnchorSelectionIndex(0); - this.listBox.getSelectionModel().setLeadSelectionIndex(0); - this.listBox.ensureIndexIsVisible(0); - } - } - - /** - * minimize scope of suppressed warnings - */ - @SuppressWarnings("unchecked") - private T entry(int index) { - return (T) this.completeList[index]; - } - - /** - * Build a list model that wraps only a portion of the specified array. - * The model will include the array entries from 0 to (size - 1). - */ - private ListModel buildPartialArrayListModel(final Object[] array, final int size) { - return new AbstractListModel() { - public int getSize() { - return size; - } - public Object getElementAt(int index) { - return array[index]; - } - }; - } -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java deleted file mode 100644 index 9abc2e58f8..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java +++ /dev/null @@ -1,425 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.AWTEvent; -import java.awt.AWTException; -import java.awt.Component; -import java.awt.EventQueue; -import java.awt.Point; -import java.awt.Robot; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import javax.swing.ComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.ListCellRenderer; -import javax.swing.SwingConstants; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; -import javax.swing.plaf.basic.BasicComboBoxUI; -import org.eclipse.jpt.utility.internal.ClassTools; - -/** - * This component provides a way to handle selecting an item from a - * list that may grow too large to be handled conveniently by a combo-box. - * If the list's size is less than the designated "long" list size, - * the choice list will be displayed in a normal combo-box popup; - * otherwise, a dialog will be used to prompt the user to choose a selection. - * - * To change the browse mechanism, subclasses may - * - override the method #buildBrowser() - * - override the method #browse(), in which case the method - * #buildBrowser() may be ignored. - */ -public class ListChooser - extends JComboBox -{ - - /** the size of a "long" list - anything smaller is a "short" list */ - int longListSize = DEFAULT_LONG_LIST_SIZE; - - /** the default size of a "long" list, which is 20 (to match JOptionPane's behavior) */ - public static final int DEFAULT_LONG_LIST_SIZE = 20; - - /** property change associated with long list size */ - public static final String LONG_LIST_SIZE_PROPERTY = "longListSize"; - - static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(17), SwingConstants.LEADING); - - /** - * whether the chooser is choosable. if a chooser is not choosable, - * it only serves as a display widget. a user may not change its - * selected value. - */ - boolean choosable = true; - - /** property change associated with choosable */ - public static final String CHOOSABLE_PROPERTY = "choosable"; - - /** the browser used to make a selection from the long list - typically via a dialog */ - private ListBrowser browser; - - private NodeSelector nodeSelector; - - /** INTERNAL - The popup is being shown. Used to prevent infinite loop. */ - boolean popupAlreadyInProgress; - - - // **************** Constructors ****************************************** - - /** - * Construct a list chooser for the specified model. - */ - public ListChooser(ComboBoxModel model) { - this(model, new NodeSelector.DefaultNodeSelector()); - } - - public ListChooser(CachingComboBoxModel model) { - this(model, new NodeSelector.DefaultNodeSelector()); - } - - public ListChooser(ComboBoxModel model, NodeSelector nodeSelector) { - this(new NonCachingComboBoxModel(model), nodeSelector); - } - - public ListChooser(CachingComboBoxModel model, NodeSelector nodeSelector) { - super(model); - this.initialize(); - this.nodeSelector = nodeSelector; - } - // **************** Initialization **************************************** - - protected void initialize() { - this.addPopupMenuListener(this.buildPopupMenuListener()); - this.setRenderer(new DefaultListCellRenderer()); - this.addKeyListener(buildF3KeyListener()); - - //These are used to workaround problems with Swing trying to - //determine the size of a comboBox with a large model - setPrototypeDisplayValue(prototypeLabel); - listBox().setPrototypeCellValue(prototypeLabel); - } - - - private JList listBox() { - return (JList) ClassTools.fieldValue(this.ui, "listBox"); - } - - /** - * When the popup is about to be shown, the event is consumed, and - * PopupHandler determines whether to reshow the popup or to show - * the long list browser. - */ - private PopupMenuListener buildPopupMenuListener() { - return new PopupMenuListener() { - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - ListChooser.this.aboutToShowPopup(); - } - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - // do nothing - } - public void popupMenuCanceled(PopupMenuEvent e) { - // do nothing - } - @Override - public String toString() { - return "pop-up menu listener"; - } - }; - } - - /** - * If this code is being reached due to the PopupHandler already being in progress, - * then do nothing. Otherwise, set the flag to true and launch the PopupHandler. - */ - void aboutToShowPopup() { - if (this.popupAlreadyInProgress) { - return; - } - - this.popupAlreadyInProgress = true; - EventQueue.invokeLater(new PopupHandler()); - } - - - private KeyListener buildF3KeyListener() { - return new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_F3) { - goToSelectedItem(); - } - } - @Override - public String toString() { - return "F3 key listener"; - } - }; - } - - public void goToSelectedItem() { - if (getSelectedItem() != null) { - ListChooser.this.nodeSelector.selectNodeFor(getSelectedItem()); - } - } - - // **************** Browsing ********************************************** - - /** - * Lazily initialize because subclasses may have further initialization to do - * before browser can be built. - */ - protected void browse() { - if (this.browser == null) { - this.browser = this.buildBrowser(); - } - - this.browser.browse(this); - } - - /** - * Return the "browser" used to make a selection from the long list, - * typically via a dialog. - */ - protected ListChooser.ListBrowser buildBrowser() { - return new SimpleListBrowser(); - } - - - // **************** Choosable functionality ******************************* - - /** override behavior - consume selection if chooser is not choosable */ - @Override - public void setSelectedIndex(int anIndex) { - if (this.choosable) { - super.setSelectedIndex(anIndex); - } - } - - private void updateArrowButton() { - try { - BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI(); - JButton arrowButton = (JButton) ClassTools.fieldValue(comboBoxUi, "arrowButton"); - arrowButton.setEnabled(this.isEnabled() && this.choosable); - } - catch (Exception e) { - // this is a huge hack to try and make the combo box look right, - // so if it doesn't work, just swallow the exception - } - } - - - // **************** List Caching ******************************* - - void cacheList() { - ((CachingComboBoxModel) getModel()).cacheList(); - } - - void uncacheList() { - ((CachingComboBoxModel) getModel()).uncacheList(); - } - - boolean listIsCached() { - return ((CachingComboBoxModel) getModel()).isCached(); - } - - // **************** Public ************************************************ - - public int longListSize() { - return this.longListSize; - } - - public void setLongListSize(int newLongListSize) { - int oldLongListSize = this.longListSize; - this.longListSize = newLongListSize; - this.firePropertyChange(LONG_LIST_SIZE_PROPERTY, oldLongListSize, newLongListSize); - } - - public boolean isChoosable() { - return this.choosable; - } - - public void setChoosable(boolean newValue) { - boolean oldValue = this.choosable; - this.choosable = newValue; - this.firePropertyChange(CHOOSABLE_PROPERTY, oldValue, newValue); - this.updateArrowButton(); - } - - // **************** Handle selecting null as a value ********************** - - private boolean selectedIndexIsNoneSelectedItem(int index) { - return index == -1 && - getModel().getSize() > 0 && - getModel().getElementAt(0) == null; - } - - @Override - public int getSelectedIndex() { - boolean listNotCached = !listIsCached(); - if (listNotCached) { - cacheList(); - } - - int index = super.getSelectedIndex(); - - // Use index 0 to show the <none selected> item since the actual value is - // null and JComboBox does not handle null values - if (selectedIndexIsNoneSelectedItem(index)) { - index = 0; - } - - if (listNotCached) { - uncacheList(); - } - return index; - } - - //wrap the renderer to deal with the prototypeDisplayValue - @Override - public void setRenderer(final ListCellRenderer aRenderer) { - super.setRenderer(new ListCellRenderer(){ - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - if (value == prototypeLabel) { - return prototypeLabel; - } - return aRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - } - }); - } - - - // **************** Member classes **************************************** - - /** - * Define the API required by this ListChooser when it must - * prompt the user to select an item from the "long" list. - */ - public interface ListBrowser - { - /** - * Prompt the user to make a selection from the specified - * combo-box's model. - */ - void browse(ListChooser parentChooser); - } - - - /** - * Runnable class that consumes popup window and determines whether - * to reshow popup or to launch browser, based on the size of the list. - */ - private class PopupHandler - implements Runnable - { - /** The mouse event */ - private MouseEvent lastMouseEvent; - - /** The component from which the last mouse event was thrown */ - private JComponent eventComponent; - - /** The location of the component at the time the last mouse event was thrown */ - private Point componentLocation; - - /** The location of the mouse at the time the last mouse event was thrown */ - private Point mouseLocation; - - - PopupHandler() { - this.initialize(); - } - - private void initialize() { - AWTEvent event = EventQueue.getCurrentEvent(); - - if (event instanceof MouseEvent) { - this.lastMouseEvent = (MouseEvent) event; - this.eventComponent = (JComponent) this.lastMouseEvent.getSource(); - this.componentLocation = this.eventComponent.getLocationOnScreen(); - this.mouseLocation = this.lastMouseEvent.getPoint(); - } - else { - this.eventComponent = null; - this.componentLocation = null; - this.mouseLocation = null; - } - } - - public void run() { - ListChooser.this.hidePopup(); - - cacheList(); - if (ListChooser.this.choosable == true) { - // If the combo box model is of sufficient length, the browser will be shown. - // Asking the combo box model for its size should be enough to ensure that - // its size is recalculated. - if (ListChooser.this.getModel().getSize() > ListChooser.this.longListSize) { - this.checkComboBoxButton(); - ListChooser.this.browse(); - } - else { - ListChooser.this.showPopup(); - this.checkMousePosition(); - } - } - if (listIsCached()) { - uncacheList(); - } - - ListChooser.this.popupAlreadyInProgress = false; - } - - /** If this is not done, the button never becomes un-pressed */ - private void checkComboBoxButton() { - try { - BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI(); - JButton arrowButton = (JButton) ClassTools.fieldValue(comboBoxUi, "arrowButton"); - arrowButton.getModel().setPressed(false); - } - catch (Exception e) { - // this is a huge hack to try and make the combo box look right, - // so if it doesn't work, just swallow the exception - } - } - - /** - * Moves the mouse back to its original position before any jiggery pokery that we've done. - */ - private void checkMousePosition() { - if (this.eventComponent == null) { - return; - } - - final Point newComponentLocation = this.eventComponent.getLocationOnScreen(); - boolean componentMoved = - newComponentLocation.x - this.componentLocation.x != 0 - || newComponentLocation.y - this.componentLocation.y != 0; - - if (componentMoved) { - try { - new Robot().mouseMove( - newComponentLocation.x + this.mouseLocation.x, - newComponentLocation.y + this.mouseLocation.y - ); - } - catch (AWTException ex) { - // move failed - do nothing - } - } - } - } -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NodeSelector.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NodeSelector.java deleted file mode 100644 index f8b4d148e5..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NodeSelector.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -/** - * This will be called when the user presses F3 or chooses - * 'Go To' in the context menu - */ -public interface NodeSelector -{ - /** - * Select the appropriate Node in the tree or the editor panel. - */ - void selectNodeFor(Object item); - - /** - * This NodeSelector will do nothing when selectNodeFor(Object) is called - */ - class DefaultNodeSelector implements NodeSelector { - - public void selectNodeFor(Object item) { - //default is to do nothing - } - } -}
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NonCachingComboBoxModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NonCachingComboBoxModel.java deleted file mode 100644 index ee7226457f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/NonCachingComboBoxModel.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import javax.swing.ComboBoxModel; -import javax.swing.event.ListDataListener; - -/** - * This implementation of the CachingComboBoxModel interface can be used - * whenever there is no need for caching (i.e. the contents of the selection - * list can be generated with little latency). All the normal ComboBoxModel - * behavior is delegated to a client-supplied ComboBoxModel. - */ -public class NonCachingComboBoxModel implements CachingComboBoxModel { - private ComboBoxModel wrappedComboBoxModel; - - public NonCachingComboBoxModel(ComboBoxModel wrappedComboBoxModel) { - this.wrappedComboBoxModel = wrappedComboBoxModel; - } - - - // ********** CachingComboBoxModel implementation ********** - - public void cacheList() { - //do nothing - } - - public void uncacheList() { - //do nothing - } - - public boolean isCached() { - return false; - } - - - // ********** ComboBoxModel implementation ********** - - public void setSelectedItem(Object anItem) { - this.wrappedComboBoxModel.setSelectedItem(anItem); - } - - public Object getSelectedItem() { - return this.wrappedComboBoxModel.getSelectedItem(); - } - - - // ********** ListModel implementation ********** - - public int getSize() { - return this.wrappedComboBoxModel.getSize(); - } - - public Object getElementAt(int index) { - return this.wrappedComboBoxModel.getElementAt(index); - } - - public void addListDataListener(ListDataListener l) { - this.wrappedComboBoxModel.addListDataListener(l); - } - - public void removeListDataListener(ListDataListener l) { - this.wrappedComboBoxModel.removeListDataListener(l); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleDisplayable.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleDisplayable.java deleted file mode 100644 index 8d5aa452cf..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleDisplayable.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import javax.swing.Icon; -import org.eclipse.jpt.utility.internal.model.AbstractModel; - -/** - * This implementation of Displayable converts any Object - * to a Displayable. Subclass it to override #displayString() and - * #icon() if necessary. Change notification will be fired if the - * object is changed. - * - * This can be used for Strings - the display string - * will simply be the String itself. - */ -public class SimpleDisplayable - extends AbstractModel - implements Displayable -{ - /** The object to be converted to a Displayable. */ - protected Object object; - - - /** - * Construct a displayable for the specified object. - */ - public SimpleDisplayable(Object object) { - super(); - this.object = object; - } - - public SimpleDisplayable(boolean b) { - this(Boolean.valueOf(b)); - } - - public SimpleDisplayable(char c) { - this(new Character(c)); - } - - public SimpleDisplayable(byte b) { - this(new Byte(b)); - } - - public SimpleDisplayable(short s) { - this(new Short(s)); - } - - public SimpleDisplayable(int i) { - this(new Integer(i)); - } - - public SimpleDisplayable(long l) { - this(new Long(l)); - } - - public SimpleDisplayable(float f) { - this(new Float(f)); - } - - public SimpleDisplayable(double d) { - this(new Double(d)); - } - - - // ********** Displayable implementation ********** - - public String displayString() { - return this.object.toString(); - } - - public Icon icon() { - return null; - } - - - // ********** Comparable implementation ********** - - public int compareTo(Displayable o) { - return DEFAULT_COMPARATOR.compare(this, o); - } - - - // ********** accessors ********** - - public Object getObject() { - return this.object; - } - - public void setObject(Object object) { - String oldDisplayString = this.displayString(); - Icon oldIcon = this.icon(); - this.object = object; - this.firePropertyChanged(DISPLAY_STRING_PROPERTY, oldDisplayString, this.displayString()); - this.firePropertyChanged(ICON_PROPERTY, oldIcon, this.icon()); - } - - public boolean getBoolean() { - return ((Boolean) this.object).booleanValue(); - } - - public void setBoolean(boolean b) { - this.setObject(Boolean.valueOf(b)); - } - - public char getChar() { - return ((Character) this.object).charValue(); - } - - public void setChar(char c) { - this.setObject(new Character(c)); - } - - public byte getByte() { - return ((Byte) this.object).byteValue(); - } - - public void setByte(byte b) { - this.setObject(new Byte(b)); - } - - public short getShort() { - return ((Short) this.object).shortValue(); - } - - public void setShort(short s) { - this.setObject(new Short(s)); - } - - public int getInt() { - return ((Integer) this.object).intValue(); - } - - public void setInt(int i) { - this.setObject(new Integer(i)); - } - - public long getLong() { - return ((Long) this.object).longValue(); - } - - public void setLong(long l) { - this.setObject(new Long(l)); - } - - public float getFloat() { - return ((Float) this.object).floatValue(); - } - - public void setFloat(float f) { - this.setObject(new Float(f)); - } - - public double getDouble() { - return ((Double) this.object).doubleValue(); - } - - public void setDouble(double d) { - this.setObject(new Double(d)); - } - - - // ********** override methods ********** - - @Override - public void toString(StringBuilder sb) { - sb.append(this.object); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListBrowser.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListBrowser.java deleted file mode 100644 index 7215c6a387..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListBrowser.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import javax.swing.Icon; -import javax.swing.JComboBox; -import javax.swing.JOptionPane; -import javax.swing.ListModel; - -/** - * This implementation of ListChooser.Browser uses a - * JOptionPane to prompt the user for the selection. Subclasses - * can change the dialog's title, message, and/or icon. - */ -public class SimpleListBrowser - implements ListChooser.ListBrowser -{ - /** Default constructor */ - protected SimpleListBrowser() { - super(); - } - - /** - * Prompt the user using a JOptionPane. - */ - public void browse(ListChooser chooser) { - Object selection = - JOptionPane.showInputDialog( - chooser, - this.message(chooser), - this.title(chooser), - this.messageType(chooser), - this.icon(chooser), - this.selectionValues(chooser), - this.initialSelectionValue(chooser) - ); - - if (selection != null) { - chooser.getModel().setSelectedItem(selection); - } - } - - protected Object message(JComboBox comboBox) { - return null; - } - - protected String title(JComboBox comboBox) { - return null; - } - - protected int messageType(JComboBox comboBox) { - return JOptionPane.QUESTION_MESSAGE; - } - - protected Icon icon(JComboBox comboBox) { - return null; - } - - protected Object[] selectionValues(JComboBox comboBox) { - return this.convertToArray(comboBox.getModel()); - } - - protected Object initialSelectionValue(JComboBox comboBox) { - return comboBox.getModel().getSelectedItem(); - } - - /** - * Convert the list of objects in the specified list model - * into an array. - */ - protected Object[] convertToArray(ListModel model) { - int size = model.getSize(); - Object[] result = new Object[size]; - for (int i = 0; i < size; i++) { - result[i] = model.getElementAt(i); - } - return result; - } -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListCellRenderer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListCellRenderer.java deleted file mode 100644 index ea649ba33d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SimpleListCellRenderer.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Component; -import javax.swing.DefaultListCellRenderer; -import javax.swing.Icon; -import javax.swing.JList; - -/** - * This renderer should behave the same as the DefaultListCellRenderer; - * but it slightly refactors the calculation of the icon and text of the list - * cell so that subclasses can easily override the methods that build - * the icon and text. - * - * In most cases, you need only override: - * #buildIcon(Object value) - * #buildText(Object value) - */ -public class SimpleListCellRenderer - extends DefaultListCellRenderer -{ - - /** - * Construct a simple renderer. - */ - public SimpleListCellRenderer() { - super(); - } - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - // substitute null for the cell value so nothing is drawn initially... - super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); - this.setOpaque(true); - - // ...then set the icon and text manually - this.setIcon(this.buildIcon(list, value, index, isSelected, cellHasFocus)); - this.setText(this.buildText(list, value, index, isSelected, cellHasFocus)); - - this.setToolTipText(this.buildToolTipText(list, value, index, isSelected, cellHasFocus)); - - // the context will be initialized only if a reader is running - if (this.accessibleContext != null) { - this.accessibleContext.setAccessibleName(this.buildAccessibleName(list, value, index, isSelected, cellHasFocus)); - } - - return this; - } - - /** - * Return the icon representation of the specified cell - * value and other settings. (Even more settings are - * accessible via inherited getters: hasFocus, isEnabled, etc.) - */ - protected Icon buildIcon(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - return this.buildIcon(value); - } - - /** - * Return the icon representation of the specified cell - * value. The default is to display no icon at all unless the - * value itself is an icon. - */ - protected Icon buildIcon(Object value) { - // replicate the default behavior - return (value instanceof Icon) ? (Icon) value : null; - } - - /** - * Return the textual representation of the specified cell - * value and other settings. (Even more settings are - * accessible via inherited getters: hasFocus, isEnabled, etc.) - */ - protected String buildText(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - return this.buildText(value); - } - - /** - * Return the textual representation of the specified cell - * value. The default is to display the object's default string - * representation (as returned by #toString()); unless the - * value itself is an icon, in which case no text is displayed. - */ - protected String buildText(Object value) { - return (value instanceof Icon) ? "" : ((value == null) ? "" : value.toString()); - } - - /** - * Return the text displayed when the cursor lingers over the specified cell. - * (Even more settings are accessible via inherited getters: hasFocus, isEnabled, etc.) - */ - protected String buildToolTipText(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - return this.buildToolTipText(value); - } - - /** - * Return the text displayed when the cursor lingers over the specified cell. - */ - protected String buildToolTipText(Object value) { - return null; - } - - /** - * Return the accessible name to be given to the component used to render - * the given value and other settings. (Even more settings are accessible via - * inherited getters: hasFocus, isEnabled, etc.) - */ - protected String buildAccessibleName(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - return this.buildAccessibleName(value); - } - - /** - * Return the accessible name to be given to the component used to render - * the given value. - */ - protected String buildAccessibleName(Object value) { - return null; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SpinnerTableCellRenderer.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SpinnerTableCellRenderer.java deleted file mode 100644 index a15e16a570..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/SpinnerTableCellRenderer.java +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Color; -import java.awt.Component; -import javax.swing.BorderFactory; -import javax.swing.JComponent; -import javax.swing.JSpinner; -import javax.swing.JTable; -import javax.swing.SpinnerModel; -import javax.swing.UIManager; -import javax.swing.border.Border; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -/** - * Make the cell look like a spinner. - */ -public class SpinnerTableCellRenderer implements TableCellEditorAdapter.Renderer { - - /** the component used to paint the cell */ - protected JSpinner spinner; - - /** the listener to be notified on an immediate edit */ - protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener; - - - // ********** constructors/initialization ********** - - /** - * Construct a cell renderer that uses the default - * spinner model, which is a "number" model. - */ - public SpinnerTableCellRenderer() { - super(); - this.initialize(); - } - - /** - * Construct a cell renderer that uses the specified - * spinner model, which will determine how the values are displayed. - */ - public SpinnerTableCellRenderer(SpinnerModel model) { - this(); - this.setModel(model); - } - - protected void initialize() { - this.spinner = this.buildSpinner(); - } - - protected JSpinner buildSpinner() { - JSpinner s = new JSpinner(); - s.addChangeListener(this.buildChangeListener()); - return s; - } - - private ChangeListener buildChangeListener() { - return new ChangeListener() { - public void stateChanged(ChangeEvent e) { - if (SpinnerTableCellRenderer.this.immediateEditListener != null) { - SpinnerTableCellRenderer.this.immediateEditListener.immediateEdit(); - } - } - }; - } - - - // ********** TableCellRenderer implementation ********** - - public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - this.spinner.setComponentOrientation(table.getComponentOrientation()); - this.spinner.setFont(table.getFont()); - this.spinner.setEnabled(table.isEnabled()); - - JComponent editor = this.editor(); - editor.setForeground(this.foregroundColor(table, value, selected, hasFocus, row, column)); - editor.setBackground(this.backgroundColor(table, value, selected, hasFocus, row, column)); - this.spinner.setBorder(this.border(table, value, selected, hasFocus, row, column)); - - this.setValue(value); - return this.spinner; - } - - /** - * Return the cell's foreground color. - */ - protected Color foregroundColor(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return UIManager.getColor("Table.focusCellForeground"); - } - return table.getSelectionForeground(); - } - return table.getForeground(); - } - - /** - * Return the cell's background color. - */ - protected Color backgroundColor(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - if (selected) { - if (hasFocus && table.isCellEditable(row, column)) { - return UIManager.getColor("Table.focusCellBackground"); - } - return table.getSelectionBackground(); - } - return table.getBackground(); - } - - /** - * Return the cell's border. - */ - protected Border border(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { - if (hasFocus) { - return UIManager.getBorder("Table.focusCellHighlightBorder"); - } - if (selected) { - return BorderFactory.createLineBorder(table.getSelectionBackground(), 1); - } - return BorderFactory.createLineBorder(table.getBackground(), 1); - } - - /** - * Return the editor component whose colors should be set - * by the renderer. - */ - protected JComponent editor() { - JComponent editor = this.spinner.getEditor(); - if (editor instanceof JSpinner.DefaultEditor) { - // typically, the editor will be the default or one of its subclasses... - editor = ((JSpinner.DefaultEditor) editor).getTextField(); - } - return editor; - } - - /** - * Set the spinner's value - */ - protected void setValue(Object value) { - // CR#3999318 - This null check needs to be removed once JDK bug is fixed - if (value == null) { - value = new Integer(0); - } - this.spinner.setValue(value); - } - - - // ********** TableCellEditorAdapter.Renderer implementation ********** - - public Object getValue() { - return this.spinner.getValue(); - } - - public void setImmediateEditListener(TableCellEditorAdapter.ImmediateEditListener listener) { - this.immediateEditListener = listener; - } - - - // ********** public API ********** - - /** - * Set the spinner's model. - */ - public void setModel(SpinnerModel model) { - this.spinner.setModel(model); - } - - /** - * Return the renderer's preferred height. This allows you - * to set the row height to something the spinner will look good in.... - */ - public int preferredHeight() { - // add in space for the border top and bottom - return (int) this.spinner.getPreferredSize().getHeight() + 2; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/TableCellEditorAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/TableCellEditorAdapter.java deleted file mode 100644 index b19c86f08d..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/TableCellEditorAdapter.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.Component; -import javax.swing.AbstractCellEditor; -import javax.swing.JTable; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; - -/** - * A table cell editor that wraps a table cell renderer. - */ -public class TableCellEditorAdapter extends AbstractCellEditor implements TableCellEditor { - - /** delegate to a renderer */ - private Renderer renderer; - - - // ********** constructors/initialization ********** - - private TableCellEditorAdapter() { - super(); - } - - /** - * Construct a cell editor that behaves like the specified renderer. - */ - public TableCellEditorAdapter(Renderer renderer) { - this(); - this.initialize(renderer); - } - - protected void initialize(Renderer r) { - this.renderer = r; - r.setImmediateEditListener(this.buildImmediateEditListener()); - } - - private ImmediateEditListener buildImmediateEditListener() { - return new ImmediateEditListener() { - public void immediateEdit() { - TableCellEditorAdapter.this.stopCellEditing(); - } - }; - } - - - // ********** CellEditor implementation ********** - - public Object getCellEditorValue() { - return this.renderer.getValue(); - } - - - // ********** TableCellEditor implementation ********** - - public Component getTableCellEditorComponent(JTable table, Object value, boolean selected, int row, int column) { - return this.renderer.getTableCellRendererComponent(table, value, selected, true, row, column); - } - - - // ********** Member classes ********************************************** - - /** - * This interface defines the methods that must be implemented by a renderer - * that can be wrapped by a TableCellEditorAdapter. - */ - public interface Renderer extends TableCellRenderer { - - /** - * Return the current value of the renderer. - */ - Object getValue(); - - /** - * Set the immediate edit listener - */ - void setImmediateEditListener(ImmediateEditListener listener); - } - - - public interface ImmediateEditListener { - - /** - * Called when the renderer does an "immediate edit" - */ - void immediateEdit(); - } -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/Model.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/Model.java deleted file mode 100644 index 33f2fd2afd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/Model.java +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model; - -import org.eclipse.jpt.utility.model.listener.CollectionChangeListener; -import org.eclipse.jpt.utility.model.listener.ListChangeListener; -import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.utility.model.listener.StateChangeListener; -import org.eclipse.jpt.utility.model.listener.TreeChangeListener; - -/** - * Interface to be implemented by models that notify listeners of - * changes to bound properties, collections, lists, and/or trees. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface Model { - - // ********** state change ********** - - /** - * Add a listener that listens to all state change events. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addStateChangeListener(StateChangeListener listener); - - /** - * Remove the specified state change listener. If the listener - * was added more than once, it will be notified one less time - * after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeStateChangeListener(StateChangeListener listener); - - - // ********** property change ********** - - /** - * Add a listener that listens to all property change events, - * regardless of the property name associated with that event. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Add a listener that listens to all property change events with - * the specified property name. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addPropertyChangeListener(String propertyName, PropertyChangeListener listener); - - /** - * Remove a listener that listens to all property change events, - * regardless of the property name associated with that event. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removePropertyChangeListener(PropertyChangeListener listener); - - /** - * Remove a listener that listens to all property change events, - * with the specified property name. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removePropertyChangeListener(String propertyName, PropertyChangeListener listener); - - - // ********** collection change ********** - - /** - * Add a listener that listens to all collection change events, - * regardless of the collection name associated with that event. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addCollectionChangeListener(CollectionChangeListener listener); - - /** - * Add a listener that listens to all collection change events with - * the specified collection name. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addCollectionChangeListener(String collectionName, CollectionChangeListener listener); - - /** - * Remove a listener that listens to all collection change events, - * regardless of the collection name associated with that event. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeCollectionChangeListener(CollectionChangeListener listener); - - /** - * Remove a listener that listens to all collection change events, - * with the specified collection name. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener); - - - // ********** list change ********** - - /** - * Add a listener that listens to all list change events, - * regardless of the list name associated with that event. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addListChangeListener(ListChangeListener listener); - - /** - * Add a listener that listens to all list change events with - * the specified list name. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addListChangeListener(String listName, ListChangeListener listener); - - /** - * Remove a listener that listens to all list change events, - * regardless of the list name associated with that event. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeListChangeListener(ListChangeListener listener); - - /** - * Remove a listener that listens to all list change events, - * with the specified list name. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeListChangeListener(String listName, ListChangeListener listener); - - - // ********** tree change ********** - - /** - * Add a listener that listens to all tree change events, - * regardless of the tree name associated with that event. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addTreeChangeListener(TreeChangeListener listener); - - /** - * Add a listener that listens to all tree change events with - * the specified tree name. - * The same listener may be added more than once and will be called - * as many times as it is added. The listener cannot be null. - */ - void addTreeChangeListener(String treeName, TreeChangeListener listener); - - /** - * Remove a listener that listens to all tree change events, - * regardless of the tree name associated with that event. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeTreeChangeListener(TreeChangeListener listener); - - /** - * Remove a listener that listens to all tree change events, - * with the specified tree name. - * If the listener was added more than once, it will be notified one less - * time after being removed. An exception will be thrown if the - * listener is null or if the listener was never added. - */ - void removeTreeChangeListener(String treeName, TreeChangeListener listener); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ChangeEvent.java deleted file mode 100644 index 5217abbd65..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ChangeEvent.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import java.util.EventObject; -import org.eclipse.jpt.utility.internal.StringTools; -import org.eclipse.jpt.utility.model.Model; - -/** - * Abstract class for all the change events that can be fired by models. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public abstract class ChangeEvent extends EventObject { - - private static final long serialVersionUID = 1L; - - - /** - * Construct a new change event. - * - * @param source The object on which the event initially occurred. - */ - protected ChangeEvent(Model source) { - super(source); - } - - /** - * Covariant override. - */ - @Override - public Model getSource() { - return (Model) super.getSource(); - } - - /** - * Return the name of the aspect of the source that changed. - * May be null if inappropriate. - */ - public abstract String getAspectName(); - - /** - * Return a copy of the event with the specified source - * replacing the current source. - */ - public abstract ChangeEvent cloneWithSource(Model newSource); - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.getAspectName()); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/CollectionChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/CollectionChangeEvent.java deleted file mode 100644 index 386026c786..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/CollectionChangeEvent.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import org.eclipse.jpt.utility.model.Model; - -/** - * A "collection change" event gets delivered whenever a model changes a "bound" - * or "constrained" collection. A CollectionChangeEvent is sent as an - * argument to the CollectionChangeListener. - * - * Normally a CollectionChangeEvent is accompanied by the collection name and - * the items that were added to or removed from the changed collection. - * - * Design options: - * - create a collection to wrap a single added or removed item - * (this is the option we implemented below and in collaborating code) - * since there is no way to optimize downstream code for - * single items, we take another performance hit by building - * a collection each time (@see Collections#singleton(Object)) - * and forcing downstream code to use an iterator every time - * - * - fire a separate event for each item added or removed - * eliminates any potential for optimizations to downstream code - * - * - add protocol to support both single items and collections - * adds conditional logic to downstream code - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class CollectionChangeEvent extends ChangeEvent { - - /** Name of the collection that changed. */ - private final String collectionName; - - /** The items that were added to or removed from the collection. May be empty, if not known. */ - private final Collection<?> items; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a new collection change event. - * - * @param source The object on which the event initially occurred. - * @param collectionName The programmatic name of the collection that was changed. - * @param items The items that were added to or removed from the collection. - */ - public CollectionChangeEvent(Model source, String collectionName, Collection<?> items) { - super(source); - if ((collectionName == null) || (items == null)) { - throw new NullPointerException(); - } - this.collectionName = collectionName; - this.items = Collections.unmodifiableCollection(items); - } - - /** - * Construct a new collection change event. - * - * @param source The object on which the event initially occurred. - * @param collectionName The programmatic name of the collection that was changed. - */ - public CollectionChangeEvent(Model source, String collectionName) { - this(source, collectionName, Collections.emptySet()); - } - - - // ********** standard state ********** - - /** - * Return the programmatic name of the collection that was changed. - */ - public String getCollectionName() { - return this.collectionName; - } - - @Override - public String getAspectName() { - return this.collectionName; - } - - /** - * Return an iterator on the items that were added to or - * removed from the collection. - * May be empty if inappropriate or unknown. - */ - public Iterator<?> items() { - return this.items.iterator(); - } - - /** - * Return the number of items that were added to or - * removed from the collection. - * May be 0 if inappropriate or unknown. - */ - public int itemsSize() { - return this.items.size(); - } - - - // ********** cloning ********** - - /** - * Return a copy of the event with the specified source - * replacing the current source. - */ - @Override - public CollectionChangeEvent cloneWithSource(Model newSource) { - return new CollectionChangeEvent(newSource, this.collectionName, this.items); - } - - /** - * Return a copy of the event with the specified source and collection name - * replacing the current source and collection name. - */ - public CollectionChangeEvent cloneWithSource(Model newSource, String newCollectionName) { - return new CollectionChangeEvent(newSource, newCollectionName, this.items); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ListChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ListChangeEvent.java deleted file mode 100644 index 9ec18ae194..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/ListChangeEvent.java +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import java.util.Collections; -import java.util.List; -import java.util.ListIterator; -import org.eclipse.jpt.utility.model.Model; - -/** - * A "list change" event gets delivered whenever a model changes a "bound" - * or "constrained" list. A ListChangeEvent is sent as an - * argument to the ListChangeListener. - * - * Normally a ListChangeEvent is accompanied by the list name, - * the items that were added to or removed from the changed list, - * and the index of where the items are or were in the list. - * - * Design options: - * - create a list to wrap a single added or removed item - * (this is the option we implemented below and in collaborating code) - * since there is no way to optimize downstream code for - * single items, we take another performance hit by building - * a list each time (@see Collections#singletonList(Object)) - * and forcing downstream code to use a list iterator every time - * - * - fire a separate event for each item added or removed - * eliminates any potential for optimizations to downstream code - * - * - add protocol to support both single items and collections - * adds conditional logic to downstream code - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class ListChangeEvent extends ChangeEvent { - - /** - * Name of the list that changed. - */ - private final String listName; - - /** - * The index at which the items were added, removed, or replaced. - * In the case of "moved" items, this will be the "target" index. - * May be -1, if not known. - */ - private final int index; - - /** - * The items that were added to or removed from the list. In the case of - * "replaced" items, these are the new items in the list. - * In the case of "moved" items, this will be empty. - * May be empty, if not known. - */ - private final List<?> items; - - /** - * The items in the list that were replaced by the items listed above, - * in #items. May be empty, if not known. - */ - private final List<?> replacedItems; - - /** - * In the case of "moved" items, this will be the "source" index. - * May be -1, if not known. - */ - private final int sourceIndex; - - /** - * In the case of "moved" items, this will be the number of items moved. - * May be -1, if not known. - */ - private final int moveLength; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - protected ListChangeEvent(Model source, String listName, int index, List<?> items, List<?> replacedItems, int sourceIndex, int moveLength) { - super(source); - if ((listName == null) || (items == null) || (replacedItems == null)) { - throw new NullPointerException(); - } - this.listName = listName; - this.index = index; - this.items = Collections.unmodifiableList(items); - this.replacedItems = Collections.unmodifiableList(replacedItems); - this.sourceIndex = sourceIndex; - this.moveLength = moveLength; - } - - /** - * Construct a new list change event for a list of replaced items. - * - * @param source The object on which the event initially occurred. - * @param listName The programmatic name of the list that was changed. - * @param index The index at which the items in the list were replaced. - * @param items The new items in the list. - * @param replacedItems The items in the list that were replaced. - */ - public ListChangeEvent(Model source, String listName, int index, List<?> items, List<?> replacedItems) { - this(source, listName, index, items, replacedItems, -1, -1); - } - - /** - * Construct a new list change event for a list of added or removed items. - * - * @param source The object on which the event initially occurred. - * @param listName The programmatic name of the list that was changed. - * @param index The index at which the items were added to or removed from the list. - * @param items The items that were added to or removed from the list. - */ - public ListChangeEvent(Model source, String listName, int index, List<?> items) { - this(source, listName, index, items, Collections.emptyList(), -1, -1); - } - - /** - * Construct a new list change event for a list of moved items. - * - * @param source The object on which the event initially occurred. - * @param listName The programmatic name of the list that was changed. - * @param targetIndex The index to which the items were moved. - * @param sourceIndex The index from which the items were moved. - */ - public ListChangeEvent(Model source, String listName, int targetIndex, int sourceIndex, int length) { - this(source, listName, targetIndex, Collections.emptyList(), Collections.emptyList(), sourceIndex, length); - } - - /** - * Construct a new list change event. - * - * @param source The object on which the event initially occurred. - * @param listName The programmatic name of the list that was changed. - */ - public ListChangeEvent(Model source, String listName) { - this(source, listName, -1, Collections.emptyList(), Collections.emptyList(), -1, -1); - } - - - // ********** standard state ********** - - /** - * Return the programmatic name of the list that was changed. - */ - public String getListName() { - return this.listName; - } - - @Override - public String getAspectName() { - return this.listName; - } - - /** - * Return the index at which the items were added to, removed from, - * or replaced in the list. - * In the case of "moved" items, this will be the "target" index. - * May be -1 if inappropriate or unknown. - */ - public int getIndex() { - return this.index; - } - - /** - * Return a list iterator on the items that were added to or - * removed from the list. In the case of "replaced" items, these - * are the new items in the list. - * May be empty if inappropriate or unknown. - */ - public ListIterator<?> items() { - return this.items.listIterator(); - } - - /** - * Return the number of items that were added to, - * removed from, or replaced in the list. - * May be 0 if inappropriate or unknown. - */ - public int itemsSize() { - return this.items.size(); - } - - - // ********** replace ********** - - /** - * Return a list iterator on the items in the list that were replaced. - * May be empty if inappropriate or unknown. - */ - public ListIterator<?> replacedItems() { - return this.replacedItems.listIterator(); - } - - - // ********** move ********** - - /** - * In the case of "moved" items, this will be the "target" index. - * May be -1 if inappropriate or unknown. - */ - public int getTargetIndex() { - return this.index; - } - - /** - * In the case of "moved" items, this will be the "source" index. - * May be -1 if inappropriate or unknown. - */ - public int getSourceIndex() { - return this.sourceIndex; - } - - /** - * In the case of "moved" items, this will be the number of items moved. - * May be -1 if inappropriate or unknown. - */ - public int getMoveLength() { - return this.moveLength; - } - - - // ********** cloning ********** - - /** - * Return a copy of the event with the specified source - * replacing the current source. - */ - @Override - public ListChangeEvent cloneWithSource(Model newSource) { - return new ListChangeEvent(newSource, this.listName, this.index, this.items, this.replacedItems, this.sourceIndex, this.moveLength); - } - - /** - * Return a copy of the event with the specified source and list name - * replacing the current source and list name. - */ - public ListChangeEvent cloneWithSource(Model newSource, String newListName) { - return new ListChangeEvent(newSource, newListName, this.index, this.items, this.replacedItems, this.sourceIndex, this.moveLength); - } - - /** - * Return a copy of the event with the specified source and list name - * replacing the current source and list name and displacing - * the index by the specified amount. - */ - public ListChangeEvent cloneWithSource(Model newSource, String newListName, int offset) { - return new ListChangeEvent(newSource, newListName, this.index + offset, this.items, this.replacedItems, this.sourceIndex + offset, this.moveLength); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/PropertyChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/PropertyChangeEvent.java deleted file mode 100644 index ee2fa2f8b2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/PropertyChangeEvent.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import org.eclipse.jpt.utility.model.Model; - -/** - * A "property change" event gets delivered whenever a model changes a "bound" - * or "constrained" property. A PropertyChangeEvent is sent as an - * argument to the PropertyChangeListener. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class PropertyChangeEvent extends ChangeEvent { - - /** Name of the property that changed. */ - private final String propertyName; - - /** The property's old value, before the change. */ - private final Object oldValue; - - /** The property's new value, after the change. */ - private final Object newValue; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a new property change event. - * - * @param source The object on which the event initially occurred. - * @param propertyName The programmatic name of the property that was changed. - * @param oldValue The old value of the property. - * @param newValue The new value of the property. - */ - public PropertyChangeEvent(Model source, String propertyName, Object oldValue, Object newValue) { - super(source); - if (propertyName == null) { - throw new NullPointerException(); - } - this.propertyName = propertyName; - this.oldValue = oldValue; - this.newValue = newValue; - } - - - // ********** standard state ********** - - /** - * Return the programmatic name of the property that was changed. - */ - public String getPropertyName() { - return this.propertyName; - } - - @Override - public String getAspectName() { - return this.propertyName; - } - - /** - * Return the old value of the property. - */ - public Object getOldValue() { - return this.oldValue; - } - - /** - * Return the new value of the property. - */ - public Object getNewValue() { - return this.newValue; - } - - - // ********** cloning ********** - - @Override - public PropertyChangeEvent cloneWithSource(Model newSource) { - return new PropertyChangeEvent(newSource, this.propertyName, this.oldValue, this.newValue); - } - - /** - * Return a copy of the event with the specified source - * replacing the current source and the property name. - */ - public PropertyChangeEvent cloneWithSource(Model newSource, String newPropertyName) { - return new PropertyChangeEvent(newSource, newPropertyName, this.oldValue, this.newValue); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/StateChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/StateChangeEvent.java deleted file mode 100644 index 52e3690e69..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/StateChangeEvent.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import org.eclipse.jpt.utility.model.Model; - -/** - * A generic "state change" event gets delivered whenever a model changes to - * such extent that it cannot be delineated all aspects of it that have changed. - * A StateChangeEvent is sent as an argument to the StateChangeListener. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class StateChangeEvent extends ChangeEvent { - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a new state change event. - * - * @param source The object on which the event initially occurred. - */ - public StateChangeEvent(Model source) { - super(source); - } - - - // ********** standard state ********** - - @Override - public String getAspectName() { - return null; // the point of the event is that the name is unknown... - } - - - // ********** cloning ********** - - @Override - public StateChangeEvent cloneWithSource(Model newSource) { - return new StateChangeEvent(newSource); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/TreeChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/TreeChangeEvent.java deleted file mode 100644 index 2272020490..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/event/TreeChangeEvent.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.event; - -import org.eclipse.jpt.utility.model.Model; - -/** - * A "tree change" event gets delivered whenever a model changes a "bound" - * or "constrained" tree. A TreeChangeEvent is sent as an - * argument to the TreeChangeListener. - * - * Normally a TreeChangeEvent is accompanied by the tree name and a path - * to the part of the tree that was changed. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class TreeChangeEvent extends ChangeEvent { - - /** Name of the tree that changed. */ - private final String treeName; - - /** - * Path to the parent of the part of the tree that was changed. - * May be empty, if not known or if the entire tree changed. - */ - protected final Object[] path; - - private static final Object[] EMPTY_PATH = new Object[0]; - - private static final long serialVersionUID = 1L; - - - // ********** constructors ********** - - /** - * Construct a new tree change event. - * - * @param source The object on which the event initially occurred. - * @param treeName The programmatic name of the tree that was changed. - * @param path The path to the part of the tree that was changed. - */ - public TreeChangeEvent(Model source, String treeName, Object[] path) { - super(source); - if ((treeName == null) || (path == null)) { - throw new NullPointerException(); - } - this.treeName = treeName; - this.path = path; - } - - /** - * Construct a new tree change event. - * - * @param source The object on which the event initially occurred. - * @param treeName The programmatic name of the tree that was changed. - */ - public TreeChangeEvent(Model source, String treeName) { - this(source, treeName, EMPTY_PATH); - } - - - // ********** standard state ********** - - /** - * Return the programmatic name of the tree that was changed. - */ - public String getTreeName() { - return this.treeName; - } - - @Override - public String getAspectName() { - return this.treeName; - } - - /** - * Return the path to the part of the tree that was changed. - * May be empty, if not known. - */ - public Object[] getPath() { - return this.path; - } - - - // ********** cloning ********** - - @Override - public TreeChangeEvent cloneWithSource(Model newSource) { - return new TreeChangeEvent(newSource, this.treeName, this.path); - } - - /** - * Return a copy of the event with the specified source - * replacing the current source and the tree name. - */ - public TreeChangeEvent cloneWithSource(Model newSource, String newTreeName) { - return new TreeChangeEvent(newSource, newTreeName, this.path); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ChangeListener.java deleted file mode 100644 index d29a7a7de2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ChangeListener.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import java.util.EventListener; - -/** - * Marker interface. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface ChangeListener extends EventListener { - // nothing for now -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeAdapter.java deleted file mode 100644 index 88b1359e16..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeAdapter.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; - -/** - * Convenience implementation of CollectionChangeListener. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class CollectionChangeAdapter implements CollectionChangeListener { - - /** - * Default constructor. - */ - public CollectionChangeAdapter() { - super(); - } - - public void itemsAdded(CollectionChangeEvent event) { - // do nothing - } - - public void itemsRemoved(CollectionChangeEvent event) { - // do nothing - } - - public void collectionCleared(CollectionChangeEvent event) { - // do nothing - } - - public void collectionChanged(CollectionChangeEvent event) { - // do nothing - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeListener.java deleted file mode 100644 index 210388b923..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/CollectionChangeListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; - -/** - * A "collection change" event gets fired whenever a model changes a "bound" - * collection. You can register a CollectionChangeListener with a source - * model so as to be notified of any bound collection updates. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface CollectionChangeListener extends ChangeListener { - - /** - * This method gets called when items are added to a bound collection. - * - * @param event A CollectionChangeEvent describing the event source, - * the collection that changed, and the items that were added. - */ - void itemsAdded(CollectionChangeEvent event); - - /** - * This method gets called when items are removed from a bound collection. - * - * @param event A CollectionChangeEvent describing the event source, - * the collection that changed, and the items that were removed. - */ - void itemsRemoved(CollectionChangeEvent event); - - /** - * This method gets called when a bound collection is cleared. - * - * @param event A CollectionChangeEvent describing the event source - * and the collection that changed. - */ - void collectionCleared(CollectionChangeEvent event); - - /** - * This method gets called when a bound collection is changed in a manner - * that is not easily characterized by the other methods in this interface. - * - * @param event A CollectionChangeEvent describing the event source - * and the collection that changed. - */ - void collectionChanged(CollectionChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeAdapter.java deleted file mode 100644 index 052abc5cf4..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeAdapter.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.ListChangeEvent; - -/** - * Convenience implementation of ListChangeListener. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class ListChangeAdapter implements ListChangeListener { - - /** - * Default constructor. - */ - public ListChangeAdapter() { - super(); - } - - public void itemsAdded(ListChangeEvent event) { - // do nothing - } - - public void itemsRemoved(ListChangeEvent event) { - // do nothing - } - - public void itemsReplaced(ListChangeEvent event) { - // do nothing - } - - public void itemsMoved(ListChangeEvent event) { - // do nothing - } - - public void listCleared(ListChangeEvent event) { - // do nothing - } - - public void listChanged(ListChangeEvent event) { - // do nothing - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeListener.java deleted file mode 100644 index 74eab3a002..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ListChangeListener.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.ListChangeEvent; - -/** - * A "list change" event gets fired whenever a model changes a "bound" - * list. You can register a ListChangeListener with a source - * model so as to be notified of any bound list updates. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface ListChangeListener extends ChangeListener { - - /** - * This method gets called when items are added to a bound list. - * - * @param event A ListChangeEvent describing the event source, - * the list that changed, the items that were added, and the index - * at which the items were added. - */ - void itemsAdded(ListChangeEvent event); - - /** - * This method gets called when items are removed from a bound list. - * - * @param event A ListChangeEvent describing the event source, - * the list that changed, the items that were removed, and the index - * at which the items were removed. - */ - void itemsRemoved(ListChangeEvent event); - - /** - * This method gets called when items in a bound list are replaced. - * - * @param event A ListChangeEvent describing the event source, - * the list that changed, the items that were added, the items that were - * replaced, and the index at which the items were replaced. - */ - void itemsReplaced(ListChangeEvent event); - - /** - * This method gets called when items in a bound list are moved. - * - * @param event A ListChangeEvent describing the event source, - * the list that changed, and the indices of where items were moved - * from and to. - */ - void itemsMoved(ListChangeEvent event); - - /** - * This method gets called when a bound list is cleared. - * - * @param event A ListChangeEvent object describing the event source - * and the list that changed. - */ - void listCleared(ListChangeEvent event); - - /** - * This method gets called when a bound list is changed in a manner - * that is not easily characterized by the other methods in this interface. - * - * @param event A ListChangeEvent object describing the event source - * and the list that changed. - */ - void listChanged(ListChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/MultiMethodReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/MultiMethodReflectiveChangeListener.java deleted file mode 100644 index 9b69de5195..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/MultiMethodReflectiveChangeListener.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import java.lang.reflect.Method; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; - -/** - * This class is used by ReflectiveChangeListener when the requested listener - * needs to implement multiple methods (i.e. CollectionChangeListener, - * ListChangeListener, or TreeChangeListener). - */ -class MultiMethodReflectiveChangeListener - extends ReflectiveChangeListener - implements CollectionChangeListener, ListChangeListener, TreeChangeListener -{ - /** the methods we will invoke on the target object */ - private final Method addMethod; - private final Method removeMethod; - private final Method replaceMethod; // this can be null - private final Method moveMethod; // this can be null - private final Method clearMethod; - private final Method changeMethod; - - - /** - * The "replace" and "move" methods are optional. - */ - MultiMethodReflectiveChangeListener(Object target, Method addMethod, Method removeMethod, Method replaceMethod, Method moveMethod, Method clearMethod, Method changeMethod) { - super(target); - this.addMethod = addMethod; - this.removeMethod = removeMethod; - this.replaceMethod = replaceMethod; - this.moveMethod = moveMethod; - this.clearMethod = clearMethod; - this.changeMethod = changeMethod; - } - - /** - * No "replace" or "move" methods. - */ - MultiMethodReflectiveChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) { - this(target, addMethod, removeMethod, null, null, clearMethod, changeMethod); - } - - - // ********** CollectionChangeListener implementation ********** - - private void invoke(Method method, CollectionChangeEvent event) { - if (method.getParameterTypes().length == 0) { - ClassTools.executeMethod(method, this.target, EMPTY_COLLECTION_CHANGE_EVENT_ARRAY); - } else { - ClassTools.executeMethod(method, this.target, new CollectionChangeEvent[] {event}); - } - } - - public void itemsAdded(CollectionChangeEvent event) { - this.invoke(this.addMethod, event); - } - - public void itemsRemoved(CollectionChangeEvent event) { - this.invoke(this.removeMethod, event); - } - - public void collectionCleared(CollectionChangeEvent event) { - this.invoke(this.clearMethod, event); - } - - public void collectionChanged(CollectionChangeEvent event) { - this.invoke(this.changeMethod, event); - } - - - // ********** ListChangeListener implementation ********** - - private void invoke(Method method, ListChangeEvent event) { - if (method.getParameterTypes().length == 0) { - ClassTools.executeMethod(method, this.target, EMPTY_LIST_CHANGE_EVENT_ARRAY); - } else { - ClassTools.executeMethod(method, this.target, new ListChangeEvent[] {event}); - } - } - - public void itemsAdded(ListChangeEvent event) { - this.invoke(this.addMethod, event); - } - - public void itemsRemoved(ListChangeEvent event) { - this.invoke(this.removeMethod, event); - } - - public void itemsReplaced(ListChangeEvent event) { - this.invoke(this.replaceMethod, event); - } - - public void itemsMoved(ListChangeEvent event) { - this.invoke(this.moveMethod, event); - } - - public void listCleared(ListChangeEvent event) { - this.invoke(this.clearMethod, event); - } - - public void listChanged(ListChangeEvent event) { - this.invoke(this.changeMethod, event); - } - - - // ********** TreeChangeListener implementation ********** - - private void invoke(Method method, TreeChangeEvent event) { - if (method.getParameterTypes().length == 0) { - ClassTools.executeMethod(method, this.target, EMPTY_TREE_CHANGE_EVENT_ARRAY); - } else { - ClassTools.executeMethod(method, this.target, new TreeChangeEvent[] {event}); - } - } - - public void nodeAdded(TreeChangeEvent event) { - this.invoke(this.addMethod, event); - } - - public void nodeRemoved(TreeChangeEvent event) { - this.invoke(this.removeMethod, event); - } - - public void treeCleared(TreeChangeEvent event) { - this.invoke(this.clearMethod, event); - } - - public void treeChanged(TreeChangeEvent event) { - this.invoke(this.changeMethod, event); - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/PropertyChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/PropertyChangeListener.java deleted file mode 100644 index f76bed7d39..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/PropertyChangeListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; - -/** - * A "property change" event gets fired whenever a model changes a "bound" - * property. You can register a PropertyChangeListener with a source - * model so as to be notified of any bound property updates. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface PropertyChangeListener extends ChangeListener { - - /** - * This method gets called when a model has changed a bound property. - * - * @param event A StateChangeEvent describing the event source - * and the property's old and new values. - */ - void propertyChanged(PropertyChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ReflectiveChangeListener.java deleted file mode 100644 index 0cab7d7cbd..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/ReflectiveChangeListener.java +++ /dev/null @@ -1,312 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import java.lang.reflect.Method; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.model.event.ChangeEvent; -import org.eclipse.jpt.utility.model.event.CollectionChangeEvent; -import org.eclipse.jpt.utility.model.event.ListChangeEvent; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; - -/** - * This factory builds listeners that reflectively forward ChangeEvents. - * If you are worried about having too many little classes that have to be - * loaded and maintained by the class loader, you can use one of these. - * Of course, this comes with the additional overhead of reflection.... - * Also note that the validity of the method name is not checked at compile - * time, but at runtime; although we *do* check the method as soon as the - * listener is instantiated. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public abstract class ReflectiveChangeListener { - - /** the target object on which we will invoke the method */ - protected final Object target; - - - protected static final Class<StateChangeEvent> STATE_CHANGE_EVENT_CLASS = StateChangeEvent.class; - @SuppressWarnings("unchecked") - protected static final Class<StateChangeEvent>[] STATE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {STATE_CHANGE_EVENT_CLASS}; - protected static final StateChangeEvent[] EMPTY_STATE_CHANGE_EVENT_ARRAY = new StateChangeEvent[0]; - - protected static final Class<PropertyChangeEvent> PROPERTY_CHANGE_EVENT_CLASS = PropertyChangeEvent.class; - @SuppressWarnings("unchecked") - protected static final Class<PropertyChangeEvent>[] PROPERTY_CHANGE_EVENT_CLASS_ARRAY = new Class[] {PROPERTY_CHANGE_EVENT_CLASS}; - protected static final PropertyChangeEvent[] EMPTY_PROPERTY_CHANGE_EVENT_ARRAY = new PropertyChangeEvent[0]; - - protected static final Class<CollectionChangeEvent> COLLECTION_CHANGE_EVENT_CLASS = CollectionChangeEvent.class; - @SuppressWarnings("unchecked") - protected static final Class<CollectionChangeEvent>[] COLLECTION_CHANGE_EVENT_CLASS_ARRAY = new Class[] {COLLECTION_CHANGE_EVENT_CLASS}; - protected static final CollectionChangeEvent[] EMPTY_COLLECTION_CHANGE_EVENT_ARRAY = new CollectionChangeEvent[0]; - - protected static final Class<ListChangeEvent> LIST_CHANGE_EVENT_CLASS = ListChangeEvent.class; - @SuppressWarnings("unchecked") - protected static final Class<ListChangeEvent>[] LIST_CHANGE_EVENT_CLASS_ARRAY = new Class[] {LIST_CHANGE_EVENT_CLASS}; - protected static final ListChangeEvent[] EMPTY_LIST_CHANGE_EVENT_ARRAY = new ListChangeEvent[0]; - - protected static final Class<TreeChangeEvent> TREE_CHANGE_EVENT_CLASS = TreeChangeEvent.class; - @SuppressWarnings("unchecked") - protected static final Class<TreeChangeEvent>[] TREE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {TREE_CHANGE_EVENT_CLASS}; - protected static final TreeChangeEvent[] EMPTY_TREE_CHANGE_EVENT_ARRAY = new TreeChangeEvent[0]; - - - - // ********** helper methods ********** - - /** - * Find and return a method implemented by the target that can be invoked - * reflectively when a change event occurs. - */ - private static Method findChangeListenerMethod(Object target, String methodName, Class<? extends ChangeEvent>[] eventClassArray) { - Method method; - try { - method = ClassTools.method(target, methodName, eventClassArray); - } catch (NoSuchMethodException ex1) { - try { - method = ClassTools.method(target, methodName); - } catch (NoSuchMethodException ex2) { - throw new RuntimeException(ex2); // "checked" exceptions bite - } - } - return method; - } - - /** - * Check whether the specified method is suitable for being invoked when a - * change event has occurred. Throw an exception if it is not suitable. - */ - private static void checkChangeListenerMethod(Method method, Class<? extends ChangeEvent> eventClass) { - Class<?>[] parmTypes = method.getParameterTypes(); - int parmTypesLength = parmTypes.length; - if (parmTypesLength == 0) { - return; - } - if ((parmTypesLength == 1) && parmTypes[0].isAssignableFrom(eventClass)) { - return; - } - throw new IllegalArgumentException(method.toString()); - } - - - // ********** factory methods: StateChangeListener ********** - - /** - * Construct a state change listener that will invoke the specified method - * on the specified target. - */ - public static StateChangeListener buildStateChangeListener(Object target, Method method) { - checkChangeListenerMethod(method, STATE_CHANGE_EVENT_CLASS); - return new SingleMethodReflectiveChangeListener(target, method); - } - - /** - * Construct a state change listener that will invoke the specified method - * on the specified target. If a single-argument method with the specified - * name and appropriate argument is found, it will be invoked; otherwise, - * a zero-argument method with the specified name will be invoked. - */ - public static StateChangeListener buildStateChangeListener(Object target, String methodName) { - return buildStateChangeListener(target, findChangeListenerMethod(target, methodName, STATE_CHANGE_EVENT_CLASS_ARRAY)); - } - - - // ********** factory methods: PropertyChangeListener ********** - - /** - * Construct a property change listener that will invoke the specified method - * on the specified target. - */ - public static PropertyChangeListener buildPropertyChangeListener(Object target, Method method) { - checkChangeListenerMethod(method, PROPERTY_CHANGE_EVENT_CLASS); - return new SingleMethodReflectiveChangeListener(target, method); - } - - /** - * Construct a property change listener that will invoke the specified method - * on the specified target. If a single-argument method with the specified - * name and appropriate argument is found, it will be invoked; otherwise, - * a zero-argument method with the specified name will be invoked. - */ - public static PropertyChangeListener buildPropertyChangeListener(Object target, String methodName) { - return buildPropertyChangeListener(target, findChangeListenerMethod(target, methodName, PROPERTY_CHANGE_EVENT_CLASS_ARRAY)); - } - - - // ********** factory methods: CollectionChangeListener ********** - - /** - * Construct a collection change listener that will invoke the specified methods - * on the specified target. - */ - public static CollectionChangeListener buildCollectionChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) { - checkChangeListenerMethod(addMethod, COLLECTION_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(removeMethod, COLLECTION_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(clearMethod, COLLECTION_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(changeMethod, COLLECTION_CHANGE_EVENT_CLASS); - return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, clearMethod, changeMethod); - } - - /** - * Construct a collection change listener that will invoke the specified method - * on the specified target for any change event. - */ - public static CollectionChangeListener buildCollectionChangeListener(Object target, Method method) { - return buildCollectionChangeListener(target, method, method, method, method); - } - - /** - * Construct a collection change listener that will invoke the specified methods - * on the specified target for change events. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static CollectionChangeListener buildCollectionChangeListener(Object target, String addMethodName, String removeMethodName, String clearMethodName, String changeMethodName) { - return buildCollectionChangeListener( - target, - findChangeListenerMethod(target, addMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, removeMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, clearMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, changeMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY) - ); - } - - /** - * Construct a collection change listener that will invoke the specified method - * on the specified target for any change event. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static CollectionChangeListener buildCollectionChangeListener(Object target, String methodName) { - return buildCollectionChangeListener(target, findChangeListenerMethod(target, methodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY)); - } - - - // ********** factory methods: ListChangeListener ********** - - /** - * Construct a list change listener that will invoke the specified methods - * on the specified target. - */ - public static ListChangeListener buildListChangeListener(Object target, Method addMethod, Method removeMethod, Method replaceMethod, Method moveMethod, Method clearMethod, Method changeMethod) { - checkChangeListenerMethod(addMethod, LIST_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(removeMethod, LIST_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(replaceMethod, LIST_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(moveMethod, LIST_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(clearMethod, LIST_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(changeMethod, LIST_CHANGE_EVENT_CLASS); - return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, replaceMethod, moveMethod, clearMethod, changeMethod); - } - - /** - * Construct a list change listener that will invoke the specified method - * on the specified target for any change event. - */ - public static ListChangeListener buildListChangeListener(Object target, Method method) { - return buildListChangeListener(target, method, method, method, method, method, method); - } - - /** - * Construct a list change listener that will invoke the specified methods - * on the specified target for change events. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static ListChangeListener buildListChangeListener(Object target, String addMethodName, String removeMethodName, String replaceMethodName, String moveMethodName, String clearMethodName, String changeMethodName) { - return buildListChangeListener( - target, - findChangeListenerMethod(target, addMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, removeMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, replaceMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, moveMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, clearMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, changeMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY) - ); - } - - /** - * Construct a list change listener that will invoke the specified method - * on the specified target for any change event. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static ListChangeListener buildListChangeListener(Object target, String methodName) { - return buildListChangeListener(target, findChangeListenerMethod(target, methodName, LIST_CHANGE_EVENT_CLASS_ARRAY)); - } - - - // ********** factory methods: TreeChangeListener ********** - - /** - * Construct a tree change listener that will invoke the specified methods - * on the specified target. - */ - public static TreeChangeListener buildTreeChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) { - checkChangeListenerMethod(addMethod, TREE_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(removeMethod, TREE_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(clearMethod, TREE_CHANGE_EVENT_CLASS); - checkChangeListenerMethod(changeMethod, TREE_CHANGE_EVENT_CLASS); - return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, clearMethod, changeMethod); - } - - /** - * Construct a tree change listener that will invoke the specified method - * on the specified target for any change event. - */ - public static TreeChangeListener buildTreeChangeListener(Object target, Method method) { - return buildTreeChangeListener(target, method, method, method, method); - } - - /** - * Construct a tree change listener that will invoke the specified methods - * on the specified target for change events. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static TreeChangeListener buildTreeChangeListener(Object target, String addMethodName, String removeMethodName, String clearMethodName, String changeMethodName) { - return buildTreeChangeListener( - target, - findChangeListenerMethod(target, addMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, removeMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, clearMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY), - findChangeListenerMethod(target, changeMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY) - ); - } - - /** - * Construct a tree change listener that will invoke the specified method - * on the specified target for any change event. If a single-argument method - * with the specified name and appropriate argument is found, it will be invoked; - * otherwise, a zero-argument method with the specified name will be invoked. - */ - public static TreeChangeListener buildTreeChangeListener(Object target, String methodName) { - return buildTreeChangeListener(target, findChangeListenerMethod(target, methodName, TREE_CHANGE_EVENT_CLASS_ARRAY)); - } - - - // ********** constructor ********** - - /** - * Construct a listener that will invoke the specified method - * on the specified target. - */ - protected ReflectiveChangeListener(Object target) { - super(); - this.target = target; - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/SingleMethodReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/SingleMethodReflectiveChangeListener.java deleted file mode 100644 index ba7ea243e2..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/SingleMethodReflectiveChangeListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import java.lang.reflect.Method; -import org.eclipse.jpt.utility.internal.ClassTools; -import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.utility.model.event.StateChangeEvent; - -/** - * This class is used by ReflectiveChangeListener when the requested listener - * need only implement a single method (i.e. StateChangeListener or - * PropertyChangeListener). - */ -class SingleMethodReflectiveChangeListener - extends ReflectiveChangeListener - implements StateChangeListener, PropertyChangeListener -{ - - /** the method we will invoke on the target object */ - private final Method method; - /** cache the number of arguments */ - private final boolean methodIsZeroArgument; - - SingleMethodReflectiveChangeListener(Object target, Method method) { - super(target); - this.method = method; - this.methodIsZeroArgument = method.getParameterTypes().length == 0; - } - - - // ********** StateChangeListener implementation ********** - - public void stateChanged(StateChangeEvent event) { - if (this.methodIsZeroArgument) { - ClassTools.executeMethod(this.method, this.target, EMPTY_STATE_CHANGE_EVENT_ARRAY); - } else { - ClassTools.executeMethod(this.method, this.target, new StateChangeEvent[] {event}); - } - } - - - // ********** PropertyChangeListener implementation ********** - - public void propertyChanged(PropertyChangeEvent event) { - if (this.methodIsZeroArgument) { - ClassTools.executeMethod(this.method, this.target, EMPTY_PROPERTY_CHANGE_EVENT_ARRAY); - } else { - ClassTools.executeMethod(this.method, this.target, new PropertyChangeEvent[] {event}); - } - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/StateChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/StateChangeListener.java deleted file mode 100644 index 1ce6ba5d69..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/StateChangeListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.StateChangeEvent; - -/** - * A generic "state change" event gets delivered whenever a model changes to - * such extent that it cannot be delineated all aspects of it that have changed. - * You can register a StateChangeListener with a source model so as to be notified - * of any such changes. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface StateChangeListener extends ChangeListener { - - /** - * This method gets called when a model has changed in some general fashion. - * - * @param event A StateChangeEvent describing the event source. - */ - void stateChanged(StateChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeAdapter.java deleted file mode 100644 index 3b46202fd1..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeAdapter.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; - -/** - * Convenience implementation of TreeChangeListener. - * - * Provisional API: This class is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public class TreeChangeAdapter implements TreeChangeListener { - - /** - * Default constructor. - */ - public TreeChangeAdapter() { - super(); - } - - public void nodeAdded(TreeChangeEvent event) { - // do nothing - } - - public void nodeRemoved(TreeChangeEvent event) { - // do nothing - } - - public void treeCleared(TreeChangeEvent event) { - // do nothing - } - - public void treeChanged(TreeChangeEvent event) { - // do nothing - } - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeListener.java deleted file mode 100644 index 7591f9df78..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/listener/TreeChangeListener.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.listener; - -import org.eclipse.jpt.utility.model.event.TreeChangeEvent; - -/** - * A "tree change" event gets fired whenever a model changes a "bound" - * tree. You can register a TreeChangeListener with a source - * model so as to be notified of any bound tree updates. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface TreeChangeListener extends ChangeListener { - - /** - * This method gets called when a node is added to a bound tree. - * - * @param event A TreeChangeEvent describing the event source, - * the tree that changed, and the path to the node that was added. - */ - void nodeAdded(TreeChangeEvent event); - - /** - * This method gets called when a node is removed from a bound tree. - * - * @param event A TreeChangeEvent describing the event source, - * the tree that changed, and the path to the node that was removed. - */ - void nodeRemoved(TreeChangeEvent event); - - /** - * This method gets called when a bound tree is cleared. - * - * @param event A TreeChangeEvent describing the event source, - * the tree that changed, and an empty path. - */ - void treeCleared(TreeChangeEvent event); - - /** - * This method gets called when a portion of a bound tree is changed in - * a manner that is not easily characterized by the other methods in this - * interface. - * - * @param event A TreeChangeEvent describing the event source, - * the tree that changed, and the path to the branch of the - * tree that changed. - */ - void treeChanged(TreeChangeEvent event); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/CollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/CollectionValueModel.java deleted file mode 100644 index ba25cf9262..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/CollectionValueModel.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.model.Model; - -/** - * Interface used to abstract collection accessing and - * change notification and make it more pluggable. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface CollectionValueModel<E> - extends Model, Iterable<E> -{ - - /** - * Return the collection's values. - */ - Iterator<E> iterator(); - String VALUES = "values"; - - /** - * Return the size of the collection value. - */ - int size(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/ListValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/ListValueModel.java deleted file mode 100644 index 65eaa7723b..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/ListValueModel.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -import java.util.Iterator; -import java.util.ListIterator; -import org.eclipse.jpt.utility.model.Model; - -/** - * Interface used to abstract list accessing and - * change notification and make it more pluggable. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface ListValueModel<E> - extends Model, Iterable<E> -{ - /** - * Return the list's values. - */ - Iterator<E> iterator(); - String LIST_VALUES = "list values"; - - /** - * Return the list's values. - */ - ListIterator<E> listIterator(); - - /** - * Return the size of the list. - */ - int size(); - - /** - * Return the item at the specified index of the list. - */ - E get(int index); - - /** - * Return the list's values. - */ - Object[] toArray(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/PropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/PropertyValueModel.java deleted file mode 100644 index 82ee3c0096..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/PropertyValueModel.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -import org.eclipse.jpt.utility.model.Model; - -/** - * Interface used to abstract property accessing and - * change notification and make it more pluggable. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface PropertyValueModel<T> - extends Model -{ - - /** - * Return the property's value. - */ - T getValue(); - String VALUE = "value"; - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeNodeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeNodeValueModel.java deleted file mode 100644 index a6bcea8cdf..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeNodeValueModel.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -/** - * Extend WritablePropertyValueModel to better support TreeModelAdapter. - * - * Implementors of this interface should fire a "state change" event - * whenever the node's internal state changes in a way that the - * tree listeners should be notified. - * - * Implementors of this interface should also fire a "value property change" - * event whenever the node's value changes. Typically, only nodes that - * hold "primitive" data will fire this event. - * - * @see org.eclipse.jpt.utility.internal.model.value.AbstractTreeNodeValueModel - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface TreeNodeValueModel<T> - extends WritablePropertyValueModel<T> -{ - - /** - * Return the node's parent node; null if the node - * is the root. - */ - TreeNodeValueModel<T> parent(); - - /** - * Return the path to the node. - */ - TreeNodeValueModel<T>[] path(); - - /** - * Return a list value model of the node's child nodes. - */ - ListValueModel<TreeNodeValueModel<T>> childrenModel(); - - /** - * Return the node's child at the specified index. - */ - TreeNodeValueModel<T> child(int index); - - /** - * Return the size of the node's list of children. - */ - int childrenSize(); - - /** - * Return the index in the node's list of children of the specified child. - */ - int indexOfChild(TreeNodeValueModel<T> child); - - /** - * Return whether the node is a leaf (i.e. it has no children) - */ - boolean isLeaf(); - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeValueModel.java deleted file mode 100644 index ec87a2771a..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/TreeValueModel.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -import java.util.Iterator; -import org.eclipse.jpt.utility.model.Model; - -/** - * Interface used to abstract tree accessing and - * change notification and make it more pluggable. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface TreeValueModel<E> - extends Model -{ - /** - * Return the tree's nodes. - */ - Iterator<E> nodes(); - String NODES = "nodes"; - -} diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/WritablePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/WritablePropertyValueModel.java deleted file mode 100644 index c2ddacebe4..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/model/value/WritablePropertyValueModel.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.model.value; - -/** - * Extend ValueModel to allow the setting of the property's value. - * - * Provisional API: This interface is part of an interim API that is still - * under development and expected to change significantly before reaching - * stability. It is available at this early stage to solicit feedback from - * pioneering adopters on the understanding that any code that uses this API - * will almost certainly be broken (repeatedly) as the API evolves. - */ -public interface WritablePropertyValueModel<T> - extends PropertyValueModel<T> -{ - - /** - * Set the value and fire a property change notification. - * @see PropertyValueModel#VALUE - */ - void setValue(T value); - -} |