Several fixes to TextPane:
* Fix previous changes that made ImageNode (and ComponentNode) into subclasses
  of Block so that they could be inserted directly into a document.  This was
  shown to be a flawed strategy, and ComponentNode was fixed by a previous
  change.  Make ImageNode back into a direct subclass of Node.
* Add an implementation of "getCharacters" to ImageNode to satisfy the abstract
  declaration of Node (this is relatively new).
* Change Document to allow ImageNode (and previously ComponentNode) as possible
  direct inserts into a Document
* Add a method to ClassUtils to check any number of possible classes for an
  "instanceOf" check, and use this in Document.
* Unrelated, but discovered in the same test program:  fix CharUtils.selectWord
  to gracefully handle a null input sequence.


git-svn-id: https://svn.apache.org/repos/asf/pivot/trunk@1839358 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/org/apache/pivot/util/CharUtils.java b/core/src/org/apache/pivot/util/CharUtils.java
index ce3b188..6f1b1e4 100644
--- a/core/src/org/apache/pivot/util/CharUtils.java
+++ b/core/src/org/apache/pivot/util/CharUtils.java
@@ -38,9 +38,13 @@
      * @param start The starting location from which to get a "word" selection.

      * @return The {@link CharSpan} (start and length) that describes the selected

      * word around the given starting point, or {@code null} if a word selection

-     * cannot be made.

+     * cannot be made (which could be because the input sequence is {@code null}).

      */

     public static CharSpan selectWord(final CharSequence sequence, final int start) {

+        if (sequence == null) {

+            return null;

+        }

+

         int length = sequence.length();

         int adjustedStart = start;

         char ch;

diff --git a/core/src/org/apache/pivot/util/ClassUtils.java b/core/src/org/apache/pivot/util/ClassUtils.java
index 9e6e822..de2ebda 100644
--- a/core/src/org/apache/pivot/util/ClassUtils.java
+++ b/core/src/org/apache/pivot/util/ClassUtils.java
@@ -73,4 +73,22 @@
             + Integer.toHexString(System.identityHashCode(obj));

     }

 

+    /**

+     * Multi-class version of the <tt>instanceof</tt> operator.

+     * <p> Specifically checks if the given object is an instance of any of the

+     * given classes.

+     * @param obj The (non-null) object to test.

+     * @param clazz The list of classes.

+     * @return <tt>true</tt> if the object is non-null and an instance of ANY of

+     * the given classes, <tt>false</tt> otherwise.

+     */

+    public static boolean instanceOf(Object obj, Class<?> ...clazz) {

+        for (Class<?> cls : clazz) {

+            if (cls.isInstance(obj)) {

+                return true;

+            }

+        }

+        return false;

+    }

+

 }

diff --git a/wtk/src/org/apache/pivot/wtk/text/Document.java b/wtk/src/org/apache/pivot/wtk/text/Document.java
index 0de2258..df329c7 100644
--- a/wtk/src/org/apache/pivot/wtk/text/Document.java
+++ b/wtk/src/org/apache/pivot/wtk/text/Document.java
@@ -16,6 +16,8 @@
  */
 package org.apache.pivot.wtk.text;
 
+import org.apache.pivot.util.ClassUtils;
+
 /**
  * Node representing the root of an element hierarchy.
  */
@@ -40,10 +42,12 @@
 
     @Override
     public void insert(final Node node, final int index) {
-        if (!(node instanceof Block) && !(node instanceof ComponentNode)) {
+        if (!ClassUtils.instanceOf(node, Block.class, ComponentNode.class, ImageNode.class)) {
             throw new IllegalArgumentException("Child node ("
                 + node.getClass().getSimpleName() + ") must be an instance of "
-                + Block.class.getName() + " or " + ComponentNode.class.getName());
+                + Block.class.getName() + " or "
+                + ComponentNode.class.getName() + " or "
+                + ImageNode.class.getName());
         }
 
         super.insert(node, index);
diff --git a/wtk/src/org/apache/pivot/wtk/text/ImageNode.java b/wtk/src/org/apache/pivot/wtk/text/ImageNode.java
index dab0e30..1f0b77f 100644
--- a/wtk/src/org/apache/pivot/wtk/text/ImageNode.java
+++ b/wtk/src/org/apache/pivot/wtk/text/ImageNode.java
@@ -27,7 +27,7 @@
 /**
  * Node representing an image to be inserted into a {@link TextPane}.
  */
-public class ImageNode extends Block {
+public class ImageNode extends Node {
     private Image image = null;
 
     private ImageNodeListener.Listeners imageNodeListeners = new ImageNodeListener.Listeners();
@@ -109,7 +109,7 @@
     }
 
     @Override
-    public Element getRange(int offset, int characterCount) {
+    public Node getRange(int offset, int characterCount) {
         Utils.checkIndexBounds(offset, 0, 1);
 
         if (characterCount != 1) {
@@ -120,7 +120,12 @@
     }
 
     @Override
-    public Element duplicate(boolean recursive) {
+    public CharSequence getCharacters() {
+        return "";
+    }
+
+    @Override
+    public Node duplicate(boolean recursive) {
         return new ImageNode(this);
     }