src/jdk/nashorn/internal/runtime/ListAdapter.java

Print this page




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.runtime;
  27 
  28 import java.util.AbstractList;
  29 import java.util.Deque;
  30 import java.util.Iterator;
  31 import java.util.ListIterator;
  32 import java.util.NoSuchElementException;
  33 import java.util.RandomAccess;
  34 import java.util.concurrent.Callable;
  35 import jdk.nashorn.api.scripting.JSObject;

  36 import jdk.nashorn.internal.runtime.linker.Bootstrap;
  37 import jdk.nashorn.internal.runtime.linker.InvokeByName;
  38 
  39 /**
  40  * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
  41  * {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
  42  * methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
  43  * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
  44  * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
  45  * custom script object that implements an Array-like API can have a background data representation that is optimized
  46  * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the
  47  * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue
  48  * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script
  49  * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
  50  * {@code pop}.
  51  */
  52 public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
  53     // These add to the back and front of the list
  54     private static final Object PUSH    = new Object();
  55     private static InvokeByName getPUSH() {


 118                     }
 119                 });
 120     }
 121 
 122     /** wrapped object */
 123     protected final Object obj;
 124 
 125     // allow subclasses only in this package
 126     ListAdapter(final Object obj) {
 127         this.obj = obj;
 128     }
 129 
 130     /**
 131      * Factory to create a ListAdapter for a given script object.
 132      *
 133      * @param obj script object to wrap as a ListAdapter
 134      * @return A ListAdapter wrapper object
 135      */
 136     public static ListAdapter create(final Object obj) {
 137         if (obj instanceof ScriptObject) {
 138             return new ScriptObjectListAdapter((ScriptObject)obj);

 139         } else if (obj instanceof JSObject) {
 140             return new JSObjectListAdapter((JSObject)obj);
 141         } else {
 142             throw new IllegalArgumentException("ScriptObject or JSObject expected");
 143         }
 144     }
 145 
 146     @Override
 147     public final Object get(final int index) {
 148         checkRange(index);
 149         return getAt(index);
 150     }
 151 
 152     /**
 153      * Get object at an index
 154      * @param index index in list
 155      * @return object
 156      */
 157     protected abstract Object getAt(final int index);
 158 




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.runtime;
  27 
  28 import java.util.AbstractList;
  29 import java.util.Deque;
  30 import java.util.Iterator;
  31 import java.util.ListIterator;
  32 import java.util.NoSuchElementException;
  33 import java.util.RandomAccess;
  34 import java.util.concurrent.Callable;
  35 import jdk.nashorn.api.scripting.JSObject;
  36 import jdk.nashorn.api.scripting.ScriptObjectMirror;
  37 import jdk.nashorn.internal.runtime.linker.Bootstrap;
  38 import jdk.nashorn.internal.runtime.linker.InvokeByName;
  39 
  40 /**
  41  * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
  42  * {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
  43  * methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
  44  * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
  45  * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
  46  * custom script object that implements an Array-like API can have a background data representation that is optimized
  47  * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the
  48  * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue
  49  * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script
  50  * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
  51  * {@code pop}.
  52  */
  53 public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
  54     // These add to the back and front of the list
  55     private static final Object PUSH    = new Object();
  56     private static InvokeByName getPUSH() {


 119                     }
 120                 });
 121     }
 122 
 123     /** wrapped object */
 124     protected final Object obj;
 125 
 126     // allow subclasses only in this package
 127     ListAdapter(final Object obj) {
 128         this.obj = obj;
 129     }
 130 
 131     /**
 132      * Factory to create a ListAdapter for a given script object.
 133      *
 134      * @param obj script object to wrap as a ListAdapter
 135      * @return A ListAdapter wrapper object
 136      */
 137     public static ListAdapter create(final Object obj) {
 138         if (obj instanceof ScriptObject) {
 139             final Object mirror = ScriptObjectMirror.wrap(obj, Context.getGlobal());
 140             return new JSObjectListAdapter((JSObject)mirror);
 141         } else if (obj instanceof JSObject) {
 142             return new JSObjectListAdapter((JSObject)obj);
 143         } else {
 144             throw new IllegalArgumentException("ScriptObject or JSObject expected");
 145         }
 146     }
 147 
 148     @Override
 149     public final Object get(final int index) {
 150         checkRange(index);
 151         return getAt(index);
 152     }
 153 
 154     /**
 155      * Get object at an index
 156      * @param index index in list
 157      * @return object
 158      */
 159     protected abstract Object getAt(final int index);
 160