1.1 --- a/core/pom.xml Tue Feb 05 16:40:01 2013 +0100
1.2 +++ b/core/pom.xml Tue Feb 05 17:04:22 2013 +0100
1.3 @@ -38,6 +38,7 @@
1.4 <dependency>
1.5 <groupId>org.netbeans.api</groupId>
1.6 <artifactId>org-openide-util-lookup</artifactId>
1.7 + <scope>provided</scope>
1.8 </dependency>
1.9 </dependencies>
1.10 <description>Contains esential annotations for associating JavaScript code with
2.1 --- a/emul/compact/pom.xml Tue Feb 05 16:40:01 2013 +0100
2.2 +++ b/emul/compact/pom.xml Tue Feb 05 17:04:22 2013 +0100
2.3 @@ -27,6 +27,11 @@
2.4 <version>${project.version}</version>
2.5 <scope>test</scope>
2.6 </dependency>
2.7 + <dependency>
2.8 + <groupId>org.netbeans.api</groupId>
2.9 + <artifactId>org-openide-util-lookup</artifactId>
2.10 + <scope>test</scope>
2.11 + </dependency>
2.12 </dependencies>
2.13 <build>
2.14 <plugins>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/emul/compact/src/main/java/java/beans/ChangeListenerMap.java Tue Feb 05 17:04:22 2013 +0100
3.3 @@ -0,0 +1,248 @@
3.4 +/*
3.5 + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.7 + *
3.8 + * This code is free software; you can redistribute it and/or modify it
3.9 + * under the terms of the GNU General Public License version 2 only, as
3.10 + * published by the Free Software Foundation. Oracle designates this
3.11 + * particular file as subject to the "Classpath" exception as provided
3.12 + * by Oracle in the LICENSE file that accompanied this code.
3.13 + *
3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.17 + * version 2 for more details (a copy is included in the LICENSE file that
3.18 + * accompanied this code).
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License version
3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.23 + *
3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.25 + * or visit www.oracle.com if you need additional information or have any
3.26 + * questions.
3.27 + */
3.28 +package java.beans;
3.29 +
3.30 +import java.util.ArrayList;
3.31 +import java.util.Collections;
3.32 +import java.util.EventListener;
3.33 +import java.util.EventListenerProxy;
3.34 +import java.util.HashMap;
3.35 +import java.util.List;
3.36 +import java.util.Map;
3.37 +import java.util.Map.Entry;
3.38 +import java.util.Set;
3.39 +import org.apidesign.bck2brwsr.emul.lang.System;
3.40 +
3.41 +/**
3.42 + * This is an abstract class that provides base functionality
3.43 + * for the {@link PropertyChangeSupport PropertyChangeSupport} class
3.44 + * and the {@link VetoableChangeSupport VetoableChangeSupport} class.
3.45 + *
3.46 + * @see PropertyChangeListenerMap
3.47 + * @see VetoableChangeListenerMap
3.48 + *
3.49 + * @author Sergey A. Malenkov
3.50 + */
3.51 +abstract class ChangeListenerMap<L extends EventListener> {
3.52 + private Map<String, L[]> map;
3.53 +
3.54 + /**
3.55 + * Creates an array of listeners.
3.56 + * This method can be optimized by using
3.57 + * the same instance of the empty array
3.58 + * when {@code length} is equal to {@code 0}.
3.59 + *
3.60 + * @param length the array length
3.61 + * @return an array with specified length
3.62 + */
3.63 + protected abstract L[] newArray(int length);
3.64 +
3.65 + /**
3.66 + * Creates a proxy listener for the specified property.
3.67 + *
3.68 + * @param name the name of the property to listen on
3.69 + * @param listener the listener to process events
3.70 + * @return a proxy listener
3.71 + */
3.72 + protected abstract L newProxy(String name, L listener);
3.73 +
3.74 + /**
3.75 + * Adds a listener to the list of listeners for the specified property.
3.76 + * This listener is called as many times as it was added.
3.77 + *
3.78 + * @param name the name of the property to listen on
3.79 + * @param listener the listener to process events
3.80 + */
3.81 + public final synchronized void add(String name, L listener) {
3.82 + if (this.map == null) {
3.83 + this.map = new HashMap<String, L[]>();
3.84 + }
3.85 + L[] array = this.map.get(name);
3.86 + int size = (array != null)
3.87 + ? array.length
3.88 + : 0;
3.89 +
3.90 + L[] clone = newArray(size + 1);
3.91 + clone[size] = listener;
3.92 + if (array != null) {
3.93 + System.arraycopy(array, 0, clone, 0, size);
3.94 + }
3.95 + this.map.put(name, clone);
3.96 + }
3.97 +
3.98 + /**
3.99 + * Removes a listener from the list of listeners for the specified property.
3.100 + * If the listener was added more than once to the same event source,
3.101 + * this listener will be notified one less time after being removed.
3.102 + *
3.103 + * @param name the name of the property to listen on
3.104 + * @param listener the listener to process events
3.105 + */
3.106 + public final synchronized void remove(String name, L listener) {
3.107 + if (this.map != null) {
3.108 + L[] array = this.map.get(name);
3.109 + if (array != null) {
3.110 + for (int i = 0; i < array.length; i++) {
3.111 + if (listener.equals(array[i])) {
3.112 + int size = array.length - 1;
3.113 + if (size > 0) {
3.114 + L[] clone = newArray(size);
3.115 + System.arraycopy(array, 0, clone, 0, i);
3.116 + System.arraycopy(array, i + 1, clone, i, size - i);
3.117 + this.map.put(name, clone);
3.118 + }
3.119 + else {
3.120 + this.map.remove(name);
3.121 + if (this.map.isEmpty()) {
3.122 + this.map = null;
3.123 + }
3.124 + }
3.125 + break;
3.126 + }
3.127 + }
3.128 + }
3.129 + }
3.130 + }
3.131 +
3.132 + /**
3.133 + * Returns the list of listeners for the specified property.
3.134 + *
3.135 + * @param name the name of the property
3.136 + * @return the corresponding list of listeners
3.137 + */
3.138 + public final synchronized L[] get(String name) {
3.139 + return (this.map != null)
3.140 + ? this.map.get(name)
3.141 + : null;
3.142 + }
3.143 +
3.144 + /**
3.145 + * Sets new list of listeners for the specified property.
3.146 + *
3.147 + * @param name the name of the property
3.148 + * @param listeners new list of listeners
3.149 + */
3.150 + public final void set(String name, L[] listeners) {
3.151 + if (listeners != null) {
3.152 + if (this.map == null) {
3.153 + this.map = new HashMap<String, L[]>();
3.154 + }
3.155 + this.map.put(name, listeners);
3.156 + }
3.157 + else if (this.map != null) {
3.158 + this.map.remove(name);
3.159 + if (this.map.isEmpty()) {
3.160 + this.map = null;
3.161 + }
3.162 + }
3.163 + }
3.164 +
3.165 + /**
3.166 + * Returns all listeners in the map.
3.167 + *
3.168 + * @return an array of all listeners
3.169 + */
3.170 + public final synchronized L[] getListeners() {
3.171 + if (this.map == null) {
3.172 + return newArray(0);
3.173 + }
3.174 + List<L> list = new ArrayList<L>();
3.175 +
3.176 + L[] listeners = this.map.get(null);
3.177 + if (listeners != null) {
3.178 + for (L listener : listeners) {
3.179 + list.add(listener);
3.180 + }
3.181 + }
3.182 + for (Entry<String, L[]> entry : this.map.entrySet()) {
3.183 + String name = entry.getKey();
3.184 + if (name != null) {
3.185 + for (L listener : entry.getValue()) {
3.186 + list.add(newProxy(name, listener));
3.187 + }
3.188 + }
3.189 + }
3.190 + return list.toArray(newArray(list.size()));
3.191 + }
3.192 +
3.193 + /**
3.194 + * Returns listeners that have been associated with the named property.
3.195 + *
3.196 + * @param name the name of the property
3.197 + * @return an array of listeners for the named property
3.198 + */
3.199 + public final L[] getListeners(String name) {
3.200 + if (name != null) {
3.201 + L[] listeners = get(name);
3.202 + if (listeners != null) {
3.203 + return listeners.clone();
3.204 + }
3.205 + }
3.206 + return newArray(0);
3.207 + }
3.208 +
3.209 + /**
3.210 + * Indicates whether the map contains
3.211 + * at least one listener to be notified.
3.212 + *
3.213 + * @param name the name of the property
3.214 + * @return {@code true} if at least one listener exists or
3.215 + * {@code false} otherwise
3.216 + */
3.217 + public final synchronized boolean hasListeners(String name) {
3.218 + if (this.map == null) {
3.219 + return false;
3.220 + }
3.221 + L[] array = this.map.get(null);
3.222 + return (array != null) || ((name != null) && (null != this.map.get(name)));
3.223 + }
3.224 +
3.225 + /**
3.226 + * Returns a set of entries from the map.
3.227 + * Each entry is a pair consisted of the property name
3.228 + * and the corresponding list of listeners.
3.229 + *
3.230 + * @return a set of entries from the map
3.231 + */
3.232 + public final Set<Entry<String, L[]>> getEntries() {
3.233 + return (this.map != null)
3.234 + ? this.map.entrySet()
3.235 + : Collections.<Entry<String, L[]>>emptySet();
3.236 + }
3.237 +
3.238 + /**
3.239 + * Extracts a real listener from the proxy listener.
3.240 + * It is necessary because default proxy class is not serializable.
3.241 + *
3.242 + * @return a real listener
3.243 + */
3.244 + public final L extract(L listener) {
3.245 + while (listener instanceof EventListenerProxy) {
3.246 + EventListenerProxy<L> proxy = (EventListenerProxy<L>) listener;
3.247 + listener = proxy.getListener();
3.248 + }
3.249 + return listener;
3.250 + }
3.251 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/emul/compact/src/main/java/java/beans/IndexedPropertyChangeEvent.java Tue Feb 05 17:04:22 2013 +0100
4.3 @@ -0,0 +1,78 @@
4.4 +/*
4.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.7 + *
4.8 + * This code is free software; you can redistribute it and/or modify it
4.9 + * under the terms of the GNU General Public License version 2 only, as
4.10 + * published by the Free Software Foundation. Oracle designates this
4.11 + * particular file as subject to the "Classpath" exception as provided
4.12 + * by Oracle in the LICENSE file that accompanied this code.
4.13 + *
4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.17 + * version 2 for more details (a copy is included in the LICENSE file that
4.18 + * accompanied this code).
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License version
4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.23 + *
4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.25 + * or visit www.oracle.com if you need additional information or have any
4.26 + * questions.
4.27 + */
4.28 +package java.beans;
4.29 +
4.30 +/**
4.31 + * An "IndexedPropertyChange" event gets delivered whenever a component that
4.32 + * conforms to the JavaBeans™ specification (a "bean") changes a bound
4.33 + * indexed property. This class is an extension of <code>PropertyChangeEvent</code>
4.34 + * but contains the index of the property that has changed.
4.35 + * <P>
4.36 + * Null values may be provided for the old and the new values if their
4.37 + * true values are not known.
4.38 + * <P>
4.39 + * An event source may send a null object as the name to indicate that an
4.40 + * arbitrary set of if its properties have changed. In this case the
4.41 + * old and new values should also be null.
4.42 + *
4.43 + * @since 1.5
4.44 + * @author Mark Davidson
4.45 + */
4.46 +public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
4.47 + private static final long serialVersionUID = -320227448495806870L;
4.48 +
4.49 + private int index;
4.50 +
4.51 + /**
4.52 + * Constructs a new <code>IndexedPropertyChangeEvent</code> object.
4.53 + *
4.54 + * @param source The bean that fired the event.
4.55 + * @param propertyName The programmatic name of the property that
4.56 + * was changed.
4.57 + * @param oldValue The old value of the property.
4.58 + * @param newValue The new value of the property.
4.59 + * @param index index of the property element that was changed.
4.60 + */
4.61 + public IndexedPropertyChangeEvent(Object source, String propertyName,
4.62 + Object oldValue, Object newValue,
4.63 + int index) {
4.64 + super (source, propertyName, oldValue, newValue);
4.65 + this.index = index;
4.66 + }
4.67 +
4.68 + /**
4.69 + * Gets the index of the property that was changed.
4.70 + *
4.71 + * @return The index specifying the property element that was
4.72 + * changed.
4.73 + */
4.74 + public int getIndex() {
4.75 + return index;
4.76 + }
4.77 +
4.78 + void appendTo(StringBuilder sb) {
4.79 + sb.append("; index=").append(getIndex());
4.80 + }
4.81 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeEvent.java Tue Feb 05 17:04:22 2013 +0100
5.3 @@ -0,0 +1,164 @@
5.4 +/*
5.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 + *
5.8 + * This code is free software; you can redistribute it and/or modify it
5.9 + * under the terms of the GNU General Public License version 2 only, as
5.10 + * published by the Free Software Foundation. Oracle designates this
5.11 + * particular file as subject to the "Classpath" exception as provided
5.12 + * by Oracle in the LICENSE file that accompanied this code.
5.13 + *
5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.17 + * version 2 for more details (a copy is included in the LICENSE file that
5.18 + * accompanied this code).
5.19 + *
5.20 + * You should have received a copy of the GNU General Public License version
5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.23 + *
5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.25 + * or visit www.oracle.com if you need additional information or have any
5.26 + * questions.
5.27 + */
5.28 +
5.29 +package java.beans;
5.30 +
5.31 +/**
5.32 + * A "PropertyChange" event gets delivered whenever a bean changes a "bound"
5.33 + * or "constrained" property. A PropertyChangeEvent object is sent as an
5.34 + * argument to the PropertyChangeListener and VetoableChangeListener methods.
5.35 + * <P>
5.36 + * Normally PropertyChangeEvents are accompanied by the name and the old
5.37 + * and new value of the changed property. If the new value is a primitive
5.38 + * type (such as int or boolean) it must be wrapped as the
5.39 + * corresponding java.lang.* Object type (such as Integer or Boolean).
5.40 + * <P>
5.41 + * Null values may be provided for the old and the new values if their
5.42 + * true values are not known.
5.43 + * <P>
5.44 + * An event source may send a null object as the name to indicate that an
5.45 + * arbitrary set of if its properties have changed. In this case the
5.46 + * old and new values should also be null.
5.47 + */
5.48 +
5.49 +public class PropertyChangeEvent extends java.util.EventObject {
5.50 + private static final long serialVersionUID = 7042693688939648123L;
5.51 +
5.52 + /**
5.53 + * Constructs a new <code>PropertyChangeEvent</code>.
5.54 + *
5.55 + * @param source The bean that fired the event.
5.56 + * @param propertyName The programmatic name of the property
5.57 + * that was changed.
5.58 + * @param oldValue The old value of the property.
5.59 + * @param newValue The new value of the property.
5.60 + */
5.61 + public PropertyChangeEvent(Object source, String propertyName,
5.62 + Object oldValue, Object newValue) {
5.63 + super(source);
5.64 + this.propertyName = propertyName;
5.65 + this.newValue = newValue;
5.66 + this.oldValue = oldValue;
5.67 + }
5.68 +
5.69 + /**
5.70 + * Gets the programmatic name of the property that was changed.
5.71 + *
5.72 + * @return The programmatic name of the property that was changed.
5.73 + * May be null if multiple properties have changed.
5.74 + */
5.75 + public String getPropertyName() {
5.76 + return propertyName;
5.77 + }
5.78 +
5.79 + /**
5.80 + * Gets the new value for the property, expressed as an Object.
5.81 + *
5.82 + * @return The new value for the property, expressed as an Object.
5.83 + * May be null if multiple properties have changed.
5.84 + */
5.85 + public Object getNewValue() {
5.86 + return newValue;
5.87 + }
5.88 +
5.89 + /**
5.90 + * Gets the old value for the property, expressed as an Object.
5.91 + *
5.92 + * @return The old value for the property, expressed as an Object.
5.93 + * May be null if multiple properties have changed.
5.94 + */
5.95 + public Object getOldValue() {
5.96 + return oldValue;
5.97 + }
5.98 +
5.99 + /**
5.100 + * Sets the propagationId object for the event.
5.101 + *
5.102 + * @param propagationId The propagationId object for the event.
5.103 + */
5.104 + public void setPropagationId(Object propagationId) {
5.105 + this.propagationId = propagationId;
5.106 + }
5.107 +
5.108 + /**
5.109 + * The "propagationId" field is reserved for future use. In Beans 1.0
5.110 + * the sole requirement is that if a listener catches a PropertyChangeEvent
5.111 + * and then fires a PropertyChangeEvent of its own, then it should
5.112 + * make sure that it propagates the propagationId field from its
5.113 + * incoming event to its outgoing event.
5.114 + *
5.115 + * @return the propagationId object associated with a bound/constrained
5.116 + * property update.
5.117 + */
5.118 + public Object getPropagationId() {
5.119 + return propagationId;
5.120 + }
5.121 +
5.122 + /**
5.123 + * name of the property that changed. May be null, if not known.
5.124 + * @serial
5.125 + */
5.126 + private String propertyName;
5.127 +
5.128 + /**
5.129 + * New value for property. May be null if not known.
5.130 + * @serial
5.131 + */
5.132 + private Object newValue;
5.133 +
5.134 + /**
5.135 + * Previous value for property. May be null if not known.
5.136 + * @serial
5.137 + */
5.138 + private Object oldValue;
5.139 +
5.140 + /**
5.141 + * Propagation ID. May be null.
5.142 + * @serial
5.143 + * @see #getPropagationId
5.144 + */
5.145 + private Object propagationId;
5.146 +
5.147 + /**
5.148 + * Returns a string representation of the object.
5.149 + *
5.150 + * @return a string representation of the object
5.151 + *
5.152 + * @since 1.7
5.153 + */
5.154 + public String toString() {
5.155 + StringBuilder sb = new StringBuilder(getClass().getName());
5.156 + sb.append("[propertyName=").append(getPropertyName());
5.157 + appendTo(sb);
5.158 + sb.append("; oldValue=").append(getOldValue());
5.159 + sb.append("; newValue=").append(getNewValue());
5.160 + sb.append("; propagationId=").append(getPropagationId());
5.161 + sb.append("; source=").append(getSource());
5.162 + return sb.append("]").toString();
5.163 + }
5.164 +
5.165 + void appendTo(StringBuilder sb) {
5.166 + }
5.167 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListener.java Tue Feb 05 17:04:22 2013 +0100
6.3 @@ -0,0 +1,44 @@
6.4 +/*
6.5 + * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation. Oracle designates this
6.11 + * particular file as subject to the "Classpath" exception as provided
6.12 + * by Oracle in the LICENSE file that accompanied this code.
6.13 + *
6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.17 + * version 2 for more details (a copy is included in the LICENSE file that
6.18 + * accompanied this code).
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License version
6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.23 + *
6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.25 + * or visit www.oracle.com if you need additional information or have any
6.26 + * questions.
6.27 + */
6.28 +
6.29 +package java.beans;
6.30 +
6.31 +/**
6.32 + * A "PropertyChange" event gets fired whenever a bean changes a "bound"
6.33 + * property. You can register a PropertyChangeListener with a source
6.34 + * bean so as to be notified of any bound property updates.
6.35 + */
6.36 +
6.37 +public interface PropertyChangeListener extends java.util.EventListener {
6.38 +
6.39 + /**
6.40 + * This method gets called when a bound property is changed.
6.41 + * @param evt A PropertyChangeEvent object describing the event source
6.42 + * and the property that has changed.
6.43 + */
6.44 +
6.45 + void propertyChange(PropertyChangeEvent evt);
6.46 +
6.47 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListenerProxy.java Tue Feb 05 17:04:22 2013 +0100
7.3 @@ -0,0 +1,81 @@
7.4 +/*
7.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation. Oracle designates this
7.11 + * particular file as subject to the "Classpath" exception as provided
7.12 + * by Oracle in the LICENSE file that accompanied this code.
7.13 + *
7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.17 + * version 2 for more details (a copy is included in the LICENSE file that
7.18 + * accompanied this code).
7.19 + *
7.20 + * You should have received a copy of the GNU General Public License version
7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.23 + *
7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.25 + * or visit www.oracle.com if you need additional information or have any
7.26 + * questions.
7.27 + */
7.28 +
7.29 +package java.beans;
7.30 +
7.31 +import java.util.EventListenerProxy;
7.32 +
7.33 +/**
7.34 + * A class which extends the {@code EventListenerProxy}
7.35 + * specifically for adding a {@code PropertyChangeListener}
7.36 + * with a "bound" property.
7.37 + * Instances of this class can be added
7.38 + * as {@code PropertyChangeListener}s to a bean
7.39 + * which supports firing property change events.
7.40 + * <p>
7.41 + * If the object has a {@code getPropertyChangeListeners} method
7.42 + * then the array returned could be a mixture of {@code PropertyChangeListener}
7.43 + * and {@code PropertyChangeListenerProxy} objects.
7.44 + *
7.45 + * @see java.util.EventListenerProxy
7.46 + * @see PropertyChangeSupport#getPropertyChangeListeners
7.47 + * @since 1.4
7.48 + */
7.49 +public class PropertyChangeListenerProxy
7.50 + extends EventListenerProxy<PropertyChangeListener>
7.51 + implements PropertyChangeListener {
7.52 +
7.53 + private final String propertyName;
7.54 +
7.55 + /**
7.56 + * Constructor which binds the {@code PropertyChangeListener}
7.57 + * to a specific property.
7.58 + *
7.59 + * @param propertyName the name of the property to listen on
7.60 + * @param listener the listener object
7.61 + */
7.62 + public PropertyChangeListenerProxy(String propertyName, PropertyChangeListener listener) {
7.63 + super(listener);
7.64 + this.propertyName = propertyName;
7.65 + }
7.66 +
7.67 + /**
7.68 + * Forwards the property change event to the listener delegate.
7.69 + *
7.70 + * @param event the property change event
7.71 + */
7.72 + public void propertyChange(PropertyChangeEvent event) {
7.73 + getListener().propertyChange(event);
7.74 + }
7.75 +
7.76 + /**
7.77 + * Returns the name of the named property associated with the listener.
7.78 + *
7.79 + * @return the name of the named property associated with the listener
7.80 + */
7.81 + public String getPropertyName() {
7.82 + return this.propertyName;
7.83 + }
7.84 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeSupport.java Tue Feb 05 17:04:22 2013 +0100
8.3 @@ -0,0 +1,536 @@
8.4 +/*
8.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.7 + *
8.8 + * This code is free software; you can redistribute it and/or modify it
8.9 + * under the terms of the GNU General Public License version 2 only, as
8.10 + * published by the Free Software Foundation. Oracle designates this
8.11 + * particular file as subject to the "Classpath" exception as provided
8.12 + * by Oracle in the LICENSE file that accompanied this code.
8.13 + *
8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.17 + * version 2 for more details (a copy is included in the LICENSE file that
8.18 + * accompanied this code).
8.19 + *
8.20 + * You should have received a copy of the GNU General Public License version
8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.23 + *
8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8.25 + * or visit www.oracle.com if you need additional information or have any
8.26 + * questions.
8.27 + */
8.28 +package java.beans;
8.29 +
8.30 +import java.io.Serializable;
8.31 +import java.io.ObjectStreamField;
8.32 +import java.io.ObjectOutputStream;
8.33 +import java.io.ObjectInputStream;
8.34 +import java.io.IOException;
8.35 +import java.util.Hashtable;
8.36 +import java.util.Map.Entry;
8.37 +
8.38 +/**
8.39 + * This is a utility class that can be used by beans that support bound
8.40 + * properties. It manages a list of listeners and dispatches
8.41 + * {@link PropertyChangeEvent}s to them. You can use an instance of this class
8.42 + * as a member field of your bean and delegate these types of work to it.
8.43 + * The {@link PropertyChangeListener} can be registered for all properties
8.44 + * or for a property specified by name.
8.45 + * <p>
8.46 + * Here is an example of {@code PropertyChangeSupport} usage that follows
8.47 + * the rules and recommendations laid out in the JavaBeans™ specification:
8.48 + * <pre>
8.49 + * public class MyBean {
8.50 + * private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
8.51 + *
8.52 + * public void addPropertyChangeListener(PropertyChangeListener listener) {
8.53 + * this.pcs.addPropertyChangeListener(listener);
8.54 + * }
8.55 + *
8.56 + * public void removePropertyChangeListener(PropertyChangeListener listener) {
8.57 + * this.pcs.removePropertyChangeListener(listener);
8.58 + * }
8.59 + *
8.60 + * private String value;
8.61 + *
8.62 + * public String getValue() {
8.63 + * return this.value;
8.64 + * }
8.65 + *
8.66 + * public void setValue(String newValue) {
8.67 + * String oldValue = this.value;
8.68 + * this.value = newValue;
8.69 + * this.pcs.firePropertyChange("value", oldValue, newValue);
8.70 + * }
8.71 + *
8.72 + * [...]
8.73 + * }
8.74 + * </pre>
8.75 + * <p>
8.76 + * A {@code PropertyChangeSupport} instance is thread-safe.
8.77 + * <p>
8.78 + * This class is serializable. When it is serialized it will save
8.79 + * (and restore) any listeners that are themselves serializable. Any
8.80 + * non-serializable listeners will be skipped during serialization.
8.81 + *
8.82 + * @see VetoableChangeSupport
8.83 + */
8.84 +public class PropertyChangeSupport implements Serializable {
8.85 + private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
8.86 +
8.87 + /**
8.88 + * Constructs a <code>PropertyChangeSupport</code> object.
8.89 + *
8.90 + * @param sourceBean The bean to be given as the source for any events.
8.91 + */
8.92 + public PropertyChangeSupport(Object sourceBean) {
8.93 + if (sourceBean == null) {
8.94 + throw new NullPointerException();
8.95 + }
8.96 + source = sourceBean;
8.97 + }
8.98 +
8.99 + /**
8.100 + * Add a PropertyChangeListener to the listener list.
8.101 + * The listener is registered for all properties.
8.102 + * The same listener object may be added more than once, and will be called
8.103 + * as many times as it is added.
8.104 + * If <code>listener</code> is null, no exception is thrown and no action
8.105 + * is taken.
8.106 + *
8.107 + * @param listener The PropertyChangeListener to be added
8.108 + */
8.109 + public void addPropertyChangeListener(PropertyChangeListener listener) {
8.110 + if (listener == null) {
8.111 + return;
8.112 + }
8.113 + if (listener instanceof PropertyChangeListenerProxy) {
8.114 + PropertyChangeListenerProxy proxy =
8.115 + (PropertyChangeListenerProxy)listener;
8.116 + // Call two argument add method.
8.117 + addPropertyChangeListener(proxy.getPropertyName(),
8.118 + proxy.getListener());
8.119 + } else {
8.120 + this.map.add(null, listener);
8.121 + }
8.122 + }
8.123 +
8.124 + /**
8.125 + * Remove a PropertyChangeListener from the listener list.
8.126 + * This removes a PropertyChangeListener that was registered
8.127 + * for all properties.
8.128 + * If <code>listener</code> was added more than once to the same event
8.129 + * source, it will be notified one less time after being removed.
8.130 + * If <code>listener</code> is null, or was never added, no exception is
8.131 + * thrown and no action is taken.
8.132 + *
8.133 + * @param listener The PropertyChangeListener to be removed
8.134 + */
8.135 + public void removePropertyChangeListener(PropertyChangeListener listener) {
8.136 + if (listener == null) {
8.137 + return;
8.138 + }
8.139 + if (listener instanceof PropertyChangeListenerProxy) {
8.140 + PropertyChangeListenerProxy proxy =
8.141 + (PropertyChangeListenerProxy)listener;
8.142 + // Call two argument remove method.
8.143 + removePropertyChangeListener(proxy.getPropertyName(),
8.144 + proxy.getListener());
8.145 + } else {
8.146 + this.map.remove(null, listener);
8.147 + }
8.148 + }
8.149 +
8.150 + /**
8.151 + * Returns an array of all the listeners that were added to the
8.152 + * PropertyChangeSupport object with addPropertyChangeListener().
8.153 + * <p>
8.154 + * If some listeners have been added with a named property, then
8.155 + * the returned array will be a mixture of PropertyChangeListeners
8.156 + * and <code>PropertyChangeListenerProxy</code>s. If the calling
8.157 + * method is interested in distinguishing the listeners then it must
8.158 + * test each element to see if it's a
8.159 + * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
8.160 + * the parameter.
8.161 + *
8.162 + * <pre>
8.163 + * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
8.164 + * for (int i = 0; i < listeners.length; i++) {
8.165 + * if (listeners[i] instanceof PropertyChangeListenerProxy) {
8.166 + * PropertyChangeListenerProxy proxy =
8.167 + * (PropertyChangeListenerProxy)listeners[i];
8.168 + * if (proxy.getPropertyName().equals("foo")) {
8.169 + * // proxy is a PropertyChangeListener which was associated
8.170 + * // with the property named "foo"
8.171 + * }
8.172 + * }
8.173 + * }
8.174 + *</pre>
8.175 + *
8.176 + * @see PropertyChangeListenerProxy
8.177 + * @return all of the <code>PropertyChangeListeners</code> added or an
8.178 + * empty array if no listeners have been added
8.179 + * @since 1.4
8.180 + */
8.181 + public PropertyChangeListener[] getPropertyChangeListeners() {
8.182 + return this.map.getListeners();
8.183 + }
8.184 +
8.185 + /**
8.186 + * Add a PropertyChangeListener for a specific property. The listener
8.187 + * will be invoked only when a call on firePropertyChange names that
8.188 + * specific property.
8.189 + * The same listener object may be added more than once. For each
8.190 + * property, the listener will be invoked the number of times it was added
8.191 + * for that property.
8.192 + * If <code>propertyName</code> or <code>listener</code> is null, no
8.193 + * exception is thrown and no action is taken.
8.194 + *
8.195 + * @param propertyName The name of the property to listen on.
8.196 + * @param listener The PropertyChangeListener to be added
8.197 + */
8.198 + public void addPropertyChangeListener(
8.199 + String propertyName,
8.200 + PropertyChangeListener listener) {
8.201 + if (listener == null || propertyName == null) {
8.202 + return;
8.203 + }
8.204 + listener = this.map.extract(listener);
8.205 + if (listener != null) {
8.206 + this.map.add(propertyName, listener);
8.207 + }
8.208 + }
8.209 +
8.210 + /**
8.211 + * Remove a PropertyChangeListener for a specific property.
8.212 + * If <code>listener</code> was added more than once to the same event
8.213 + * source for the specified property, it will be notified one less time
8.214 + * after being removed.
8.215 + * If <code>propertyName</code> is null, no exception is thrown and no
8.216 + * action is taken.
8.217 + * If <code>listener</code> is null, or was never added for the specified
8.218 + * property, no exception is thrown and no action is taken.
8.219 + *
8.220 + * @param propertyName The name of the property that was listened on.
8.221 + * @param listener The PropertyChangeListener to be removed
8.222 + */
8.223 + public void removePropertyChangeListener(
8.224 + String propertyName,
8.225 + PropertyChangeListener listener) {
8.226 + if (listener == null || propertyName == null) {
8.227 + return;
8.228 + }
8.229 + listener = this.map.extract(listener);
8.230 + if (listener != null) {
8.231 + this.map.remove(propertyName, listener);
8.232 + }
8.233 + }
8.234 +
8.235 + /**
8.236 + * Returns an array of all the listeners which have been associated
8.237 + * with the named property.
8.238 + *
8.239 + * @param propertyName The name of the property being listened to
8.240 + * @return all of the <code>PropertyChangeListeners</code> associated with
8.241 + * the named property. If no such listeners have been added,
8.242 + * or if <code>propertyName</code> is null, an empty array is
8.243 + * returned.
8.244 + * @since 1.4
8.245 + */
8.246 + public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
8.247 + return this.map.getListeners(propertyName);
8.248 + }
8.249 +
8.250 + /**
8.251 + * Reports a bound property update to listeners
8.252 + * that have been registered to track updates of
8.253 + * all properties or a property with the specified name.
8.254 + * <p>
8.255 + * No event is fired if old and new values are equal and non-null.
8.256 + * <p>
8.257 + * This is merely a convenience wrapper around the more general
8.258 + * {@link #firePropertyChange(PropertyChangeEvent)} method.
8.259 + *
8.260 + * @param propertyName the programmatic name of the property that was changed
8.261 + * @param oldValue the old value of the property
8.262 + * @param newValue the new value of the property
8.263 + */
8.264 + public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
8.265 + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
8.266 + firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
8.267 + }
8.268 + }
8.269 +
8.270 + /**
8.271 + * Reports an integer bound property update to listeners
8.272 + * that have been registered to track updates of
8.273 + * all properties or a property with the specified name.
8.274 + * <p>
8.275 + * No event is fired if old and new values are equal.
8.276 + * <p>
8.277 + * This is merely a convenience wrapper around the more general
8.278 + * {@link #firePropertyChange(String, Object, Object)} method.
8.279 + *
8.280 + * @param propertyName the programmatic name of the property that was changed
8.281 + * @param oldValue the old value of the property
8.282 + * @param newValue the new value of the property
8.283 + */
8.284 + public void firePropertyChange(String propertyName, int oldValue, int newValue) {
8.285 + if (oldValue != newValue) {
8.286 + firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
8.287 + }
8.288 + }
8.289 +
8.290 + /**
8.291 + * Reports a boolean bound property update to listeners
8.292 + * that have been registered to track updates of
8.293 + * all properties or a property with the specified name.
8.294 + * <p>
8.295 + * No event is fired if old and new values are equal.
8.296 + * <p>
8.297 + * This is merely a convenience wrapper around the more general
8.298 + * {@link #firePropertyChange(String, Object, Object)} method.
8.299 + *
8.300 + * @param propertyName the programmatic name of the property that was changed
8.301 + * @param oldValue the old value of the property
8.302 + * @param newValue the new value of the property
8.303 + */
8.304 + public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
8.305 + if (oldValue != newValue) {
8.306 + firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
8.307 + }
8.308 + }
8.309 +
8.310 + /**
8.311 + * Fires a property change event to listeners
8.312 + * that have been registered to track updates of
8.313 + * all properties or a property with the specified name.
8.314 + * <p>
8.315 + * No event is fired if the given event's old and new values are equal and non-null.
8.316 + *
8.317 + * @param event the {@code PropertyChangeEvent} to be fired
8.318 + */
8.319 + public void firePropertyChange(PropertyChangeEvent event) {
8.320 + Object oldValue = event.getOldValue();
8.321 + Object newValue = event.getNewValue();
8.322 + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
8.323 + String name = event.getPropertyName();
8.324 +
8.325 + PropertyChangeListener[] common = this.map.get(null);
8.326 + PropertyChangeListener[] named = (name != null)
8.327 + ? this.map.get(name)
8.328 + : null;
8.329 +
8.330 + fire(common, event);
8.331 + fire(named, event);
8.332 + }
8.333 + }
8.334 +
8.335 + private static void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) {
8.336 + if (listeners != null) {
8.337 + for (PropertyChangeListener listener : listeners) {
8.338 + listener.propertyChange(event);
8.339 + }
8.340 + }
8.341 + }
8.342 +
8.343 + /**
8.344 + * Reports a bound indexed property update to listeners
8.345 + * that have been registered to track updates of
8.346 + * all properties or a property with the specified name.
8.347 + * <p>
8.348 + * No event is fired if old and new values are equal and non-null.
8.349 + * <p>
8.350 + * This is merely a convenience wrapper around the more general
8.351 + * {@link #firePropertyChange(PropertyChangeEvent)} method.
8.352 + *
8.353 + * @param propertyName the programmatic name of the property that was changed
8.354 + * @param index the index of the property element that was changed
8.355 + * @param oldValue the old value of the property
8.356 + * @param newValue the new value of the property
8.357 + * @since 1.5
8.358 + */
8.359 + public void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
8.360 + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
8.361 + firePropertyChange(new IndexedPropertyChangeEvent(source, propertyName, oldValue, newValue, index));
8.362 + }
8.363 + }
8.364 +
8.365 + /**
8.366 + * Reports an integer bound indexed property update to listeners
8.367 + * that have been registered to track updates of
8.368 + * all properties or a property with the specified name.
8.369 + * <p>
8.370 + * No event is fired if old and new values are equal.
8.371 + * <p>
8.372 + * This is merely a convenience wrapper around the more general
8.373 + * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
8.374 + *
8.375 + * @param propertyName the programmatic name of the property that was changed
8.376 + * @param index the index of the property element that was changed
8.377 + * @param oldValue the old value of the property
8.378 + * @param newValue the new value of the property
8.379 + * @since 1.5
8.380 + */
8.381 + public void fireIndexedPropertyChange(String propertyName, int index, int oldValue, int newValue) {
8.382 + if (oldValue != newValue) {
8.383 + fireIndexedPropertyChange(propertyName, index, Integer.valueOf(oldValue), Integer.valueOf(newValue));
8.384 + }
8.385 + }
8.386 +
8.387 + /**
8.388 + * Reports a boolean bound indexed property update to listeners
8.389 + * that have been registered to track updates of
8.390 + * all properties or a property with the specified name.
8.391 + * <p>
8.392 + * No event is fired if old and new values are equal.
8.393 + * <p>
8.394 + * This is merely a convenience wrapper around the more general
8.395 + * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
8.396 + *
8.397 + * @param propertyName the programmatic name of the property that was changed
8.398 + * @param index the index of the property element that was changed
8.399 + * @param oldValue the old value of the property
8.400 + * @param newValue the new value of the property
8.401 + * @since 1.5
8.402 + */
8.403 + public void fireIndexedPropertyChange(String propertyName, int index, boolean oldValue, boolean newValue) {
8.404 + if (oldValue != newValue) {
8.405 + fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
8.406 + }
8.407 + }
8.408 +
8.409 + /**
8.410 + * Check if there are any listeners for a specific property, including
8.411 + * those registered on all properties. If <code>propertyName</code>
8.412 + * is null, only check for listeners registered on all properties.
8.413 + *
8.414 + * @param propertyName the property name.
8.415 + * @return true if there are one or more listeners for the given property
8.416 + */
8.417 + public boolean hasListeners(String propertyName) {
8.418 + return this.map.hasListeners(propertyName);
8.419 + }
8.420 +
8.421 + /**
8.422 + * @serialData Null terminated list of <code>PropertyChangeListeners</code>.
8.423 + * <p>
8.424 + * At serialization time we skip non-serializable listeners and
8.425 + * only serialize the serializable listeners.
8.426 + */
8.427 + private void writeObject(ObjectOutputStream s) throws IOException {
8.428 + Hashtable<String, PropertyChangeSupport> children = null;
8.429 + PropertyChangeListener[] listeners = null;
8.430 + synchronized (this.map) {
8.431 + for (Entry<String, PropertyChangeListener[]> entry : this.map.getEntries()) {
8.432 + String property = entry.getKey();
8.433 + if (property == null) {
8.434 + listeners = entry.getValue();
8.435 + } else {
8.436 + if (children == null) {
8.437 + children = new Hashtable<String, PropertyChangeSupport>();
8.438 + }
8.439 + PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
8.440 + pcs.map.set(null, entry.getValue());
8.441 + children.put(property, pcs);
8.442 + }
8.443 + }
8.444 + }
8.445 + ObjectOutputStream.PutField fields = s.putFields();
8.446 + fields.put("children", children);
8.447 + fields.put("source", this.source);
8.448 + fields.put("propertyChangeSupportSerializedDataVersion", 2);
8.449 + s.writeFields();
8.450 +
8.451 + if (listeners != null) {
8.452 + for (PropertyChangeListener l : listeners) {
8.453 + if (l instanceof Serializable) {
8.454 + s.writeObject(l);
8.455 + }
8.456 + }
8.457 + }
8.458 + s.writeObject(null);
8.459 + }
8.460 +
8.461 + private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
8.462 + this.map = new PropertyChangeListenerMap();
8.463 +
8.464 + ObjectInputStream.GetField fields = s.readFields();
8.465 +
8.466 + Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
8.467 + this.source = fields.get("source", null);
8.468 + fields.get("propertyChangeSupportSerializedDataVersion", 2);
8.469 +
8.470 + Object listenerOrNull;
8.471 + while (null != (listenerOrNull = s.readObject())) {
8.472 + this.map.add(null, (PropertyChangeListener)listenerOrNull);
8.473 + }
8.474 + if (children != null) {
8.475 + for (Entry<String, PropertyChangeSupport> entry : children.entrySet()) {
8.476 + for (PropertyChangeListener listener : entry.getValue().getPropertyChangeListeners()) {
8.477 + this.map.add(entry.getKey(), listener);
8.478 + }
8.479 + }
8.480 + }
8.481 + }
8.482 +
8.483 + /**
8.484 + * The object to be provided as the "source" for any generated events.
8.485 + */
8.486 + private Object source;
8.487 +
8.488 + /**
8.489 + * @serialField children Hashtable
8.490 + * @serialField source Object
8.491 + * @serialField propertyChangeSupportSerializedDataVersion int
8.492 + */
8.493 + private static final ObjectStreamField[] serialPersistentFields = {
8.494 + new ObjectStreamField("children", Hashtable.class),
8.495 + new ObjectStreamField("source", Object.class),
8.496 + new ObjectStreamField("propertyChangeSupportSerializedDataVersion", Integer.TYPE)
8.497 + };
8.498 +
8.499 + /**
8.500 + * Serialization version ID, so we're compatible with JDK 1.1
8.501 + */
8.502 + static final long serialVersionUID = 6401253773779951803L;
8.503 +
8.504 + /**
8.505 + * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
8.506 + * that works with {@link PropertyChangeListener PropertyChangeListener} objects.
8.507 + */
8.508 + private static final class PropertyChangeListenerMap extends ChangeListenerMap<PropertyChangeListener> {
8.509 + private static final PropertyChangeListener[] EMPTY = {};
8.510 +
8.511 + /**
8.512 + * Creates an array of {@link PropertyChangeListener PropertyChangeListener} objects.
8.513 + * This method uses the same instance of the empty array
8.514 + * when {@code length} equals {@code 0}.
8.515 + *
8.516 + * @param length the array length
8.517 + * @return an array with specified length
8.518 + */
8.519 + @Override
8.520 + protected PropertyChangeListener[] newArray(int length) {
8.521 + return (0 < length)
8.522 + ? new PropertyChangeListener[length]
8.523 + : EMPTY;
8.524 + }
8.525 +
8.526 + /**
8.527 + * Creates a {@link PropertyChangeListenerProxy PropertyChangeListenerProxy}
8.528 + * object for the specified property.
8.529 + *
8.530 + * @param name the name of the property to listen on
8.531 + * @param listener the listener to process events
8.532 + * @return a {@code PropertyChangeListenerProxy} object
8.533 + */
8.534 + @Override
8.535 + protected PropertyChangeListener newProxy(String name, PropertyChangeListener listener) {
8.536 + return new PropertyChangeListenerProxy(name, listener);
8.537 + }
8.538 + }
8.539 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/emul/compact/src/main/java/java/beans/PropertyVetoException.java Tue Feb 05 17:04:22 2013 +0100
9.3 @@ -0,0 +1,64 @@
9.4 +/*
9.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.7 + *
9.8 + * This code is free software; you can redistribute it and/or modify it
9.9 + * under the terms of the GNU General Public License version 2 only, as
9.10 + * published by the Free Software Foundation. Oracle designates this
9.11 + * particular file as subject to the "Classpath" exception as provided
9.12 + * by Oracle in the LICENSE file that accompanied this code.
9.13 + *
9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.17 + * version 2 for more details (a copy is included in the LICENSE file that
9.18 + * accompanied this code).
9.19 + *
9.20 + * You should have received a copy of the GNU General Public License version
9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.23 + *
9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9.25 + * or visit www.oracle.com if you need additional information or have any
9.26 + * questions.
9.27 + */
9.28 +
9.29 +package java.beans;
9.30 +
9.31 +
9.32 +/**
9.33 + * A PropertyVetoException is thrown when a proposed change to a
9.34 + * property represents an unacceptable value.
9.35 + */
9.36 +
9.37 +public
9.38 +class PropertyVetoException extends Exception {
9.39 + private static final long serialVersionUID = 129596057694162164L;
9.40 +
9.41 + /**
9.42 + * Constructs a <code>PropertyVetoException</code> with a
9.43 + * detailed message.
9.44 + *
9.45 + * @param mess Descriptive message
9.46 + * @param evt A PropertyChangeEvent describing the vetoed change.
9.47 + */
9.48 + public PropertyVetoException(String mess, PropertyChangeEvent evt) {
9.49 + super(mess);
9.50 + this.evt = evt;
9.51 + }
9.52 +
9.53 + /**
9.54 + * Gets the vetoed <code>PropertyChangeEvent</code>.
9.55 + *
9.56 + * @return A PropertyChangeEvent describing the vetoed change.
9.57 + */
9.58 + public PropertyChangeEvent getPropertyChangeEvent() {
9.59 + return evt;
9.60 + }
9.61 +
9.62 + /**
9.63 + * A PropertyChangeEvent describing the vetoed change.
9.64 + * @serial
9.65 + */
9.66 + private PropertyChangeEvent evt;
9.67 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListener.java Tue Feb 05 17:04:22 2013 +0100
10.3 @@ -0,0 +1,44 @@
10.4 +/*
10.5 + * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 + *
10.8 + * This code is free software; you can redistribute it and/or modify it
10.9 + * under the terms of the GNU General Public License version 2 only, as
10.10 + * published by the Free Software Foundation. Oracle designates this
10.11 + * particular file as subject to the "Classpath" exception as provided
10.12 + * by Oracle in the LICENSE file that accompanied this code.
10.13 + *
10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.17 + * version 2 for more details (a copy is included in the LICENSE file that
10.18 + * accompanied this code).
10.19 + *
10.20 + * You should have received a copy of the GNU General Public License version
10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.23 + *
10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.25 + * or visit www.oracle.com if you need additional information or have any
10.26 + * questions.
10.27 + */
10.28 +
10.29 +package java.beans;
10.30 +
10.31 +/**
10.32 + * A VetoableChange event gets fired whenever a bean changes a "constrained"
10.33 + * property. You can register a VetoableChangeListener with a source bean
10.34 + * so as to be notified of any constrained property updates.
10.35 + */
10.36 +public interface VetoableChangeListener extends java.util.EventListener {
10.37 + /**
10.38 + * This method gets called when a constrained property is changed.
10.39 + *
10.40 + * @param evt a <code>PropertyChangeEvent</code> object describing the
10.41 + * event source and the property that has changed.
10.42 + * @exception PropertyVetoException if the recipient wishes the property
10.43 + * change to be rolled back.
10.44 + */
10.45 + void vetoableChange(PropertyChangeEvent evt)
10.46 + throws PropertyVetoException;
10.47 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListenerProxy.java Tue Feb 05 17:04:22 2013 +0100
11.3 @@ -0,0 +1,84 @@
11.4 +/*
11.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 + *
11.8 + * This code is free software; you can redistribute it and/or modify it
11.9 + * under the terms of the GNU General Public License version 2 only, as
11.10 + * published by the Free Software Foundation. Oracle designates this
11.11 + * particular file as subject to the "Classpath" exception as provided
11.12 + * by Oracle in the LICENSE file that accompanied this code.
11.13 + *
11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 + * version 2 for more details (a copy is included in the LICENSE file that
11.18 + * accompanied this code).
11.19 + *
11.20 + * You should have received a copy of the GNU General Public License version
11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 + *
11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.25 + * or visit www.oracle.com if you need additional information or have any
11.26 + * questions.
11.27 + */
11.28 +
11.29 +package java.beans;
11.30 +
11.31 +import java.util.EventListenerProxy;
11.32 +
11.33 +/**
11.34 + * A class which extends the {@code EventListenerProxy}
11.35 + * specifically for adding a {@code VetoableChangeListener}
11.36 + * with a "constrained" property.
11.37 + * Instances of this class can be added
11.38 + * as {@code VetoableChangeListener}s to a bean
11.39 + * which supports firing vetoable change events.
11.40 + * <p>
11.41 + * If the object has a {@code getVetoableChangeListeners} method
11.42 + * then the array returned could be a mixture of {@code VetoableChangeListener}
11.43 + * and {@code VetoableChangeListenerProxy} objects.
11.44 + *
11.45 + * @see java.util.EventListenerProxy
11.46 + * @see VetoableChangeSupport#getVetoableChangeListeners
11.47 + * @since 1.4
11.48 + */
11.49 +public class VetoableChangeListenerProxy
11.50 + extends EventListenerProxy<VetoableChangeListener>
11.51 + implements VetoableChangeListener {
11.52 +
11.53 + private final String propertyName;
11.54 +
11.55 + /**
11.56 + * Constructor which binds the {@code VetoableChangeListener}
11.57 + * to a specific property.
11.58 + *
11.59 + * @param propertyName the name of the property to listen on
11.60 + * @param listener the listener object
11.61 + */
11.62 + public VetoableChangeListenerProxy(String propertyName, VetoableChangeListener listener) {
11.63 + super(listener);
11.64 + this.propertyName = propertyName;
11.65 + }
11.66 +
11.67 + /**
11.68 + * Forwards the property change event to the listener delegate.
11.69 + *
11.70 + * @param event the property change event
11.71 + *
11.72 + * @exception PropertyVetoException if the recipient wishes the property
11.73 + * change to be rolled back
11.74 + */
11.75 + public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException{
11.76 + getListener().vetoableChange(event);
11.77 + }
11.78 +
11.79 + /**
11.80 + * Returns the name of the named property associated with the listener.
11.81 + *
11.82 + * @return the name of the named property associated with the listener
11.83 + */
11.84 + public String getPropertyName() {
11.85 + return this.propertyName;
11.86 + }
11.87 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java Tue Feb 05 17:04:22 2013 +0100
12.3 @@ -0,0 +1,526 @@
12.4 +/*
12.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 + *
12.8 + * This code is free software; you can redistribute it and/or modify it
12.9 + * under the terms of the GNU General Public License version 2 only, as
12.10 + * published by the Free Software Foundation. Oracle designates this
12.11 + * particular file as subject to the "Classpath" exception as provided
12.12 + * by Oracle in the LICENSE file that accompanied this code.
12.13 + *
12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 + * version 2 for more details (a copy is included in the LICENSE file that
12.18 + * accompanied this code).
12.19 + *
12.20 + * You should have received a copy of the GNU General Public License version
12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 + *
12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
12.25 + * or visit www.oracle.com if you need additional information or have any
12.26 + * questions.
12.27 + */
12.28 +package java.beans;
12.29 +
12.30 +import java.io.Serializable;
12.31 +import java.io.ObjectStreamField;
12.32 +import java.io.ObjectOutputStream;
12.33 +import java.io.ObjectInputStream;
12.34 +import java.io.IOException;
12.35 +import java.util.Hashtable;
12.36 +import java.util.Map.Entry;
12.37 +import org.apidesign.bck2brwsr.emul.lang.System;
12.38 +
12.39 +/**
12.40 + * This is a utility class that can be used by beans that support constrained
12.41 + * properties. It manages a list of listeners and dispatches
12.42 + * {@link PropertyChangeEvent}s to them. You can use an instance of this class
12.43 + * as a member field of your bean and delegate these types of work to it.
12.44 + * The {@link VetoableChangeListener} can be registered for all properties
12.45 + * or for a property specified by name.
12.46 + * <p>
12.47 + * Here is an example of {@code VetoableChangeSupport} usage that follows
12.48 + * the rules and recommendations laid out in the JavaBeans™ specification:
12.49 + * <pre>
12.50 + * public class MyBean {
12.51 + * private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
12.52 + *
12.53 + * public void addVetoableChangeListener(VetoableChangeListener listener) {
12.54 + * this.vcs.addVetoableChangeListener(listener);
12.55 + * }
12.56 + *
12.57 + * public void removeVetoableChangeListener(VetoableChangeListener listener) {
12.58 + * this.vcs.removeVetoableChangeListener(listener);
12.59 + * }
12.60 + *
12.61 + * private String value;
12.62 + *
12.63 + * public String getValue() {
12.64 + * return this.value;
12.65 + * }
12.66 + *
12.67 + * public void setValue(String newValue) throws PropertyVetoException {
12.68 + * String oldValue = this.value;
12.69 + * this.vcs.fireVetoableChange("value", oldValue, newValue);
12.70 + * this.value = newValue;
12.71 + * }
12.72 + *
12.73 + * [...]
12.74 + * }
12.75 + * </pre>
12.76 + * <p>
12.77 + * A {@code VetoableChangeSupport} instance is thread-safe.
12.78 + * <p>
12.79 + * This class is serializable. When it is serialized it will save
12.80 + * (and restore) any listeners that are themselves serializable. Any
12.81 + * non-serializable listeners will be skipped during serialization.
12.82 + *
12.83 + * @see PropertyChangeSupport
12.84 + */
12.85 +public class VetoableChangeSupport implements Serializable {
12.86 + private VetoableChangeListenerMap map = new VetoableChangeListenerMap();
12.87 +
12.88 + /**
12.89 + * Constructs a <code>VetoableChangeSupport</code> object.
12.90 + *
12.91 + * @param sourceBean The bean to be given as the source for any events.
12.92 + */
12.93 + public VetoableChangeSupport(Object sourceBean) {
12.94 + if (sourceBean == null) {
12.95 + throw new NullPointerException();
12.96 + }
12.97 + source = sourceBean;
12.98 + }
12.99 +
12.100 + /**
12.101 + * Add a VetoableChangeListener to the listener list.
12.102 + * The listener is registered for all properties.
12.103 + * The same listener object may be added more than once, and will be called
12.104 + * as many times as it is added.
12.105 + * If <code>listener</code> is null, no exception is thrown and no action
12.106 + * is taken.
12.107 + *
12.108 + * @param listener The VetoableChangeListener to be added
12.109 + */
12.110 + public void addVetoableChangeListener(VetoableChangeListener listener) {
12.111 + if (listener == null) {
12.112 + return;
12.113 + }
12.114 + if (listener instanceof VetoableChangeListenerProxy) {
12.115 + VetoableChangeListenerProxy proxy =
12.116 + (VetoableChangeListenerProxy)listener;
12.117 + // Call two argument add method.
12.118 + addVetoableChangeListener(proxy.getPropertyName(),
12.119 + proxy.getListener());
12.120 + } else {
12.121 + this.map.add(null, listener);
12.122 + }
12.123 + }
12.124 +
12.125 + /**
12.126 + * Remove a VetoableChangeListener from the listener list.
12.127 + * This removes a VetoableChangeListener that was registered
12.128 + * for all properties.
12.129 + * If <code>listener</code> was added more than once to the same event
12.130 + * source, it will be notified one less time after being removed.
12.131 + * If <code>listener</code> is null, or was never added, no exception is
12.132 + * thrown and no action is taken.
12.133 + *
12.134 + * @param listener The VetoableChangeListener to be removed
12.135 + */
12.136 + public void removeVetoableChangeListener(VetoableChangeListener listener) {
12.137 + if (listener == null) {
12.138 + return;
12.139 + }
12.140 + if (listener instanceof VetoableChangeListenerProxy) {
12.141 + VetoableChangeListenerProxy proxy =
12.142 + (VetoableChangeListenerProxy)listener;
12.143 + // Call two argument remove method.
12.144 + removeVetoableChangeListener(proxy.getPropertyName(),
12.145 + proxy.getListener());
12.146 + } else {
12.147 + this.map.remove(null, listener);
12.148 + }
12.149 + }
12.150 +
12.151 + /**
12.152 + * Returns an array of all the listeners that were added to the
12.153 + * VetoableChangeSupport object with addVetoableChangeListener().
12.154 + * <p>
12.155 + * If some listeners have been added with a named property, then
12.156 + * the returned array will be a mixture of VetoableChangeListeners
12.157 + * and <code>VetoableChangeListenerProxy</code>s. If the calling
12.158 + * method is interested in distinguishing the listeners then it must
12.159 + * test each element to see if it's a
12.160 + * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine
12.161 + * the parameter.
12.162 + *
12.163 + * <pre>
12.164 + * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
12.165 + * for (int i = 0; i < listeners.length; i++) {
12.166 + * if (listeners[i] instanceof VetoableChangeListenerProxy) {
12.167 + * VetoableChangeListenerProxy proxy =
12.168 + * (VetoableChangeListenerProxy)listeners[i];
12.169 + * if (proxy.getPropertyName().equals("foo")) {
12.170 + * // proxy is a VetoableChangeListener which was associated
12.171 + * // with the property named "foo"
12.172 + * }
12.173 + * }
12.174 + * }
12.175 + *</pre>
12.176 + *
12.177 + * @see VetoableChangeListenerProxy
12.178 + * @return all of the <code>VetoableChangeListeners</code> added or an
12.179 + * empty array if no listeners have been added
12.180 + * @since 1.4
12.181 + */
12.182 + public VetoableChangeListener[] getVetoableChangeListeners(){
12.183 + return this.map.getListeners();
12.184 + }
12.185 +
12.186 + /**
12.187 + * Add a VetoableChangeListener for a specific property. The listener
12.188 + * will be invoked only when a call on fireVetoableChange names that
12.189 + * specific property.
12.190 + * The same listener object may be added more than once. For each
12.191 + * property, the listener will be invoked the number of times it was added
12.192 + * for that property.
12.193 + * If <code>propertyName</code> or <code>listener</code> is null, no
12.194 + * exception is thrown and no action is taken.
12.195 + *
12.196 + * @param propertyName The name of the property to listen on.
12.197 + * @param listener The VetoableChangeListener to be added
12.198 + */
12.199 + public void addVetoableChangeListener(
12.200 + String propertyName,
12.201 + VetoableChangeListener listener) {
12.202 + if (listener == null || propertyName == null) {
12.203 + return;
12.204 + }
12.205 + listener = this.map.extract(listener);
12.206 + if (listener != null) {
12.207 + this.map.add(propertyName, listener);
12.208 + }
12.209 + }
12.210 +
12.211 + /**
12.212 + * Remove a VetoableChangeListener for a specific property.
12.213 + * If <code>listener</code> was added more than once to the same event
12.214 + * source for the specified property, it will be notified one less time
12.215 + * after being removed.
12.216 + * If <code>propertyName</code> is null, no exception is thrown and no
12.217 + * action is taken.
12.218 + * If <code>listener</code> is null, or was never added for the specified
12.219 + * property, no exception is thrown and no action is taken.
12.220 + *
12.221 + * @param propertyName The name of the property that was listened on.
12.222 + * @param listener The VetoableChangeListener to be removed
12.223 + */
12.224 + public void removeVetoableChangeListener(
12.225 + String propertyName,
12.226 + VetoableChangeListener listener) {
12.227 + if (listener == null || propertyName == null) {
12.228 + return;
12.229 + }
12.230 + listener = this.map.extract(listener);
12.231 + if (listener != null) {
12.232 + this.map.remove(propertyName, listener);
12.233 + }
12.234 + }
12.235 +
12.236 + /**
12.237 + * Returns an array of all the listeners which have been associated
12.238 + * with the named property.
12.239 + *
12.240 + * @param propertyName The name of the property being listened to
12.241 + * @return all the <code>VetoableChangeListeners</code> associated with
12.242 + * the named property. If no such listeners have been added,
12.243 + * or if <code>propertyName</code> is null, an empty array is
12.244 + * returned.
12.245 + * @since 1.4
12.246 + */
12.247 + public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
12.248 + return this.map.getListeners(propertyName);
12.249 + }
12.250 +
12.251 + /**
12.252 + * Reports a constrained property update to listeners
12.253 + * that have been registered to track updates of
12.254 + * all properties or a property with the specified name.
12.255 + * <p>
12.256 + * Any listener can throw a {@code PropertyVetoException} to veto the update.
12.257 + * If one of the listeners vetoes the update, this method passes
12.258 + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
12.259 + * to all listeners that already confirmed this update
12.260 + * and throws the {@code PropertyVetoException} again.
12.261 + * <p>
12.262 + * No event is fired if old and new values are equal and non-null.
12.263 + * <p>
12.264 + * This is merely a convenience wrapper around the more general
12.265 + * {@link #fireVetoableChange(PropertyChangeEvent)} method.
12.266 + *
12.267 + * @param propertyName the programmatic name of the property that is about to change
12.268 + * @param oldValue the old value of the property
12.269 + * @param newValue the new value of the property
12.270 + * @throws PropertyVetoException if one of listeners vetoes the property update
12.271 + */
12.272 + public void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
12.273 + throws PropertyVetoException {
12.274 + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
12.275 + fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
12.276 + }
12.277 + }
12.278 +
12.279 + /**
12.280 + * Reports an integer constrained property update to listeners
12.281 + * that have been registered to track updates of
12.282 + * all properties or a property with the specified name.
12.283 + * <p>
12.284 + * Any listener can throw a {@code PropertyVetoException} to veto the update.
12.285 + * If one of the listeners vetoes the update, this method passes
12.286 + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
12.287 + * to all listeners that already confirmed this update
12.288 + * and throws the {@code PropertyVetoException} again.
12.289 + * <p>
12.290 + * No event is fired if old and new values are equal.
12.291 + * <p>
12.292 + * This is merely a convenience wrapper around the more general
12.293 + * {@link #fireVetoableChange(String, Object, Object)} method.
12.294 + *
12.295 + * @param propertyName the programmatic name of the property that is about to change
12.296 + * @param oldValue the old value of the property
12.297 + * @param newValue the new value of the property
12.298 + * @throws PropertyVetoException if one of listeners vetoes the property update
12.299 + */
12.300 + public void fireVetoableChange(String propertyName, int oldValue, int newValue)
12.301 + throws PropertyVetoException {
12.302 + if (oldValue != newValue) {
12.303 + fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
12.304 + }
12.305 + }
12.306 +
12.307 + /**
12.308 + * Reports a boolean constrained property update to listeners
12.309 + * that have been registered to track updates of
12.310 + * all properties or a property with the specified name.
12.311 + * <p>
12.312 + * Any listener can throw a {@code PropertyVetoException} to veto the update.
12.313 + * If one of the listeners vetoes the update, this method passes
12.314 + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
12.315 + * to all listeners that already confirmed this update
12.316 + * and throws the {@code PropertyVetoException} again.
12.317 + * <p>
12.318 + * No event is fired if old and new values are equal.
12.319 + * <p>
12.320 + * This is merely a convenience wrapper around the more general
12.321 + * {@link #fireVetoableChange(String, Object, Object)} method.
12.322 + *
12.323 + * @param propertyName the programmatic name of the property that is about to change
12.324 + * @param oldValue the old value of the property
12.325 + * @param newValue the new value of the property
12.326 + * @throws PropertyVetoException if one of listeners vetoes the property update
12.327 + */
12.328 + public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue)
12.329 + throws PropertyVetoException {
12.330 + if (oldValue != newValue) {
12.331 + fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
12.332 + }
12.333 + }
12.334 +
12.335 + /**
12.336 + * Fires a property change event to listeners
12.337 + * that have been registered to track updates of
12.338 + * all properties or a property with the specified name.
12.339 + * <p>
12.340 + * Any listener can throw a {@code PropertyVetoException} to veto the update.
12.341 + * If one of the listeners vetoes the update, this method passes
12.342 + * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
12.343 + * to all listeners that already confirmed this update
12.344 + * and throws the {@code PropertyVetoException} again.
12.345 + * <p>
12.346 + * No event is fired if the given event's old and new values are equal and non-null.
12.347 + *
12.348 + * @param event the {@code PropertyChangeEvent} to be fired
12.349 + * @throws PropertyVetoException if one of listeners vetoes the property update
12.350 + */
12.351 + public void fireVetoableChange(PropertyChangeEvent event)
12.352 + throws PropertyVetoException {
12.353 + Object oldValue = event.getOldValue();
12.354 + Object newValue = event.getNewValue();
12.355 + if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
12.356 + String name = event.getPropertyName();
12.357 +
12.358 + VetoableChangeListener[] common = this.map.get(null);
12.359 + VetoableChangeListener[] named = (name != null)
12.360 + ? this.map.get(name)
12.361 + : null;
12.362 +
12.363 + VetoableChangeListener[] listeners;
12.364 + if (common == null) {
12.365 + listeners = named;
12.366 + }
12.367 + else if (named == null) {
12.368 + listeners = common;
12.369 + }
12.370 + else {
12.371 + listeners = new VetoableChangeListener[common.length + named.length];
12.372 + System.arraycopy(common, 0, listeners, 0, common.length);
12.373 + System.arraycopy(named, 0, listeners, common.length, named.length);
12.374 + }
12.375 + if (listeners != null) {
12.376 + int current = 0;
12.377 + try {
12.378 + while (current < listeners.length) {
12.379 + listeners[current].vetoableChange(event);
12.380 + current++;
12.381 + }
12.382 + }
12.383 + catch (PropertyVetoException veto) {
12.384 + event = new PropertyChangeEvent(this.source, name, newValue, oldValue);
12.385 + for (int i = 0; i < current; i++) {
12.386 + try {
12.387 + listeners[i].vetoableChange(event);
12.388 + }
12.389 + catch (PropertyVetoException exception) {
12.390 + // ignore exceptions that occur during rolling back
12.391 + }
12.392 + }
12.393 + throw veto; // rethrow the veto exception
12.394 + }
12.395 + }
12.396 + }
12.397 + }
12.398 +
12.399 + /**
12.400 + * Check if there are any listeners for a specific property, including
12.401 + * those registered on all properties. If <code>propertyName</code>
12.402 + * is null, only check for listeners registered on all properties.
12.403 + *
12.404 + * @param propertyName the property name.
12.405 + * @return true if there are one or more listeners for the given property
12.406 + */
12.407 + public boolean hasListeners(String propertyName) {
12.408 + return this.map.hasListeners(propertyName);
12.409 + }
12.410 +
12.411 + /**
12.412 + * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
12.413 + * <p>
12.414 + * At serialization time we skip non-serializable listeners and
12.415 + * only serialize the serializable listeners.
12.416 + */
12.417 + private void writeObject(ObjectOutputStream s) throws IOException {
12.418 + Hashtable<String, VetoableChangeSupport> children = null;
12.419 + VetoableChangeListener[] listeners = null;
12.420 + synchronized (this.map) {
12.421 + for (Entry<String, VetoableChangeListener[]> entry : this.map.getEntries()) {
12.422 + String property = entry.getKey();
12.423 + if (property == null) {
12.424 + listeners = entry.getValue();
12.425 + } else {
12.426 + if (children == null) {
12.427 + children = new Hashtable<String, VetoableChangeSupport>();
12.428 + }
12.429 + VetoableChangeSupport vcs = new VetoableChangeSupport(this.source);
12.430 + vcs.map.set(null, entry.getValue());
12.431 + children.put(property, vcs);
12.432 + }
12.433 + }
12.434 + }
12.435 + ObjectOutputStream.PutField fields = s.putFields();
12.436 + fields.put("children", children);
12.437 + fields.put("source", this.source);
12.438 + fields.put("vetoableChangeSupportSerializedDataVersion", 2);
12.439 + s.writeFields();
12.440 +
12.441 + if (listeners != null) {
12.442 + for (VetoableChangeListener l : listeners) {
12.443 + if (l instanceof Serializable) {
12.444 + s.writeObject(l);
12.445 + }
12.446 + }
12.447 + }
12.448 + s.writeObject(null);
12.449 + }
12.450 +
12.451 + private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
12.452 + this.map = new VetoableChangeListenerMap();
12.453 +
12.454 + ObjectInputStream.GetField fields = s.readFields();
12.455 +
12.456 + Hashtable<String, VetoableChangeSupport> children = (Hashtable<String, VetoableChangeSupport>) fields.get("children", null);
12.457 + this.source = fields.get("source", null);
12.458 + fields.get("vetoableChangeSupportSerializedDataVersion", 2);
12.459 +
12.460 + Object listenerOrNull;
12.461 + while (null != (listenerOrNull = s.readObject())) {
12.462 + this.map.add(null, (VetoableChangeListener)listenerOrNull);
12.463 + }
12.464 + if (children != null) {
12.465 + for (Entry<String, VetoableChangeSupport> entry : children.entrySet()) {
12.466 + for (VetoableChangeListener listener : entry.getValue().getVetoableChangeListeners()) {
12.467 + this.map.add(entry.getKey(), listener);
12.468 + }
12.469 + }
12.470 + }
12.471 + }
12.472 +
12.473 + /**
12.474 + * The object to be provided as the "source" for any generated events.
12.475 + */
12.476 + private Object source;
12.477 +
12.478 + /**
12.479 + * @serialField children Hashtable
12.480 + * @serialField source Object
12.481 + * @serialField vetoableChangeSupportSerializedDataVersion int
12.482 + */
12.483 + private static final ObjectStreamField[] serialPersistentFields = {
12.484 + new ObjectStreamField("children", Hashtable.class),
12.485 + new ObjectStreamField("source", Object.class),
12.486 + new ObjectStreamField("vetoableChangeSupportSerializedDataVersion", Integer.TYPE)
12.487 + };
12.488 +
12.489 + /**
12.490 + * Serialization version ID, so we're compatible with JDK 1.1
12.491 + */
12.492 + static final long serialVersionUID = -5090210921595982017L;
12.493 +
12.494 + /**
12.495 + * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
12.496 + * that works with {@link VetoableChangeListener VetoableChangeListener} objects.
12.497 + */
12.498 + private static final class VetoableChangeListenerMap extends ChangeListenerMap<VetoableChangeListener> {
12.499 + private static final VetoableChangeListener[] EMPTY = {};
12.500 +
12.501 + /**
12.502 + * Creates an array of {@link VetoableChangeListener VetoableChangeListener} objects.
12.503 + * This method uses the same instance of the empty array
12.504 + * when {@code length} equals {@code 0}.
12.505 + *
12.506 + * @param length the array length
12.507 + * @return an array with specified length
12.508 + */
12.509 + @Override
12.510 + protected VetoableChangeListener[] newArray(int length) {
12.511 + return (0 < length)
12.512 + ? new VetoableChangeListener[length]
12.513 + : EMPTY;
12.514 + }
12.515 +
12.516 + /**
12.517 + * Creates a {@link VetoableChangeListenerProxy VetoableChangeListenerProxy}
12.518 + * object for the specified property.
12.519 + *
12.520 + * @param name the name of the property to listen on
12.521 + * @param listener the listener to process events
12.522 + * @return a {@code VetoableChangeListenerProxy} object
12.523 + */
12.524 + @Override
12.525 + protected VetoableChangeListener newProxy(String name, VetoableChangeListener listener) {
12.526 + return new VetoableChangeListenerProxy(name, listener);
12.527 + }
12.528 + }
12.529 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/emul/compact/src/main/java/java/io/Bits.java Tue Feb 05 17:04:22 2013 +0100
13.3 @@ -0,0 +1,123 @@
13.4 +/*
13.5 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 + *
13.8 + * This code is free software; you can redistribute it and/or modify it
13.9 + * under the terms of the GNU General Public License version 2 only, as
13.10 + * published by the Free Software Foundation. Oracle designates this
13.11 + * particular file as subject to the "Classpath" exception as provided
13.12 + * by Oracle in the LICENSE file that accompanied this code.
13.13 + *
13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 + * version 2 for more details (a copy is included in the LICENSE file that
13.18 + * accompanied this code).
13.19 + *
13.20 + * You should have received a copy of the GNU General Public License version
13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 + *
13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
13.25 + * or visit www.oracle.com if you need additional information or have any
13.26 + * questions.
13.27 + */
13.28 +
13.29 +package java.io;
13.30 +
13.31 +/**
13.32 + * Utility methods for packing/unpacking primitive values in/out of byte arrays
13.33 + * using big-endian byte ordering.
13.34 + */
13.35 +class Bits {
13.36 +
13.37 + /*
13.38 + * Methods for unpacking primitive values from byte arrays starting at
13.39 + * given offsets.
13.40 + */
13.41 +
13.42 + static boolean getBoolean(byte[] b, int off) {
13.43 + return b[off] != 0;
13.44 + }
13.45 +
13.46 + static char getChar(byte[] b, int off) {
13.47 + return (char) ((b[off + 1] & 0xFF) +
13.48 + (b[off] << 8));
13.49 + }
13.50 +
13.51 + static short getShort(byte[] b, int off) {
13.52 + return (short) ((b[off + 1] & 0xFF) +
13.53 + (b[off] << 8));
13.54 + }
13.55 +
13.56 + static int getInt(byte[] b, int off) {
13.57 + return ((b[off + 3] & 0xFF) ) +
13.58 + ((b[off + 2] & 0xFF) << 8) +
13.59 + ((b[off + 1] & 0xFF) << 16) +
13.60 + ((b[off ] ) << 24);
13.61 + }
13.62 +
13.63 + static float getFloat(byte[] b, int off) {
13.64 + return Float.intBitsToFloat(getInt(b, off));
13.65 + }
13.66 +
13.67 + static long getLong(byte[] b, int off) {
13.68 + return ((b[off + 7] & 0xFFL) ) +
13.69 + ((b[off + 6] & 0xFFL) << 8) +
13.70 + ((b[off + 5] & 0xFFL) << 16) +
13.71 + ((b[off + 4] & 0xFFL) << 24) +
13.72 + ((b[off + 3] & 0xFFL) << 32) +
13.73 + ((b[off + 2] & 0xFFL) << 40) +
13.74 + ((b[off + 1] & 0xFFL) << 48) +
13.75 + (((long) b[off]) << 56);
13.76 + }
13.77 +
13.78 + static double getDouble(byte[] b, int off) {
13.79 + return Double.longBitsToDouble(getLong(b, off));
13.80 + }
13.81 +
13.82 + /*
13.83 + * Methods for packing primitive values into byte arrays starting at given
13.84 + * offsets.
13.85 + */
13.86 +
13.87 + static void putBoolean(byte[] b, int off, boolean val) {
13.88 + b[off] = (byte) (val ? 1 : 0);
13.89 + }
13.90 +
13.91 + static void putChar(byte[] b, int off, char val) {
13.92 + b[off + 1] = (byte) (val );
13.93 + b[off ] = (byte) (val >>> 8);
13.94 + }
13.95 +
13.96 + static void putShort(byte[] b, int off, short val) {
13.97 + b[off + 1] = (byte) (val );
13.98 + b[off ] = (byte) (val >>> 8);
13.99 + }
13.100 +
13.101 + static void putInt(byte[] b, int off, int val) {
13.102 + b[off + 3] = (byte) (val );
13.103 + b[off + 2] = (byte) (val >>> 8);
13.104 + b[off + 1] = (byte) (val >>> 16);
13.105 + b[off ] = (byte) (val >>> 24);
13.106 + }
13.107 +
13.108 + static void putFloat(byte[] b, int off, float val) {
13.109 + putInt(b, off, Float.floatToIntBits(val));
13.110 + }
13.111 +
13.112 + static void putLong(byte[] b, int off, long val) {
13.113 + b[off + 7] = (byte) (val );
13.114 + b[off + 6] = (byte) (val >>> 8);
13.115 + b[off + 5] = (byte) (val >>> 16);
13.116 + b[off + 4] = (byte) (val >>> 24);
13.117 + b[off + 3] = (byte) (val >>> 32);
13.118 + b[off + 2] = (byte) (val >>> 40);
13.119 + b[off + 1] = (byte) (val >>> 48);
13.120 + b[off ] = (byte) (val >>> 56);
13.121 + }
13.122 +
13.123 + static void putDouble(byte[] b, int off, double val) {
13.124 + putLong(b, off, Double.doubleToLongBits(val));
13.125 + }
13.126 +}
14.1 --- a/emul/compact/src/main/java/java/io/BufferedReader.java Tue Feb 05 16:40:01 2013 +0100
14.2 +++ b/emul/compact/src/main/java/java/io/BufferedReader.java Tue Feb 05 17:04:22 2013 +0100
14.3 @@ -25,7 +25,6 @@
14.4
14.5 package java.io;
14.6
14.7 -import org.apidesign.bck2brwsr.emul.lang.System;
14.8
14.9
14.10 /**
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/emul/compact/src/main/java/java/io/DataOutput.java Tue Feb 05 17:04:22 2013 +0100
15.3 @@ -0,0 +1,354 @@
15.4 +/*
15.5 + * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.7 + *
15.8 + * This code is free software; you can redistribute it and/or modify it
15.9 + * under the terms of the GNU General Public License version 2 only, as
15.10 + * published by the Free Software Foundation. Oracle designates this
15.11 + * particular file as subject to the "Classpath" exception as provided
15.12 + * by Oracle in the LICENSE file that accompanied this code.
15.13 + *
15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.17 + * version 2 for more details (a copy is included in the LICENSE file that
15.18 + * accompanied this code).
15.19 + *
15.20 + * You should have received a copy of the GNU General Public License version
15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.23 + *
15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
15.25 + * or visit www.oracle.com if you need additional information or have any
15.26 + * questions.
15.27 + */
15.28 +
15.29 +package java.io;
15.30 +
15.31 +/**
15.32 + * The <code>DataOutput</code> interface provides
15.33 + * for converting data from any of the Java
15.34 + * primitive types to a series of bytes and
15.35 + * writing these bytes to a binary stream.
15.36 + * There is also a facility for converting
15.37 + * a <code>String</code> into
15.38 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
15.39 + * format and writing the resulting series
15.40 + * of bytes.
15.41 + * <p>
15.42 + * For all the methods in this interface that
15.43 + * write bytes, it is generally true that if
15.44 + * a byte cannot be written for any reason,
15.45 + * an <code>IOException</code> is thrown.
15.46 + *
15.47 + * @author Frank Yellin
15.48 + * @see java.io.DataInput
15.49 + * @see java.io.DataOutputStream
15.50 + * @since JDK1.0
15.51 + */
15.52 +public
15.53 +interface DataOutput {
15.54 + /**
15.55 + * Writes to the output stream the eight
15.56 + * low-order bits of the argument <code>b</code>.
15.57 + * The 24 high-order bits of <code>b</code>
15.58 + * are ignored.
15.59 + *
15.60 + * @param b the byte to be written.
15.61 + * @throws IOException if an I/O error occurs.
15.62 + */
15.63 + void write(int b) throws IOException;
15.64 +
15.65 + /**
15.66 + * Writes to the output stream all the bytes in array <code>b</code>.
15.67 + * If <code>b</code> is <code>null</code>,
15.68 + * a <code>NullPointerException</code> is thrown.
15.69 + * If <code>b.length</code> is zero, then
15.70 + * no bytes are written. Otherwise, the byte
15.71 + * <code>b[0]</code> is written first, then
15.72 + * <code>b[1]</code>, and so on; the last byte
15.73 + * written is <code>b[b.length-1]</code>.
15.74 + *
15.75 + * @param b the data.
15.76 + * @throws IOException if an I/O error occurs.
15.77 + */
15.78 + void write(byte b[]) throws IOException;
15.79 +
15.80 + /**
15.81 + * Writes <code>len</code> bytes from array
15.82 + * <code>b</code>, in order, to
15.83 + * the output stream. If <code>b</code>
15.84 + * is <code>null</code>, a <code>NullPointerException</code>
15.85 + * is thrown. If <code>off</code> is negative,
15.86 + * or <code>len</code> is negative, or <code>off+len</code>
15.87 + * is greater than the length of the array
15.88 + * <code>b</code>, then an <code>IndexOutOfBoundsException</code>
15.89 + * is thrown. If <code>len</code> is zero,
15.90 + * then no bytes are written. Otherwise, the
15.91 + * byte <code>b[off]</code> is written first,
15.92 + * then <code>b[off+1]</code>, and so on; the
15.93 + * last byte written is <code>b[off+len-1]</code>.
15.94 + *
15.95 + * @param b the data.
15.96 + * @param off the start offset in the data.
15.97 + * @param len the number of bytes to write.
15.98 + * @throws IOException if an I/O error occurs.
15.99 + */
15.100 + void write(byte b[], int off, int len) throws IOException;
15.101 +
15.102 + /**
15.103 + * Writes a <code>boolean</code> value to this output stream.
15.104 + * If the argument <code>v</code>
15.105 + * is <code>true</code>, the value <code>(byte)1</code>
15.106 + * is written; if <code>v</code> is <code>false</code>,
15.107 + * the value <code>(byte)0</code> is written.
15.108 + * The byte written by this method may
15.109 + * be read by the <code>readBoolean</code>
15.110 + * method of interface <code>DataInput</code>,
15.111 + * which will then return a <code>boolean</code>
15.112 + * equal to <code>v</code>.
15.113 + *
15.114 + * @param v the boolean to be written.
15.115 + * @throws IOException if an I/O error occurs.
15.116 + */
15.117 + void writeBoolean(boolean v) throws IOException;
15.118 +
15.119 + /**
15.120 + * Writes to the output stream the eight low-
15.121 + * order bits of the argument <code>v</code>.
15.122 + * The 24 high-order bits of <code>v</code>
15.123 + * are ignored. (This means that <code>writeByte</code>
15.124 + * does exactly the same thing as <code>write</code>
15.125 + * for an integer argument.) The byte written
15.126 + * by this method may be read by the <code>readByte</code>
15.127 + * method of interface <code>DataInput</code>,
15.128 + * which will then return a <code>byte</code>
15.129 + * equal to <code>(byte)v</code>.
15.130 + *
15.131 + * @param v the byte value to be written.
15.132 + * @throws IOException if an I/O error occurs.
15.133 + */
15.134 + void writeByte(int v) throws IOException;
15.135 +
15.136 + /**
15.137 + * Writes two bytes to the output
15.138 + * stream to represent the value of the argument.
15.139 + * The byte values to be written, in the order
15.140 + * shown, are: <p>
15.141 + * <pre><code>
15.142 + * (byte)(0xff & (v >> 8))
15.143 + * (byte)(0xff & v)
15.144 + * </code> </pre> <p>
15.145 + * The bytes written by this method may be
15.146 + * read by the <code>readShort</code> method
15.147 + * of interface <code>DataInput</code> , which
15.148 + * will then return a <code>short</code> equal
15.149 + * to <code>(short)v</code>.
15.150 + *
15.151 + * @param v the <code>short</code> value to be written.
15.152 + * @throws IOException if an I/O error occurs.
15.153 + */
15.154 + void writeShort(int v) throws IOException;
15.155 +
15.156 + /**
15.157 + * Writes a <code>char</code> value, which
15.158 + * is comprised of two bytes, to the
15.159 + * output stream.
15.160 + * The byte values to be written, in the order
15.161 + * shown, are:
15.162 + * <p><pre><code>
15.163 + * (byte)(0xff & (v >> 8))
15.164 + * (byte)(0xff & v)
15.165 + * </code></pre><p>
15.166 + * The bytes written by this method may be
15.167 + * read by the <code>readChar</code> method
15.168 + * of interface <code>DataInput</code> , which
15.169 + * will then return a <code>char</code> equal
15.170 + * to <code>(char)v</code>.
15.171 + *
15.172 + * @param v the <code>char</code> value to be written.
15.173 + * @throws IOException if an I/O error occurs.
15.174 + */
15.175 + void writeChar(int v) throws IOException;
15.176 +
15.177 + /**
15.178 + * Writes an <code>int</code> value, which is
15.179 + * comprised of four bytes, to the output stream.
15.180 + * The byte values to be written, in the order
15.181 + * shown, are:
15.182 + * <p><pre><code>
15.183 + * (byte)(0xff & (v >> 24))
15.184 + * (byte)(0xff & (v >> 16))
15.185 + * (byte)(0xff & (v >>    8))
15.186 + * (byte)(0xff & v)
15.187 + * </code></pre><p>
15.188 + * The bytes written by this method may be read
15.189 + * by the <code>readInt</code> method of interface
15.190 + * <code>DataInput</code> , which will then
15.191 + * return an <code>int</code> equal to <code>v</code>.
15.192 + *
15.193 + * @param v the <code>int</code> value to be written.
15.194 + * @throws IOException if an I/O error occurs.
15.195 + */
15.196 + void writeInt(int v) throws IOException;
15.197 +
15.198 + /**
15.199 + * Writes a <code>long</code> value, which is
15.200 + * comprised of eight bytes, to the output stream.
15.201 + * The byte values to be written, in the order
15.202 + * shown, are:
15.203 + * <p><pre><code>
15.204 + * (byte)(0xff & (v >> 56))
15.205 + * (byte)(0xff & (v >> 48))
15.206 + * (byte)(0xff & (v >> 40))
15.207 + * (byte)(0xff & (v >> 32))
15.208 + * (byte)(0xff & (v >> 24))
15.209 + * (byte)(0xff & (v >> 16))
15.210 + * (byte)(0xff & (v >> 8))
15.211 + * (byte)(0xff & v)
15.212 + * </code></pre><p>
15.213 + * The bytes written by this method may be
15.214 + * read by the <code>readLong</code> method
15.215 + * of interface <code>DataInput</code> , which
15.216 + * will then return a <code>long</code> equal
15.217 + * to <code>v</code>.
15.218 + *
15.219 + * @param v the <code>long</code> value to be written.
15.220 + * @throws IOException if an I/O error occurs.
15.221 + */
15.222 + void writeLong(long v) throws IOException;
15.223 +
15.224 + /**
15.225 + * Writes a <code>float</code> value,
15.226 + * which is comprised of four bytes, to the output stream.
15.227 + * It does this as if it first converts this
15.228 + * <code>float</code> value to an <code>int</code>
15.229 + * in exactly the manner of the <code>Float.floatToIntBits</code>
15.230 + * method and then writes the <code>int</code>
15.231 + * value in exactly the manner of the <code>writeInt</code>
15.232 + * method. The bytes written by this method
15.233 + * may be read by the <code>readFloat</code>
15.234 + * method of interface <code>DataInput</code>,
15.235 + * which will then return a <code>float</code>
15.236 + * equal to <code>v</code>.
15.237 + *
15.238 + * @param v the <code>float</code> value to be written.
15.239 + * @throws IOException if an I/O error occurs.
15.240 + */
15.241 + void writeFloat(float v) throws IOException;
15.242 +
15.243 + /**
15.244 + * Writes a <code>double</code> value,
15.245 + * which is comprised of eight bytes, to the output stream.
15.246 + * It does this as if it first converts this
15.247 + * <code>double</code> value to a <code>long</code>
15.248 + * in exactly the manner of the <code>Double.doubleToLongBits</code>
15.249 + * method and then writes the <code>long</code>
15.250 + * value in exactly the manner of the <code>writeLong</code>
15.251 + * method. The bytes written by this method
15.252 + * may be read by the <code>readDouble</code>
15.253 + * method of interface <code>DataInput</code>,
15.254 + * which will then return a <code>double</code>
15.255 + * equal to <code>v</code>.
15.256 + *
15.257 + * @param v the <code>double</code> value to be written.
15.258 + * @throws IOException if an I/O error occurs.
15.259 + */
15.260 + void writeDouble(double v) throws IOException;
15.261 +
15.262 + /**
15.263 + * Writes a string to the output stream.
15.264 + * For every character in the string
15.265 + * <code>s</code>, taken in order, one byte
15.266 + * is written to the output stream. If
15.267 + * <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
15.268 + * is thrown.<p> If <code>s.length</code>
15.269 + * is zero, then no bytes are written. Otherwise,
15.270 + * the character <code>s[0]</code> is written
15.271 + * first, then <code>s[1]</code>, and so on;
15.272 + * the last character written is <code>s[s.length-1]</code>.
15.273 + * For each character, one byte is written,
15.274 + * the low-order byte, in exactly the manner
15.275 + * of the <code>writeByte</code> method . The
15.276 + * high-order eight bits of each character
15.277 + * in the string are ignored.
15.278 + *
15.279 + * @param s the string of bytes to be written.
15.280 + * @throws IOException if an I/O error occurs.
15.281 + */
15.282 + void writeBytes(String s) throws IOException;
15.283 +
15.284 + /**
15.285 + * Writes every character in the string <code>s</code>,
15.286 + * to the output stream, in order,
15.287 + * two bytes per character. If <code>s</code>
15.288 + * is <code>null</code>, a <code>NullPointerException</code>
15.289 + * is thrown. If <code>s.length</code>
15.290 + * is zero, then no characters are written.
15.291 + * Otherwise, the character <code>s[0]</code>
15.292 + * is written first, then <code>s[1]</code>,
15.293 + * and so on; the last character written is
15.294 + * <code>s[s.length-1]</code>. For each character,
15.295 + * two bytes are actually written, high-order
15.296 + * byte first, in exactly the manner of the
15.297 + * <code>writeChar</code> method.
15.298 + *
15.299 + * @param s the string value to be written.
15.300 + * @throws IOException if an I/O error occurs.
15.301 + */
15.302 + void writeChars(String s) throws IOException;
15.303 +
15.304 + /**
15.305 + * Writes two bytes of length information
15.306 + * to the output stream, followed
15.307 + * by the
15.308 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
15.309 + * representation
15.310 + * of every character in the string <code>s</code>.
15.311 + * If <code>s</code> is <code>null</code>,
15.312 + * a <code>NullPointerException</code> is thrown.
15.313 + * Each character in the string <code>s</code>
15.314 + * is converted to a group of one, two, or
15.315 + * three bytes, depending on the value of the
15.316 + * character.<p>
15.317 + * If a character <code>c</code>
15.318 + * is in the range <code>\u0001</code> through
15.319 + * <code>\u007f</code>, it is represented
15.320 + * by one byte:<p>
15.321 + * <pre>(byte)c </pre> <p>
15.322 + * If a character <code>c</code> is <code>\u0000</code>
15.323 + * or is in the range <code>\u0080</code>
15.324 + * through <code>\u07ff</code>, then it is
15.325 + * represented by two bytes, to be written
15.326 + * in the order shown:<p> <pre><code>
15.327 + * (byte)(0xc0 | (0x1f & (c >> 6)))
15.328 + * (byte)(0x80 | (0x3f & c))
15.329 + * </code></pre> <p> If a character
15.330 + * <code>c</code> is in the range <code>\u0800</code>
15.331 + * through <code>uffff</code>, then it is
15.332 + * represented by three bytes, to be written
15.333 + * in the order shown:<p> <pre><code>
15.334 + * (byte)(0xe0 | (0x0f & (c >> 12)))
15.335 + * (byte)(0x80 | (0x3f & (c >> 6)))
15.336 + * (byte)(0x80 | (0x3f & c))
15.337 + * </code></pre> <p> First,
15.338 + * the total number of bytes needed to represent
15.339 + * all the characters of <code>s</code> is
15.340 + * calculated. If this number is larger than
15.341 + * <code>65535</code>, then a <code>UTFDataFormatException</code>
15.342 + * is thrown. Otherwise, this length is written
15.343 + * to the output stream in exactly the manner
15.344 + * of the <code>writeShort</code> method;
15.345 + * after this, the one-, two-, or three-byte
15.346 + * representation of each character in the
15.347 + * string <code>s</code> is written.<p> The
15.348 + * bytes written by this method may be read
15.349 + * by the <code>readUTF</code> method of interface
15.350 + * <code>DataInput</code> , which will then
15.351 + * return a <code>String</code> equal to <code>s</code>.
15.352 + *
15.353 + * @param s the string value to be written.
15.354 + * @throws IOException if an I/O error occurs.
15.355 + */
15.356 + void writeUTF(String s) throws IOException;
15.357 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/emul/compact/src/main/java/java/io/DataOutputStream.java Tue Feb 05 17:04:22 2013 +0100
16.3 @@ -0,0 +1,416 @@
16.4 +/*
16.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.7 + *
16.8 + * This code is free software; you can redistribute it and/or modify it
16.9 + * under the terms of the GNU General Public License version 2 only, as
16.10 + * published by the Free Software Foundation. Oracle designates this
16.11 + * particular file as subject to the "Classpath" exception as provided
16.12 + * by Oracle in the LICENSE file that accompanied this code.
16.13 + *
16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.17 + * version 2 for more details (a copy is included in the LICENSE file that
16.18 + * accompanied this code).
16.19 + *
16.20 + * You should have received a copy of the GNU General Public License version
16.21 + * 2 along with this work; if not, write to the Free Software Foundation,
16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.23 + *
16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16.25 + * or visit www.oracle.com if you need additional information or have any
16.26 + * questions.
16.27 + */
16.28 +
16.29 +package java.io;
16.30 +
16.31 +/**
16.32 + * A data output stream lets an application write primitive Java data
16.33 + * types to an output stream in a portable way. An application can
16.34 + * then use a data input stream to read the data back in.
16.35 + *
16.36 + * @author unascribed
16.37 + * @see java.io.DataInputStream
16.38 + * @since JDK1.0
16.39 + */
16.40 +public
16.41 +class DataOutputStream extends FilterOutputStream implements DataOutput {
16.42 + /**
16.43 + * The number of bytes written to the data output stream so far.
16.44 + * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
16.45 + */
16.46 + protected int written;
16.47 +
16.48 + /**
16.49 + * bytearr is initialized on demand by writeUTF
16.50 + */
16.51 + private byte[] bytearr = null;
16.52 +
16.53 + /**
16.54 + * Creates a new data output stream to write data to the specified
16.55 + * underlying output stream. The counter <code>written</code> is
16.56 + * set to zero.
16.57 + *
16.58 + * @param out the underlying output stream, to be saved for later
16.59 + * use.
16.60 + * @see java.io.FilterOutputStream#out
16.61 + */
16.62 + public DataOutputStream(OutputStream out) {
16.63 + super(out);
16.64 + }
16.65 +
16.66 + /**
16.67 + * Increases the written counter by the specified value
16.68 + * until it reaches Integer.MAX_VALUE.
16.69 + */
16.70 + private void incCount(int value) {
16.71 + int temp = written + value;
16.72 + if (temp < 0) {
16.73 + temp = Integer.MAX_VALUE;
16.74 + }
16.75 + written = temp;
16.76 + }
16.77 +
16.78 + /**
16.79 + * Writes the specified byte (the low eight bits of the argument
16.80 + * <code>b</code>) to the underlying output stream. If no exception
16.81 + * is thrown, the counter <code>written</code> is incremented by
16.82 + * <code>1</code>.
16.83 + * <p>
16.84 + * Implements the <code>write</code> method of <code>OutputStream</code>.
16.85 + *
16.86 + * @param b the <code>byte</code> to be written.
16.87 + * @exception IOException if an I/O error occurs.
16.88 + * @see java.io.FilterOutputStream#out
16.89 + */
16.90 + public synchronized void write(int b) throws IOException {
16.91 + out.write(b);
16.92 + incCount(1);
16.93 + }
16.94 +
16.95 + /**
16.96 + * Writes <code>len</code> bytes from the specified byte array
16.97 + * starting at offset <code>off</code> to the underlying output stream.
16.98 + * If no exception is thrown, the counter <code>written</code> is
16.99 + * incremented by <code>len</code>.
16.100 + *
16.101 + * @param b the data.
16.102 + * @param off the start offset in the data.
16.103 + * @param len the number of bytes to write.
16.104 + * @exception IOException if an I/O error occurs.
16.105 + * @see java.io.FilterOutputStream#out
16.106 + */
16.107 + public synchronized void write(byte b[], int off, int len)
16.108 + throws IOException
16.109 + {
16.110 + out.write(b, off, len);
16.111 + incCount(len);
16.112 + }
16.113 +
16.114 + /**
16.115 + * Flushes this data output stream. This forces any buffered output
16.116 + * bytes to be written out to the stream.
16.117 + * <p>
16.118 + * The <code>flush</code> method of <code>DataOutputStream</code>
16.119 + * calls the <code>flush</code> method of its underlying output stream.
16.120 + *
16.121 + * @exception IOException if an I/O error occurs.
16.122 + * @see java.io.FilterOutputStream#out
16.123 + * @see java.io.OutputStream#flush()
16.124 + */
16.125 + public void flush() throws IOException {
16.126 + out.flush();
16.127 + }
16.128 +
16.129 + /**
16.130 + * Writes a <code>boolean</code> to the underlying output stream as
16.131 + * a 1-byte value. The value <code>true</code> is written out as the
16.132 + * value <code>(byte)1</code>; the value <code>false</code> is
16.133 + * written out as the value <code>(byte)0</code>. If no exception is
16.134 + * thrown, the counter <code>written</code> is incremented by
16.135 + * <code>1</code>.
16.136 + *
16.137 + * @param v a <code>boolean</code> value to be written.
16.138 + * @exception IOException if an I/O error occurs.
16.139 + * @see java.io.FilterOutputStream#out
16.140 + */
16.141 + public final void writeBoolean(boolean v) throws IOException {
16.142 + out.write(v ? 1 : 0);
16.143 + incCount(1);
16.144 + }
16.145 +
16.146 + /**
16.147 + * Writes out a <code>byte</code> to the underlying output stream as
16.148 + * a 1-byte value. If no exception is thrown, the counter
16.149 + * <code>written</code> is incremented by <code>1</code>.
16.150 + *
16.151 + * @param v a <code>byte</code> value to be written.
16.152 + * @exception IOException if an I/O error occurs.
16.153 + * @see java.io.FilterOutputStream#out
16.154 + */
16.155 + public final void writeByte(int v) throws IOException {
16.156 + out.write(v);
16.157 + incCount(1);
16.158 + }
16.159 +
16.160 + /**
16.161 + * Writes a <code>short</code> to the underlying output stream as two
16.162 + * bytes, high byte first. If no exception is thrown, the counter
16.163 + * <code>written</code> is incremented by <code>2</code>.
16.164 + *
16.165 + * @param v a <code>short</code> to be written.
16.166 + * @exception IOException if an I/O error occurs.
16.167 + * @see java.io.FilterOutputStream#out
16.168 + */
16.169 + public final void writeShort(int v) throws IOException {
16.170 + out.write((v >>> 8) & 0xFF);
16.171 + out.write((v >>> 0) & 0xFF);
16.172 + incCount(2);
16.173 + }
16.174 +
16.175 + /**
16.176 + * Writes a <code>char</code> to the underlying output stream as a
16.177 + * 2-byte value, high byte first. If no exception is thrown, the
16.178 + * counter <code>written</code> is incremented by <code>2</code>.
16.179 + *
16.180 + * @param v a <code>char</code> value to be written.
16.181 + * @exception IOException if an I/O error occurs.
16.182 + * @see java.io.FilterOutputStream#out
16.183 + */
16.184 + public final void writeChar(int v) throws IOException {
16.185 + out.write((v >>> 8) & 0xFF);
16.186 + out.write((v >>> 0) & 0xFF);
16.187 + incCount(2);
16.188 + }
16.189 +
16.190 + /**
16.191 + * Writes an <code>int</code> to the underlying output stream as four
16.192 + * bytes, high byte first. If no exception is thrown, the counter
16.193 + * <code>written</code> is incremented by <code>4</code>.
16.194 + *
16.195 + * @param v an <code>int</code> to be written.
16.196 + * @exception IOException if an I/O error occurs.
16.197 + * @see java.io.FilterOutputStream#out
16.198 + */
16.199 + public final void writeInt(int v) throws IOException {
16.200 + out.write((v >>> 24) & 0xFF);
16.201 + out.write((v >>> 16) & 0xFF);
16.202 + out.write((v >>> 8) & 0xFF);
16.203 + out.write((v >>> 0) & 0xFF);
16.204 + incCount(4);
16.205 + }
16.206 +
16.207 + private byte writeBuffer[] = new byte[8];
16.208 +
16.209 + /**
16.210 + * Writes a <code>long</code> to the underlying output stream as eight
16.211 + * bytes, high byte first. In no exception is thrown, the counter
16.212 + * <code>written</code> is incremented by <code>8</code>.
16.213 + *
16.214 + * @param v a <code>long</code> to be written.
16.215 + * @exception IOException if an I/O error occurs.
16.216 + * @see java.io.FilterOutputStream#out
16.217 + */
16.218 + public final void writeLong(long v) throws IOException {
16.219 + writeBuffer[0] = (byte)(v >>> 56);
16.220 + writeBuffer[1] = (byte)(v >>> 48);
16.221 + writeBuffer[2] = (byte)(v >>> 40);
16.222 + writeBuffer[3] = (byte)(v >>> 32);
16.223 + writeBuffer[4] = (byte)(v >>> 24);
16.224 + writeBuffer[5] = (byte)(v >>> 16);
16.225 + writeBuffer[6] = (byte)(v >>> 8);
16.226 + writeBuffer[7] = (byte)(v >>> 0);
16.227 + out.write(writeBuffer, 0, 8);
16.228 + incCount(8);
16.229 + }
16.230 +
16.231 + /**
16.232 + * Converts the float argument to an <code>int</code> using the
16.233 + * <code>floatToIntBits</code> method in class <code>Float</code>,
16.234 + * and then writes that <code>int</code> value to the underlying
16.235 + * output stream as a 4-byte quantity, high byte first. If no
16.236 + * exception is thrown, the counter <code>written</code> is
16.237 + * incremented by <code>4</code>.
16.238 + *
16.239 + * @param v a <code>float</code> value to be written.
16.240 + * @exception IOException if an I/O error occurs.
16.241 + * @see java.io.FilterOutputStream#out
16.242 + * @see java.lang.Float#floatToIntBits(float)
16.243 + */
16.244 + public final void writeFloat(float v) throws IOException {
16.245 + writeInt(Float.floatToIntBits(v));
16.246 + }
16.247 +
16.248 + /**
16.249 + * Converts the double argument to a <code>long</code> using the
16.250 + * <code>doubleToLongBits</code> method in class <code>Double</code>,
16.251 + * and then writes that <code>long</code> value to the underlying
16.252 + * output stream as an 8-byte quantity, high byte first. If no
16.253 + * exception is thrown, the counter <code>written</code> is
16.254 + * incremented by <code>8</code>.
16.255 + *
16.256 + * @param v a <code>double</code> value to be written.
16.257 + * @exception IOException if an I/O error occurs.
16.258 + * @see java.io.FilterOutputStream#out
16.259 + * @see java.lang.Double#doubleToLongBits(double)
16.260 + */
16.261 + public final void writeDouble(double v) throws IOException {
16.262 + writeLong(Double.doubleToLongBits(v));
16.263 + }
16.264 +
16.265 + /**
16.266 + * Writes out the string to the underlying output stream as a
16.267 + * sequence of bytes. Each character in the string is written out, in
16.268 + * sequence, by discarding its high eight bits. If no exception is
16.269 + * thrown, the counter <code>written</code> is incremented by the
16.270 + * length of <code>s</code>.
16.271 + *
16.272 + * @param s a string of bytes to be written.
16.273 + * @exception IOException if an I/O error occurs.
16.274 + * @see java.io.FilterOutputStream#out
16.275 + */
16.276 + public final void writeBytes(String s) throws IOException {
16.277 + int len = s.length();
16.278 + for (int i = 0 ; i < len ; i++) {
16.279 + out.write((byte)s.charAt(i));
16.280 + }
16.281 + incCount(len);
16.282 + }
16.283 +
16.284 + /**
16.285 + * Writes a string to the underlying output stream as a sequence of
16.286 + * characters. Each character is written to the data output stream as
16.287 + * if by the <code>writeChar</code> method. If no exception is
16.288 + * thrown, the counter <code>written</code> is incremented by twice
16.289 + * the length of <code>s</code>.
16.290 + *
16.291 + * @param s a <code>String</code> value to be written.
16.292 + * @exception IOException if an I/O error occurs.
16.293 + * @see java.io.DataOutputStream#writeChar(int)
16.294 + * @see java.io.FilterOutputStream#out
16.295 + */
16.296 + public final void writeChars(String s) throws IOException {
16.297 + int len = s.length();
16.298 + for (int i = 0 ; i < len ; i++) {
16.299 + int v = s.charAt(i);
16.300 + out.write((v >>> 8) & 0xFF);
16.301 + out.write((v >>> 0) & 0xFF);
16.302 + }
16.303 + incCount(len * 2);
16.304 + }
16.305 +
16.306 + /**
16.307 + * Writes a string to the underlying output stream using
16.308 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
16.309 + * encoding in a machine-independent manner.
16.310 + * <p>
16.311 + * First, two bytes are written to the output stream as if by the
16.312 + * <code>writeShort</code> method giving the number of bytes to
16.313 + * follow. This value is the number of bytes actually written out,
16.314 + * not the length of the string. Following the length, each character
16.315 + * of the string is output, in sequence, using the modified UTF-8 encoding
16.316 + * for the character. If no exception is thrown, the counter
16.317 + * <code>written</code> is incremented by the total number of
16.318 + * bytes written to the output stream. This will be at least two
16.319 + * plus the length of <code>str</code>, and at most two plus
16.320 + * thrice the length of <code>str</code>.
16.321 + *
16.322 + * @param str a string to be written.
16.323 + * @exception IOException if an I/O error occurs.
16.324 + */
16.325 + public final void writeUTF(String str) throws IOException {
16.326 + writeUTF(str, this);
16.327 + }
16.328 +
16.329 + /**
16.330 + * Writes a string to the specified DataOutput using
16.331 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
16.332 + * encoding in a machine-independent manner.
16.333 + * <p>
16.334 + * First, two bytes are written to out as if by the <code>writeShort</code>
16.335 + * method giving the number of bytes to follow. This value is the number of
16.336 + * bytes actually written out, not the length of the string. Following the
16.337 + * length, each character of the string is output, in sequence, using the
16.338 + * modified UTF-8 encoding for the character. If no exception is thrown, the
16.339 + * counter <code>written</code> is incremented by the total number of
16.340 + * bytes written to the output stream. This will be at least two
16.341 + * plus the length of <code>str</code>, and at most two plus
16.342 + * thrice the length of <code>str</code>.
16.343 + *
16.344 + * @param str a string to be written.
16.345 + * @param out destination to write to
16.346 + * @return The number of bytes written out.
16.347 + * @exception IOException if an I/O error occurs.
16.348 + */
16.349 + static int writeUTF(String str, DataOutput out) throws IOException {
16.350 + int strlen = str.length();
16.351 + int utflen = 0;
16.352 + int c, count = 0;
16.353 +
16.354 + /* use charAt instead of copying String to char array */
16.355 + for (int i = 0; i < strlen; i++) {
16.356 + c = str.charAt(i);
16.357 + if ((c >= 0x0001) && (c <= 0x007F)) {
16.358 + utflen++;
16.359 + } else if (c > 0x07FF) {
16.360 + utflen += 3;
16.361 + } else {
16.362 + utflen += 2;
16.363 + }
16.364 + }
16.365 +
16.366 + if (utflen > 65535)
16.367 + throw new UTFDataFormatException(
16.368 + "encoded string too long: " + utflen + " bytes");
16.369 +
16.370 + byte[] bytearr = null;
16.371 + if (out instanceof DataOutputStream) {
16.372 + DataOutputStream dos = (DataOutputStream)out;
16.373 + if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
16.374 + dos.bytearr = new byte[(utflen*2) + 2];
16.375 + bytearr = dos.bytearr;
16.376 + } else {
16.377 + bytearr = new byte[utflen+2];
16.378 + }
16.379 +
16.380 + bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
16.381 + bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
16.382 +
16.383 + int i=0;
16.384 + for (i=0; i<strlen; i++) {
16.385 + c = str.charAt(i);
16.386 + if (!((c >= 0x0001) && (c <= 0x007F))) break;
16.387 + bytearr[count++] = (byte) c;
16.388 + }
16.389 +
16.390 + for (;i < strlen; i++){
16.391 + c = str.charAt(i);
16.392 + if ((c >= 0x0001) && (c <= 0x007F)) {
16.393 + bytearr[count++] = (byte) c;
16.394 +
16.395 + } else if (c > 0x07FF) {
16.396 + bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
16.397 + bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
16.398 + bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
16.399 + } else {
16.400 + bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
16.401 + bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
16.402 + }
16.403 + }
16.404 + out.write(bytearr, 0, utflen+2);
16.405 + return utflen + 2;
16.406 + }
16.407 +
16.408 + /**
16.409 + * Returns the current value of the counter <code>written</code>,
16.410 + * the number of bytes written to this data output stream so far.
16.411 + * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
16.412 + *
16.413 + * @return the value of the <code>written</code> field.
16.414 + * @see java.io.DataOutputStream#written
16.415 + */
16.416 + public final int size() {
16.417 + return written;
16.418 + }
16.419 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/emul/compact/src/main/java/java/io/Externalizable.java Tue Feb 05 17:04:22 2013 +0100
17.3 @@ -0,0 +1,97 @@
17.4 +/*
17.5 + * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.7 + *
17.8 + * This code is free software; you can redistribute it and/or modify it
17.9 + * under the terms of the GNU General Public License version 2 only, as
17.10 + * published by the Free Software Foundation. Oracle designates this
17.11 + * particular file as subject to the "Classpath" exception as provided
17.12 + * by Oracle in the LICENSE file that accompanied this code.
17.13 + *
17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.17 + * version 2 for more details (a copy is included in the LICENSE file that
17.18 + * accompanied this code).
17.19 + *
17.20 + * You should have received a copy of the GNU General Public License version
17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.23 + *
17.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
17.25 + * or visit www.oracle.com if you need additional information or have any
17.26 + * questions.
17.27 + */
17.28 +
17.29 +package java.io;
17.30 +
17.31 +import java.io.ObjectOutput;
17.32 +import java.io.ObjectInput;
17.33 +
17.34 +/**
17.35 + * Only the identity of the class of an Externalizable instance is
17.36 + * written in the serialization stream and it is the responsibility
17.37 + * of the class to save and restore the contents of its instances.
17.38 + *
17.39 + * The writeExternal and readExternal methods of the Externalizable
17.40 + * interface are implemented by a class to give the class complete
17.41 + * control over the format and contents of the stream for an object
17.42 + * and its supertypes. These methods must explicitly
17.43 + * coordinate with the supertype to save its state. These methods supersede
17.44 + * customized implementations of writeObject and readObject methods.<br>
17.45 + *
17.46 + * Object Serialization uses the Serializable and Externalizable
17.47 + * interfaces. Object persistence mechanisms can use them as well. Each
17.48 + * object to be stored is tested for the Externalizable interface. If
17.49 + * the object supports Externalizable, the writeExternal method is called. If the
17.50 + * object does not support Externalizable and does implement
17.51 + * Serializable, the object is saved using
17.52 + * ObjectOutputStream. <br> When an Externalizable object is
17.53 + * reconstructed, an instance is created using the public no-arg
17.54 + * constructor, then the readExternal method called. Serializable
17.55 + * objects are restored by reading them from an ObjectInputStream.<br>
17.56 + *
17.57 + * An Externalizable instance can designate a substitution object via
17.58 + * the writeReplace and readResolve methods documented in the Serializable
17.59 + * interface.<br>
17.60 + *
17.61 + * @author unascribed
17.62 + * @see java.io.ObjectOutputStream
17.63 + * @see java.io.ObjectInputStream
17.64 + * @see java.io.ObjectOutput
17.65 + * @see java.io.ObjectInput
17.66 + * @see java.io.Serializable
17.67 + * @since JDK1.1
17.68 + */
17.69 +public interface Externalizable extends java.io.Serializable {
17.70 + /**
17.71 + * The object implements the writeExternal method to save its contents
17.72 + * by calling the methods of DataOutput for its primitive values or
17.73 + * calling the writeObject method of ObjectOutput for objects, strings,
17.74 + * and arrays.
17.75 + *
17.76 + * @serialData Overriding methods should use this tag to describe
17.77 + * the data layout of this Externalizable object.
17.78 + * List the sequence of element types and, if possible,
17.79 + * relate the element to a public/protected field and/or
17.80 + * method of this Externalizable class.
17.81 + *
17.82 + * @param out the stream to write the object to
17.83 + * @exception IOException Includes any I/O exceptions that may occur
17.84 + */
17.85 + void writeExternal(ObjectOutput out) throws IOException;
17.86 +
17.87 + /**
17.88 + * The object implements the readExternal method to restore its
17.89 + * contents by calling the methods of DataInput for primitive
17.90 + * types and readObject for objects, strings and arrays. The
17.91 + * readExternal method must read the values in the same sequence
17.92 + * and with the same types as were written by writeExternal.
17.93 + *
17.94 + * @param in the stream to read data from in order to restore the object
17.95 + * @exception IOException if I/O errors occur
17.96 + * @exception ClassNotFoundException If the class for an object being
17.97 + * restored cannot be found.
17.98 + */
17.99 + void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
17.100 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/emul/compact/src/main/java/java/io/FilterOutputStream.java Tue Feb 05 17:04:22 2013 +0100
18.3 @@ -0,0 +1,162 @@
18.4 +/*
18.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.7 + *
18.8 + * This code is free software; you can redistribute it and/or modify it
18.9 + * under the terms of the GNU General Public License version 2 only, as
18.10 + * published by the Free Software Foundation. Oracle designates this
18.11 + * particular file as subject to the "Classpath" exception as provided
18.12 + * by Oracle in the LICENSE file that accompanied this code.
18.13 + *
18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.17 + * version 2 for more details (a copy is included in the LICENSE file that
18.18 + * accompanied this code).
18.19 + *
18.20 + * You should have received a copy of the GNU General Public License version
18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.23 + *
18.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
18.25 + * or visit www.oracle.com if you need additional information or have any
18.26 + * questions.
18.27 + */
18.28 +
18.29 +package java.io;
18.30 +
18.31 +/**
18.32 + * This class is the superclass of all classes that filter output
18.33 + * streams. These streams sit on top of an already existing output
18.34 + * stream (the <i>underlying</i> output stream) which it uses as its
18.35 + * basic sink of data, but possibly transforming the data along the
18.36 + * way or providing additional functionality.
18.37 + * <p>
18.38 + * The class <code>FilterOutputStream</code> itself simply overrides
18.39 + * all methods of <code>OutputStream</code> with versions that pass
18.40 + * all requests to the underlying output stream. Subclasses of
18.41 + * <code>FilterOutputStream</code> may further override some of these
18.42 + * methods as well as provide additional methods and fields.
18.43 + *
18.44 + * @author Jonathan Payne
18.45 + * @since JDK1.0
18.46 + */
18.47 +public
18.48 +class FilterOutputStream extends OutputStream {
18.49 + /**
18.50 + * The underlying output stream to be filtered.
18.51 + */
18.52 + protected OutputStream out;
18.53 +
18.54 + /**
18.55 + * Creates an output stream filter built on top of the specified
18.56 + * underlying output stream.
18.57 + *
18.58 + * @param out the underlying output stream to be assigned to
18.59 + * the field <tt>this.out</tt> for later use, or
18.60 + * <code>null</code> if this instance is to be
18.61 + * created without an underlying stream.
18.62 + */
18.63 + public FilterOutputStream(OutputStream out) {
18.64 + this.out = out;
18.65 + }
18.66 +
18.67 + /**
18.68 + * Writes the specified <code>byte</code> to this output stream.
18.69 + * <p>
18.70 + * The <code>write</code> method of <code>FilterOutputStream</code>
18.71 + * calls the <code>write</code> method of its underlying output stream,
18.72 + * that is, it performs <tt>out.write(b)</tt>.
18.73 + * <p>
18.74 + * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>.
18.75 + *
18.76 + * @param b the <code>byte</code>.
18.77 + * @exception IOException if an I/O error occurs.
18.78 + */
18.79 + public void write(int b) throws IOException {
18.80 + out.write(b);
18.81 + }
18.82 +
18.83 + /**
18.84 + * Writes <code>b.length</code> bytes to this output stream.
18.85 + * <p>
18.86 + * The <code>write</code> method of <code>FilterOutputStream</code>
18.87 + * calls its <code>write</code> method of three arguments with the
18.88 + * arguments <code>b</code>, <code>0</code>, and
18.89 + * <code>b.length</code>.
18.90 + * <p>
18.91 + * Note that this method does not call the one-argument
18.92 + * <code>write</code> method of its underlying stream with the single
18.93 + * argument <code>b</code>.
18.94 + *
18.95 + * @param b the data to be written.
18.96 + * @exception IOException if an I/O error occurs.
18.97 + * @see java.io.FilterOutputStream#write(byte[], int, int)
18.98 + */
18.99 + public void write(byte b[]) throws IOException {
18.100 + write(b, 0, b.length);
18.101 + }
18.102 +
18.103 + /**
18.104 + * Writes <code>len</code> bytes from the specified
18.105 + * <code>byte</code> array starting at offset <code>off</code> to
18.106 + * this output stream.
18.107 + * <p>
18.108 + * The <code>write</code> method of <code>FilterOutputStream</code>
18.109 + * calls the <code>write</code> method of one argument on each
18.110 + * <code>byte</code> to output.
18.111 + * <p>
18.112 + * Note that this method does not call the <code>write</code> method
18.113 + * of its underlying input stream with the same arguments. Subclasses
18.114 + * of <code>FilterOutputStream</code> should provide a more efficient
18.115 + * implementation of this method.
18.116 + *
18.117 + * @param b the data.
18.118 + * @param off the start offset in the data.
18.119 + * @param len the number of bytes to write.
18.120 + * @exception IOException if an I/O error occurs.
18.121 + * @see java.io.FilterOutputStream#write(int)
18.122 + */
18.123 + public void write(byte b[], int off, int len) throws IOException {
18.124 + if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
18.125 + throw new IndexOutOfBoundsException();
18.126 +
18.127 + for (int i = 0 ; i < len ; i++) {
18.128 + write(b[off + i]);
18.129 + }
18.130 + }
18.131 +
18.132 + /**
18.133 + * Flushes this output stream and forces any buffered output bytes
18.134 + * to be written out to the stream.
18.135 + * <p>
18.136 + * The <code>flush</code> method of <code>FilterOutputStream</code>
18.137 + * calls the <code>flush</code> method of its underlying output stream.
18.138 + *
18.139 + * @exception IOException if an I/O error occurs.
18.140 + * @see java.io.FilterOutputStream#out
18.141 + */
18.142 + public void flush() throws IOException {
18.143 + out.flush();
18.144 + }
18.145 +
18.146 + /**
18.147 + * Closes this output stream and releases any system resources
18.148 + * associated with the stream.
18.149 + * <p>
18.150 + * The <code>close</code> method of <code>FilterOutputStream</code>
18.151 + * calls its <code>flush</code> method, and then calls the
18.152 + * <code>close</code> method of its underlying output stream.
18.153 + *
18.154 + * @exception IOException if an I/O error occurs.
18.155 + * @see java.io.FilterOutputStream#flush()
18.156 + * @see java.io.FilterOutputStream#out
18.157 + */
18.158 + public void close() throws IOException {
18.159 + try {
18.160 + flush();
18.161 + } catch (IOException ignored) {
18.162 + }
18.163 + out.close();
18.164 + }
18.165 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/emul/compact/src/main/java/java/io/Flushable.java Tue Feb 05 17:04:22 2013 +0100
19.3 @@ -0,0 +1,47 @@
19.4 +/*
19.5 + * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.7 + *
19.8 + * This code is free software; you can redistribute it and/or modify it
19.9 + * under the terms of the GNU General Public License version 2 only, as
19.10 + * published by the Free Software Foundation. Oracle designates this
19.11 + * particular file as subject to the "Classpath" exception as provided
19.12 + * by Oracle in the LICENSE file that accompanied this code.
19.13 + *
19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.17 + * version 2 for more details (a copy is included in the LICENSE file that
19.18 + * accompanied this code).
19.19 + *
19.20 + * You should have received a copy of the GNU General Public License version
19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.23 + *
19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19.25 + * or visit www.oracle.com if you need additional information or have any
19.26 + * questions.
19.27 + */
19.28 +
19.29 +package java.io;
19.30 +
19.31 +import java.io.IOException;
19.32 +
19.33 +/**
19.34 + * A <tt>Flushable</tt> is a destination of data that can be flushed. The
19.35 + * flush method is invoked to write any buffered output to the underlying
19.36 + * stream.
19.37 + *
19.38 + * @since 1.5
19.39 + */
19.40 +
19.41 +public interface Flushable {
19.42 +
19.43 + /**
19.44 + * Flushes this stream by writing any buffered output to the underlying
19.45 + * stream.
19.46 + *
19.47 + * @throws IOException If an I/O error occurs
19.48 + */
19.49 + void flush() throws IOException;
19.50 +}
20.1 --- a/emul/compact/src/main/java/java/io/InputStreamReader.java Tue Feb 05 16:40:01 2013 +0100
20.2 +++ b/emul/compact/src/main/java/java/io/InputStreamReader.java Tue Feb 05 17:04:22 2013 +0100
20.3 @@ -156,9 +156,39 @@
20.4 * @exception IOException If an I/O error occurs
20.5 */
20.6 public int read() throws IOException {
20.7 - return ((InputStream)lock).read();
20.8 + final InputStream is = (InputStream)lock;
20.9 + int c = is.read();
20.10 + if (c == -1) {
20.11 + return -1;
20.12 + }
20.13 + c = (int) c & 0xff;
20.14 + switch (c >> 4) {
20.15 + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
20.16 + /* 0xxxxxxx*/
20.17 + return c;
20.18 + case 12: case 13: {
20.19 + /* 110x xxxx 10xx xxxx*/
20.20 + int char2 = (int) is.read();
20.21 + if ((char2 & 0xC0) != 0x80)
20.22 + throw new UTFDataFormatException("malformed input");
20.23 + return (((c & 0x1F) << 6) | (char2 & 0x3F));
20.24 + }
20.25 + case 14: {
20.26 + /* 1110 xxxx 10xx xxxx 10xx xxxx */
20.27 + int char2 = is.read();
20.28 + int char3 = is.read();
20.29 + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
20.30 + throw new UTFDataFormatException("malformed input");
20.31 + return (((c & 0x0F) << 12) |
20.32 + ((char2 & 0x3F) << 6) |
20.33 + ((char3 & 0x3F) << 0));
20.34 + }
20.35 + default:
20.36 + /* 10xx xxxx, 1111 xxxx */
20.37 + throw new UTFDataFormatException("malformed input");
20.38 + }
20.39 }
20.40 -
20.41 +
20.42 /**
20.43 * Reads characters into a portion of an array.
20.44 *
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/emul/compact/src/main/java/java/io/InvalidClassException.java Tue Feb 05 17:04:22 2013 +0100
21.3 @@ -0,0 +1,81 @@
21.4 +/*
21.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.7 + *
21.8 + * This code is free software; you can redistribute it and/or modify it
21.9 + * under the terms of the GNU General Public License version 2 only, as
21.10 + * published by the Free Software Foundation. Oracle designates this
21.11 + * particular file as subject to the "Classpath" exception as provided
21.12 + * by Oracle in the LICENSE file that accompanied this code.
21.13 + *
21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.17 + * version 2 for more details (a copy is included in the LICENSE file that
21.18 + * accompanied this code).
21.19 + *
21.20 + * You should have received a copy of the GNU General Public License version
21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.23 + *
21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21.25 + * or visit www.oracle.com if you need additional information or have any
21.26 + * questions.
21.27 + */
21.28 +
21.29 +package java.io;
21.30 +
21.31 +/**
21.32 + * Thrown when the Serialization runtime detects one of the following
21.33 + * problems with a Class.
21.34 + * <UL>
21.35 + * <LI> The serial version of the class does not match that of the class
21.36 + * descriptor read from the stream
21.37 + * <LI> The class contains unknown datatypes
21.38 + * <LI> The class does not have an accessible no-arg constructor
21.39 + * </UL>
21.40 + *
21.41 + * @author unascribed
21.42 + * @since JDK1.1
21.43 + */
21.44 +public class InvalidClassException extends ObjectStreamException {
21.45 +
21.46 + private static final long serialVersionUID = -4333316296251054416L;
21.47 +
21.48 + /**
21.49 + * Name of the invalid class.
21.50 + *
21.51 + * @serial Name of the invalid class.
21.52 + */
21.53 + public String classname;
21.54 +
21.55 + /**
21.56 + * Report an InvalidClassException for the reason specified.
21.57 + *
21.58 + * @param reason String describing the reason for the exception.
21.59 + */
21.60 + public InvalidClassException(String reason) {
21.61 + super(reason);
21.62 + }
21.63 +
21.64 + /**
21.65 + * Constructs an InvalidClassException object.
21.66 + *
21.67 + * @param cname a String naming the invalid class.
21.68 + * @param reason a String describing the reason for the exception.
21.69 + */
21.70 + public InvalidClassException(String cname, String reason) {
21.71 + super(reason);
21.72 + classname = cname;
21.73 + }
21.74 +
21.75 + /**
21.76 + * Produce the message and include the classname, if present.
21.77 + */
21.78 + public String getMessage() {
21.79 + if (classname == null)
21.80 + return super.getMessage();
21.81 + else
21.82 + return classname + "; " + super.getMessage();
21.83 + }
21.84 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/emul/compact/src/main/java/java/io/InvalidObjectException.java Tue Feb 05 17:04:22 2013 +0100
22.3 @@ -0,0 +1,51 @@
22.4 +/*
22.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.7 + *
22.8 + * This code is free software; you can redistribute it and/or modify it
22.9 + * under the terms of the GNU General Public License version 2 only, as
22.10 + * published by the Free Software Foundation. Oracle designates this
22.11 + * particular file as subject to the "Classpath" exception as provided
22.12 + * by Oracle in the LICENSE file that accompanied this code.
22.13 + *
22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22.17 + * version 2 for more details (a copy is included in the LICENSE file that
22.18 + * accompanied this code).
22.19 + *
22.20 + * You should have received a copy of the GNU General Public License version
22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22.23 + *
22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22.25 + * or visit www.oracle.com if you need additional information or have any
22.26 + * questions.
22.27 + */
22.28 +
22.29 +package java.io;
22.30 +
22.31 +/**
22.32 + * Indicates that one or more deserialized objects failed validation
22.33 + * tests. The argument should provide the reason for the failure.
22.34 + *
22.35 + * @see ObjectInputValidation
22.36 + * @since JDK1.1
22.37 + *
22.38 + * @author unascribed
22.39 + * @since JDK1.1
22.40 + */
22.41 +public class InvalidObjectException extends ObjectStreamException {
22.42 +
22.43 + private static final long serialVersionUID = 3233174318281839583L;
22.44 +
22.45 + /**
22.46 + * Constructs an <code>InvalidObjectException</code>.
22.47 + * @param reason Detailed message explaining the reason for the failure.
22.48 + *
22.49 + * @see ObjectInputValidation
22.50 + */
22.51 + public InvalidObjectException(String reason) {
22.52 + super(reason);
22.53 + }
22.54 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/emul/compact/src/main/java/java/io/NotActiveException.java Tue Feb 05 17:04:22 2013 +0100
23.3 @@ -0,0 +1,53 @@
23.4 +/*
23.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23.7 + *
23.8 + * This code is free software; you can redistribute it and/or modify it
23.9 + * under the terms of the GNU General Public License version 2 only, as
23.10 + * published by the Free Software Foundation. Oracle designates this
23.11 + * particular file as subject to the "Classpath" exception as provided
23.12 + * by Oracle in the LICENSE file that accompanied this code.
23.13 + *
23.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
23.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23.17 + * version 2 for more details (a copy is included in the LICENSE file that
23.18 + * accompanied this code).
23.19 + *
23.20 + * You should have received a copy of the GNU General Public License version
23.21 + * 2 along with this work; if not, write to the Free Software Foundation,
23.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23.23 + *
23.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23.25 + * or visit www.oracle.com if you need additional information or have any
23.26 + * questions.
23.27 + */
23.28 +
23.29 +package java.io;
23.30 +
23.31 +/**
23.32 + * Thrown when serialization or deserialization is not active.
23.33 + *
23.34 + * @author unascribed
23.35 + * @since JDK1.1
23.36 + */
23.37 +public class NotActiveException extends ObjectStreamException {
23.38 +
23.39 + private static final long serialVersionUID = -3893467273049808895L;
23.40 +
23.41 + /**
23.42 + * Constructor to create a new NotActiveException with the reason given.
23.43 + *
23.44 + * @param reason a String describing the reason for the exception.
23.45 + */
23.46 + public NotActiveException(String reason) {
23.47 + super(reason);
23.48 + }
23.49 +
23.50 + /**
23.51 + * Constructor to create a new NotActiveException without a reason.
23.52 + */
23.53 + public NotActiveException() {
23.54 + super();
23.55 + }
23.56 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/emul/compact/src/main/java/java/io/NotSerializableException.java Tue Feb 05 17:04:22 2013 +0100
24.3 @@ -0,0 +1,55 @@
24.4 +/*
24.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.7 + *
24.8 + * This code is free software; you can redistribute it and/or modify it
24.9 + * under the terms of the GNU General Public License version 2 only, as
24.10 + * published by the Free Software Foundation. Oracle designates this
24.11 + * particular file as subject to the "Classpath" exception as provided
24.12 + * by Oracle in the LICENSE file that accompanied this code.
24.13 + *
24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.17 + * version 2 for more details (a copy is included in the LICENSE file that
24.18 + * accompanied this code).
24.19 + *
24.20 + * You should have received a copy of the GNU General Public License version
24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.23 + *
24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24.25 + * or visit www.oracle.com if you need additional information or have any
24.26 + * questions.
24.27 + */
24.28 +
24.29 +package java.io;
24.30 +
24.31 +/**
24.32 + * Thrown when an instance is required to have a Serializable interface.
24.33 + * The serialization runtime or the class of the instance can throw
24.34 + * this exception. The argument should be the name of the class.
24.35 + *
24.36 + * @author unascribed
24.37 + * @since JDK1.1
24.38 + */
24.39 +public class NotSerializableException extends ObjectStreamException {
24.40 +
24.41 + private static final long serialVersionUID = 2906642554793891381L;
24.42 +
24.43 + /**
24.44 + * Constructs a NotSerializableException object with message string.
24.45 + *
24.46 + * @param classname Class of the instance being serialized/deserialized.
24.47 + */
24.48 + public NotSerializableException(String classname) {
24.49 + super(classname);
24.50 + }
24.51 +
24.52 + /**
24.53 + * Constructs a NotSerializableException object.
24.54 + */
24.55 + public NotSerializableException() {
24.56 + super();
24.57 + }
24.58 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/emul/compact/src/main/java/java/io/ObjectInput.java Tue Feb 05 17:04:22 2013 +0100
25.3 @@ -0,0 +1,107 @@
25.4 +/*
25.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
25.7 + *
25.8 + * This code is free software; you can redistribute it and/or modify it
25.9 + * under the terms of the GNU General Public License version 2 only, as
25.10 + * published by the Free Software Foundation. Oracle designates this
25.11 + * particular file as subject to the "Classpath" exception as provided
25.12 + * by Oracle in the LICENSE file that accompanied this code.
25.13 + *
25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25.17 + * version 2 for more details (a copy is included in the LICENSE file that
25.18 + * accompanied this code).
25.19 + *
25.20 + * You should have received a copy of the GNU General Public License version
25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25.23 + *
25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
25.25 + * or visit www.oracle.com if you need additional information or have any
25.26 + * questions.
25.27 + */
25.28 +
25.29 +package java.io;
25.30 +
25.31 +/**
25.32 + * ObjectInput extends the DataInput interface to include the reading of
25.33 + * objects. DataInput includes methods for the input of primitive types,
25.34 + * ObjectInput extends that interface to include objects, arrays, and Strings.
25.35 + *
25.36 + * @author unascribed
25.37 + * @see java.io.InputStream
25.38 + * @see java.io.ObjectOutputStream
25.39 + * @see java.io.ObjectInputStream
25.40 + * @since JDK1.1
25.41 + */
25.42 +public interface ObjectInput extends DataInput, AutoCloseable {
25.43 + /**
25.44 + * Read and return an object. The class that implements this interface
25.45 + * defines where the object is "read" from.
25.46 + *
25.47 + * @return the object read from the stream
25.48 + * @exception java.lang.ClassNotFoundException If the class of a serialized
25.49 + * object cannot be found.
25.50 + * @exception IOException If any of the usual Input/Output
25.51 + * related exceptions occur.
25.52 + */
25.53 + public Object readObject()
25.54 + throws ClassNotFoundException, IOException;
25.55 +
25.56 + /**
25.57 + * Reads a byte of data. This method will block if no input is
25.58 + * available.
25.59 + * @return the byte read, or -1 if the end of the
25.60 + * stream is reached.
25.61 + * @exception IOException If an I/O error has occurred.
25.62 + */
25.63 + public int read() throws IOException;
25.64 +
25.65 + /**
25.66 + * Reads into an array of bytes. This method will
25.67 + * block until some input is available.
25.68 + * @param b the buffer into which the data is read
25.69 + * @return the actual number of bytes read, -1 is
25.70 + * returned when the end of the stream is reached.
25.71 + * @exception IOException If an I/O error has occurred.
25.72 + */
25.73 + public int read(byte b[]) throws IOException;
25.74 +
25.75 + /**
25.76 + * Reads into an array of bytes. This method will
25.77 + * block until some input is available.
25.78 + * @param b the buffer into which the data is read
25.79 + * @param off the start offset of the data
25.80 + * @param len the maximum number of bytes read
25.81 + * @return the actual number of bytes read, -1 is
25.82 + * returned when the end of the stream is reached.
25.83 + * @exception IOException If an I/O error has occurred.
25.84 + */
25.85 + public int read(byte b[], int off, int len) throws IOException;
25.86 +
25.87 + /**
25.88 + * Skips n bytes of input.
25.89 + * @param n the number of bytes to be skipped
25.90 + * @return the actual number of bytes skipped.
25.91 + * @exception IOException If an I/O error has occurred.
25.92 + */
25.93 + public long skip(long n) throws IOException;
25.94 +
25.95 + /**
25.96 + * Returns the number of bytes that can be read
25.97 + * without blocking.
25.98 + * @return the number of available bytes.
25.99 + * @exception IOException If an I/O error has occurred.
25.100 + */
25.101 + public int available() throws IOException;
25.102 +
25.103 + /**
25.104 + * Closes the input stream. Must be called
25.105 + * to release any resources associated with
25.106 + * the stream.
25.107 + * @exception IOException If an I/O error has occurred.
25.108 + */
25.109 + public void close() throws IOException;
25.110 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputStream.java Tue Feb 05 17:04:22 2013 +0100
26.3 @@ -0,0 +1,3357 @@
26.4 +/*
26.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.7 + *
26.8 + * This code is free software; you can redistribute it and/or modify it
26.9 + * under the terms of the GNU General Public License version 2 only, as
26.10 + * published by the Free Software Foundation. Oracle designates this
26.11 + * particular file as subject to the "Classpath" exception as provided
26.12 + * by Oracle in the LICENSE file that accompanied this code.
26.13 + *
26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.17 + * version 2 for more details (a copy is included in the LICENSE file that
26.18 + * accompanied this code).
26.19 + *
26.20 + * You should have received a copy of the GNU General Public License version
26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.23 + *
26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
26.25 + * or visit www.oracle.com if you need additional information or have any
26.26 + * questions.
26.27 + */
26.28 +
26.29 +package java.io;
26.30 +
26.31 +import java.lang.reflect.Array;
26.32 +import java.lang.reflect.Modifier;
26.33 +import java.lang.reflect.Proxy;
26.34 +import java.util.Arrays;
26.35 +import java.util.HashMap;
26.36 +import org.apidesign.bck2brwsr.emul.lang.System;
26.37 +
26.38 +/**
26.39 + * An ObjectInputStream deserializes primitive data and objects previously
26.40 + * written using an ObjectOutputStream.
26.41 + *
26.42 + * <p>ObjectOutputStream and ObjectInputStream can provide an application with
26.43 + * persistent storage for graphs of objects when used with a FileOutputStream
26.44 + * and FileInputStream respectively. ObjectInputStream is used to recover
26.45 + * those objects previously serialized. Other uses include passing objects
26.46 + * between hosts using a socket stream or for marshaling and unmarshaling
26.47 + * arguments and parameters in a remote communication system.
26.48 + *
26.49 + * <p>ObjectInputStream ensures that the types of all objects in the graph
26.50 + * created from the stream match the classes present in the Java Virtual
26.51 + * Machine. Classes are loaded as required using the standard mechanisms.
26.52 + *
26.53 + * <p>Only objects that support the java.io.Serializable or
26.54 + * java.io.Externalizable interface can be read from streams.
26.55 + *
26.56 + * <p>The method <code>readObject</code> is used to read an object from the
26.57 + * stream. Java's safe casting should be used to get the desired type. In
26.58 + * Java, strings and arrays are objects and are treated as objects during
26.59 + * serialization. When read they need to be cast to the expected type.
26.60 + *
26.61 + * <p>Primitive data types can be read from the stream using the appropriate
26.62 + * method on DataInput.
26.63 + *
26.64 + * <p>The default deserialization mechanism for objects restores the contents
26.65 + * of each field to the value and type it had when it was written. Fields
26.66 + * declared as transient or static are ignored by the deserialization process.
26.67 + * References to other objects cause those objects to be read from the stream
26.68 + * as necessary. Graphs of objects are restored correctly using a reference
26.69 + * sharing mechanism. New objects are always allocated when deserializing,
26.70 + * which prevents existing objects from being overwritten.
26.71 + *
26.72 + * <p>Reading an object is analogous to running the constructors of a new
26.73 + * object. Memory is allocated for the object and initialized to zero (NULL).
26.74 + * No-arg constructors are invoked for the non-serializable classes and then
26.75 + * the fields of the serializable classes are restored from the stream starting
26.76 + * with the serializable class closest to java.lang.object and finishing with
26.77 + * the object's most specific class.
26.78 + *
26.79 + * <p>For example to read from a stream as written by the example in
26.80 + * ObjectOutputStream:
26.81 + * <br>
26.82 + * <pre>
26.83 + * FileInputStream fis = new FileInputStream("t.tmp");
26.84 + * ObjectInputStream ois = new ObjectInputStream(fis);
26.85 + *
26.86 + * int i = ois.readInt();
26.87 + * String today = (String) ois.readObject();
26.88 + * Date date = (Date) ois.readObject();
26.89 + *
26.90 + * ois.close();
26.91 + * </pre>
26.92 + *
26.93 + * <p>Classes control how they are serialized by implementing either the
26.94 + * java.io.Serializable or java.io.Externalizable interfaces.
26.95 + *
26.96 + * <p>Implementing the Serializable interface allows object serialization to
26.97 + * save and restore the entire state of the object and it allows classes to
26.98 + * evolve between the time the stream is written and the time it is read. It
26.99 + * automatically traverses references between objects, saving and restoring
26.100 + * entire graphs.
26.101 + *
26.102 + * <p>Serializable classes that require special handling during the
26.103 + * serialization and deserialization process should implement the following
26.104 + * methods:<p>
26.105 + *
26.106 + * <pre>
26.107 + * private void writeObject(java.io.ObjectOutputStream stream)
26.108 + * throws IOException;
26.109 + * private void readObject(java.io.ObjectInputStream stream)
26.110 + * throws IOException, ClassNotFoundException;
26.111 + * private void readObjectNoData()
26.112 + * throws ObjectStreamException;
26.113 + * </pre>
26.114 + *
26.115 + * <p>The readObject method is responsible for reading and restoring the state
26.116 + * of the object for its particular class using data written to the stream by
26.117 + * the corresponding writeObject method. The method does not need to concern
26.118 + * itself with the state belonging to its superclasses or subclasses. State is
26.119 + * restored by reading data from the ObjectInputStream for the individual
26.120 + * fields and making assignments to the appropriate fields of the object.
26.121 + * Reading primitive data types is supported by DataInput.
26.122 + *
26.123 + * <p>Any attempt to read object data which exceeds the boundaries of the
26.124 + * custom data written by the corresponding writeObject method will cause an
26.125 + * OptionalDataException to be thrown with an eof field value of true.
26.126 + * Non-object reads which exceed the end of the allotted data will reflect the
26.127 + * end of data in the same way that they would indicate the end of the stream:
26.128 + * bytewise reads will return -1 as the byte read or number of bytes read, and
26.129 + * primitive reads will throw EOFExceptions. If there is no corresponding
26.130 + * writeObject method, then the end of default serialized data marks the end of
26.131 + * the allotted data.
26.132 + *
26.133 + * <p>Primitive and object read calls issued from within a readExternal method
26.134 + * behave in the same manner--if the stream is already positioned at the end of
26.135 + * data written by the corresponding writeExternal method, object reads will
26.136 + * throw OptionalDataExceptions with eof set to true, bytewise reads will
26.137 + * return -1, and primitive reads will throw EOFExceptions. Note that this
26.138 + * behavior does not hold for streams written with the old
26.139 + * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
26.140 + * end of data written by writeExternal methods is not demarcated, and hence
26.141 + * cannot be detected.
26.142 + *
26.143 + * <p>The readObjectNoData method is responsible for initializing the state of
26.144 + * the object for its particular class in the event that the serialization
26.145 + * stream does not list the given class as a superclass of the object being
26.146 + * deserialized. This may occur in cases where the receiving party uses a
26.147 + * different version of the deserialized instance's class than the sending
26.148 + * party, and the receiver's version extends classes that are not extended by
26.149 + * the sender's version. This may also occur if the serialization stream has
26.150 + * been tampered; hence, readObjectNoData is useful for initializing
26.151 + * deserialized objects properly despite a "hostile" or incomplete source
26.152 + * stream.
26.153 + *
26.154 + * <p>Serialization does not read or assign values to the fields of any object
26.155 + * that does not implement the java.io.Serializable interface. Subclasses of
26.156 + * Objects that are not serializable can be serializable. In this case the
26.157 + * non-serializable class must have a no-arg constructor to allow its fields to
26.158 + * be initialized. In this case it is the responsibility of the subclass to
26.159 + * save and restore the state of the non-serializable class. It is frequently
26.160 + * the case that the fields of that class are accessible (public, package, or
26.161 + * protected) or that there are get and set methods that can be used to restore
26.162 + * the state.
26.163 + *
26.164 + * <p>Any exception that occurs while deserializing an object will be caught by
26.165 + * the ObjectInputStream and abort the reading process.
26.166 + *
26.167 + * <p>Implementing the Externalizable interface allows the object to assume
26.168 + * complete control over the contents and format of the object's serialized
26.169 + * form. The methods of the Externalizable interface, writeExternal and
26.170 + * readExternal, are called to save and restore the objects state. When
26.171 + * implemented by a class they can write and read their own state using all of
26.172 + * the methods of ObjectOutput and ObjectInput. It is the responsibility of
26.173 + * the objects to handle any versioning that occurs.
26.174 + *
26.175 + * <p>Enum constants are deserialized differently than ordinary serializable or
26.176 + * externalizable objects. The serialized form of an enum constant consists
26.177 + * solely of its name; field values of the constant are not transmitted. To
26.178 + * deserialize an enum constant, ObjectInputStream reads the constant name from
26.179 + * the stream; the deserialized constant is then obtained by calling the static
26.180 + * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
26.181 + * base type and the received constant name as arguments. Like other
26.182 + * serializable or externalizable objects, enum constants can function as the
26.183 + * targets of back references appearing subsequently in the serialization
26.184 + * stream. The process by which enum constants are deserialized cannot be
26.185 + * customized: any class-specific readObject, readObjectNoData, and readResolve
26.186 + * methods defined by enum types are ignored during deserialization.
26.187 + * Similarly, any serialPersistentFields or serialVersionUID field declarations
26.188 + * are also ignored--all enum types have a fixed serialVersionUID of 0L.
26.189 + *
26.190 + * @author Mike Warres
26.191 + * @author Roger Riggs
26.192 + * @see java.io.DataInput
26.193 + * @see java.io.ObjectOutputStream
26.194 + * @see java.io.Serializable
26.195 + * @see <a href="../../../platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
26.196 + * @since JDK1.1
26.197 + */
26.198 +public class ObjectInputStream
26.199 + extends InputStream implements ObjectInput, ObjectStreamConstants
26.200 +{
26.201 + /** handle value representing null */
26.202 + private static final int NULL_HANDLE = -1;
26.203 +
26.204 + /** marker for unshared objects in internal handle table */
26.205 + private static final Object unsharedMarker = new Object();
26.206 +
26.207 + /** table mapping primitive type names to corresponding class objects */
26.208 + private static final HashMap<String, Class<?>> primClasses
26.209 + = new HashMap<>(8, 1.0F);
26.210 + static {
26.211 + primClasses.put("boolean", boolean.class);
26.212 + primClasses.put("byte", byte.class);
26.213 + primClasses.put("char", char.class);
26.214 + primClasses.put("short", short.class);
26.215 + primClasses.put("int", int.class);
26.216 + primClasses.put("long", long.class);
26.217 + primClasses.put("float", float.class);
26.218 + primClasses.put("double", double.class);
26.219 + primClasses.put("void", void.class);
26.220 + }
26.221 +
26.222 + /** filter stream for handling block data conversion */
26.223 + private final BlockDataInputStream bin;
26.224 + /** validation callback list */
26.225 + private final ValidationList vlist;
26.226 + /** recursion depth */
26.227 + private int depth;
26.228 + /** whether stream is closed */
26.229 + private boolean closed;
26.230 +
26.231 + /** wire handle -> obj/exception map */
26.232 + private final HandleTable handles;
26.233 + /** scratch field for passing handle values up/down call stack */
26.234 + private int passHandle = NULL_HANDLE;
26.235 + /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
26.236 + private boolean defaultDataEnd = false;
26.237 +
26.238 + /** buffer for reading primitive field values */
26.239 + private byte[] primVals;
26.240 +
26.241 + /** if true, invoke readObjectOverride() instead of readObject() */
26.242 + private final boolean enableOverride;
26.243 + /** if true, invoke resolveObject() */
26.244 + private boolean enableResolve;
26.245 +
26.246 + /**
26.247 + * Context during upcalls to class-defined readObject methods; holds
26.248 + * object currently being deserialized and descriptor for current class.
26.249 + * Null when not during readObject upcall.
26.250 + */
26.251 + private Object curContext;
26.252 +
26.253 + /**
26.254 + * Creates an ObjectInputStream that reads from the specified InputStream.
26.255 + * A serialization stream header is read from the stream and verified.
26.256 + * This constructor will block until the corresponding ObjectOutputStream
26.257 + * has written and flushed the header.
26.258 + *
26.259 + * <p>If a security manager is installed, this constructor will check for
26.260 + * the "enableSubclassImplementation" SerializablePermission when invoked
26.261 + * directly or indirectly by the constructor of a subclass which overrides
26.262 + * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
26.263 + * methods.
26.264 + *
26.265 + * @param in input stream to read from
26.266 + * @throws StreamCorruptedException if the stream header is incorrect
26.267 + * @throws IOException if an I/O error occurs while reading stream header
26.268 + * @throws SecurityException if untrusted subclass illegally overrides
26.269 + * security-sensitive methods
26.270 + * @throws NullPointerException if <code>in</code> is <code>null</code>
26.271 + * @see ObjectInputStream#ObjectInputStream()
26.272 + * @see ObjectInputStream#readFields()
26.273 + * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
26.274 + */
26.275 + public ObjectInputStream(InputStream in) throws IOException {
26.276 + verifySubclass();
26.277 + bin = new BlockDataInputStream(in);
26.278 + handles = new HandleTable(10);
26.279 + vlist = new ValidationList();
26.280 + enableOverride = false;
26.281 + readStreamHeader();
26.282 + bin.setBlockDataMode(true);
26.283 + }
26.284 +
26.285 + /**
26.286 + * Provide a way for subclasses that are completely reimplementing
26.287 + * ObjectInputStream to not have to allocate private data just used by this
26.288 + * implementation of ObjectInputStream.
26.289 + *
26.290 + * <p>If there is a security manager installed, this method first calls the
26.291 + * security manager's <code>checkPermission</code> method with the
26.292 + * <code>SerializablePermission("enableSubclassImplementation")</code>
26.293 + * permission to ensure it's ok to enable subclassing.
26.294 + *
26.295 + * @throws SecurityException if a security manager exists and its
26.296 + * <code>checkPermission</code> method denies enabling
26.297 + * subclassing.
26.298 + * @see SecurityManager#checkPermission
26.299 + * @see java.io.SerializablePermission
26.300 + */
26.301 + protected ObjectInputStream() throws IOException, SecurityException {
26.302 + throw new SecurityException();
26.303 + }
26.304 +
26.305 + /**
26.306 + * Read an object from the ObjectInputStream. The class of the object, the
26.307 + * signature of the class, and the values of the non-transient and
26.308 + * non-static fields of the class and all of its supertypes are read.
26.309 + * Default deserializing for a class can be overriden using the writeObject
26.310 + * and readObject methods. Objects referenced by this object are read
26.311 + * transitively so that a complete equivalent graph of objects is
26.312 + * reconstructed by readObject.
26.313 + *
26.314 + * <p>The root object is completely restored when all of its fields and the
26.315 + * objects it references are completely restored. At this point the object
26.316 + * validation callbacks are executed in order based on their registered
26.317 + * priorities. The callbacks are registered by objects (in the readObject
26.318 + * special methods) as they are individually restored.
26.319 + *
26.320 + * <p>Exceptions are thrown for problems with the InputStream and for
26.321 + * classes that should not be deserialized. All exceptions are fatal to
26.322 + * the InputStream and leave it in an indeterminate state; it is up to the
26.323 + * caller to ignore or recover the stream state.
26.324 + *
26.325 + * @throws ClassNotFoundException Class of a serialized object cannot be
26.326 + * found.
26.327 + * @throws InvalidClassException Something is wrong with a class used by
26.328 + * serialization.
26.329 + * @throws StreamCorruptedException Control information in the
26.330 + * stream is inconsistent.
26.331 + * @throws OptionalDataException Primitive data was found in the
26.332 + * stream instead of objects.
26.333 + * @throws IOException Any of the usual Input/Output related exceptions.
26.334 + */
26.335 + public final Object readObject()
26.336 + throws IOException, ClassNotFoundException
26.337 + {
26.338 + throw new IOException();
26.339 + }
26.340 +
26.341 + /**
26.342 + * This method is called by trusted subclasses of ObjectOutputStream that
26.343 + * constructed ObjectOutputStream using the protected no-arg constructor.
26.344 + * The subclass is expected to provide an override method with the modifier
26.345 + * "final".
26.346 + *
26.347 + * @return the Object read from the stream.
26.348 + * @throws ClassNotFoundException Class definition of a serialized object
26.349 + * cannot be found.
26.350 + * @throws OptionalDataException Primitive data was found in the stream
26.351 + * instead of objects.
26.352 + * @throws IOException if I/O errors occurred while reading from the
26.353 + * underlying stream
26.354 + * @see #ObjectInputStream()
26.355 + * @see #readObject()
26.356 + * @since 1.2
26.357 + */
26.358 + protected Object readObjectOverride()
26.359 + throws IOException, ClassNotFoundException
26.360 + {
26.361 + return null;
26.362 + }
26.363 +
26.364 + /**
26.365 + * Reads an "unshared" object from the ObjectInputStream. This method is
26.366 + * identical to readObject, except that it prevents subsequent calls to
26.367 + * readObject and readUnshared from returning additional references to the
26.368 + * deserialized instance obtained via this call. Specifically:
26.369 + * <ul>
26.370 + * <li>If readUnshared is called to deserialize a back-reference (the
26.371 + * stream representation of an object which has been written
26.372 + * previously to the stream), an ObjectStreamException will be
26.373 + * thrown.
26.374 + *
26.375 + * <li>If readUnshared returns successfully, then any subsequent attempts
26.376 + * to deserialize back-references to the stream handle deserialized
26.377 + * by readUnshared will cause an ObjectStreamException to be thrown.
26.378 + * </ul>
26.379 + * Deserializing an object via readUnshared invalidates the stream handle
26.380 + * associated with the returned object. Note that this in itself does not
26.381 + * always guarantee that the reference returned by readUnshared is unique;
26.382 + * the deserialized object may define a readResolve method which returns an
26.383 + * object visible to other parties, or readUnshared may return a Class
26.384 + * object or enum constant obtainable elsewhere in the stream or through
26.385 + * external means. If the deserialized object defines a readResolve method
26.386 + * and the invocation of that method returns an array, then readUnshared
26.387 + * returns a shallow clone of that array; this guarantees that the returned
26.388 + * array object is unique and cannot be obtained a second time from an
26.389 + * invocation of readObject or readUnshared on the ObjectInputStream,
26.390 + * even if the underlying data stream has been manipulated.
26.391 + *
26.392 + * <p>ObjectInputStream subclasses which override this method can only be
26.393 + * constructed in security contexts possessing the
26.394 + * "enableSubclassImplementation" SerializablePermission; any attempt to
26.395 + * instantiate such a subclass without this permission will cause a
26.396 + * SecurityException to be thrown.
26.397 + *
26.398 + * @return reference to deserialized object
26.399 + * @throws ClassNotFoundException if class of an object to deserialize
26.400 + * cannot be found
26.401 + * @throws StreamCorruptedException if control information in the stream
26.402 + * is inconsistent
26.403 + * @throws ObjectStreamException if object to deserialize has already
26.404 + * appeared in stream
26.405 + * @throws OptionalDataException if primitive data is next in stream
26.406 + * @throws IOException if an I/O error occurs during deserialization
26.407 + * @since 1.4
26.408 + */
26.409 + public Object readUnshared() throws IOException, ClassNotFoundException {
26.410 + // if nested read, passHandle contains handle of enclosing object
26.411 + int outerHandle = passHandle;
26.412 + try {
26.413 + Object obj = readObject0(true);
26.414 + handles.markDependency(outerHandle, passHandle);
26.415 + ClassNotFoundException ex = handles.lookupException(passHandle);
26.416 + if (ex != null) {
26.417 + throw ex;
26.418 + }
26.419 + if (depth == 0) {
26.420 + vlist.doCallbacks();
26.421 + }
26.422 + return obj;
26.423 + } finally {
26.424 + passHandle = outerHandle;
26.425 + if (closed && depth == 0) {
26.426 + clear();
26.427 + }
26.428 + }
26.429 + }
26.430 +
26.431 + /**
26.432 + * Read the non-static and non-transient fields of the current class from
26.433 + * this stream. This may only be called from the readObject method of the
26.434 + * class being deserialized. It will throw the NotActiveException if it is
26.435 + * called otherwise.
26.436 + *
26.437 + * @throws ClassNotFoundException if the class of a serialized object
26.438 + * could not be found.
26.439 + * @throws IOException if an I/O error occurs.
26.440 + * @throws NotActiveException if the stream is not currently reading
26.441 + * objects.
26.442 + */
26.443 + public void defaultReadObject()
26.444 + throws IOException, ClassNotFoundException
26.445 + {
26.446 + if (curContext == null) {
26.447 + throw new NotActiveException("not in call to readObject");
26.448 + }
26.449 + Object curObj = null; // curContext.getObj();
26.450 + ObjectStreamClass curDesc = null; // curContext.getDesc();
26.451 + bin.setBlockDataMode(false);
26.452 + defaultReadFields(curObj, curDesc);
26.453 + bin.setBlockDataMode(true);
26.454 + if (!curDesc.hasWriteObjectData()) {
26.455 + /*
26.456 + * Fix for 4360508: since stream does not contain terminating
26.457 + * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
26.458 + * knows to simulate end-of-custom-data behavior.
26.459 + */
26.460 + defaultDataEnd = true;
26.461 + }
26.462 + ClassNotFoundException ex = handles.lookupException(passHandle);
26.463 + if (ex != null) {
26.464 + throw ex;
26.465 + }
26.466 + }
26.467 +
26.468 + /**
26.469 + * Reads the persistent fields from the stream and makes them available by
26.470 + * name.
26.471 + *
26.472 + * @return the <code>GetField</code> object representing the persistent
26.473 + * fields of the object being deserialized
26.474 + * @throws ClassNotFoundException if the class of a serialized object
26.475 + * could not be found.
26.476 + * @throws IOException if an I/O error occurs.
26.477 + * @throws NotActiveException if the stream is not currently reading
26.478 + * objects.
26.479 + * @since 1.2
26.480 + */
26.481 + public ObjectInputStream.GetField readFields()
26.482 + throws IOException, ClassNotFoundException
26.483 + {
26.484 + if (curContext == null) {
26.485 + throw new NotActiveException("not in call to readObject");
26.486 + }
26.487 + Object curObj = null; // curContext.getObj();
26.488 + ObjectStreamClass curDesc = null; // curContext.getDesc();
26.489 + bin.setBlockDataMode(false);
26.490 + GetFieldImpl getField = new GetFieldImpl(curDesc);
26.491 + getField.readFields();
26.492 + bin.setBlockDataMode(true);
26.493 + if (!curDesc.hasWriteObjectData()) {
26.494 + /*
26.495 + * Fix for 4360508: since stream does not contain terminating
26.496 + * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
26.497 + * knows to simulate end-of-custom-data behavior.
26.498 + */
26.499 + defaultDataEnd = true;
26.500 + }
26.501 +
26.502 + return getField;
26.503 + }
26.504 +
26.505 + /**
26.506 + * Register an object to be validated before the graph is returned. While
26.507 + * similar to resolveObject these validations are called after the entire
26.508 + * graph has been reconstituted. Typically, a readObject method will
26.509 + * register the object with the stream so that when all of the objects are
26.510 + * restored a final set of validations can be performed.
26.511 + *
26.512 + * @param obj the object to receive the validation callback.
26.513 + * @param prio controls the order of callbacks;zero is a good default.
26.514 + * Use higher numbers to be called back earlier, lower numbers for
26.515 + * later callbacks. Within a priority, callbacks are processed in
26.516 + * no particular order.
26.517 + * @throws NotActiveException The stream is not currently reading objects
26.518 + * so it is invalid to register a callback.
26.519 + * @throws InvalidObjectException The validation object is null.
26.520 + */
26.521 + public void registerValidation(ObjectInputValidation obj, int prio)
26.522 + throws NotActiveException, InvalidObjectException
26.523 + {
26.524 + if (depth == 0) {
26.525 + throw new NotActiveException("stream inactive");
26.526 + }
26.527 + vlist.register(obj, prio);
26.528 + }
26.529 +
26.530 + /**
26.531 + * Load the local class equivalent of the specified stream class
26.532 + * description. Subclasses may implement this method to allow classes to
26.533 + * be fetched from an alternate source.
26.534 + *
26.535 + * <p>The corresponding method in <code>ObjectOutputStream</code> is
26.536 + * <code>annotateClass</code>. This method will be invoked only once for
26.537 + * each unique class in the stream. This method can be implemented by
26.538 + * subclasses to use an alternate loading mechanism but must return a
26.539 + * <code>Class</code> object. Once returned, if the class is not an array
26.540 + * class, its serialVersionUID is compared to the serialVersionUID of the
26.541 + * serialized class, and if there is a mismatch, the deserialization fails
26.542 + * and an {@link InvalidClassException} is thrown.
26.543 + *
26.544 + * <p>The default implementation of this method in
26.545 + * <code>ObjectInputStream</code> returns the result of calling
26.546 + * <pre>
26.547 + * Class.forName(desc.getName(), false, loader)
26.548 + * </pre>
26.549 + * where <code>loader</code> is determined as follows: if there is a
26.550 + * method on the current thread's stack whose declaring class was
26.551 + * defined by a user-defined class loader (and was not a generated to
26.552 + * implement reflective invocations), then <code>loader</code> is class
26.553 + * loader corresponding to the closest such method to the currently
26.554 + * executing frame; otherwise, <code>loader</code> is
26.555 + * <code>null</code>. If this call results in a
26.556 + * <code>ClassNotFoundException</code> and the name of the passed
26.557 + * <code>ObjectStreamClass</code> instance is the Java language keyword
26.558 + * for a primitive type or void, then the <code>Class</code> object
26.559 + * representing that primitive type or void will be returned
26.560 + * (e.g., an <code>ObjectStreamClass</code> with the name
26.561 + * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
26.562 + * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
26.563 + * the caller of this method.
26.564 + *
26.565 + * @param desc an instance of class <code>ObjectStreamClass</code>
26.566 + * @return a <code>Class</code> object corresponding to <code>desc</code>
26.567 + * @throws IOException any of the usual Input/Output exceptions.
26.568 + * @throws ClassNotFoundException if class of a serialized object cannot
26.569 + * be found.
26.570 + */
26.571 + protected Class<?> resolveClass(ObjectStreamClass desc)
26.572 + throws IOException, ClassNotFoundException
26.573 + {
26.574 + String name = desc.getName();
26.575 + try {
26.576 + return Class.forName(name, false, latestUserDefinedLoader());
26.577 + } catch (ClassNotFoundException ex) {
26.578 + Class<?> cl = primClasses.get(name);
26.579 + if (cl != null) {
26.580 + return cl;
26.581 + } else {
26.582 + throw ex;
26.583 + }
26.584 + }
26.585 + }
26.586 +
26.587 + /**
26.588 + * Returns a proxy class that implements the interfaces named in a proxy
26.589 + * class descriptor; subclasses may implement this method to read custom
26.590 + * data from the stream along with the descriptors for dynamic proxy
26.591 + * classes, allowing them to use an alternate loading mechanism for the
26.592 + * interfaces and the proxy class.
26.593 + *
26.594 + * <p>This method is called exactly once for each unique proxy class
26.595 + * descriptor in the stream.
26.596 + *
26.597 + * <p>The corresponding method in <code>ObjectOutputStream</code> is
26.598 + * <code>annotateProxyClass</code>. For a given subclass of
26.599 + * <code>ObjectInputStream</code> that overrides this method, the
26.600 + * <code>annotateProxyClass</code> method in the corresponding subclass of
26.601 + * <code>ObjectOutputStream</code> must write any data or objects read by
26.602 + * this method.
26.603 + *
26.604 + * <p>The default implementation of this method in
26.605 + * <code>ObjectInputStream</code> returns the result of calling
26.606 + * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
26.607 + * objects for the interfaces that are named in the <code>interfaces</code>
26.608 + * parameter. The <code>Class</code> object for each interface name
26.609 + * <code>i</code> is the value returned by calling
26.610 + * <pre>
26.611 + * Class.forName(i, false, loader)
26.612 + * </pre>
26.613 + * where <code>loader</code> is that of the first non-<code>null</code>
26.614 + * class loader up the execution stack, or <code>null</code> if no
26.615 + * non-<code>null</code> class loaders are on the stack (the same class
26.616 + * loader choice used by the <code>resolveClass</code> method). Unless any
26.617 + * of the resolved interfaces are non-public, this same value of
26.618 + * <code>loader</code> is also the class loader passed to
26.619 + * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
26.620 + * their class loader is passed instead (if more than one non-public
26.621 + * interface class loader is encountered, an
26.622 + * <code>IllegalAccessError</code> is thrown).
26.623 + * If <code>Proxy.getProxyClass</code> throws an
26.624 + * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
26.625 + * will throw a <code>ClassNotFoundException</code> containing the
26.626 + * <code>IllegalArgumentException</code>.
26.627 + *
26.628 + * @param interfaces the list of interface names that were
26.629 + * deserialized in the proxy class descriptor
26.630 + * @return a proxy class for the specified interfaces
26.631 + * @throws IOException any exception thrown by the underlying
26.632 + * <code>InputStream</code>
26.633 + * @throws ClassNotFoundException if the proxy class or any of the
26.634 + * named interfaces could not be found
26.635 + * @see ObjectOutputStream#annotateProxyClass(Class)
26.636 + * @since 1.3
26.637 + */
26.638 + protected Class<?> resolveProxyClass(String[] interfaces)
26.639 + throws IOException, ClassNotFoundException
26.640 + {
26.641 + ClassLoader latestLoader = latestUserDefinedLoader();
26.642 + ClassLoader nonPublicLoader = null;
26.643 + boolean hasNonPublicInterface = false;
26.644 +
26.645 + // define proxy in class loader of non-public interface(s), if any
26.646 + Class[] classObjs = new Class[interfaces.length];
26.647 + for (int i = 0; i < interfaces.length; i++) {
26.648 + Class cl = Class.forName(interfaces[i], false, latestLoader);
26.649 + if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
26.650 + if (hasNonPublicInterface) {
26.651 + if (nonPublicLoader != cl.getClassLoader()) {
26.652 + throw new IllegalAccessError(
26.653 + "conflicting non-public interface class loaders");
26.654 + }
26.655 + } else {
26.656 + nonPublicLoader = cl.getClassLoader();
26.657 + hasNonPublicInterface = true;
26.658 + }
26.659 + }
26.660 + classObjs[i] = cl;
26.661 + }
26.662 + try {
26.663 + return Proxy.getProxyClass(
26.664 + hasNonPublicInterface ? nonPublicLoader : latestLoader,
26.665 + classObjs);
26.666 + } catch (IllegalArgumentException e) {
26.667 + throw new ClassNotFoundException(null, e);
26.668 + }
26.669 + }
26.670 +
26.671 + /**
26.672 + * This method will allow trusted subclasses of ObjectInputStream to
26.673 + * substitute one object for another during deserialization. Replacing
26.674 + * objects is disabled until enableResolveObject is called. The
26.675 + * enableResolveObject method checks that the stream requesting to resolve
26.676 + * object can be trusted. Every reference to serializable objects is passed
26.677 + * to resolveObject. To insure that the private state of objects is not
26.678 + * unintentionally exposed only trusted streams may use resolveObject.
26.679 + *
26.680 + * <p>This method is called after an object has been read but before it is
26.681 + * returned from readObject. The default resolveObject method just returns
26.682 + * the same object.
26.683 + *
26.684 + * <p>When a subclass is replacing objects it must insure that the
26.685 + * substituted object is compatible with every field where the reference
26.686 + * will be stored. Objects whose type is not a subclass of the type of the
26.687 + * field or array element abort the serialization by raising an exception
26.688 + * and the object is not be stored.
26.689 + *
26.690 + * <p>This method is called only once when each object is first
26.691 + * encountered. All subsequent references to the object will be redirected
26.692 + * to the new object.
26.693 + *
26.694 + * @param obj object to be substituted
26.695 + * @return the substituted object
26.696 + * @throws IOException Any of the usual Input/Output exceptions.
26.697 + */
26.698 + protected Object resolveObject(Object obj) throws IOException {
26.699 + return obj;
26.700 + }
26.701 +
26.702 + /**
26.703 + * Enable the stream to allow objects read from the stream to be replaced.
26.704 + * When enabled, the resolveObject method is called for every object being
26.705 + * deserialized.
26.706 + *
26.707 + * <p>If <i>enable</i> is true, and there is a security manager installed,
26.708 + * this method first calls the security manager's
26.709 + * <code>checkPermission</code> method with the
26.710 + * <code>SerializablePermission("enableSubstitution")</code> permission to
26.711 + * ensure it's ok to enable the stream to allow objects read from the
26.712 + * stream to be replaced.
26.713 + *
26.714 + * @param enable true for enabling use of <code>resolveObject</code> for
26.715 + * every object being deserialized
26.716 + * @return the previous setting before this method was invoked
26.717 + * @throws SecurityException if a security manager exists and its
26.718 + * <code>checkPermission</code> method denies enabling the stream
26.719 + * to allow objects read from the stream to be replaced.
26.720 + * @see SecurityManager#checkPermission
26.721 + * @see java.io.SerializablePermission
26.722 + */
26.723 + protected boolean enableResolveObject(boolean enable)
26.724 + throws SecurityException
26.725 + {
26.726 + throw new SecurityException();
26.727 + }
26.728 +
26.729 + /**
26.730 + * The readStreamHeader method is provided to allow subclasses to read and
26.731 + * verify their own stream headers. It reads and verifies the magic number
26.732 + * and version number.
26.733 + *
26.734 + * @throws IOException if there are I/O errors while reading from the
26.735 + * underlying <code>InputStream</code>
26.736 + * @throws StreamCorruptedException if control information in the stream
26.737 + * is inconsistent
26.738 + */
26.739 + protected void readStreamHeader()
26.740 + throws IOException, StreamCorruptedException
26.741 + {
26.742 + short s0 = bin.readShort();
26.743 + short s1 = bin.readShort();
26.744 + if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
26.745 + throw new StreamCorruptedException(
26.746 + String.format("invalid stream header: %04X%04X", s0, s1));
26.747 + }
26.748 + }
26.749 +
26.750 + /**
26.751 + * Read a class descriptor from the serialization stream. This method is
26.752 + * called when the ObjectInputStream expects a class descriptor as the next
26.753 + * item in the serialization stream. Subclasses of ObjectInputStream may
26.754 + * override this method to read in class descriptors that have been written
26.755 + * in non-standard formats (by subclasses of ObjectOutputStream which have
26.756 + * overridden the <code>writeClassDescriptor</code> method). By default,
26.757 + * this method reads class descriptors according to the format defined in
26.758 + * the Object Serialization specification.
26.759 + *
26.760 + * @return the class descriptor read
26.761 + * @throws IOException If an I/O error has occurred.
26.762 + * @throws ClassNotFoundException If the Class of a serialized object used
26.763 + * in the class descriptor representation cannot be found
26.764 + * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
26.765 + * @since 1.3
26.766 + */
26.767 + protected ObjectStreamClass readClassDescriptor()
26.768 + throws IOException, ClassNotFoundException
26.769 + {
26.770 + ObjectStreamClass desc = new ObjectStreamClass();
26.771 + desc.readNonProxy(this);
26.772 + return desc;
26.773 + }
26.774 +
26.775 + /**
26.776 + * Reads a byte of data. This method will block if no input is available.
26.777 + *
26.778 + * @return the byte read, or -1 if the end of the stream is reached.
26.779 + * @throws IOException If an I/O error has occurred.
26.780 + */
26.781 + public int read() throws IOException {
26.782 + return bin.read();
26.783 + }
26.784 +
26.785 + /**
26.786 + * Reads into an array of bytes. This method will block until some input
26.787 + * is available. Consider using java.io.DataInputStream.readFully to read
26.788 + * exactly 'length' bytes.
26.789 + *
26.790 + * @param buf the buffer into which the data is read
26.791 + * @param off the start offset of the data
26.792 + * @param len the maximum number of bytes read
26.793 + * @return the actual number of bytes read, -1 is returned when the end of
26.794 + * the stream is reached.
26.795 + * @throws IOException If an I/O error has occurred.
26.796 + * @see java.io.DataInputStream#readFully(byte[],int,int)
26.797 + */
26.798 + public int read(byte[] buf, int off, int len) throws IOException {
26.799 + if (buf == null) {
26.800 + throw new NullPointerException();
26.801 + }
26.802 + int endoff = off + len;
26.803 + if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
26.804 + throw new IndexOutOfBoundsException();
26.805 + }
26.806 + return bin.read(buf, off, len, false);
26.807 + }
26.808 +
26.809 + /**
26.810 + * Returns the number of bytes that can be read without blocking.
26.811 + *
26.812 + * @return the number of available bytes.
26.813 + * @throws IOException if there are I/O errors while reading from the
26.814 + * underlying <code>InputStream</code>
26.815 + */
26.816 + public int available() throws IOException {
26.817 + return bin.available();
26.818 + }
26.819 +
26.820 + /**
26.821 + * Closes the input stream. Must be called to release any resources
26.822 + * associated with the stream.
26.823 + *
26.824 + * @throws IOException If an I/O error has occurred.
26.825 + */
26.826 + public void close() throws IOException {
26.827 + /*
26.828 + * Even if stream already closed, propagate redundant close to
26.829 + * underlying stream to stay consistent with previous implementations.
26.830 + */
26.831 + closed = true;
26.832 + if (depth == 0) {
26.833 + clear();
26.834 + }
26.835 + bin.close();
26.836 + }
26.837 +
26.838 + /**
26.839 + * Reads in a boolean.
26.840 + *
26.841 + * @return the boolean read.
26.842 + * @throws EOFException If end of file is reached.
26.843 + * @throws IOException If other I/O error has occurred.
26.844 + */
26.845 + public boolean readBoolean() throws IOException {
26.846 + return bin.readBoolean();
26.847 + }
26.848 +
26.849 + /**
26.850 + * Reads an 8 bit byte.
26.851 + *
26.852 + * @return the 8 bit byte read.
26.853 + * @throws EOFException If end of file is reached.
26.854 + * @throws IOException If other I/O error has occurred.
26.855 + */
26.856 + public byte readByte() throws IOException {
26.857 + return bin.readByte();
26.858 + }
26.859 +
26.860 + /**
26.861 + * Reads an unsigned 8 bit byte.
26.862 + *
26.863 + * @return the 8 bit byte read.
26.864 + * @throws EOFException If end of file is reached.
26.865 + * @throws IOException If other I/O error has occurred.
26.866 + */
26.867 + public int readUnsignedByte() throws IOException {
26.868 + return bin.readUnsignedByte();
26.869 + }
26.870 +
26.871 + /**
26.872 + * Reads a 16 bit char.
26.873 + *
26.874 + * @return the 16 bit char read.
26.875 + * @throws EOFException If end of file is reached.
26.876 + * @throws IOException If other I/O error has occurred.
26.877 + */
26.878 + public char readChar() throws IOException {
26.879 + return bin.readChar();
26.880 + }
26.881 +
26.882 + /**
26.883 + * Reads a 16 bit short.
26.884 + *
26.885 + * @return the 16 bit short read.
26.886 + * @throws EOFException If end of file is reached.
26.887 + * @throws IOException If other I/O error has occurred.
26.888 + */
26.889 + public short readShort() throws IOException {
26.890 + return bin.readShort();
26.891 + }
26.892 +
26.893 + /**
26.894 + * Reads an unsigned 16 bit short.
26.895 + *
26.896 + * @return the 16 bit short read.
26.897 + * @throws EOFException If end of file is reached.
26.898 + * @throws IOException If other I/O error has occurred.
26.899 + */
26.900 + public int readUnsignedShort() throws IOException {
26.901 + return bin.readUnsignedShort();
26.902 + }
26.903 +
26.904 + /**
26.905 + * Reads a 32 bit int.
26.906 + *
26.907 + * @return the 32 bit integer read.
26.908 + * @throws EOFException If end of file is reached.
26.909 + * @throws IOException If other I/O error has occurred.
26.910 + */
26.911 + public int readInt() throws IOException {
26.912 + return bin.readInt();
26.913 + }
26.914 +
26.915 + /**
26.916 + * Reads a 64 bit long.
26.917 + *
26.918 + * @return the read 64 bit long.
26.919 + * @throws EOFException If end of file is reached.
26.920 + * @throws IOException If other I/O error has occurred.
26.921 + */
26.922 + public long readLong() throws IOException {
26.923 + return bin.readLong();
26.924 + }
26.925 +
26.926 + /**
26.927 + * Reads a 32 bit float.
26.928 + *
26.929 + * @return the 32 bit float read.
26.930 + * @throws EOFException If end of file is reached.
26.931 + * @throws IOException If other I/O error has occurred.
26.932 + */
26.933 + public float readFloat() throws IOException {
26.934 + return bin.readFloat();
26.935 + }
26.936 +
26.937 + /**
26.938 + * Reads a 64 bit double.
26.939 + *
26.940 + * @return the 64 bit double read.
26.941 + * @throws EOFException If end of file is reached.
26.942 + * @throws IOException If other I/O error has occurred.
26.943 + */
26.944 + public double readDouble() throws IOException {
26.945 + return bin.readDouble();
26.946 + }
26.947 +
26.948 + /**
26.949 + * Reads bytes, blocking until all bytes are read.
26.950 + *
26.951 + * @param buf the buffer into which the data is read
26.952 + * @throws EOFException If end of file is reached.
26.953 + * @throws IOException If other I/O error has occurred.
26.954 + */
26.955 + public void readFully(byte[] buf) throws IOException {
26.956 + bin.readFully(buf, 0, buf.length, false);
26.957 + }
26.958 +
26.959 + /**
26.960 + * Reads bytes, blocking until all bytes are read.
26.961 + *
26.962 + * @param buf the buffer into which the data is read
26.963 + * @param off the start offset of the data
26.964 + * @param len the maximum number of bytes to read
26.965 + * @throws EOFException If end of file is reached.
26.966 + * @throws IOException If other I/O error has occurred.
26.967 + */
26.968 + public void readFully(byte[] buf, int off, int len) throws IOException {
26.969 + int endoff = off + len;
26.970 + if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
26.971 + throw new IndexOutOfBoundsException();
26.972 + }
26.973 + bin.readFully(buf, off, len, false);
26.974 + }
26.975 +
26.976 + /**
26.977 + * Skips bytes.
26.978 + *
26.979 + * @param len the number of bytes to be skipped
26.980 + * @return the actual number of bytes skipped.
26.981 + * @throws IOException If an I/O error has occurred.
26.982 + */
26.983 + public int skipBytes(int len) throws IOException {
26.984 + return bin.skipBytes(len);
26.985 + }
26.986 +
26.987 + /**
26.988 + * Reads in a line that has been terminated by a \n, \r, \r\n or EOF.
26.989 + *
26.990 + * @return a String copy of the line.
26.991 + * @throws IOException if there are I/O errors while reading from the
26.992 + * underlying <code>InputStream</code>
26.993 + * @deprecated This method does not properly convert bytes to characters.
26.994 + * see DataInputStream for the details and alternatives.
26.995 + */
26.996 + @Deprecated
26.997 + public String readLine() throws IOException {
26.998 + return bin.readLine();
26.999 + }
26.1000 +
26.1001 + /**
26.1002 + * Reads a String in
26.1003 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
26.1004 + * format.
26.1005 + *
26.1006 + * @return the String.
26.1007 + * @throws IOException if there are I/O errors while reading from the
26.1008 + * underlying <code>InputStream</code>
26.1009 + * @throws UTFDataFormatException if read bytes do not represent a valid
26.1010 + * modified UTF-8 encoding of a string
26.1011 + */
26.1012 + public String readUTF() throws IOException {
26.1013 + return bin.readUTF();
26.1014 + }
26.1015 +
26.1016 + /**
26.1017 + * Provide access to the persistent fields read from the input stream.
26.1018 + */
26.1019 + public static abstract class GetField {
26.1020 +
26.1021 + /**
26.1022 + * Get the ObjectStreamClass that describes the fields in the stream.
26.1023 + *
26.1024 + * @return the descriptor class that describes the serializable fields
26.1025 + */
26.1026 + public abstract ObjectStreamClass getObjectStreamClass();
26.1027 +
26.1028 + /**
26.1029 + * Return true if the named field is defaulted and has no value in this
26.1030 + * stream.
26.1031 + *
26.1032 + * @param name the name of the field
26.1033 + * @return true, if and only if the named field is defaulted
26.1034 + * @throws IOException if there are I/O errors while reading from
26.1035 + * the underlying <code>InputStream</code>
26.1036 + * @throws IllegalArgumentException if <code>name</code> does not
26.1037 + * correspond to a serializable field
26.1038 + */
26.1039 + public abstract boolean defaulted(String name) throws IOException;
26.1040 +
26.1041 + /**
26.1042 + * Get the value of the named boolean field from the persistent field.
26.1043 + *
26.1044 + * @param name the name of the field
26.1045 + * @param val the default value to use if <code>name</code> does not
26.1046 + * have a value
26.1047 + * @return the value of the named <code>boolean</code> field
26.1048 + * @throws IOException if there are I/O errors while reading from the
26.1049 + * underlying <code>InputStream</code>
26.1050 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1051 + * not serializable or if the field type is incorrect
26.1052 + */
26.1053 + public abstract boolean get(String name, boolean val)
26.1054 + throws IOException;
26.1055 +
26.1056 + /**
26.1057 + * Get the value of the named byte field from the persistent field.
26.1058 + *
26.1059 + * @param name the name of the field
26.1060 + * @param val the default value to use if <code>name</code> does not
26.1061 + * have a value
26.1062 + * @return the value of the named <code>byte</code> field
26.1063 + * @throws IOException if there are I/O errors while reading from the
26.1064 + * underlying <code>InputStream</code>
26.1065 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1066 + * not serializable or if the field type is incorrect
26.1067 + */
26.1068 + public abstract byte get(String name, byte val) throws IOException;
26.1069 +
26.1070 + /**
26.1071 + * Get the value of the named char field from the persistent field.
26.1072 + *
26.1073 + * @param name the name of the field
26.1074 + * @param val the default value to use if <code>name</code> does not
26.1075 + * have a value
26.1076 + * @return the value of the named <code>char</code> field
26.1077 + * @throws IOException if there are I/O errors while reading from the
26.1078 + * underlying <code>InputStream</code>
26.1079 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1080 + * not serializable or if the field type is incorrect
26.1081 + */
26.1082 + public abstract char get(String name, char val) throws IOException;
26.1083 +
26.1084 + /**
26.1085 + * Get the value of the named short field from the persistent field.
26.1086 + *
26.1087 + * @param name the name of the field
26.1088 + * @param val the default value to use if <code>name</code> does not
26.1089 + * have a value
26.1090 + * @return the value of the named <code>short</code> field
26.1091 + * @throws IOException if there are I/O errors while reading from the
26.1092 + * underlying <code>InputStream</code>
26.1093 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1094 + * not serializable or if the field type is incorrect
26.1095 + */
26.1096 + public abstract short get(String name, short val) throws IOException;
26.1097 +
26.1098 + /**
26.1099 + * Get the value of the named int field from the persistent field.
26.1100 + *
26.1101 + * @param name the name of the field
26.1102 + * @param val the default value to use if <code>name</code> does not
26.1103 + * have a value
26.1104 + * @return the value of the named <code>int</code> field
26.1105 + * @throws IOException if there are I/O errors while reading from the
26.1106 + * underlying <code>InputStream</code>
26.1107 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1108 + * not serializable or if the field type is incorrect
26.1109 + */
26.1110 + public abstract int get(String name, int val) throws IOException;
26.1111 +
26.1112 + /**
26.1113 + * Get the value of the named long field from the persistent field.
26.1114 + *
26.1115 + * @param name the name of the field
26.1116 + * @param val the default value to use if <code>name</code> does not
26.1117 + * have a value
26.1118 + * @return the value of the named <code>long</code> field
26.1119 + * @throws IOException if there are I/O errors while reading from the
26.1120 + * underlying <code>InputStream</code>
26.1121 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1122 + * not serializable or if the field type is incorrect
26.1123 + */
26.1124 + public abstract long get(String name, long val) throws IOException;
26.1125 +
26.1126 + /**
26.1127 + * Get the value of the named float field from the persistent field.
26.1128 + *
26.1129 + * @param name the name of the field
26.1130 + * @param val the default value to use if <code>name</code> does not
26.1131 + * have a value
26.1132 + * @return the value of the named <code>float</code> field
26.1133 + * @throws IOException if there are I/O errors while reading from the
26.1134 + * underlying <code>InputStream</code>
26.1135 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1136 + * not serializable or if the field type is incorrect
26.1137 + */
26.1138 + public abstract float get(String name, float val) throws IOException;
26.1139 +
26.1140 + /**
26.1141 + * Get the value of the named double field from the persistent field.
26.1142 + *
26.1143 + * @param name the name of the field
26.1144 + * @param val the default value to use if <code>name</code> does not
26.1145 + * have a value
26.1146 + * @return the value of the named <code>double</code> field
26.1147 + * @throws IOException if there are I/O errors while reading from the
26.1148 + * underlying <code>InputStream</code>
26.1149 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1150 + * not serializable or if the field type is incorrect
26.1151 + */
26.1152 + public abstract double get(String name, double val) throws IOException;
26.1153 +
26.1154 + /**
26.1155 + * Get the value of the named Object field from the persistent field.
26.1156 + *
26.1157 + * @param name the name of the field
26.1158 + * @param val the default value to use if <code>name</code> does not
26.1159 + * have a value
26.1160 + * @return the value of the named <code>Object</code> field
26.1161 + * @throws IOException if there are I/O errors while reading from the
26.1162 + * underlying <code>InputStream</code>
26.1163 + * @throws IllegalArgumentException if type of <code>name</code> is
26.1164 + * not serializable or if the field type is incorrect
26.1165 + */
26.1166 + public abstract Object get(String name, Object val) throws IOException;
26.1167 + }
26.1168 +
26.1169 + /**
26.1170 + * Verifies that this (possibly subclass) instance can be constructed
26.1171 + * without violating security constraints: the subclass must not override
26.1172 + * security-sensitive non-final methods, or else the
26.1173 + * "enableSubclassImplementation" SerializablePermission is checked.
26.1174 + */
26.1175 + private void verifySubclass() {
26.1176 + Class cl = getClass();
26.1177 + if (cl == ObjectInputStream.class) {
26.1178 + return;
26.1179 + }
26.1180 + throw new SecurityException();
26.1181 + }
26.1182 +
26.1183 + /**
26.1184 + * Clears internal data structures.
26.1185 + */
26.1186 + private void clear() {
26.1187 + handles.clear();
26.1188 + vlist.clear();
26.1189 + }
26.1190 +
26.1191 + /**
26.1192 + * Underlying readObject implementation.
26.1193 + */
26.1194 + private Object readObject0(boolean unshared) throws IOException {
26.1195 + boolean oldMode = bin.getBlockDataMode();
26.1196 + if (oldMode) {
26.1197 + int remain = bin.currentBlockRemaining();
26.1198 + if (remain > 0) {
26.1199 + throw new OptionalDataException(remain);
26.1200 + } else if (defaultDataEnd) {
26.1201 + /*
26.1202 + * Fix for 4360508: stream is currently at the end of a field
26.1203 + * value block written via default serialization; since there
26.1204 + * is no terminating TC_ENDBLOCKDATA tag, simulate
26.1205 + * end-of-custom-data behavior explicitly.
26.1206 + */
26.1207 + throw new OptionalDataException(true);
26.1208 + }
26.1209 + bin.setBlockDataMode(false);
26.1210 + }
26.1211 +
26.1212 + byte tc;
26.1213 + while ((tc = bin.peekByte()) == TC_RESET) {
26.1214 + bin.readByte();
26.1215 + handleReset();
26.1216 + }
26.1217 +
26.1218 + depth++;
26.1219 + try {
26.1220 + switch (tc) {
26.1221 + case TC_NULL:
26.1222 + return readNull();
26.1223 +
26.1224 + case TC_REFERENCE:
26.1225 + return readHandle(unshared);
26.1226 +
26.1227 + case TC_CLASS:
26.1228 + return readClass(unshared);
26.1229 +
26.1230 + case TC_CLASSDESC:
26.1231 + case TC_PROXYCLASSDESC:
26.1232 + return readClassDesc(unshared);
26.1233 +
26.1234 + case TC_STRING:
26.1235 + case TC_LONGSTRING:
26.1236 + return checkResolve(readString(unshared));
26.1237 +
26.1238 + case TC_ARRAY:
26.1239 + return checkResolve(readArray(unshared));
26.1240 +
26.1241 + case TC_ENUM:
26.1242 + return checkResolve(readEnum(unshared));
26.1243 +
26.1244 + case TC_OBJECT:
26.1245 + return checkResolve(readOrdinaryObject(unshared));
26.1246 +
26.1247 + case TC_EXCEPTION:
26.1248 + IOException ex = readFatalException();
26.1249 + throw new WriteAbortedException("writing aborted", ex);
26.1250 +
26.1251 + case TC_BLOCKDATA:
26.1252 + case TC_BLOCKDATALONG:
26.1253 + if (oldMode) {
26.1254 + bin.setBlockDataMode(true);
26.1255 + bin.peek(); // force header read
26.1256 + throw new OptionalDataException(
26.1257 + bin.currentBlockRemaining());
26.1258 + } else {
26.1259 + throw new StreamCorruptedException(
26.1260 + "unexpected block data");
26.1261 + }
26.1262 +
26.1263 + case TC_ENDBLOCKDATA:
26.1264 + if (oldMode) {
26.1265 + throw new OptionalDataException(true);
26.1266 + } else {
26.1267 + throw new StreamCorruptedException(
26.1268 + "unexpected end of block data");
26.1269 + }
26.1270 +
26.1271 + default:
26.1272 + throw new StreamCorruptedException(
26.1273 + String.format("invalid type code: %02X", tc));
26.1274 + }
26.1275 + } finally {
26.1276 + depth--;
26.1277 + bin.setBlockDataMode(oldMode);
26.1278 + }
26.1279 + }
26.1280 +
26.1281 + /**
26.1282 + * If resolveObject has been enabled and given object does not have an
26.1283 + * exception associated with it, calls resolveObject to determine
26.1284 + * replacement for object, and updates handle table accordingly. Returns
26.1285 + * replacement object, or echoes provided object if no replacement
26.1286 + * occurred. Expects that passHandle is set to given object's handle prior
26.1287 + * to calling this method.
26.1288 + */
26.1289 + private Object checkResolve(Object obj) throws IOException {
26.1290 + if (!enableResolve || handles.lookupException(passHandle) != null) {
26.1291 + return obj;
26.1292 + }
26.1293 + Object rep = resolveObject(obj);
26.1294 + if (rep != obj) {
26.1295 + handles.setObject(passHandle, rep);
26.1296 + }
26.1297 + return rep;
26.1298 + }
26.1299 +
26.1300 + /**
26.1301 + * Reads string without allowing it to be replaced in stream. Called from
26.1302 + * within ObjectStreamClass.read().
26.1303 + */
26.1304 + String readTypeString() throws IOException {
26.1305 + int oldHandle = passHandle;
26.1306 + try {
26.1307 + byte tc = bin.peekByte();
26.1308 + switch (tc) {
26.1309 + case TC_NULL:
26.1310 + return (String) readNull();
26.1311 +
26.1312 + case TC_REFERENCE:
26.1313 + return (String) readHandle(false);
26.1314 +
26.1315 + case TC_STRING:
26.1316 + case TC_LONGSTRING:
26.1317 + return readString(false);
26.1318 +
26.1319 + default:
26.1320 + throw new StreamCorruptedException(
26.1321 + String.format("invalid type code: %02X", tc));
26.1322 + }
26.1323 + } finally {
26.1324 + passHandle = oldHandle;
26.1325 + }
26.1326 + }
26.1327 +
26.1328 + /**
26.1329 + * Reads in null code, sets passHandle to NULL_HANDLE and returns null.
26.1330 + */
26.1331 + private Object readNull() throws IOException {
26.1332 + if (bin.readByte() != TC_NULL) {
26.1333 + throw new InternalError();
26.1334 + }
26.1335 + passHandle = NULL_HANDLE;
26.1336 + return null;
26.1337 + }
26.1338 +
26.1339 + /**
26.1340 + * Reads in object handle, sets passHandle to the read handle, and returns
26.1341 + * object associated with the handle.
26.1342 + */
26.1343 + private Object readHandle(boolean unshared) throws IOException {
26.1344 + if (bin.readByte() != TC_REFERENCE) {
26.1345 + throw new InternalError();
26.1346 + }
26.1347 + passHandle = bin.readInt() - baseWireHandle;
26.1348 + if (passHandle < 0 || passHandle >= handles.size()) {
26.1349 + throw new StreamCorruptedException(
26.1350 + String.format("invalid handle value: %08X", passHandle +
26.1351 + baseWireHandle));
26.1352 + }
26.1353 + if (unshared) {
26.1354 + // REMIND: what type of exception to throw here?
26.1355 + throw new InvalidObjectException(
26.1356 + "cannot read back reference as unshared");
26.1357 + }
26.1358 +
26.1359 + Object obj = handles.lookupObject(passHandle);
26.1360 + if (obj == unsharedMarker) {
26.1361 + // REMIND: what type of exception to throw here?
26.1362 + throw new InvalidObjectException(
26.1363 + "cannot read back reference to unshared object");
26.1364 + }
26.1365 + return obj;
26.1366 + }
26.1367 +
26.1368 + /**
26.1369 + * Reads in and returns class object. Sets passHandle to class object's
26.1370 + * assigned handle. Returns null if class is unresolvable (in which case a
26.1371 + * ClassNotFoundException will be associated with the class' handle in the
26.1372 + * handle table).
26.1373 + */
26.1374 + private Class readClass(boolean unshared) throws IOException {
26.1375 + if (bin.readByte() != TC_CLASS) {
26.1376 + throw new InternalError();
26.1377 + }
26.1378 + ObjectStreamClass desc = readClassDesc(false);
26.1379 + Class cl = desc.forClass();
26.1380 + passHandle = handles.assign(unshared ? unsharedMarker : cl);
26.1381 +
26.1382 + ClassNotFoundException resolveEx = desc.getResolveException();
26.1383 + if (resolveEx != null) {
26.1384 + handles.markException(passHandle, resolveEx);
26.1385 + }
26.1386 +
26.1387 + handles.finish(passHandle);
26.1388 + return cl;
26.1389 + }
26.1390 +
26.1391 + /**
26.1392 + * Reads in and returns (possibly null) class descriptor. Sets passHandle
26.1393 + * to class descriptor's assigned handle. If class descriptor cannot be
26.1394 + * resolved to a class in the local VM, a ClassNotFoundException is
26.1395 + * associated with the class descriptor's handle.
26.1396 + */
26.1397 + private ObjectStreamClass readClassDesc(boolean unshared)
26.1398 + throws IOException
26.1399 + {
26.1400 + byte tc = bin.peekByte();
26.1401 + switch (tc) {
26.1402 + case TC_NULL:
26.1403 + return (ObjectStreamClass) readNull();
26.1404 +
26.1405 + case TC_REFERENCE:
26.1406 + return (ObjectStreamClass) readHandle(unshared);
26.1407 +
26.1408 + case TC_PROXYCLASSDESC:
26.1409 + return readProxyDesc(unshared);
26.1410 +
26.1411 + case TC_CLASSDESC:
26.1412 + return readNonProxyDesc(unshared);
26.1413 +
26.1414 + default:
26.1415 + throw new StreamCorruptedException(
26.1416 + String.format("invalid type code: %02X", tc));
26.1417 + }
26.1418 + }
26.1419 +
26.1420 + /**
26.1421 + * Reads in and returns class descriptor for a dynamic proxy class. Sets
26.1422 + * passHandle to proxy class descriptor's assigned handle. If proxy class
26.1423 + * descriptor cannot be resolved to a class in the local VM, a
26.1424 + * ClassNotFoundException is associated with the descriptor's handle.
26.1425 + */
26.1426 + private ObjectStreamClass readProxyDesc(boolean unshared)
26.1427 + throws IOException
26.1428 + {
26.1429 + if (bin.readByte() != TC_PROXYCLASSDESC) {
26.1430 + throw new InternalError();
26.1431 + }
26.1432 +
26.1433 + ObjectStreamClass desc = new ObjectStreamClass();
26.1434 + int descHandle = handles.assign(unshared ? unsharedMarker : desc);
26.1435 + passHandle = NULL_HANDLE;
26.1436 +
26.1437 + int numIfaces = bin.readInt();
26.1438 + String[] ifaces = new String[numIfaces];
26.1439 + for (int i = 0; i < numIfaces; i++) {
26.1440 + ifaces[i] = bin.readUTF();
26.1441 + }
26.1442 +
26.1443 + Class cl = null;
26.1444 + ClassNotFoundException resolveEx = null;
26.1445 + bin.setBlockDataMode(true);
26.1446 + try {
26.1447 + if ((cl = resolveProxyClass(ifaces)) == null) {
26.1448 + resolveEx = new ClassNotFoundException("null class");
26.1449 + }
26.1450 + } catch (ClassNotFoundException ex) {
26.1451 + resolveEx = ex;
26.1452 + }
26.1453 + skipCustomData();
26.1454 +
26.1455 + desc.initProxy(cl, resolveEx, readClassDesc(false));
26.1456 +
26.1457 + handles.finish(descHandle);
26.1458 + passHandle = descHandle;
26.1459 + return desc;
26.1460 + }
26.1461 +
26.1462 + /**
26.1463 + * Reads in and returns class descriptor for a class that is not a dynamic
26.1464 + * proxy class. Sets passHandle to class descriptor's assigned handle. If
26.1465 + * class descriptor cannot be resolved to a class in the local VM, a
26.1466 + * ClassNotFoundException is associated with the descriptor's handle.
26.1467 + */
26.1468 + private ObjectStreamClass readNonProxyDesc(boolean unshared)
26.1469 + throws IOException
26.1470 + {
26.1471 + if (bin.readByte() != TC_CLASSDESC) {
26.1472 + throw new InternalError();
26.1473 + }
26.1474 +
26.1475 + ObjectStreamClass desc = new ObjectStreamClass();
26.1476 + int descHandle = handles.assign(unshared ? unsharedMarker : desc);
26.1477 + passHandle = NULL_HANDLE;
26.1478 +
26.1479 + ObjectStreamClass readDesc = null;
26.1480 + try {
26.1481 + readDesc = readClassDescriptor();
26.1482 + } catch (ClassNotFoundException ex) {
26.1483 + throw (IOException) new InvalidClassException(
26.1484 + "failed to read class descriptor").initCause(ex);
26.1485 + }
26.1486 +
26.1487 + Class cl = null;
26.1488 + ClassNotFoundException resolveEx = null;
26.1489 + bin.setBlockDataMode(true);
26.1490 + try {
26.1491 + if ((cl = resolveClass(readDesc)) == null) {
26.1492 + resolveEx = new ClassNotFoundException("null class");
26.1493 + }
26.1494 + } catch (ClassNotFoundException ex) {
26.1495 + resolveEx = ex;
26.1496 + }
26.1497 + skipCustomData();
26.1498 +
26.1499 + desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
26.1500 +
26.1501 + handles.finish(descHandle);
26.1502 + passHandle = descHandle;
26.1503 + return desc;
26.1504 + }
26.1505 +
26.1506 + /**
26.1507 + * Reads in and returns new string. Sets passHandle to new string's
26.1508 + * assigned handle.
26.1509 + */
26.1510 + private String readString(boolean unshared) throws IOException {
26.1511 + String str;
26.1512 + byte tc = bin.readByte();
26.1513 + switch (tc) {
26.1514 + case TC_STRING:
26.1515 + str = bin.readUTF();
26.1516 + break;
26.1517 +
26.1518 + case TC_LONGSTRING:
26.1519 + str = bin.readLongUTF();
26.1520 + break;
26.1521 +
26.1522 + default:
26.1523 + throw new StreamCorruptedException(
26.1524 + String.format("invalid type code: %02X", tc));
26.1525 + }
26.1526 + passHandle = handles.assign(unshared ? unsharedMarker : str);
26.1527 + handles.finish(passHandle);
26.1528 + return str;
26.1529 + }
26.1530 +
26.1531 + /**
26.1532 + * Reads in and returns array object, or null if array class is
26.1533 + * unresolvable. Sets passHandle to array's assigned handle.
26.1534 + */
26.1535 + private Object readArray(boolean unshared) throws IOException {
26.1536 + if (bin.readByte() != TC_ARRAY) {
26.1537 + throw new InternalError();
26.1538 + }
26.1539 +
26.1540 + ObjectStreamClass desc = readClassDesc(false);
26.1541 + int len = bin.readInt();
26.1542 +
26.1543 + Object array = null;
26.1544 + Class cl, ccl = null;
26.1545 + if ((cl = desc.forClass()) != null) {
26.1546 + ccl = cl.getComponentType();
26.1547 + array = Array.newInstance(ccl, len);
26.1548 + }
26.1549 +
26.1550 + int arrayHandle = handles.assign(unshared ? unsharedMarker : array);
26.1551 + ClassNotFoundException resolveEx = desc.getResolveException();
26.1552 + if (resolveEx != null) {
26.1553 + handles.markException(arrayHandle, resolveEx);
26.1554 + }
26.1555 +
26.1556 + if (ccl == null) {
26.1557 + for (int i = 0; i < len; i++) {
26.1558 + readObject0(false);
26.1559 + }
26.1560 + } else if (ccl.isPrimitive()) {
26.1561 + if (ccl == Integer.TYPE) {
26.1562 + bin.readInts((int[]) array, 0, len);
26.1563 + } else if (ccl == Byte.TYPE) {
26.1564 + bin.readFully((byte[]) array, 0, len, true);
26.1565 + } else if (ccl == Long.TYPE) {
26.1566 + bin.readLongs((long[]) array, 0, len);
26.1567 + } else if (ccl == Float.TYPE) {
26.1568 + bin.readFloats((float[]) array, 0, len);
26.1569 + } else if (ccl == Double.TYPE) {
26.1570 + bin.readDoubles((double[]) array, 0, len);
26.1571 + } else if (ccl == Short.TYPE) {
26.1572 + bin.readShorts((short[]) array, 0, len);
26.1573 + } else if (ccl == Character.TYPE) {
26.1574 + bin.readChars((char[]) array, 0, len);
26.1575 + } else if (ccl == Boolean.TYPE) {
26.1576 + bin.readBooleans((boolean[]) array, 0, len);
26.1577 + } else {
26.1578 + throw new InternalError();
26.1579 + }
26.1580 + } else {
26.1581 + Object[] oa = (Object[]) array;
26.1582 + for (int i = 0; i < len; i++) {
26.1583 + oa[i] = readObject0(false);
26.1584 + handles.markDependency(arrayHandle, passHandle);
26.1585 + }
26.1586 + }
26.1587 +
26.1588 + handles.finish(arrayHandle);
26.1589 + passHandle = arrayHandle;
26.1590 + return array;
26.1591 + }
26.1592 +
26.1593 + /**
26.1594 + * Reads in and returns enum constant, or null if enum type is
26.1595 + * unresolvable. Sets passHandle to enum constant's assigned handle.
26.1596 + */
26.1597 + private Enum readEnum(boolean unshared) throws IOException {
26.1598 + if (bin.readByte() != TC_ENUM) {
26.1599 + throw new InternalError();
26.1600 + }
26.1601 +
26.1602 + ObjectStreamClass desc = readClassDesc(false);
26.1603 + if (!desc.isEnum()) {
26.1604 + throw new InvalidClassException("non-enum class: " + desc);
26.1605 + }
26.1606 +
26.1607 + int enumHandle = handles.assign(unshared ? unsharedMarker : null);
26.1608 + ClassNotFoundException resolveEx = desc.getResolveException();
26.1609 + if (resolveEx != null) {
26.1610 + handles.markException(enumHandle, resolveEx);
26.1611 + }
26.1612 +
26.1613 + String name = readString(false);
26.1614 + Enum en = null;
26.1615 + Class cl = desc.forClass();
26.1616 + if (cl != null) {
26.1617 + try {
26.1618 + en = Enum.valueOf(cl, name);
26.1619 + } catch (IllegalArgumentException ex) {
26.1620 + throw (IOException) new InvalidObjectException(
26.1621 + "enum constant " + name + " does not exist in " +
26.1622 + cl).initCause(ex);
26.1623 + }
26.1624 + if (!unshared) {
26.1625 + handles.setObject(enumHandle, en);
26.1626 + }
26.1627 + }
26.1628 +
26.1629 + handles.finish(enumHandle);
26.1630 + passHandle = enumHandle;
26.1631 + return en;
26.1632 + }
26.1633 +
26.1634 + /**
26.1635 + * Reads and returns "ordinary" (i.e., not a String, Class,
26.1636 + * ObjectStreamClass, array, or enum constant) object, or null if object's
26.1637 + * class is unresolvable (in which case a ClassNotFoundException will be
26.1638 + * associated with object's handle). Sets passHandle to object's assigned
26.1639 + * handle.
26.1640 + */
26.1641 + private Object readOrdinaryObject(boolean unshared)
26.1642 + throws IOException
26.1643 + {
26.1644 + if (bin.readByte() != TC_OBJECT) {
26.1645 + throw new InternalError();
26.1646 + }
26.1647 +
26.1648 + ObjectStreamClass desc = readClassDesc(false);
26.1649 + desc.checkDeserialize();
26.1650 +
26.1651 + Object obj;
26.1652 + try {
26.1653 + obj = desc.isInstantiable() ? desc.newInstance() : null;
26.1654 + } catch (Exception ex) {
26.1655 + throw (IOException) new InvalidClassException(
26.1656 + desc.forClass().getName(),
26.1657 + "unable to create instance").initCause(ex);
26.1658 + }
26.1659 +
26.1660 + passHandle = handles.assign(unshared ? unsharedMarker : obj);
26.1661 + ClassNotFoundException resolveEx = desc.getResolveException();
26.1662 + if (resolveEx != null) {
26.1663 + handles.markException(passHandle, resolveEx);
26.1664 + }
26.1665 +
26.1666 + if (desc.isExternalizable()) {
26.1667 + readExternalData((Externalizable) obj, desc);
26.1668 + } else {
26.1669 + readSerialData(obj, desc);
26.1670 + }
26.1671 +
26.1672 + handles.finish(passHandle);
26.1673 +
26.1674 + if (obj != null &&
26.1675 + handles.lookupException(passHandle) == null &&
26.1676 + desc.hasReadResolveMethod())
26.1677 + {
26.1678 + Object rep = desc.invokeReadResolve(obj);
26.1679 + if (unshared && rep.getClass().isArray()) {
26.1680 + rep = cloneArray(rep);
26.1681 + }
26.1682 + if (rep != obj) {
26.1683 + handles.setObject(passHandle, obj = rep);
26.1684 + }
26.1685 + }
26.1686 +
26.1687 + return obj;
26.1688 + }
26.1689 +
26.1690 + /**
26.1691 + * If obj is non-null, reads externalizable data by invoking readExternal()
26.1692 + * method of obj; otherwise, attempts to skip over externalizable data.
26.1693 + * Expects that passHandle is set to obj's handle before this method is
26.1694 + * called.
26.1695 + */
26.1696 + private void readExternalData(Externalizable obj, ObjectStreamClass desc)
26.1697 + throws IOException
26.1698 + {
26.1699 + Object oldContext = curContext;
26.1700 + curContext = null;
26.1701 + try {
26.1702 + boolean blocked = desc.hasBlockExternalData();
26.1703 + if (blocked) {
26.1704 + bin.setBlockDataMode(true);
26.1705 + }
26.1706 + if (obj != null) {
26.1707 + try {
26.1708 + obj.readExternal(this);
26.1709 + } catch (ClassNotFoundException ex) {
26.1710 + /*
26.1711 + * In most cases, the handle table has already propagated
26.1712 + * a CNFException to passHandle at this point; this mark
26.1713 + * call is included to address cases where the readExternal
26.1714 + * method has cons'ed and thrown a new CNFException of its
26.1715 + * own.
26.1716 + */
26.1717 + handles.markException(passHandle, ex);
26.1718 + }
26.1719 + }
26.1720 + if (blocked) {
26.1721 + skipCustomData();
26.1722 + }
26.1723 + } finally {
26.1724 + curContext = oldContext;
26.1725 + }
26.1726 + /*
26.1727 + * At this point, if the externalizable data was not written in
26.1728 + * block-data form and either the externalizable class doesn't exist
26.1729 + * locally (i.e., obj == null) or readExternal() just threw a
26.1730 + * CNFException, then the stream is probably in an inconsistent state,
26.1731 + * since some (or all) of the externalizable data may not have been
26.1732 + * consumed. Since there's no "correct" action to take in this case,
26.1733 + * we mimic the behavior of past serialization implementations and
26.1734 + * blindly hope that the stream is in sync; if it isn't and additional
26.1735 + * externalizable data remains in the stream, a subsequent read will
26.1736 + * most likely throw a StreamCorruptedException.
26.1737 + */
26.1738 + }
26.1739 +
26.1740 + /**
26.1741 + * Reads (or attempts to skip, if obj is null or is tagged with a
26.1742 + * ClassNotFoundException) instance data for each serializable class of
26.1743 + * object in stream, from superclass to subclass. Expects that passHandle
26.1744 + * is set to obj's handle before this method is called.
26.1745 + */
26.1746 + private void readSerialData(Object obj, ObjectStreamClass desc)
26.1747 + throws IOException
26.1748 + {
26.1749 + ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
26.1750 + for (int i = 0; i < slots.length; i++) {
26.1751 + ObjectStreamClass slotDesc = slots[i].desc;
26.1752 +
26.1753 + if (slots[i].hasData) {
26.1754 + if (obj != null &&
26.1755 + slotDesc.hasReadObjectMethod() &&
26.1756 + handles.lookupException(passHandle) == null)
26.1757 + {
26.1758 + Object oldContext = curContext;
26.1759 +
26.1760 + try {
26.1761 + curContext = null; //new SerialCallbackContext(obj, slotDesc);
26.1762 +
26.1763 + bin.setBlockDataMode(true);
26.1764 + slotDesc.invokeReadObject(obj, this);
26.1765 + } catch (ClassNotFoundException ex) {
26.1766 + /*
26.1767 + * In most cases, the handle table has already
26.1768 + * propagated a CNFException to passHandle at this
26.1769 + * point; this mark call is included to address cases
26.1770 + * where the custom readObject method has cons'ed and
26.1771 + * thrown a new CNFException of its own.
26.1772 + */
26.1773 + handles.markException(passHandle, ex);
26.1774 + } finally {
26.1775 + //curContext.setUsed();
26.1776 + curContext = oldContext;
26.1777 + }
26.1778 +
26.1779 + /*
26.1780 + * defaultDataEnd may have been set indirectly by custom
26.1781 + * readObject() method when calling defaultReadObject() or
26.1782 + * readFields(); clear it to restore normal read behavior.
26.1783 + */
26.1784 + defaultDataEnd = false;
26.1785 + } else {
26.1786 + defaultReadFields(obj, slotDesc);
26.1787 + }
26.1788 + if (slotDesc.hasWriteObjectData()) {
26.1789 + skipCustomData();
26.1790 + } else {
26.1791 + bin.setBlockDataMode(false);
26.1792 + }
26.1793 + } else {
26.1794 + if (obj != null &&
26.1795 + slotDesc.hasReadObjectNoDataMethod() &&
26.1796 + handles.lookupException(passHandle) == null)
26.1797 + {
26.1798 + slotDesc.invokeReadObjectNoData(obj);
26.1799 + }
26.1800 + }
26.1801 + }
26.1802 + }
26.1803 +
26.1804 + /**
26.1805 + * Skips over all block data and objects until TC_ENDBLOCKDATA is
26.1806 + * encountered.
26.1807 + */
26.1808 + private void skipCustomData() throws IOException {
26.1809 + int oldHandle = passHandle;
26.1810 + for (;;) {
26.1811 + if (bin.getBlockDataMode()) {
26.1812 + bin.skipBlockData();
26.1813 + bin.setBlockDataMode(false);
26.1814 + }
26.1815 + switch (bin.peekByte()) {
26.1816 + case TC_BLOCKDATA:
26.1817 + case TC_BLOCKDATALONG:
26.1818 + bin.setBlockDataMode(true);
26.1819 + break;
26.1820 +
26.1821 + case TC_ENDBLOCKDATA:
26.1822 + bin.readByte();
26.1823 + passHandle = oldHandle;
26.1824 + return;
26.1825 +
26.1826 + default:
26.1827 + readObject0(false);
26.1828 + break;
26.1829 + }
26.1830 + }
26.1831 + }
26.1832 +
26.1833 + /**
26.1834 + * Reads in values of serializable fields declared by given class
26.1835 + * descriptor. If obj is non-null, sets field values in obj. Expects that
26.1836 + * passHandle is set to obj's handle before this method is called.
26.1837 + */
26.1838 + private void defaultReadFields(Object obj, ObjectStreamClass desc)
26.1839 + throws IOException
26.1840 + {
26.1841 + // REMIND: is isInstance check necessary?
26.1842 + Class cl = desc.forClass();
26.1843 + if (cl != null && obj != null && !cl.isInstance(obj)) {
26.1844 + throw new ClassCastException();
26.1845 + }
26.1846 +
26.1847 + int primDataSize = desc.getPrimDataSize();
26.1848 + if (primVals == null || primVals.length < primDataSize) {
26.1849 + primVals = new byte[primDataSize];
26.1850 + }
26.1851 + bin.readFully(primVals, 0, primDataSize, false);
26.1852 + if (obj != null) {
26.1853 + desc.setPrimFieldValues(obj, primVals);
26.1854 + }
26.1855 +
26.1856 + int objHandle = passHandle;
26.1857 + ObjectStreamField[] fields = desc.getFields(false);
26.1858 + Object[] objVals = new Object[desc.getNumObjFields()];
26.1859 + int numPrimFields = fields.length - objVals.length;
26.1860 + for (int i = 0; i < objVals.length; i++) {
26.1861 + ObjectStreamField f = fields[numPrimFields + i];
26.1862 + objVals[i] = readObject0(f.isUnshared());
26.1863 + if (f.getField() != null) {
26.1864 + handles.markDependency(objHandle, passHandle);
26.1865 + }
26.1866 + }
26.1867 + if (obj != null) {
26.1868 + desc.setObjFieldValues(obj, objVals);
26.1869 + }
26.1870 + passHandle = objHandle;
26.1871 + }
26.1872 +
26.1873 + /**
26.1874 + * Reads in and returns IOException that caused serialization to abort.
26.1875 + * All stream state is discarded prior to reading in fatal exception. Sets
26.1876 + * passHandle to fatal exception's handle.
26.1877 + */
26.1878 + private IOException readFatalException() throws IOException {
26.1879 + if (bin.readByte() != TC_EXCEPTION) {
26.1880 + throw new InternalError();
26.1881 + }
26.1882 + clear();
26.1883 + return (IOException) readObject0(false);
26.1884 + }
26.1885 +
26.1886 + /**
26.1887 + * If recursion depth is 0, clears internal data structures; otherwise,
26.1888 + * throws a StreamCorruptedException. This method is called when a
26.1889 + * TC_RESET typecode is encountered.
26.1890 + */
26.1891 + private void handleReset() throws StreamCorruptedException {
26.1892 + if (depth > 0) {
26.1893 + throw new StreamCorruptedException(
26.1894 + "unexpected reset; recursion depth: " + depth);
26.1895 + }
26.1896 + clear();
26.1897 + }
26.1898 +
26.1899 + /**
26.1900 + * Converts specified span of bytes into float values.
26.1901 + */
26.1902 + // REMIND: remove once hotspot inlines Float.intBitsToFloat
26.1903 + private static native void bytesToFloats(byte[] src, int srcpos,
26.1904 + float[] dst, int dstpos,
26.1905 + int nfloats);
26.1906 +
26.1907 + /**
26.1908 + * Converts specified span of bytes into double values.
26.1909 + */
26.1910 + // REMIND: remove once hotspot inlines Double.longBitsToDouble
26.1911 + private static native void bytesToDoubles(byte[] src, int srcpos,
26.1912 + double[] dst, int dstpos,
26.1913 + int ndoubles);
26.1914 +
26.1915 + /**
26.1916 + * Returns the first non-null class loader (not counting class loaders of
26.1917 + * generated reflection implementation classes) up the execution stack, or
26.1918 + * null if only code from the null class loader is on the stack. This
26.1919 + * method is also called via reflection by the following RMI-IIOP class:
26.1920 + *
26.1921 + * com.sun.corba.se.internal.util.JDKClassLoader
26.1922 + *
26.1923 + * This method should not be removed or its signature changed without
26.1924 + * corresponding modifications to the above class.
26.1925 + */
26.1926 + // REMIND: change name to something more accurate?
26.1927 + private static native ClassLoader latestUserDefinedLoader();
26.1928 +
26.1929 + /**
26.1930 + * Default GetField implementation.
26.1931 + */
26.1932 + private class GetFieldImpl extends GetField {
26.1933 +
26.1934 + /** class descriptor describing serializable fields */
26.1935 + private final ObjectStreamClass desc;
26.1936 + /** primitive field values */
26.1937 + private final byte[] primVals;
26.1938 + /** object field values */
26.1939 + private final Object[] objVals;
26.1940 + /** object field value handles */
26.1941 + private final int[] objHandles;
26.1942 +
26.1943 + /**
26.1944 + * Creates GetFieldImpl object for reading fields defined in given
26.1945 + * class descriptor.
26.1946 + */
26.1947 + GetFieldImpl(ObjectStreamClass desc) {
26.1948 + this.desc = desc;
26.1949 + primVals = new byte[desc.getPrimDataSize()];
26.1950 + objVals = new Object[desc.getNumObjFields()];
26.1951 + objHandles = new int[objVals.length];
26.1952 + }
26.1953 +
26.1954 + public ObjectStreamClass getObjectStreamClass() {
26.1955 + return desc;
26.1956 + }
26.1957 +
26.1958 + public boolean defaulted(String name) throws IOException {
26.1959 + return (getFieldOffset(name, null) < 0);
26.1960 + }
26.1961 +
26.1962 + public boolean get(String name, boolean val) throws IOException {
26.1963 + int off = getFieldOffset(name, Boolean.TYPE);
26.1964 + return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
26.1965 + }
26.1966 +
26.1967 + public byte get(String name, byte val) throws IOException {
26.1968 + int off = getFieldOffset(name, Byte.TYPE);
26.1969 + return (off >= 0) ? primVals[off] : val;
26.1970 + }
26.1971 +
26.1972 + public char get(String name, char val) throws IOException {
26.1973 + int off = getFieldOffset(name, Character.TYPE);
26.1974 + return (off >= 0) ? Bits.getChar(primVals, off) : val;
26.1975 + }
26.1976 +
26.1977 + public short get(String name, short val) throws IOException {
26.1978 + int off = getFieldOffset(name, Short.TYPE);
26.1979 + return (off >= 0) ? Bits.getShort(primVals, off) : val;
26.1980 + }
26.1981 +
26.1982 + public int get(String name, int val) throws IOException {
26.1983 + int off = getFieldOffset(name, Integer.TYPE);
26.1984 + return (off >= 0) ? Bits.getInt(primVals, off) : val;
26.1985 + }
26.1986 +
26.1987 + public float get(String name, float val) throws IOException {
26.1988 + int off = getFieldOffset(name, Float.TYPE);
26.1989 + return (off >= 0) ? Bits.getFloat(primVals, off) : val;
26.1990 + }
26.1991 +
26.1992 + public long get(String name, long val) throws IOException {
26.1993 + int off = getFieldOffset(name, Long.TYPE);
26.1994 + return (off >= 0) ? Bits.getLong(primVals, off) : val;
26.1995 + }
26.1996 +
26.1997 + public double get(String name, double val) throws IOException {
26.1998 + int off = getFieldOffset(name, Double.TYPE);
26.1999 + return (off >= 0) ? Bits.getDouble(primVals, off) : val;
26.2000 + }
26.2001 +
26.2002 + public Object get(String name, Object val) throws IOException {
26.2003 + int off = getFieldOffset(name, Object.class);
26.2004 + if (off >= 0) {
26.2005 + int objHandle = objHandles[off];
26.2006 + handles.markDependency(passHandle, objHandle);
26.2007 + return (handles.lookupException(objHandle) == null) ?
26.2008 + objVals[off] : null;
26.2009 + } else {
26.2010 + return val;
26.2011 + }
26.2012 + }
26.2013 +
26.2014 + /**
26.2015 + * Reads primitive and object field values from stream.
26.2016 + */
26.2017 + void readFields() throws IOException {
26.2018 + bin.readFully(primVals, 0, primVals.length, false);
26.2019 +
26.2020 + int oldHandle = passHandle;
26.2021 + ObjectStreamField[] fields = desc.getFields(false);
26.2022 + int numPrimFields = fields.length - objVals.length;
26.2023 + for (int i = 0; i < objVals.length; i++) {
26.2024 + objVals[i] =
26.2025 + readObject0(fields[numPrimFields + i].isUnshared());
26.2026 + objHandles[i] = passHandle;
26.2027 + }
26.2028 + passHandle = oldHandle;
26.2029 + }
26.2030 +
26.2031 + /**
26.2032 + * Returns offset of field with given name and type. A specified type
26.2033 + * of null matches all types, Object.class matches all non-primitive
26.2034 + * types, and any other non-null type matches assignable types only.
26.2035 + * If no matching field is found in the (incoming) class
26.2036 + * descriptor but a matching field is present in the associated local
26.2037 + * class descriptor, returns -1. Throws IllegalArgumentException if
26.2038 + * neither incoming nor local class descriptor contains a match.
26.2039 + */
26.2040 + private int getFieldOffset(String name, Class type) {
26.2041 + ObjectStreamField field = desc.getField(name, type);
26.2042 + if (field != null) {
26.2043 + return field.getOffset();
26.2044 + } else if (desc.getLocalDesc().getField(name, type) != null) {
26.2045 + return -1;
26.2046 + } else {
26.2047 + throw new IllegalArgumentException("no such field " + name +
26.2048 + " with type " + type);
26.2049 + }
26.2050 + }
26.2051 + }
26.2052 +
26.2053 + /**
26.2054 + * Prioritized list of callbacks to be performed once object graph has been
26.2055 + * completely deserialized.
26.2056 + */
26.2057 + private static class ValidationList {
26.2058 +
26.2059 +
26.2060 + /**
26.2061 + * Creates new (empty) ValidationList.
26.2062 + */
26.2063 + ValidationList() {
26.2064 + }
26.2065 +
26.2066 + /**
26.2067 + * Registers callback. Throws InvalidObjectException if callback
26.2068 + * object is null.
26.2069 + */
26.2070 + void register(ObjectInputValidation obj, int priority)
26.2071 + throws InvalidObjectException
26.2072 + {
26.2073 + if (obj == null) {
26.2074 + throw new InvalidObjectException("null callback");
26.2075 + }
26.2076 + throw new InvalidObjectException("Does not work.");
26.2077 + }
26.2078 +
26.2079 + /**
26.2080 + * Invokes all registered callbacks and clears the callback list.
26.2081 + * Callbacks with higher priorities are called first; those with equal
26.2082 + * priorities may be called in any order. If any of the callbacks
26.2083 + * throws an InvalidObjectException, the callback process is terminated
26.2084 + * and the exception propagated upwards.
26.2085 + */
26.2086 + void doCallbacks() throws InvalidObjectException {
26.2087 + }
26.2088 +
26.2089 + /**
26.2090 + * Resets the callback list to its initial (empty) state.
26.2091 + */
26.2092 + public void clear() {
26.2093 + }
26.2094 + }
26.2095 +
26.2096 + /**
26.2097 + * Input stream supporting single-byte peek operations.
26.2098 + */
26.2099 + private static class PeekInputStream extends InputStream {
26.2100 +
26.2101 + /** underlying stream */
26.2102 + private final InputStream in;
26.2103 + /** peeked byte */
26.2104 + private int peekb = -1;
26.2105 +
26.2106 + /**
26.2107 + * Creates new PeekInputStream on top of given underlying stream.
26.2108 + */
26.2109 + PeekInputStream(InputStream in) {
26.2110 + this.in = in;
26.2111 + }
26.2112 +
26.2113 + /**
26.2114 + * Peeks at next byte value in stream. Similar to read(), except
26.2115 + * that it does not consume the read value.
26.2116 + */
26.2117 + int peek() throws IOException {
26.2118 + return (peekb >= 0) ? peekb : (peekb = in.read());
26.2119 + }
26.2120 +
26.2121 + public int read() throws IOException {
26.2122 + if (peekb >= 0) {
26.2123 + int v = peekb;
26.2124 + peekb = -1;
26.2125 + return v;
26.2126 + } else {
26.2127 + return in.read();
26.2128 + }
26.2129 + }
26.2130 +
26.2131 + public int read(byte[] b, int off, int len) throws IOException {
26.2132 + if (len == 0) {
26.2133 + return 0;
26.2134 + } else if (peekb < 0) {
26.2135 + return in.read(b, off, len);
26.2136 + } else {
26.2137 + b[off++] = (byte) peekb;
26.2138 + len--;
26.2139 + peekb = -1;
26.2140 + int n = in.read(b, off, len);
26.2141 + return (n >= 0) ? (n + 1) : 1;
26.2142 + }
26.2143 + }
26.2144 +
26.2145 + void readFully(byte[] b, int off, int len) throws IOException {
26.2146 + int n = 0;
26.2147 + while (n < len) {
26.2148 + int count = read(b, off + n, len - n);
26.2149 + if (count < 0) {
26.2150 + throw new EOFException();
26.2151 + }
26.2152 + n += count;
26.2153 + }
26.2154 + }
26.2155 +
26.2156 + public long skip(long n) throws IOException {
26.2157 + if (n <= 0) {
26.2158 + return 0;
26.2159 + }
26.2160 + int skipped = 0;
26.2161 + if (peekb >= 0) {
26.2162 + peekb = -1;
26.2163 + skipped++;
26.2164 + n--;
26.2165 + }
26.2166 + return skipped + skip(n);
26.2167 + }
26.2168 +
26.2169 + public int available() throws IOException {
26.2170 + return in.available() + ((peekb >= 0) ? 1 : 0);
26.2171 + }
26.2172 +
26.2173 + public void close() throws IOException {
26.2174 + in.close();
26.2175 + }
26.2176 + }
26.2177 +
26.2178 + /**
26.2179 + * Input stream with two modes: in default mode, inputs data written in the
26.2180 + * same format as DataOutputStream; in "block data" mode, inputs data
26.2181 + * bracketed by block data markers (see object serialization specification
26.2182 + * for details). Buffering depends on block data mode: when in default
26.2183 + * mode, no data is buffered in advance; when in block data mode, all data
26.2184 + * for the current data block is read in at once (and buffered).
26.2185 + */
26.2186 + private class BlockDataInputStream
26.2187 + extends InputStream implements DataInput
26.2188 + {
26.2189 + /** maximum data block length */
26.2190 + private static final int MAX_BLOCK_SIZE = 1024;
26.2191 + /** maximum data block header length */
26.2192 + private static final int MAX_HEADER_SIZE = 5;
26.2193 + /** (tunable) length of char buffer (for reading strings) */
26.2194 + private static final int CHAR_BUF_SIZE = 256;
26.2195 + /** readBlockHeader() return value indicating header read may block */
26.2196 + private static final int HEADER_BLOCKED = -2;
26.2197 +
26.2198 + /** buffer for reading general/block data */
26.2199 + private final byte[] buf = new byte[MAX_BLOCK_SIZE];
26.2200 + /** buffer for reading block data headers */
26.2201 + private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
26.2202 + /** char buffer for fast string reads */
26.2203 + private final char[] cbuf = new char[CHAR_BUF_SIZE];
26.2204 +
26.2205 + /** block data mode */
26.2206 + private boolean blkmode = false;
26.2207 +
26.2208 + // block data state fields; values meaningful only when blkmode true
26.2209 + /** current offset into buf */
26.2210 + private int pos = 0;
26.2211 + /** end offset of valid data in buf, or -1 if no more block data */
26.2212 + private int end = -1;
26.2213 + /** number of bytes in current block yet to be read from stream */
26.2214 + private int unread = 0;
26.2215 +
26.2216 + /** underlying stream (wrapped in peekable filter stream) */
26.2217 + private final PeekInputStream in;
26.2218 + /** loopback stream (for data reads that span data blocks) */
26.2219 + private final DataInputStream din;
26.2220 +
26.2221 + /**
26.2222 + * Creates new BlockDataInputStream on top of given underlying stream.
26.2223 + * Block data mode is turned off by default.
26.2224 + */
26.2225 + BlockDataInputStream(InputStream in) {
26.2226 + this.in = new PeekInputStream(in);
26.2227 + din = new DataInputStream(this);
26.2228 + }
26.2229 +
26.2230 + /**
26.2231 + * Sets block data mode to the given mode (true == on, false == off)
26.2232 + * and returns the previous mode value. If the new mode is the same as
26.2233 + * the old mode, no action is taken. Throws IllegalStateException if
26.2234 + * block data mode is being switched from on to off while unconsumed
26.2235 + * block data is still present in the stream.
26.2236 + */
26.2237 + boolean setBlockDataMode(boolean newmode) throws IOException {
26.2238 + if (blkmode == newmode) {
26.2239 + return blkmode;
26.2240 + }
26.2241 + if (newmode) {
26.2242 + pos = 0;
26.2243 + end = 0;
26.2244 + unread = 0;
26.2245 + } else if (pos < end) {
26.2246 + throw new IllegalStateException("unread block data");
26.2247 + }
26.2248 + blkmode = newmode;
26.2249 + return !blkmode;
26.2250 + }
26.2251 +
26.2252 + /**
26.2253 + * Returns true if the stream is currently in block data mode, false
26.2254 + * otherwise.
26.2255 + */
26.2256 + boolean getBlockDataMode() {
26.2257 + return blkmode;
26.2258 + }
26.2259 +
26.2260 + /**
26.2261 + * If in block data mode, skips to the end of the current group of data
26.2262 + * blocks (but does not unset block data mode). If not in block data
26.2263 + * mode, throws an IllegalStateException.
26.2264 + */
26.2265 + void skipBlockData() throws IOException {
26.2266 + if (!blkmode) {
26.2267 + throw new IllegalStateException("not in block data mode");
26.2268 + }
26.2269 + while (end >= 0) {
26.2270 + refill();
26.2271 + }
26.2272 + }
26.2273 +
26.2274 + /**
26.2275 + * Attempts to read in the next block data header (if any). If
26.2276 + * canBlock is false and a full header cannot be read without possibly
26.2277 + * blocking, returns HEADER_BLOCKED, else if the next element in the
26.2278 + * stream is a block data header, returns the block data length
26.2279 + * specified by the header, else returns -1.
26.2280 + */
26.2281 + private int readBlockHeader(boolean canBlock) throws IOException {
26.2282 + if (defaultDataEnd) {
26.2283 + /*
26.2284 + * Fix for 4360508: stream is currently at the end of a field
26.2285 + * value block written via default serialization; since there
26.2286 + * is no terminating TC_ENDBLOCKDATA tag, simulate
26.2287 + * end-of-custom-data behavior explicitly.
26.2288 + */
26.2289 + return -1;
26.2290 + }
26.2291 + try {
26.2292 + for (;;) {
26.2293 + int avail = canBlock ? Integer.MAX_VALUE : in.available();
26.2294 + if (avail == 0) {
26.2295 + return HEADER_BLOCKED;
26.2296 + }
26.2297 +
26.2298 + int tc = in.peek();
26.2299 + switch (tc) {
26.2300 + case TC_BLOCKDATA:
26.2301 + if (avail < 2) {
26.2302 + return HEADER_BLOCKED;
26.2303 + }
26.2304 + in.readFully(hbuf, 0, 2);
26.2305 + return hbuf[1] & 0xFF;
26.2306 +
26.2307 + case TC_BLOCKDATALONG:
26.2308 + if (avail < 5) {
26.2309 + return HEADER_BLOCKED;
26.2310 + }
26.2311 + in.readFully(hbuf, 0, 5);
26.2312 + int len = Bits.getInt(hbuf, 1);
26.2313 + if (len < 0) {
26.2314 + throw new StreamCorruptedException(
26.2315 + "illegal block data header length: " +
26.2316 + len);
26.2317 + }
26.2318 + return len;
26.2319 +
26.2320 + /*
26.2321 + * TC_RESETs may occur in between data blocks.
26.2322 + * Unfortunately, this case must be parsed at a lower
26.2323 + * level than other typecodes, since primitive data
26.2324 + * reads may span data blocks separated by a TC_RESET.
26.2325 + */
26.2326 + case TC_RESET:
26.2327 + in.read();
26.2328 + handleReset();
26.2329 + break;
26.2330 +
26.2331 + default:
26.2332 + if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
26.2333 + throw new StreamCorruptedException(
26.2334 + String.format("invalid type code: %02X",
26.2335 + tc));
26.2336 + }
26.2337 + return -1;
26.2338 + }
26.2339 + }
26.2340 + } catch (EOFException ex) {
26.2341 + throw new StreamCorruptedException(
26.2342 + "unexpected EOF while reading block data header");
26.2343 + }
26.2344 + }
26.2345 +
26.2346 + /**
26.2347 + * Refills internal buffer buf with block data. Any data in buf at the
26.2348 + * time of the call is considered consumed. Sets the pos, end, and
26.2349 + * unread fields to reflect the new amount of available block data; if
26.2350 + * the next element in the stream is not a data block, sets pos and
26.2351 + * unread to 0 and end to -1.
26.2352 + */
26.2353 + private void refill() throws IOException {
26.2354 + try {
26.2355 + do {
26.2356 + pos = 0;
26.2357 + if (unread > 0) {
26.2358 + int n =
26.2359 + in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
26.2360 + if (n >= 0) {
26.2361 + end = n;
26.2362 + unread -= n;
26.2363 + } else {
26.2364 + throw new StreamCorruptedException(
26.2365 + "unexpected EOF in middle of data block");
26.2366 + }
26.2367 + } else {
26.2368 + int n = readBlockHeader(true);
26.2369 + if (n >= 0) {
26.2370 + end = 0;
26.2371 + unread = n;
26.2372 + } else {
26.2373 + end = -1;
26.2374 + unread = 0;
26.2375 + }
26.2376 + }
26.2377 + } while (pos == end);
26.2378 + } catch (IOException ex) {
26.2379 + pos = 0;
26.2380 + end = -1;
26.2381 + unread = 0;
26.2382 + throw ex;
26.2383 + }
26.2384 + }
26.2385 +
26.2386 + /**
26.2387 + * If in block data mode, returns the number of unconsumed bytes
26.2388 + * remaining in the current data block. If not in block data mode,
26.2389 + * throws an IllegalStateException.
26.2390 + */
26.2391 + int currentBlockRemaining() {
26.2392 + if (blkmode) {
26.2393 + return (end >= 0) ? (end - pos) + unread : 0;
26.2394 + } else {
26.2395 + throw new IllegalStateException();
26.2396 + }
26.2397 + }
26.2398 +
26.2399 + /**
26.2400 + * Peeks at (but does not consume) and returns the next byte value in
26.2401 + * the stream, or -1 if the end of the stream/block data (if in block
26.2402 + * data mode) has been reached.
26.2403 + */
26.2404 + int peek() throws IOException {
26.2405 + if (blkmode) {
26.2406 + if (pos == end) {
26.2407 + refill();
26.2408 + }
26.2409 + return (end >= 0) ? (buf[pos] & 0xFF) : -1;
26.2410 + } else {
26.2411 + return in.peek();
26.2412 + }
26.2413 + }
26.2414 +
26.2415 + /**
26.2416 + * Peeks at (but does not consume) and returns the next byte value in
26.2417 + * the stream, or throws EOFException if end of stream/block data has
26.2418 + * been reached.
26.2419 + */
26.2420 + byte peekByte() throws IOException {
26.2421 + int val = peek();
26.2422 + if (val < 0) {
26.2423 + throw new EOFException();
26.2424 + }
26.2425 + return (byte) val;
26.2426 + }
26.2427 +
26.2428 +
26.2429 + /* ----------------- generic input stream methods ------------------ */
26.2430 + /*
26.2431 + * The following methods are equivalent to their counterparts in
26.2432 + * InputStream, except that they interpret data block boundaries and
26.2433 + * read the requested data from within data blocks when in block data
26.2434 + * mode.
26.2435 + */
26.2436 +
26.2437 + public int read() throws IOException {
26.2438 + if (blkmode) {
26.2439 + if (pos == end) {
26.2440 + refill();
26.2441 + }
26.2442 + return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
26.2443 + } else {
26.2444 + return in.read();
26.2445 + }
26.2446 + }
26.2447 +
26.2448 + public int read(byte[] b, int off, int len) throws IOException {
26.2449 + return read(b, off, len, false);
26.2450 + }
26.2451 +
26.2452 + public long skip(long len) throws IOException {
26.2453 + long remain = len;
26.2454 + while (remain > 0) {
26.2455 + if (blkmode) {
26.2456 + if (pos == end) {
26.2457 + refill();
26.2458 + }
26.2459 + if (end < 0) {
26.2460 + break;
26.2461 + }
26.2462 + int nread = (int) Math.min(remain, end - pos);
26.2463 + remain -= nread;
26.2464 + pos += nread;
26.2465 + } else {
26.2466 + int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
26.2467 + if ((nread = in.read(buf, 0, nread)) < 0) {
26.2468 + break;
26.2469 + }
26.2470 + remain -= nread;
26.2471 + }
26.2472 + }
26.2473 + return len - remain;
26.2474 + }
26.2475 +
26.2476 + public int available() throws IOException {
26.2477 + if (blkmode) {
26.2478 + if ((pos == end) && (unread == 0)) {
26.2479 + int n;
26.2480 + while ((n = readBlockHeader(false)) == 0) ;
26.2481 + switch (n) {
26.2482 + case HEADER_BLOCKED:
26.2483 + break;
26.2484 +
26.2485 + case -1:
26.2486 + pos = 0;
26.2487 + end = -1;
26.2488 + break;
26.2489 +
26.2490 + default:
26.2491 + pos = 0;
26.2492 + end = 0;
26.2493 + unread = n;
26.2494 + break;
26.2495 + }
26.2496 + }
26.2497 + // avoid unnecessary call to in.available() if possible
26.2498 + int unreadAvail = (unread > 0) ?
26.2499 + Math.min(in.available(), unread) : 0;
26.2500 + return (end >= 0) ? (end - pos) + unreadAvail : 0;
26.2501 + } else {
26.2502 + return in.available();
26.2503 + }
26.2504 + }
26.2505 +
26.2506 + public void close() throws IOException {
26.2507 + if (blkmode) {
26.2508 + pos = 0;
26.2509 + end = -1;
26.2510 + unread = 0;
26.2511 + }
26.2512 + in.close();
26.2513 + }
26.2514 +
26.2515 + /**
26.2516 + * Attempts to read len bytes into byte array b at offset off. Returns
26.2517 + * the number of bytes read, or -1 if the end of stream/block data has
26.2518 + * been reached. If copy is true, reads values into an intermediate
26.2519 + * buffer before copying them to b (to avoid exposing a reference to
26.2520 + * b).
26.2521 + */
26.2522 + int read(byte[] b, int off, int len, boolean copy) throws IOException {
26.2523 + if (len == 0) {
26.2524 + return 0;
26.2525 + } else if (blkmode) {
26.2526 + if (pos == end) {
26.2527 + refill();
26.2528 + }
26.2529 + if (end < 0) {
26.2530 + return -1;
26.2531 + }
26.2532 + int nread = Math.min(len, end - pos);
26.2533 + System.arraycopy(buf, pos, b, off, nread);
26.2534 + pos += nread;
26.2535 + return nread;
26.2536 + } else if (copy) {
26.2537 + int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
26.2538 + if (nread > 0) {
26.2539 + System.arraycopy(buf, 0, b, off, nread);
26.2540 + }
26.2541 + return nread;
26.2542 + } else {
26.2543 + return in.read(b, off, len);
26.2544 + }
26.2545 + }
26.2546 +
26.2547 + /* ----------------- primitive data input methods ------------------ */
26.2548 + /*
26.2549 + * The following methods are equivalent to their counterparts in
26.2550 + * DataInputStream, except that they interpret data block boundaries
26.2551 + * and read the requested data from within data blocks when in block
26.2552 + * data mode.
26.2553 + */
26.2554 +
26.2555 + public void readFully(byte[] b) throws IOException {
26.2556 + readFully(b, 0, b.length, false);
26.2557 + }
26.2558 +
26.2559 + public void readFully(byte[] b, int off, int len) throws IOException {
26.2560 + readFully(b, off, len, false);
26.2561 + }
26.2562 +
26.2563 + public void readFully(byte[] b, int off, int len, boolean copy)
26.2564 + throws IOException
26.2565 + {
26.2566 + while (len > 0) {
26.2567 + int n = read(b, off, len, copy);
26.2568 + if (n < 0) {
26.2569 + throw new EOFException();
26.2570 + }
26.2571 + off += n;
26.2572 + len -= n;
26.2573 + }
26.2574 + }
26.2575 +
26.2576 + public int skipBytes(int n) throws IOException {
26.2577 + return din.skipBytes(n);
26.2578 + }
26.2579 +
26.2580 + public boolean readBoolean() throws IOException {
26.2581 + int v = read();
26.2582 + if (v < 0) {
26.2583 + throw new EOFException();
26.2584 + }
26.2585 + return (v != 0);
26.2586 + }
26.2587 +
26.2588 + public byte readByte() throws IOException {
26.2589 + int v = read();
26.2590 + if (v < 0) {
26.2591 + throw new EOFException();
26.2592 + }
26.2593 + return (byte) v;
26.2594 + }
26.2595 +
26.2596 + public int readUnsignedByte() throws IOException {
26.2597 + int v = read();
26.2598 + if (v < 0) {
26.2599 + throw new EOFException();
26.2600 + }
26.2601 + return v;
26.2602 + }
26.2603 +
26.2604 + public char readChar() throws IOException {
26.2605 + if (!blkmode) {
26.2606 + pos = 0;
26.2607 + in.readFully(buf, 0, 2);
26.2608 + } else if (end - pos < 2) {
26.2609 + return din.readChar();
26.2610 + }
26.2611 + char v = Bits.getChar(buf, pos);
26.2612 + pos += 2;
26.2613 + return v;
26.2614 + }
26.2615 +
26.2616 + public short readShort() throws IOException {
26.2617 + if (!blkmode) {
26.2618 + pos = 0;
26.2619 + in.readFully(buf, 0, 2);
26.2620 + } else if (end - pos < 2) {
26.2621 + return din.readShort();
26.2622 + }
26.2623 + short v = Bits.getShort(buf, pos);
26.2624 + pos += 2;
26.2625 + return v;
26.2626 + }
26.2627 +
26.2628 + public int readUnsignedShort() throws IOException {
26.2629 + if (!blkmode) {
26.2630 + pos = 0;
26.2631 + in.readFully(buf, 0, 2);
26.2632 + } else if (end - pos < 2) {
26.2633 + return din.readUnsignedShort();
26.2634 + }
26.2635 + int v = Bits.getShort(buf, pos) & 0xFFFF;
26.2636 + pos += 2;
26.2637 + return v;
26.2638 + }
26.2639 +
26.2640 + public int readInt() throws IOException {
26.2641 + if (!blkmode) {
26.2642 + pos = 0;
26.2643 + in.readFully(buf, 0, 4);
26.2644 + } else if (end - pos < 4) {
26.2645 + return din.readInt();
26.2646 + }
26.2647 + int v = Bits.getInt(buf, pos);
26.2648 + pos += 4;
26.2649 + return v;
26.2650 + }
26.2651 +
26.2652 + public float readFloat() throws IOException {
26.2653 + if (!blkmode) {
26.2654 + pos = 0;
26.2655 + in.readFully(buf, 0, 4);
26.2656 + } else if (end - pos < 4) {
26.2657 + return din.readFloat();
26.2658 + }
26.2659 + float v = Bits.getFloat(buf, pos);
26.2660 + pos += 4;
26.2661 + return v;
26.2662 + }
26.2663 +
26.2664 + public long readLong() throws IOException {
26.2665 + if (!blkmode) {
26.2666 + pos = 0;
26.2667 + in.readFully(buf, 0, 8);
26.2668 + } else if (end - pos < 8) {
26.2669 + return din.readLong();
26.2670 + }
26.2671 + long v = Bits.getLong(buf, pos);
26.2672 + pos += 8;
26.2673 + return v;
26.2674 + }
26.2675 +
26.2676 + public double readDouble() throws IOException {
26.2677 + if (!blkmode) {
26.2678 + pos = 0;
26.2679 + in.readFully(buf, 0, 8);
26.2680 + } else if (end - pos < 8) {
26.2681 + return din.readDouble();
26.2682 + }
26.2683 + double v = Bits.getDouble(buf, pos);
26.2684 + pos += 8;
26.2685 + return v;
26.2686 + }
26.2687 +
26.2688 + public String readUTF() throws IOException {
26.2689 + return readUTFBody(readUnsignedShort());
26.2690 + }
26.2691 +
26.2692 + public String readLine() throws IOException {
26.2693 + return din.readLine(); // deprecated, not worth optimizing
26.2694 + }
26.2695 +
26.2696 + /* -------------- primitive data array input methods --------------- */
26.2697 + /*
26.2698 + * The following methods read in spans of primitive data values.
26.2699 + * Though equivalent to calling the corresponding primitive read
26.2700 + * methods repeatedly, these methods are optimized for reading groups
26.2701 + * of primitive data values more efficiently.
26.2702 + */
26.2703 +
26.2704 + void readBooleans(boolean[] v, int off, int len) throws IOException {
26.2705 + int stop, endoff = off + len;
26.2706 + while (off < endoff) {
26.2707 + if (!blkmode) {
26.2708 + int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
26.2709 + in.readFully(buf, 0, span);
26.2710 + stop = off + span;
26.2711 + pos = 0;
26.2712 + } else if (end - pos < 1) {
26.2713 + v[off++] = din.readBoolean();
26.2714 + continue;
26.2715 + } else {
26.2716 + stop = Math.min(endoff, off + end - pos);
26.2717 + }
26.2718 +
26.2719 + while (off < stop) {
26.2720 + v[off++] = Bits.getBoolean(buf, pos++);
26.2721 + }
26.2722 + }
26.2723 + }
26.2724 +
26.2725 + void readChars(char[] v, int off, int len) throws IOException {
26.2726 + int stop, endoff = off + len;
26.2727 + while (off < endoff) {
26.2728 + if (!blkmode) {
26.2729 + int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
26.2730 + in.readFully(buf, 0, span << 1);
26.2731 + stop = off + span;
26.2732 + pos = 0;
26.2733 + } else if (end - pos < 2) {
26.2734 + v[off++] = din.readChar();
26.2735 + continue;
26.2736 + } else {
26.2737 + stop = Math.min(endoff, off + ((end - pos) >> 1));
26.2738 + }
26.2739 +
26.2740 + while (off < stop) {
26.2741 + v[off++] = Bits.getChar(buf, pos);
26.2742 + pos += 2;
26.2743 + }
26.2744 + }
26.2745 + }
26.2746 +
26.2747 + void readShorts(short[] v, int off, int len) throws IOException {
26.2748 + int stop, endoff = off + len;
26.2749 + while (off < endoff) {
26.2750 + if (!blkmode) {
26.2751 + int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
26.2752 + in.readFully(buf, 0, span << 1);
26.2753 + stop = off + span;
26.2754 + pos = 0;
26.2755 + } else if (end - pos < 2) {
26.2756 + v[off++] = din.readShort();
26.2757 + continue;
26.2758 + } else {
26.2759 + stop = Math.min(endoff, off + ((end - pos) >> 1));
26.2760 + }
26.2761 +
26.2762 + while (off < stop) {
26.2763 + v[off++] = Bits.getShort(buf, pos);
26.2764 + pos += 2;
26.2765 + }
26.2766 + }
26.2767 + }
26.2768 +
26.2769 + void readInts(int[] v, int off, int len) throws IOException {
26.2770 + int stop, endoff = off + len;
26.2771 + while (off < endoff) {
26.2772 + if (!blkmode) {
26.2773 + int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
26.2774 + in.readFully(buf, 0, span << 2);
26.2775 + stop = off + span;
26.2776 + pos = 0;
26.2777 + } else if (end - pos < 4) {
26.2778 + v[off++] = din.readInt();
26.2779 + continue;
26.2780 + } else {
26.2781 + stop = Math.min(endoff, off + ((end - pos) >> 2));
26.2782 + }
26.2783 +
26.2784 + while (off < stop) {
26.2785 + v[off++] = Bits.getInt(buf, pos);
26.2786 + pos += 4;
26.2787 + }
26.2788 + }
26.2789 + }
26.2790 +
26.2791 + void readFloats(float[] v, int off, int len) throws IOException {
26.2792 + int span, endoff = off + len;
26.2793 + while (off < endoff) {
26.2794 + if (!blkmode) {
26.2795 + span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
26.2796 + in.readFully(buf, 0, span << 2);
26.2797 + pos = 0;
26.2798 + } else if (end - pos < 4) {
26.2799 + v[off++] = din.readFloat();
26.2800 + continue;
26.2801 + } else {
26.2802 + span = Math.min(endoff - off, ((end - pos) >> 2));
26.2803 + }
26.2804 +
26.2805 + bytesToFloats(buf, pos, v, off, span);
26.2806 + off += span;
26.2807 + pos += span << 2;
26.2808 + }
26.2809 + }
26.2810 +
26.2811 + void readLongs(long[] v, int off, int len) throws IOException {
26.2812 + int stop, endoff = off + len;
26.2813 + while (off < endoff) {
26.2814 + if (!blkmode) {
26.2815 + int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
26.2816 + in.readFully(buf, 0, span << 3);
26.2817 + stop = off + span;
26.2818 + pos = 0;
26.2819 + } else if (end - pos < 8) {
26.2820 + v[off++] = din.readLong();
26.2821 + continue;
26.2822 + } else {
26.2823 + stop = Math.min(endoff, off + ((end - pos) >> 3));
26.2824 + }
26.2825 +
26.2826 + while (off < stop) {
26.2827 + v[off++] = Bits.getLong(buf, pos);
26.2828 + pos += 8;
26.2829 + }
26.2830 + }
26.2831 + }
26.2832 +
26.2833 + void readDoubles(double[] v, int off, int len) throws IOException {
26.2834 + int span, endoff = off + len;
26.2835 + while (off < endoff) {
26.2836 + if (!blkmode) {
26.2837 + span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
26.2838 + in.readFully(buf, 0, span << 3);
26.2839 + pos = 0;
26.2840 + } else if (end - pos < 8) {
26.2841 + v[off++] = din.readDouble();
26.2842 + continue;
26.2843 + } else {
26.2844 + span = Math.min(endoff - off, ((end - pos) >> 3));
26.2845 + }
26.2846 +
26.2847 + bytesToDoubles(buf, pos, v, off, span);
26.2848 + off += span;
26.2849 + pos += span << 3;
26.2850 + }
26.2851 + }
26.2852 +
26.2853 + /**
26.2854 + * Reads in string written in "long" UTF format. "Long" UTF format is
26.2855 + * identical to standard UTF, except that it uses an 8 byte header
26.2856 + * (instead of the standard 2 bytes) to convey the UTF encoding length.
26.2857 + */
26.2858 + String readLongUTF() throws IOException {
26.2859 + return readUTFBody(readLong());
26.2860 + }
26.2861 +
26.2862 + /**
26.2863 + * Reads in the "body" (i.e., the UTF representation minus the 2-byte
26.2864 + * or 8-byte length header) of a UTF encoding, which occupies the next
26.2865 + * utflen bytes.
26.2866 + */
26.2867 + private String readUTFBody(long utflen) throws IOException {
26.2868 + StringBuilder sbuf = new StringBuilder();
26.2869 + if (!blkmode) {
26.2870 + end = pos = 0;
26.2871 + }
26.2872 +
26.2873 + while (utflen > 0) {
26.2874 + int avail = end - pos;
26.2875 + if (avail >= 3 || (long) avail == utflen) {
26.2876 + utflen -= readUTFSpan(sbuf, utflen);
26.2877 + } else {
26.2878 + if (blkmode) {
26.2879 + // near block boundary, read one byte at a time
26.2880 + utflen -= readUTFChar(sbuf, utflen);
26.2881 + } else {
26.2882 + // shift and refill buffer manually
26.2883 + if (avail > 0) {
26.2884 + System.arraycopy(buf, pos, buf, 0, avail);
26.2885 + }
26.2886 + pos = 0;
26.2887 + end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
26.2888 + in.readFully(buf, avail, end - avail);
26.2889 + }
26.2890 + }
26.2891 + }
26.2892 +
26.2893 + return sbuf.toString();
26.2894 + }
26.2895 +
26.2896 + /**
26.2897 + * Reads span of UTF-encoded characters out of internal buffer
26.2898 + * (starting at offset pos and ending at or before offset end),
26.2899 + * consuming no more than utflen bytes. Appends read characters to
26.2900 + * sbuf. Returns the number of bytes consumed.
26.2901 + */
26.2902 + private long readUTFSpan(StringBuilder sbuf, long utflen)
26.2903 + throws IOException
26.2904 + {
26.2905 + int cpos = 0;
26.2906 + int start = pos;
26.2907 + int avail = Math.min(end - pos, CHAR_BUF_SIZE);
26.2908 + // stop short of last char unless all of utf bytes in buffer
26.2909 + int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
26.2910 + boolean outOfBounds = false;
26.2911 +
26.2912 + try {
26.2913 + while (pos < stop) {
26.2914 + int b1, b2, b3;
26.2915 + b1 = buf[pos++] & 0xFF;
26.2916 + switch (b1 >> 4) {
26.2917 + case 0:
26.2918 + case 1:
26.2919 + case 2:
26.2920 + case 3:
26.2921 + case 4:
26.2922 + case 5:
26.2923 + case 6:
26.2924 + case 7: // 1 byte format: 0xxxxxxx
26.2925 + cbuf[cpos++] = (char) b1;
26.2926 + break;
26.2927 +
26.2928 + case 12:
26.2929 + case 13: // 2 byte format: 110xxxxx 10xxxxxx
26.2930 + b2 = buf[pos++];
26.2931 + if ((b2 & 0xC0) != 0x80) {
26.2932 + throw new UTFDataFormatException();
26.2933 + }
26.2934 + cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
26.2935 + ((b2 & 0x3F) << 0));
26.2936 + break;
26.2937 +
26.2938 + case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
26.2939 + b3 = buf[pos + 1];
26.2940 + b2 = buf[pos + 0];
26.2941 + pos += 2;
26.2942 + if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
26.2943 + throw new UTFDataFormatException();
26.2944 + }
26.2945 + cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
26.2946 + ((b2 & 0x3F) << 6) |
26.2947 + ((b3 & 0x3F) << 0));
26.2948 + break;
26.2949 +
26.2950 + default: // 10xx xxxx, 1111 xxxx
26.2951 + throw new UTFDataFormatException();
26.2952 + }
26.2953 + }
26.2954 + } catch (ArrayIndexOutOfBoundsException ex) {
26.2955 + outOfBounds = true;
26.2956 + } finally {
26.2957 + if (outOfBounds || (pos - start) > utflen) {
26.2958 + /*
26.2959 + * Fix for 4450867: if a malformed utf char causes the
26.2960 + * conversion loop to scan past the expected end of the utf
26.2961 + * string, only consume the expected number of utf bytes.
26.2962 + */
26.2963 + pos = start + (int) utflen;
26.2964 + throw new UTFDataFormatException();
26.2965 + }
26.2966 + }
26.2967 +
26.2968 + sbuf.append(cbuf, 0, cpos);
26.2969 + return pos - start;
26.2970 + }
26.2971 +
26.2972 + /**
26.2973 + * Reads in single UTF-encoded character one byte at a time, appends
26.2974 + * the character to sbuf, and returns the number of bytes consumed.
26.2975 + * This method is used when reading in UTF strings written in block
26.2976 + * data mode to handle UTF-encoded characters which (potentially)
26.2977 + * straddle block-data boundaries.
26.2978 + */
26.2979 + private int readUTFChar(StringBuilder sbuf, long utflen)
26.2980 + throws IOException
26.2981 + {
26.2982 + int b1, b2, b3;
26.2983 + b1 = readByte() & 0xFF;
26.2984 + switch (b1 >> 4) {
26.2985 + case 0:
26.2986 + case 1:
26.2987 + case 2:
26.2988 + case 3:
26.2989 + case 4:
26.2990 + case 5:
26.2991 + case 6:
26.2992 + case 7: // 1 byte format: 0xxxxxxx
26.2993 + sbuf.append((char) b1);
26.2994 + return 1;
26.2995 +
26.2996 + case 12:
26.2997 + case 13: // 2 byte format: 110xxxxx 10xxxxxx
26.2998 + if (utflen < 2) {
26.2999 + throw new UTFDataFormatException();
26.3000 + }
26.3001 + b2 = readByte();
26.3002 + if ((b2 & 0xC0) != 0x80) {
26.3003 + throw new UTFDataFormatException();
26.3004 + }
26.3005 + sbuf.append((char) (((b1 & 0x1F) << 6) |
26.3006 + ((b2 & 0x3F) << 0)));
26.3007 + return 2;
26.3008 +
26.3009 + case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
26.3010 + if (utflen < 3) {
26.3011 + if (utflen == 2) {
26.3012 + readByte(); // consume remaining byte
26.3013 + }
26.3014 + throw new UTFDataFormatException();
26.3015 + }
26.3016 + b2 = readByte();
26.3017 + b3 = readByte();
26.3018 + if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
26.3019 + throw new UTFDataFormatException();
26.3020 + }
26.3021 + sbuf.append((char) (((b1 & 0x0F) << 12) |
26.3022 + ((b2 & 0x3F) << 6) |
26.3023 + ((b3 & 0x3F) << 0)));
26.3024 + return 3;
26.3025 +
26.3026 + default: // 10xx xxxx, 1111 xxxx
26.3027 + throw new UTFDataFormatException();
26.3028 + }
26.3029 + }
26.3030 + }
26.3031 +
26.3032 + /**
26.3033 + * Unsynchronized table which tracks wire handle to object mappings, as
26.3034 + * well as ClassNotFoundExceptions associated with deserialized objects.
26.3035 + * This class implements an exception-propagation algorithm for
26.3036 + * determining which objects should have ClassNotFoundExceptions associated
26.3037 + * with them, taking into account cycles and discontinuities (e.g., skipped
26.3038 + * fields) in the object graph.
26.3039 + *
26.3040 + * <p>General use of the table is as follows: during deserialization, a
26.3041 + * given object is first assigned a handle by calling the assign method.
26.3042 + * This method leaves the assigned handle in an "open" state, wherein
26.3043 + * dependencies on the exception status of other handles can be registered
26.3044 + * by calling the markDependency method, or an exception can be directly
26.3045 + * associated with the handle by calling markException. When a handle is
26.3046 + * tagged with an exception, the HandleTable assumes responsibility for
26.3047 + * propagating the exception to any other objects which depend
26.3048 + * (transitively) on the exception-tagged object.
26.3049 + *
26.3050 + * <p>Once all exception information/dependencies for the handle have been
26.3051 + * registered, the handle should be "closed" by calling the finish method
26.3052 + * on it. The act of finishing a handle allows the exception propagation
26.3053 + * algorithm to aggressively prune dependency links, lessening the
26.3054 + * performance/memory impact of exception tracking.
26.3055 + *
26.3056 + * <p>Note that the exception propagation algorithm used depends on handles
26.3057 + * being assigned/finished in LIFO order; however, for simplicity as well
26.3058 + * as memory conservation, it does not enforce this constraint.
26.3059 + */
26.3060 + // REMIND: add full description of exception propagation algorithm?
26.3061 + private static class HandleTable {
26.3062 +
26.3063 + /* status codes indicating whether object has associated exception */
26.3064 + private static final byte STATUS_OK = 1;
26.3065 + private static final byte STATUS_UNKNOWN = 2;
26.3066 + private static final byte STATUS_EXCEPTION = 3;
26.3067 +
26.3068 + /** array mapping handle -> object status */
26.3069 + byte[] status;
26.3070 + /** array mapping handle -> object/exception (depending on status) */
26.3071 + Object[] entries;
26.3072 + /** array mapping handle -> list of dependent handles (if any) */
26.3073 + HandleList[] deps;
26.3074 + /** lowest unresolved dependency */
26.3075 + int lowDep = -1;
26.3076 + /** number of handles in table */
26.3077 + int size = 0;
26.3078 +
26.3079 + /**
26.3080 + * Creates handle table with the given initial capacity.
26.3081 + */
26.3082 + HandleTable(int initialCapacity) {
26.3083 + status = new byte[initialCapacity];
26.3084 + entries = new Object[initialCapacity];
26.3085 + deps = new HandleList[initialCapacity];
26.3086 + }
26.3087 +
26.3088 + /**
26.3089 + * Assigns next available handle to given object, and returns assigned
26.3090 + * handle. Once object has been completely deserialized (and all
26.3091 + * dependencies on other objects identified), the handle should be
26.3092 + * "closed" by passing it to finish().
26.3093 + */
26.3094 + int assign(Object obj) {
26.3095 + if (size >= entries.length) {
26.3096 + grow();
26.3097 + }
26.3098 + status[size] = STATUS_UNKNOWN;
26.3099 + entries[size] = obj;
26.3100 + return size++;
26.3101 + }
26.3102 +
26.3103 + /**
26.3104 + * Registers a dependency (in exception status) of one handle on
26.3105 + * another. The dependent handle must be "open" (i.e., assigned, but
26.3106 + * not finished yet). No action is taken if either dependent or target
26.3107 + * handle is NULL_HANDLE.
26.3108 + */
26.3109 + void markDependency(int dependent, int target) {
26.3110 + if (dependent == NULL_HANDLE || target == NULL_HANDLE) {
26.3111 + return;
26.3112 + }
26.3113 + switch (status[dependent]) {
26.3114 +
26.3115 + case STATUS_UNKNOWN:
26.3116 + switch (status[target]) {
26.3117 + case STATUS_OK:
26.3118 + // ignore dependencies on objs with no exception
26.3119 + break;
26.3120 +
26.3121 + case STATUS_EXCEPTION:
26.3122 + // eagerly propagate exception
26.3123 + markException(dependent,
26.3124 + (ClassNotFoundException) entries[target]);
26.3125 + break;
26.3126 +
26.3127 + case STATUS_UNKNOWN:
26.3128 + // add to dependency list of target
26.3129 + if (deps[target] == null) {
26.3130 + deps[target] = new HandleList();
26.3131 + }
26.3132 + deps[target].add(dependent);
26.3133 +
26.3134 + // remember lowest unresolved target seen
26.3135 + if (lowDep < 0 || lowDep > target) {
26.3136 + lowDep = target;
26.3137 + }
26.3138 + break;
26.3139 +
26.3140 + default:
26.3141 + throw new InternalError();
26.3142 + }
26.3143 + break;
26.3144 +
26.3145 + case STATUS_EXCEPTION:
26.3146 + break;
26.3147 +
26.3148 + default:
26.3149 + throw new InternalError();
26.3150 + }
26.3151 + }
26.3152 +
26.3153 + /**
26.3154 + * Associates a ClassNotFoundException (if one not already associated)
26.3155 + * with the currently active handle and propagates it to other
26.3156 + * referencing objects as appropriate. The specified handle must be
26.3157 + * "open" (i.e., assigned, but not finished yet).
26.3158 + */
26.3159 + void markException(int handle, ClassNotFoundException ex) {
26.3160 + switch (status[handle]) {
26.3161 + case STATUS_UNKNOWN:
26.3162 + status[handle] = STATUS_EXCEPTION;
26.3163 + entries[handle] = ex;
26.3164 +
26.3165 + // propagate exception to dependents
26.3166 + HandleList dlist = deps[handle];
26.3167 + if (dlist != null) {
26.3168 + int ndeps = dlist.size();
26.3169 + for (int i = 0; i < ndeps; i++) {
26.3170 + markException(dlist.get(i), ex);
26.3171 + }
26.3172 + deps[handle] = null;
26.3173 + }
26.3174 + break;
26.3175 +
26.3176 + case STATUS_EXCEPTION:
26.3177 + break;
26.3178 +
26.3179 + default:
26.3180 + throw new InternalError();
26.3181 + }
26.3182 + }
26.3183 +
26.3184 + /**
26.3185 + * Marks given handle as finished, meaning that no new dependencies
26.3186 + * will be marked for handle. Calls to the assign and finish methods
26.3187 + * must occur in LIFO order.
26.3188 + */
26.3189 + void finish(int handle) {
26.3190 + int end;
26.3191 + if (lowDep < 0) {
26.3192 + // no pending unknowns, only resolve current handle
26.3193 + end = handle + 1;
26.3194 + } else if (lowDep >= handle) {
26.3195 + // pending unknowns now clearable, resolve all upward handles
26.3196 + end = size;
26.3197 + lowDep = -1;
26.3198 + } else {
26.3199 + // unresolved backrefs present, can't resolve anything yet
26.3200 + return;
26.3201 + }
26.3202 +
26.3203 + // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles
26.3204 + for (int i = handle; i < end; i++) {
26.3205 + switch (status[i]) {
26.3206 + case STATUS_UNKNOWN:
26.3207 + status[i] = STATUS_OK;
26.3208 + deps[i] = null;
26.3209 + break;
26.3210 +
26.3211 + case STATUS_OK:
26.3212 + case STATUS_EXCEPTION:
26.3213 + break;
26.3214 +
26.3215 + default:
26.3216 + throw new InternalError();
26.3217 + }
26.3218 + }
26.3219 + }
26.3220 +
26.3221 + /**
26.3222 + * Assigns a new object to the given handle. The object previously
26.3223 + * associated with the handle is forgotten. This method has no effect
26.3224 + * if the given handle already has an exception associated with it.
26.3225 + * This method may be called at any time after the handle is assigned.
26.3226 + */
26.3227 + void setObject(int handle, Object obj) {
26.3228 + switch (status[handle]) {
26.3229 + case STATUS_UNKNOWN:
26.3230 + case STATUS_OK:
26.3231 + entries[handle] = obj;
26.3232 + break;
26.3233 +
26.3234 + case STATUS_EXCEPTION:
26.3235 + break;
26.3236 +
26.3237 + default:
26.3238 + throw new InternalError();
26.3239 + }
26.3240 + }
26.3241 +
26.3242 + /**
26.3243 + * Looks up and returns object associated with the given handle.
26.3244 + * Returns null if the given handle is NULL_HANDLE, or if it has an
26.3245 + * associated ClassNotFoundException.
26.3246 + */
26.3247 + Object lookupObject(int handle) {
26.3248 + return (handle != NULL_HANDLE &&
26.3249 + status[handle] != STATUS_EXCEPTION) ?
26.3250 + entries[handle] : null;
26.3251 + }
26.3252 +
26.3253 + /**
26.3254 + * Looks up and returns ClassNotFoundException associated with the
26.3255 + * given handle. Returns null if the given handle is NULL_HANDLE, or
26.3256 + * if there is no ClassNotFoundException associated with the handle.
26.3257 + */
26.3258 + ClassNotFoundException lookupException(int handle) {
26.3259 + return (handle != NULL_HANDLE &&
26.3260 + status[handle] == STATUS_EXCEPTION) ?
26.3261 + (ClassNotFoundException) entries[handle] : null;
26.3262 + }
26.3263 +
26.3264 + /**
26.3265 + * Resets table to its initial state.
26.3266 + */
26.3267 + void clear() {
26.3268 + Arrays.fill(status, 0, size, (byte) 0);
26.3269 + Arrays.fill(entries, 0, size, null);
26.3270 + Arrays.fill(deps, 0, size, null);
26.3271 + lowDep = -1;
26.3272 + size = 0;
26.3273 + }
26.3274 +
26.3275 + /**
26.3276 + * Returns number of handles registered in table.
26.3277 + */
26.3278 + int size() {
26.3279 + return size;
26.3280 + }
26.3281 +
26.3282 + /**
26.3283 + * Expands capacity of internal arrays.
26.3284 + */
26.3285 + private void grow() {
26.3286 + int newCapacity = (entries.length << 1) + 1;
26.3287 +
26.3288 + byte[] newStatus = new byte[newCapacity];
26.3289 + Object[] newEntries = new Object[newCapacity];
26.3290 + HandleList[] newDeps = new HandleList[newCapacity];
26.3291 +
26.3292 + System.arraycopy(status, 0, newStatus, 0, size);
26.3293 + System.arraycopy(entries, 0, newEntries, 0, size);
26.3294 + System.arraycopy(deps, 0, newDeps, 0, size);
26.3295 +
26.3296 + status = newStatus;
26.3297 + entries = newEntries;
26.3298 + deps = newDeps;
26.3299 + }
26.3300 +
26.3301 + /**
26.3302 + * Simple growable list of (integer) handles.
26.3303 + */
26.3304 + private static class HandleList {
26.3305 + private int[] list = new int[4];
26.3306 + private int size = 0;
26.3307 +
26.3308 + public HandleList() {
26.3309 + }
26.3310 +
26.3311 + public void add(int handle) {
26.3312 + if (size >= list.length) {
26.3313 + int[] newList = new int[list.length << 1];
26.3314 + System.arraycopy(list, 0, newList, 0, list.length);
26.3315 + list = newList;
26.3316 + }
26.3317 + list[size++] = handle;
26.3318 + }
26.3319 +
26.3320 + public int get(int index) {
26.3321 + if (index >= size) {
26.3322 + throw new ArrayIndexOutOfBoundsException();
26.3323 + }
26.3324 + return list[index];
26.3325 + }
26.3326 +
26.3327 + public int size() {
26.3328 + return size;
26.3329 + }
26.3330 + }
26.3331 + }
26.3332 +
26.3333 + /**
26.3334 + * Method for cloning arrays in case of using unsharing reading
26.3335 + */
26.3336 + private static Object cloneArray(Object array) {
26.3337 + if (array instanceof Object[]) {
26.3338 + return ((Object[]) array).clone();
26.3339 + } else if (array instanceof boolean[]) {
26.3340 + return ((boolean[]) array).clone();
26.3341 + } else if (array instanceof byte[]) {
26.3342 + return ((byte[]) array).clone();
26.3343 + } else if (array instanceof char[]) {
26.3344 + return ((char[]) array).clone();
26.3345 + } else if (array instanceof double[]) {
26.3346 + return ((double[]) array).clone();
26.3347 + } else if (array instanceof float[]) {
26.3348 + return ((float[]) array).clone();
26.3349 + } else if (array instanceof int[]) {
26.3350 + return ((int[]) array).clone();
26.3351 + } else if (array instanceof long[]) {
26.3352 + return ((long[]) array).clone();
26.3353 + } else if (array instanceof short[]) {
26.3354 + return ((short[]) array).clone();
26.3355 + } else {
26.3356 + throw new AssertionError();
26.3357 + }
26.3358 + }
26.3359 +
26.3360 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputValidation.java Tue Feb 05 17:04:22 2013 +0100
27.3 @@ -0,0 +1,45 @@
27.4 +/*
27.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27.7 + *
27.8 + * This code is free software; you can redistribute it and/or modify it
27.9 + * under the terms of the GNU General Public License version 2 only, as
27.10 + * published by the Free Software Foundation. Oracle designates this
27.11 + * particular file as subject to the "Classpath" exception as provided
27.12 + * by Oracle in the LICENSE file that accompanied this code.
27.13 + *
27.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
27.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27.17 + * version 2 for more details (a copy is included in the LICENSE file that
27.18 + * accompanied this code).
27.19 + *
27.20 + * You should have received a copy of the GNU General Public License version
27.21 + * 2 along with this work; if not, write to the Free Software Foundation,
27.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27.23 + *
27.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
27.25 + * or visit www.oracle.com if you need additional information or have any
27.26 + * questions.
27.27 + */
27.28 +
27.29 +package java.io;
27.30 +
27.31 +/**
27.32 + * Callback interface to allow validation of objects within a graph.
27.33 + * Allows an object to be called when a complete graph of objects has
27.34 + * been deserialized.
27.35 + *
27.36 + * @author unascribed
27.37 + * @see ObjectInputStream
27.38 + * @see ObjectInputStream#registerValidation(java.io.ObjectInputValidation, int)
27.39 + * @since JDK1.1
27.40 + */
27.41 +public interface ObjectInputValidation {
27.42 + /**
27.43 + * Validates the object.
27.44 + *
27.45 + * @exception InvalidObjectException If the object cannot validate itself.
27.46 + */
27.47 + public void validateObject() throws InvalidObjectException;
27.48 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutput.java Tue Feb 05 17:04:22 2013 +0100
28.3 @@ -0,0 +1,90 @@
28.4 +/*
28.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28.7 + *
28.8 + * This code is free software; you can redistribute it and/or modify it
28.9 + * under the terms of the GNU General Public License version 2 only, as
28.10 + * published by the Free Software Foundation. Oracle designates this
28.11 + * particular file as subject to the "Classpath" exception as provided
28.12 + * by Oracle in the LICENSE file that accompanied this code.
28.13 + *
28.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
28.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28.17 + * version 2 for more details (a copy is included in the LICENSE file that
28.18 + * accompanied this code).
28.19 + *
28.20 + * You should have received a copy of the GNU General Public License version
28.21 + * 2 along with this work; if not, write to the Free Software Foundation,
28.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28.23 + *
28.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28.25 + * or visit www.oracle.com if you need additional information or have any
28.26 + * questions.
28.27 + */
28.28 +
28.29 +package java.io;
28.30 +
28.31 +/**
28.32 + * ObjectOutput extends the DataOutput interface to include writing of objects.
28.33 + * DataOutput includes methods for output of primitive types, ObjectOutput
28.34 + * extends that interface to include objects, arrays, and Strings.
28.35 + *
28.36 + * @author unascribed
28.37 + * @see java.io.InputStream
28.38 + * @see java.io.ObjectOutputStream
28.39 + * @see java.io.ObjectInputStream
28.40 + * @since JDK1.1
28.41 + */
28.42 +public interface ObjectOutput extends DataOutput, AutoCloseable {
28.43 + /**
28.44 + * Write an object to the underlying storage or stream. The
28.45 + * class that implements this interface defines how the object is
28.46 + * written.
28.47 + *
28.48 + * @param obj the object to be written
28.49 + * @exception IOException Any of the usual Input/Output related exceptions.
28.50 + */
28.51 + public void writeObject(Object obj)
28.52 + throws IOException;
28.53 +
28.54 + /**
28.55 + * Writes a byte. This method will block until the byte is actually
28.56 + * written.
28.57 + * @param b the byte
28.58 + * @exception IOException If an I/O error has occurred.
28.59 + */
28.60 + public void write(int b) throws IOException;
28.61 +
28.62 + /**
28.63 + * Writes an array of bytes. This method will block until the bytes
28.64 + * are actually written.
28.65 + * @param b the data to be written
28.66 + * @exception IOException If an I/O error has occurred.
28.67 + */
28.68 + public void write(byte b[]) throws IOException;
28.69 +
28.70 + /**
28.71 + * Writes a sub array of bytes.
28.72 + * @param b the data to be written
28.73 + * @param off the start offset in the data
28.74 + * @param len the number of bytes that are written
28.75 + * @exception IOException If an I/O error has occurred.
28.76 + */
28.77 + public void write(byte b[], int off, int len) throws IOException;
28.78 +
28.79 + /**
28.80 + * Flushes the stream. This will write any buffered
28.81 + * output bytes.
28.82 + * @exception IOException If an I/O error has occurred.
28.83 + */
28.84 + public void flush() throws IOException;
28.85 +
28.86 + /**
28.87 + * Closes the stream. This method must be called
28.88 + * to release any resources associated with the
28.89 + * stream.
28.90 + * @exception IOException If an I/O error has occurred.
28.91 + */
28.92 + public void close() throws IOException;
28.93 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutputStream.java Tue Feb 05 17:04:22 2013 +0100
29.3 @@ -0,0 +1,2369 @@
29.4 +/*
29.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29.7 + *
29.8 + * This code is free software; you can redistribute it and/or modify it
29.9 + * under the terms of the GNU General Public License version 2 only, as
29.10 + * published by the Free Software Foundation. Oracle designates this
29.11 + * particular file as subject to the "Classpath" exception as provided
29.12 + * by Oracle in the LICENSE file that accompanied this code.
29.13 + *
29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29.17 + * version 2 for more details (a copy is included in the LICENSE file that
29.18 + * accompanied this code).
29.19 + *
29.20 + * You should have received a copy of the GNU General Public License version
29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29.23 + *
29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
29.25 + * or visit www.oracle.com if you need additional information or have any
29.26 + * questions.
29.27 + */
29.28 +
29.29 +package java.io;
29.30 +
29.31 +import java.util.ArrayList;
29.32 +import java.util.Arrays;
29.33 +import java.util.List;
29.34 +import org.apidesign.bck2brwsr.emul.lang.System;
29.35 +
29.36 +/**
29.37 + * An ObjectOutputStream writes primitive data types and graphs of Java objects
29.38 + * to an OutputStream. The objects can be read (reconstituted) using an
29.39 + * ObjectInputStream. Persistent storage of objects can be accomplished by
29.40 + * using a file for the stream. If the stream is a network socket stream, the
29.41 + * objects can be reconstituted on another host or in another process.
29.42 + *
29.43 + * <p>Only objects that support the java.io.Serializable interface can be
29.44 + * written to streams. The class of each serializable object is encoded
29.45 + * including the class name and signature of the class, the values of the
29.46 + * object's fields and arrays, and the closure of any other objects referenced
29.47 + * from the initial objects.
29.48 + *
29.49 + * <p>The method writeObject is used to write an object to the stream. Any
29.50 + * object, including Strings and arrays, is written with writeObject. Multiple
29.51 + * objects or primitives can be written to the stream. The objects must be
29.52 + * read back from the corresponding ObjectInputstream with the same types and
29.53 + * in the same order as they were written.
29.54 + *
29.55 + * <p>Primitive data types can also be written to the stream using the
29.56 + * appropriate methods from DataOutput. Strings can also be written using the
29.57 + * writeUTF method.
29.58 + *
29.59 + * <p>The default serialization mechanism for an object writes the class of the
29.60 + * object, the class signature, and the values of all non-transient and
29.61 + * non-static fields. References to other objects (except in transient or
29.62 + * static fields) cause those objects to be written also. Multiple references
29.63 + * to a single object are encoded using a reference sharing mechanism so that
29.64 + * graphs of objects can be restored to the same shape as when the original was
29.65 + * written.
29.66 + *
29.67 + * <p>For example to write an object that can be read by the example in
29.68 + * ObjectInputStream:
29.69 + * <br>
29.70 + * <pre>
29.71 + * FileOutputStream fos = new FileOutputStream("t.tmp");
29.72 + * ObjectOutputStream oos = new ObjectOutputStream(fos);
29.73 + *
29.74 + * oos.writeInt(12345);
29.75 + * oos.writeObject("Today");
29.76 + * oos.writeObject(new Date());
29.77 + *
29.78 + * oos.close();
29.79 + * </pre>
29.80 + *
29.81 + * <p>Classes that require special handling during the serialization and
29.82 + * deserialization process must implement special methods with these exact
29.83 + * signatures:
29.84 + * <br>
29.85 + * <pre>
29.86 + * private void readObject(java.io.ObjectInputStream stream)
29.87 + * throws IOException, ClassNotFoundException;
29.88 + * private void writeObject(java.io.ObjectOutputStream stream)
29.89 + * throws IOException
29.90 + * private void readObjectNoData()
29.91 + * throws ObjectStreamException;
29.92 + * </pre>
29.93 + *
29.94 + * <p>The writeObject method is responsible for writing the state of the object
29.95 + * for its particular class so that the corresponding readObject method can
29.96 + * restore it. The method does not need to concern itself with the state
29.97 + * belonging to the object's superclasses or subclasses. State is saved by
29.98 + * writing the individual fields to the ObjectOutputStream using the
29.99 + * writeObject method or by using the methods for primitive data types
29.100 + * supported by DataOutput.
29.101 + *
29.102 + * <p>Serialization does not write out the fields of any object that does not
29.103 + * implement the java.io.Serializable interface. Subclasses of Objects that
29.104 + * are not serializable can be serializable. In this case the non-serializable
29.105 + * class must have a no-arg constructor to allow its fields to be initialized.
29.106 + * In this case it is the responsibility of the subclass to save and restore
29.107 + * the state of the non-serializable class. It is frequently the case that the
29.108 + * fields of that class are accessible (public, package, or protected) or that
29.109 + * there are get and set methods that can be used to restore the state.
29.110 + *
29.111 + * <p>Serialization of an object can be prevented by implementing writeObject
29.112 + * and readObject methods that throw the NotSerializableException. The
29.113 + * exception will be caught by the ObjectOutputStream and abort the
29.114 + * serialization process.
29.115 + *
29.116 + * <p>Implementing the Externalizable interface allows the object to assume
29.117 + * complete control over the contents and format of the object's serialized
29.118 + * form. The methods of the Externalizable interface, writeExternal and
29.119 + * readExternal, are called to save and restore the objects state. When
29.120 + * implemented by a class they can write and read their own state using all of
29.121 + * the methods of ObjectOutput and ObjectInput. It is the responsibility of
29.122 + * the objects to handle any versioning that occurs.
29.123 + *
29.124 + * <p>Enum constants are serialized differently than ordinary serializable or
29.125 + * externalizable objects. The serialized form of an enum constant consists
29.126 + * solely of its name; field values of the constant are not transmitted. To
29.127 + * serialize an enum constant, ObjectOutputStream writes the string returned by
29.128 + * the constant's name method. Like other serializable or externalizable
29.129 + * objects, enum constants can function as the targets of back references
29.130 + * appearing subsequently in the serialization stream. The process by which
29.131 + * enum constants are serialized cannot be customized; any class-specific
29.132 + * writeObject and writeReplace methods defined by enum types are ignored
29.133 + * during serialization. Similarly, any serialPersistentFields or
29.134 + * serialVersionUID field declarations are also ignored--all enum types have a
29.135 + * fixed serialVersionUID of 0L.
29.136 + *
29.137 + * <p>Primitive data, excluding serializable fields and externalizable data, is
29.138 + * written to the ObjectOutputStream in block-data records. A block data record
29.139 + * is composed of a header and data. The block data header consists of a marker
29.140 + * and the number of bytes to follow the header. Consecutive primitive data
29.141 + * writes are merged into one block-data record. The blocking factor used for
29.142 + * a block-data record will be 1024 bytes. Each block-data record will be
29.143 + * filled up to 1024 bytes, or be written whenever there is a termination of
29.144 + * block-data mode. Calls to the ObjectOutputStream methods writeObject,
29.145 + * defaultWriteObject and writeFields initially terminate any existing
29.146 + * block-data record.
29.147 + *
29.148 + * @author Mike Warres
29.149 + * @author Roger Riggs
29.150 + * @see java.io.DataOutput
29.151 + * @see java.io.ObjectInputStream
29.152 + * @see java.io.Serializable
29.153 + * @see java.io.Externalizable
29.154 + * @see <a href="../../../platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
29.155 + * @since JDK1.1
29.156 + */
29.157 +public class ObjectOutputStream
29.158 + extends OutputStream implements ObjectOutput, ObjectStreamConstants
29.159 +{
29.160 + /** filter stream for handling block data conversion */
29.161 + private final BlockDataOutputStream bout;
29.162 + /** obj -> wire handle map */
29.163 + private final HandleTable handles;
29.164 + /** obj -> replacement obj map */
29.165 + private final ReplaceTable subs;
29.166 + /** stream protocol version */
29.167 + private int protocol = PROTOCOL_VERSION_2;
29.168 + /** recursion depth */
29.169 + private int depth;
29.170 +
29.171 + /** buffer for writing primitive field values */
29.172 + private byte[] primVals;
29.173 +
29.174 + /** if true, invoke writeObjectOverride() instead of writeObject() */
29.175 + private final boolean enableOverride;
29.176 + /** if true, invoke replaceObject() */
29.177 + private boolean enableReplace;
29.178 +
29.179 + // values below valid only during upcalls to writeObject()/writeExternal()
29.180 + /**
29.181 + * Context during upcalls to class-defined writeObject methods; holds
29.182 + * object currently being serialized and descriptor for current class.
29.183 + * Null when not during writeObject upcall.
29.184 + */
29.185 + private Object curContext;
29.186 + /** current PutField object */
29.187 + private PutFieldImpl curPut;
29.188 +
29.189 + /** custom storage for debug trace info */
29.190 + private final DebugTraceInfoStack debugInfoStack;
29.191 +
29.192 + /**
29.193 + * value of "sun.io.serialization.extendedDebugInfo" property,
29.194 + * as true or false for extended information about exception's place
29.195 + */
29.196 + private static final boolean extendedDebugInfo = false;
29.197 +
29.198 + /**
29.199 + * Creates an ObjectOutputStream that writes to the specified OutputStream.
29.200 + * This constructor writes the serialization stream header to the
29.201 + * underlying stream; callers may wish to flush the stream immediately to
29.202 + * ensure that constructors for receiving ObjectInputStreams will not block
29.203 + * when reading the header.
29.204 + *
29.205 + * <p>If a security manager is installed, this constructor will check for
29.206 + * the "enableSubclassImplementation" SerializablePermission when invoked
29.207 + * directly or indirectly by the constructor of a subclass which overrides
29.208 + * the ObjectOutputStream.putFields or ObjectOutputStream.writeUnshared
29.209 + * methods.
29.210 + *
29.211 + * @param out output stream to write to
29.212 + * @throws IOException if an I/O error occurs while writing stream header
29.213 + * @throws SecurityException if untrusted subclass illegally overrides
29.214 + * security-sensitive methods
29.215 + * @throws NullPointerException if <code>out</code> is <code>null</code>
29.216 + * @since 1.4
29.217 + * @see ObjectOutputStream#ObjectOutputStream()
29.218 + * @see ObjectOutputStream#putFields()
29.219 + * @see ObjectInputStream#ObjectInputStream(InputStream)
29.220 + */
29.221 + public ObjectOutputStream(OutputStream out) throws IOException {
29.222 + verifySubclass();
29.223 + bout = new BlockDataOutputStream(out);
29.224 + handles = new HandleTable(10, (float) 3.00);
29.225 + subs = new ReplaceTable(10, (float) 3.00);
29.226 + enableOverride = false;
29.227 + writeStreamHeader();
29.228 + bout.setBlockDataMode(true);
29.229 + if (extendedDebugInfo) {
29.230 + debugInfoStack = new DebugTraceInfoStack();
29.231 + } else {
29.232 + debugInfoStack = null;
29.233 + }
29.234 + }
29.235 +
29.236 + /**
29.237 + * Provide a way for subclasses that are completely reimplementing
29.238 + * ObjectOutputStream to not have to allocate private data just used by
29.239 + * this implementation of ObjectOutputStream.
29.240 + *
29.241 + * <p>If there is a security manager installed, this method first calls the
29.242 + * security manager's <code>checkPermission</code> method with a
29.243 + * <code>SerializablePermission("enableSubclassImplementation")</code>
29.244 + * permission to ensure it's ok to enable subclassing.
29.245 + *
29.246 + * @throws SecurityException if a security manager exists and its
29.247 + * <code>checkPermission</code> method denies enabling
29.248 + * subclassing.
29.249 + * @see SecurityManager#checkPermission
29.250 + * @see java.io.SerializablePermission
29.251 + */
29.252 + protected ObjectOutputStream() throws IOException, SecurityException {
29.253 + throw new SecurityException();
29.254 + }
29.255 +
29.256 + /**
29.257 + * Specify stream protocol version to use when writing the stream.
29.258 + *
29.259 + * <p>This routine provides a hook to enable the current version of
29.260 + * Serialization to write in a format that is backwards compatible to a
29.261 + * previous version of the stream format.
29.262 + *
29.263 + * <p>Every effort will be made to avoid introducing additional
29.264 + * backwards incompatibilities; however, sometimes there is no
29.265 + * other alternative.
29.266 + *
29.267 + * @param version use ProtocolVersion from java.io.ObjectStreamConstants.
29.268 + * @throws IllegalStateException if called after any objects
29.269 + * have been serialized.
29.270 + * @throws IllegalArgumentException if invalid version is passed in.
29.271 + * @throws IOException if I/O errors occur
29.272 + * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
29.273 + * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_2
29.274 + * @since 1.2
29.275 + */
29.276 + public void useProtocolVersion(int version) throws IOException {
29.277 + if (handles.size() != 0) {
29.278 + // REMIND: implement better check for pristine stream?
29.279 + throw new IllegalStateException("stream non-empty");
29.280 + }
29.281 + switch (version) {
29.282 + case PROTOCOL_VERSION_1:
29.283 + case PROTOCOL_VERSION_2:
29.284 + protocol = version;
29.285 + break;
29.286 +
29.287 + default:
29.288 + throw new IllegalArgumentException(
29.289 + "unknown version: " + version);
29.290 + }
29.291 + }
29.292 +
29.293 + /**
29.294 + * Write the specified object to the ObjectOutputStream. The class of the
29.295 + * object, the signature of the class, and the values of the non-transient
29.296 + * and non-static fields of the class and all of its supertypes are
29.297 + * written. Default serialization for a class can be overridden using the
29.298 + * writeObject and the readObject methods. Objects referenced by this
29.299 + * object are written transitively so that a complete equivalent graph of
29.300 + * objects can be reconstructed by an ObjectInputStream.
29.301 + *
29.302 + * <p>Exceptions are thrown for problems with the OutputStream and for
29.303 + * classes that should not be serialized. All exceptions are fatal to the
29.304 + * OutputStream, which is left in an indeterminate state, and it is up to
29.305 + * the caller to ignore or recover the stream state.
29.306 + *
29.307 + * @throws InvalidClassException Something is wrong with a class used by
29.308 + * serialization.
29.309 + * @throws NotSerializableException Some object to be serialized does not
29.310 + * implement the java.io.Serializable interface.
29.311 + * @throws IOException Any exception thrown by the underlying
29.312 + * OutputStream.
29.313 + */
29.314 + public final void writeObject(Object obj) throws IOException {
29.315 + if (enableOverride) {
29.316 + writeObjectOverride(obj);
29.317 + return;
29.318 + }
29.319 + try {
29.320 + writeObject0(obj, false);
29.321 + } catch (IOException ex) {
29.322 + if (depth == 0) {
29.323 + writeFatalException(ex);
29.324 + }
29.325 + throw ex;
29.326 + }
29.327 + }
29.328 +
29.329 + /**
29.330 + * Method used by subclasses to override the default writeObject method.
29.331 + * This method is called by trusted subclasses of ObjectInputStream that
29.332 + * constructed ObjectInputStream using the protected no-arg constructor.
29.333 + * The subclass is expected to provide an override method with the modifier
29.334 + * "final".
29.335 + *
29.336 + * @param obj object to be written to the underlying stream
29.337 + * @throws IOException if there are I/O errors while writing to the
29.338 + * underlying stream
29.339 + * @see #ObjectOutputStream()
29.340 + * @see #writeObject(Object)
29.341 + * @since 1.2
29.342 + */
29.343 + protected void writeObjectOverride(Object obj) throws IOException {
29.344 + }
29.345 +
29.346 + /**
29.347 + * Writes an "unshared" object to the ObjectOutputStream. This method is
29.348 + * identical to writeObject, except that it always writes the given object
29.349 + * as a new, unique object in the stream (as opposed to a back-reference
29.350 + * pointing to a previously serialized instance). Specifically:
29.351 + * <ul>
29.352 + * <li>An object written via writeUnshared is always serialized in the
29.353 + * same manner as a newly appearing object (an object that has not
29.354 + * been written to the stream yet), regardless of whether or not the
29.355 + * object has been written previously.
29.356 + *
29.357 + * <li>If writeObject is used to write an object that has been previously
29.358 + * written with writeUnshared, the previous writeUnshared operation
29.359 + * is treated as if it were a write of a separate object. In other
29.360 + * words, ObjectOutputStream will never generate back-references to
29.361 + * object data written by calls to writeUnshared.
29.362 + * </ul>
29.363 + * While writing an object via writeUnshared does not in itself guarantee a
29.364 + * unique reference to the object when it is deserialized, it allows a
29.365 + * single object to be defined multiple times in a stream, so that multiple
29.366 + * calls to readUnshared by the receiver will not conflict. Note that the
29.367 + * rules described above only apply to the base-level object written with
29.368 + * writeUnshared, and not to any transitively referenced sub-objects in the
29.369 + * object graph to be serialized.
29.370 + *
29.371 + * <p>ObjectOutputStream subclasses which override this method can only be
29.372 + * constructed in security contexts possessing the
29.373 + * "enableSubclassImplementation" SerializablePermission; any attempt to
29.374 + * instantiate such a subclass without this permission will cause a
29.375 + * SecurityException to be thrown.
29.376 + *
29.377 + * @param obj object to write to stream
29.378 + * @throws NotSerializableException if an object in the graph to be
29.379 + * serialized does not implement the Serializable interface
29.380 + * @throws InvalidClassException if a problem exists with the class of an
29.381 + * object to be serialized
29.382 + * @throws IOException if an I/O error occurs during serialization
29.383 + * @since 1.4
29.384 + */
29.385 + public void writeUnshared(Object obj) throws IOException {
29.386 + try {
29.387 + writeObject0(obj, true);
29.388 + } catch (IOException ex) {
29.389 + if (depth == 0) {
29.390 + writeFatalException(ex);
29.391 + }
29.392 + throw ex;
29.393 + }
29.394 + }
29.395 +
29.396 + /**
29.397 + * Write the non-static and non-transient fields of the current class to
29.398 + * this stream. This may only be called from the writeObject method of the
29.399 + * class being serialized. It will throw the NotActiveException if it is
29.400 + * called otherwise.
29.401 + *
29.402 + * @throws IOException if I/O errors occur while writing to the underlying
29.403 + * <code>OutputStream</code>
29.404 + */
29.405 + public void defaultWriteObject() throws IOException {
29.406 + if ( curContext == null ) {
29.407 + throw new NotActiveException("not in call to writeObject");
29.408 + }
29.409 + Object curObj = null; // curContext.getObj();
29.410 + ObjectStreamClass curDesc = null; // curContext.getDesc();
29.411 + bout.setBlockDataMode(false);
29.412 + defaultWriteFields(curObj, curDesc);
29.413 + bout.setBlockDataMode(true);
29.414 + }
29.415 +
29.416 + /**
29.417 + * Retrieve the object used to buffer persistent fields to be written to
29.418 + * the stream. The fields will be written to the stream when writeFields
29.419 + * method is called.
29.420 + *
29.421 + * @return an instance of the class Putfield that holds the serializable
29.422 + * fields
29.423 + * @throws IOException if I/O errors occur
29.424 + * @since 1.2
29.425 + */
29.426 + public ObjectOutputStream.PutField putFields() throws IOException {
29.427 + if (curPut == null) {
29.428 + if (curContext == null) {
29.429 + throw new NotActiveException("not in call to writeObject");
29.430 + }
29.431 + Object curObj = null; // curContext.getObj();
29.432 + ObjectStreamClass curDesc = null; // curContext.getDesc();
29.433 + curPut = new PutFieldImpl(curDesc);
29.434 + }
29.435 + return curPut;
29.436 + }
29.437 +
29.438 + /**
29.439 + * Write the buffered fields to the stream.
29.440 + *
29.441 + * @throws IOException if I/O errors occur while writing to the underlying
29.442 + * stream
29.443 + * @throws NotActiveException Called when a classes writeObject method was
29.444 + * not called to write the state of the object.
29.445 + * @since 1.2
29.446 + */
29.447 + public void writeFields() throws IOException {
29.448 + if (curPut == null) {
29.449 + throw new NotActiveException("no current PutField object");
29.450 + }
29.451 + bout.setBlockDataMode(false);
29.452 + curPut.writeFields();
29.453 + bout.setBlockDataMode(true);
29.454 + }
29.455 +
29.456 + /**
29.457 + * Reset will disregard the state of any objects already written to the
29.458 + * stream. The state is reset to be the same as a new ObjectOutputStream.
29.459 + * The current point in the stream is marked as reset so the corresponding
29.460 + * ObjectInputStream will be reset at the same point. Objects previously
29.461 + * written to the stream will not be refered to as already being in the
29.462 + * stream. They will be written to the stream again.
29.463 + *
29.464 + * @throws IOException if reset() is invoked while serializing an object.
29.465 + */
29.466 + public void reset() throws IOException {
29.467 + if (depth != 0) {
29.468 + throw new IOException("stream active");
29.469 + }
29.470 + bout.setBlockDataMode(false);
29.471 + bout.writeByte(TC_RESET);
29.472 + clear();
29.473 + bout.setBlockDataMode(true);
29.474 + }
29.475 +
29.476 + /**
29.477 + * Subclasses may implement this method to allow class data to be stored in
29.478 + * the stream. By default this method does nothing. The corresponding
29.479 + * method in ObjectInputStream is resolveClass. This method is called
29.480 + * exactly once for each unique class in the stream. The class name and
29.481 + * signature will have already been written to the stream. This method may
29.482 + * make free use of the ObjectOutputStream to save any representation of
29.483 + * the class it deems suitable (for example, the bytes of the class file).
29.484 + * The resolveClass method in the corresponding subclass of
29.485 + * ObjectInputStream must read and use any data or objects written by
29.486 + * annotateClass.
29.487 + *
29.488 + * @param cl the class to annotate custom data for
29.489 + * @throws IOException Any exception thrown by the underlying
29.490 + * OutputStream.
29.491 + */
29.492 + protected void annotateClass(Class<?> cl) throws IOException {
29.493 + }
29.494 +
29.495 + /**
29.496 + * Subclasses may implement this method to store custom data in the stream
29.497 + * along with descriptors for dynamic proxy classes.
29.498 + *
29.499 + * <p>This method is called exactly once for each unique proxy class
29.500 + * descriptor in the stream. The default implementation of this method in
29.501 + * <code>ObjectOutputStream</code> does nothing.
29.502 + *
29.503 + * <p>The corresponding method in <code>ObjectInputStream</code> is
29.504 + * <code>resolveProxyClass</code>. For a given subclass of
29.505 + * <code>ObjectOutputStream</code> that overrides this method, the
29.506 + * <code>resolveProxyClass</code> method in the corresponding subclass of
29.507 + * <code>ObjectInputStream</code> must read any data or objects written by
29.508 + * <code>annotateProxyClass</code>.
29.509 + *
29.510 + * @param cl the proxy class to annotate custom data for
29.511 + * @throws IOException any exception thrown by the underlying
29.512 + * <code>OutputStream</code>
29.513 + * @see ObjectInputStream#resolveProxyClass(String[])
29.514 + * @since 1.3
29.515 + */
29.516 + protected void annotateProxyClass(Class<?> cl) throws IOException {
29.517 + }
29.518 +
29.519 + /**
29.520 + * This method will allow trusted subclasses of ObjectOutputStream to
29.521 + * substitute one object for another during serialization. Replacing
29.522 + * objects is disabled until enableReplaceObject is called. The
29.523 + * enableReplaceObject method checks that the stream requesting to do
29.524 + * replacement can be trusted. The first occurrence of each object written
29.525 + * into the serialization stream is passed to replaceObject. Subsequent
29.526 + * references to the object are replaced by the object returned by the
29.527 + * original call to replaceObject. To ensure that the private state of
29.528 + * objects is not unintentionally exposed, only trusted streams may use
29.529 + * replaceObject.
29.530 + *
29.531 + * <p>The ObjectOutputStream.writeObject method takes a parameter of type
29.532 + * Object (as opposed to type Serializable) to allow for cases where
29.533 + * non-serializable objects are replaced by serializable ones.
29.534 + *
29.535 + * <p>When a subclass is replacing objects it must insure that either a
29.536 + * complementary substitution must be made during deserialization or that
29.537 + * the substituted object is compatible with every field where the
29.538 + * reference will be stored. Objects whose type is not a subclass of the
29.539 + * type of the field or array element abort the serialization by raising an
29.540 + * exception and the object is not be stored.
29.541 + *
29.542 + * <p>This method is called only once when each object is first
29.543 + * encountered. All subsequent references to the object will be redirected
29.544 + * to the new object. This method should return the object to be
29.545 + * substituted or the original object.
29.546 + *
29.547 + * <p>Null can be returned as the object to be substituted, but may cause
29.548 + * NullReferenceException in classes that contain references to the
29.549 + * original object since they may be expecting an object instead of
29.550 + * null.
29.551 + *
29.552 + * @param obj the object to be replaced
29.553 + * @return the alternate object that replaced the specified one
29.554 + * @throws IOException Any exception thrown by the underlying
29.555 + * OutputStream.
29.556 + */
29.557 + protected Object replaceObject(Object obj) throws IOException {
29.558 + return obj;
29.559 + }
29.560 +
29.561 + /**
29.562 + * Enable the stream to do replacement of objects in the stream. When
29.563 + * enabled, the replaceObject method is called for every object being
29.564 + * serialized.
29.565 + *
29.566 + * <p>If <code>enable</code> is true, and there is a security manager
29.567 + * installed, this method first calls the security manager's
29.568 + * <code>checkPermission</code> method with a
29.569 + * <code>SerializablePermission("enableSubstitution")</code> permission to
29.570 + * ensure it's ok to enable the stream to do replacement of objects in the
29.571 + * stream.
29.572 + *
29.573 + * @param enable boolean parameter to enable replacement of objects
29.574 + * @return the previous setting before this method was invoked
29.575 + * @throws SecurityException if a security manager exists and its
29.576 + * <code>checkPermission</code> method denies enabling the stream
29.577 + * to do replacement of objects in the stream.
29.578 + * @see SecurityManager#checkPermission
29.579 + * @see java.io.SerializablePermission
29.580 + */
29.581 + protected boolean enableReplaceObject(boolean enable)
29.582 + throws SecurityException
29.583 + {
29.584 + throw new SecurityException();
29.585 + }
29.586 +
29.587 + /**
29.588 + * The writeStreamHeader method is provided so subclasses can append or
29.589 + * prepend their own header to the stream. It writes the magic number and
29.590 + * version to the stream.
29.591 + *
29.592 + * @throws IOException if I/O errors occur while writing to the underlying
29.593 + * stream
29.594 + */
29.595 + protected void writeStreamHeader() throws IOException {
29.596 + bout.writeShort(STREAM_MAGIC);
29.597 + bout.writeShort(STREAM_VERSION);
29.598 + }
29.599 +
29.600 + /**
29.601 + * Write the specified class descriptor to the ObjectOutputStream. Class
29.602 + * descriptors are used to identify the classes of objects written to the
29.603 + * stream. Subclasses of ObjectOutputStream may override this method to
29.604 + * customize the way in which class descriptors are written to the
29.605 + * serialization stream. The corresponding method in ObjectInputStream,
29.606 + * <code>readClassDescriptor</code>, should then be overridden to
29.607 + * reconstitute the class descriptor from its custom stream representation.
29.608 + * By default, this method writes class descriptors according to the format
29.609 + * defined in the Object Serialization specification.
29.610 + *
29.611 + * <p>Note that this method will only be called if the ObjectOutputStream
29.612 + * is not using the old serialization stream format (set by calling
29.613 + * ObjectOutputStream's <code>useProtocolVersion</code> method). If this
29.614 + * serialization stream is using the old format
29.615 + * (<code>PROTOCOL_VERSION_1</code>), the class descriptor will be written
29.616 + * internally in a manner that cannot be overridden or customized.
29.617 + *
29.618 + * @param desc class descriptor to write to the stream
29.619 + * @throws IOException If an I/O error has occurred.
29.620 + * @see java.io.ObjectInputStream#readClassDescriptor()
29.621 + * @see #useProtocolVersion(int)
29.622 + * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
29.623 + * @since 1.3
29.624 + */
29.625 + protected void writeClassDescriptor(ObjectStreamClass desc)
29.626 + throws IOException
29.627 + {
29.628 + desc.writeNonProxy(this);
29.629 + }
29.630 +
29.631 + /**
29.632 + * Writes a byte. This method will block until the byte is actually
29.633 + * written.
29.634 + *
29.635 + * @param val the byte to be written to the stream
29.636 + * @throws IOException If an I/O error has occurred.
29.637 + */
29.638 + public void write(int val) throws IOException {
29.639 + bout.write(val);
29.640 + }
29.641 +
29.642 + /**
29.643 + * Writes an array of bytes. This method will block until the bytes are
29.644 + * actually written.
29.645 + *
29.646 + * @param buf the data to be written
29.647 + * @throws IOException If an I/O error has occurred.
29.648 + */
29.649 + public void write(byte[] buf) throws IOException {
29.650 + bout.write(buf, 0, buf.length, false);
29.651 + }
29.652 +
29.653 + /**
29.654 + * Writes a sub array of bytes.
29.655 + *
29.656 + * @param buf the data to be written
29.657 + * @param off the start offset in the data
29.658 + * @param len the number of bytes that are written
29.659 + * @throws IOException If an I/O error has occurred.
29.660 + */
29.661 + public void write(byte[] buf, int off, int len) throws IOException {
29.662 + if (buf == null) {
29.663 + throw new NullPointerException();
29.664 + }
29.665 + int endoff = off + len;
29.666 + if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
29.667 + throw new IndexOutOfBoundsException();
29.668 + }
29.669 + bout.write(buf, off, len, false);
29.670 + }
29.671 +
29.672 + /**
29.673 + * Flushes the stream. This will write any buffered output bytes and flush
29.674 + * through to the underlying stream.
29.675 + *
29.676 + * @throws IOException If an I/O error has occurred.
29.677 + */
29.678 + public void flush() throws IOException {
29.679 + bout.flush();
29.680 + }
29.681 +
29.682 + /**
29.683 + * Drain any buffered data in ObjectOutputStream. Similar to flush but
29.684 + * does not propagate the flush to the underlying stream.
29.685 + *
29.686 + * @throws IOException if I/O errors occur while writing to the underlying
29.687 + * stream
29.688 + */
29.689 + protected void drain() throws IOException {
29.690 + bout.drain();
29.691 + }
29.692 +
29.693 + /**
29.694 + * Closes the stream. This method must be called to release any resources
29.695 + * associated with the stream.
29.696 + *
29.697 + * @throws IOException If an I/O error has occurred.
29.698 + */
29.699 + public void close() throws IOException {
29.700 + flush();
29.701 + clear();
29.702 + bout.close();
29.703 + }
29.704 +
29.705 + /**
29.706 + * Writes a boolean.
29.707 + *
29.708 + * @param val the boolean to be written
29.709 + * @throws IOException if I/O errors occur while writing to the underlying
29.710 + * stream
29.711 + */
29.712 + public void writeBoolean(boolean val) throws IOException {
29.713 + bout.writeBoolean(val);
29.714 + }
29.715 +
29.716 + /**
29.717 + * Writes an 8 bit byte.
29.718 + *
29.719 + * @param val the byte value to be written
29.720 + * @throws IOException if I/O errors occur while writing to the underlying
29.721 + * stream
29.722 + */
29.723 + public void writeByte(int val) throws IOException {
29.724 + bout.writeByte(val);
29.725 + }
29.726 +
29.727 + /**
29.728 + * Writes a 16 bit short.
29.729 + *
29.730 + * @param val the short value to be written
29.731 + * @throws IOException if I/O errors occur while writing to the underlying
29.732 + * stream
29.733 + */
29.734 + public void writeShort(int val) throws IOException {
29.735 + bout.writeShort(val);
29.736 + }
29.737 +
29.738 + /**
29.739 + * Writes a 16 bit char.
29.740 + *
29.741 + * @param val the char value to be written
29.742 + * @throws IOException if I/O errors occur while writing to the underlying
29.743 + * stream
29.744 + */
29.745 + public void writeChar(int val) throws IOException {
29.746 + bout.writeChar(val);
29.747 + }
29.748 +
29.749 + /**
29.750 + * Writes a 32 bit int.
29.751 + *
29.752 + * @param val the integer value to be written
29.753 + * @throws IOException if I/O errors occur while writing to the underlying
29.754 + * stream
29.755 + */
29.756 + public void writeInt(int val) throws IOException {
29.757 + bout.writeInt(val);
29.758 + }
29.759 +
29.760 + /**
29.761 + * Writes a 64 bit long.
29.762 + *
29.763 + * @param val the long value to be written
29.764 + * @throws IOException if I/O errors occur while writing to the underlying
29.765 + * stream
29.766 + */
29.767 + public void writeLong(long val) throws IOException {
29.768 + bout.writeLong(val);
29.769 + }
29.770 +
29.771 + /**
29.772 + * Writes a 32 bit float.
29.773 + *
29.774 + * @param val the float value to be written
29.775 + * @throws IOException if I/O errors occur while writing to the underlying
29.776 + * stream
29.777 + */
29.778 + public void writeFloat(float val) throws IOException {
29.779 + bout.writeFloat(val);
29.780 + }
29.781 +
29.782 + /**
29.783 + * Writes a 64 bit double.
29.784 + *
29.785 + * @param val the double value to be written
29.786 + * @throws IOException if I/O errors occur while writing to the underlying
29.787 + * stream
29.788 + */
29.789 + public void writeDouble(double val) throws IOException {
29.790 + bout.writeDouble(val);
29.791 + }
29.792 +
29.793 + /**
29.794 + * Writes a String as a sequence of bytes.
29.795 + *
29.796 + * @param str the String of bytes to be written
29.797 + * @throws IOException if I/O errors occur while writing to the underlying
29.798 + * stream
29.799 + */
29.800 + public void writeBytes(String str) throws IOException {
29.801 + bout.writeBytes(str);
29.802 + }
29.803 +
29.804 + /**
29.805 + * Writes a String as a sequence of chars.
29.806 + *
29.807 + * @param str the String of chars to be written
29.808 + * @throws IOException if I/O errors occur while writing to the underlying
29.809 + * stream
29.810 + */
29.811 + public void writeChars(String str) throws IOException {
29.812 + bout.writeChars(str);
29.813 + }
29.814 +
29.815 + /**
29.816 + * Primitive data write of this String in
29.817 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
29.818 + * format. Note that there is a
29.819 + * significant difference between writing a String into the stream as
29.820 + * primitive data or as an Object. A String instance written by writeObject
29.821 + * is written into the stream as a String initially. Future writeObject()
29.822 + * calls write references to the string into the stream.
29.823 + *
29.824 + * @param str the String to be written
29.825 + * @throws IOException if I/O errors occur while writing to the underlying
29.826 + * stream
29.827 + */
29.828 + public void writeUTF(String str) throws IOException {
29.829 + bout.writeUTF(str);
29.830 + }
29.831 +
29.832 + /**
29.833 + * Provide programmatic access to the persistent fields to be written
29.834 + * to ObjectOutput.
29.835 + *
29.836 + * @since 1.2
29.837 + */
29.838 + public static abstract class PutField {
29.839 +
29.840 + /**
29.841 + * Put the value of the named boolean field into the persistent field.
29.842 + *
29.843 + * @param name the name of the serializable field
29.844 + * @param val the value to assign to the field
29.845 + * @throws IllegalArgumentException if <code>name</code> does not
29.846 + * match the name of a serializable field for the class whose fields
29.847 + * are being written, or if the type of the named field is not
29.848 + * <code>boolean</code>
29.849 + */
29.850 + public abstract void put(String name, boolean val);
29.851 +
29.852 + /**
29.853 + * Put the value of the named byte field into the persistent field.
29.854 + *
29.855 + * @param name the name of the serializable field
29.856 + * @param val the value to assign to the field
29.857 + * @throws IllegalArgumentException if <code>name</code> does not
29.858 + * match the name of a serializable field for the class whose fields
29.859 + * are being written, or if the type of the named field is not
29.860 + * <code>byte</code>
29.861 + */
29.862 + public abstract void put(String name, byte val);
29.863 +
29.864 + /**
29.865 + * Put the value of the named char field into the persistent field.
29.866 + *
29.867 + * @param name the name of the serializable field
29.868 + * @param val the value to assign to the field
29.869 + * @throws IllegalArgumentException if <code>name</code> does not
29.870 + * match the name of a serializable field for the class whose fields
29.871 + * are being written, or if the type of the named field is not
29.872 + * <code>char</code>
29.873 + */
29.874 + public abstract void put(String name, char val);
29.875 +
29.876 + /**
29.877 + * Put the value of the named short field into the persistent field.
29.878 + *
29.879 + * @param name the name of the serializable field
29.880 + * @param val the value to assign to the field
29.881 + * @throws IllegalArgumentException if <code>name</code> does not
29.882 + * match the name of a serializable field for the class whose fields
29.883 + * are being written, or if the type of the named field is not
29.884 + * <code>short</code>
29.885 + */
29.886 + public abstract void put(String name, short val);
29.887 +
29.888 + /**
29.889 + * Put the value of the named int field into the persistent field.
29.890 + *
29.891 + * @param name the name of the serializable field
29.892 + * @param val the value to assign to the field
29.893 + * @throws IllegalArgumentException if <code>name</code> does not
29.894 + * match the name of a serializable field for the class whose fields
29.895 + * are being written, or if the type of the named field is not
29.896 + * <code>int</code>
29.897 + */
29.898 + public abstract void put(String name, int val);
29.899 +
29.900 + /**
29.901 + * Put the value of the named long field into the persistent field.
29.902 + *
29.903 + * @param name the name of the serializable field
29.904 + * @param val the value to assign to the field
29.905 + * @throws IllegalArgumentException if <code>name</code> does not
29.906 + * match the name of a serializable field for the class whose fields
29.907 + * are being written, or if the type of the named field is not
29.908 + * <code>long</code>
29.909 + */
29.910 + public abstract void put(String name, long val);
29.911 +
29.912 + /**
29.913 + * Put the value of the named float field into the persistent field.
29.914 + *
29.915 + * @param name the name of the serializable field
29.916 + * @param val the value to assign to the field
29.917 + * @throws IllegalArgumentException if <code>name</code> does not
29.918 + * match the name of a serializable field for the class whose fields
29.919 + * are being written, or if the type of the named field is not
29.920 + * <code>float</code>
29.921 + */
29.922 + public abstract void put(String name, float val);
29.923 +
29.924 + /**
29.925 + * Put the value of the named double field into the persistent field.
29.926 + *
29.927 + * @param name the name of the serializable field
29.928 + * @param val the value to assign to the field
29.929 + * @throws IllegalArgumentException if <code>name</code> does not
29.930 + * match the name of a serializable field for the class whose fields
29.931 + * are being written, or if the type of the named field is not
29.932 + * <code>double</code>
29.933 + */
29.934 + public abstract void put(String name, double val);
29.935 +
29.936 + /**
29.937 + * Put the value of the named Object field into the persistent field.
29.938 + *
29.939 + * @param name the name of the serializable field
29.940 + * @param val the value to assign to the field
29.941 + * (which may be <code>null</code>)
29.942 + * @throws IllegalArgumentException if <code>name</code> does not
29.943 + * match the name of a serializable field for the class whose fields
29.944 + * are being written, or if the type of the named field is not a
29.945 + * reference type
29.946 + */
29.947 + public abstract void put(String name, Object val);
29.948 +
29.949 + /**
29.950 + * Write the data and fields to the specified ObjectOutput stream,
29.951 + * which must be the same stream that produced this
29.952 + * <code>PutField</code> object.
29.953 + *
29.954 + * @param out the stream to write the data and fields to
29.955 + * @throws IOException if I/O errors occur while writing to the
29.956 + * underlying stream
29.957 + * @throws IllegalArgumentException if the specified stream is not
29.958 + * the same stream that produced this <code>PutField</code>
29.959 + * object
29.960 + * @deprecated This method does not write the values contained by this
29.961 + * <code>PutField</code> object in a proper format, and may
29.962 + * result in corruption of the serialization stream. The
29.963 + * correct way to write <code>PutField</code> data is by
29.964 + * calling the {@link java.io.ObjectOutputStream#writeFields()}
29.965 + * method.
29.966 + */
29.967 + @Deprecated
29.968 + public abstract void write(ObjectOutput out) throws IOException;
29.969 + }
29.970 +
29.971 +
29.972 + /**
29.973 + * Returns protocol version in use.
29.974 + */
29.975 + int getProtocolVersion() {
29.976 + return protocol;
29.977 + }
29.978 +
29.979 + /**
29.980 + * Writes string without allowing it to be replaced in stream. Used by
29.981 + * ObjectStreamClass to write class descriptor type strings.
29.982 + */
29.983 + void writeTypeString(String str) throws IOException {
29.984 + int handle;
29.985 + if (str == null) {
29.986 + writeNull();
29.987 + } else if ((handle = handles.lookup(str)) != -1) {
29.988 + writeHandle(handle);
29.989 + } else {
29.990 + writeString(str, false);
29.991 + }
29.992 + }
29.993 +
29.994 + /**
29.995 + * Verifies that this (possibly subclass) instance can be constructed
29.996 + * without violating security constraints: the subclass must not override
29.997 + * security-sensitive non-final methods, or else the
29.998 + * "enableSubclassImplementation" SerializablePermission is checked.
29.999 + */
29.1000 + private void verifySubclass() {
29.1001 + Class cl = getClass();
29.1002 + if (cl == ObjectOutputStream.class) {
29.1003 + return;
29.1004 + }
29.1005 + throw new SecurityException();
29.1006 + }
29.1007 +
29.1008 + /**
29.1009 + * Clears internal data structures.
29.1010 + */
29.1011 + private void clear() {
29.1012 + subs.clear();
29.1013 + handles.clear();
29.1014 + }
29.1015 +
29.1016 + /**
29.1017 + * Underlying writeObject/writeUnshared implementation.
29.1018 + */
29.1019 + private void writeObject0(Object obj, boolean unshared)
29.1020 + throws IOException
29.1021 + {
29.1022 + boolean oldMode = bout.setBlockDataMode(false);
29.1023 + depth++;
29.1024 + try {
29.1025 + // handle previously written and non-replaceable objects
29.1026 + int h;
29.1027 + if ((obj = subs.lookup(obj)) == null) {
29.1028 + writeNull();
29.1029 + return;
29.1030 + } else if (!unshared && (h = handles.lookup(obj)) != -1) {
29.1031 + writeHandle(h);
29.1032 + return;
29.1033 + } else if (obj instanceof Class) {
29.1034 + writeClass((Class) obj, unshared);
29.1035 + return;
29.1036 + } else if (obj instanceof ObjectStreamClass) {
29.1037 + writeClassDesc((ObjectStreamClass) obj, unshared);
29.1038 + return;
29.1039 + }
29.1040 +
29.1041 + // check for replacement object
29.1042 + Object orig = obj;
29.1043 + Class cl = obj.getClass();
29.1044 + ObjectStreamClass desc;
29.1045 + for (;;) {
29.1046 + // REMIND: skip this check for strings/arrays?
29.1047 + Class repCl;
29.1048 + desc = ObjectStreamClass.lookup(cl, true);
29.1049 + if (!desc.hasWriteReplaceMethod() ||
29.1050 + (obj = desc.invokeWriteReplace(obj)) == null ||
29.1051 + (repCl = obj.getClass()) == cl)
29.1052 + {
29.1053 + break;
29.1054 + }
29.1055 + cl = repCl;
29.1056 + }
29.1057 + if (enableReplace) {
29.1058 + Object rep = replaceObject(obj);
29.1059 + if (rep != obj && rep != null) {
29.1060 + cl = rep.getClass();
29.1061 + desc = ObjectStreamClass.lookup(cl, true);
29.1062 + }
29.1063 + obj = rep;
29.1064 + }
29.1065 +
29.1066 + // if object replaced, run through original checks a second time
29.1067 + if (obj != orig) {
29.1068 + subs.assign(orig, obj);
29.1069 + if (obj == null) {
29.1070 + writeNull();
29.1071 + return;
29.1072 + } else if (!unshared && (h = handles.lookup(obj)) != -1) {
29.1073 + writeHandle(h);
29.1074 + return;
29.1075 + } else if (obj instanceof Class) {
29.1076 + writeClass((Class) obj, unshared);
29.1077 + return;
29.1078 + } else if (obj instanceof ObjectStreamClass) {
29.1079 + writeClassDesc((ObjectStreamClass) obj, unshared);
29.1080 + return;
29.1081 + }
29.1082 + }
29.1083 +
29.1084 + // remaining cases
29.1085 + if (obj instanceof String) {
29.1086 + writeString((String) obj, unshared);
29.1087 + } else if (cl.isArray()) {
29.1088 + writeArray(obj, desc, unshared);
29.1089 + } else if (obj instanceof Enum) {
29.1090 + writeEnum((Enum) obj, desc, unshared);
29.1091 + } else if (obj instanceof Serializable) {
29.1092 + writeOrdinaryObject(obj, desc, unshared);
29.1093 + } else {
29.1094 + if (extendedDebugInfo) {
29.1095 + throw new NotSerializableException(
29.1096 + cl.getName() + "\n" + debugInfoStack.toString());
29.1097 + } else {
29.1098 + throw new NotSerializableException(cl.getName());
29.1099 + }
29.1100 + }
29.1101 + } finally {
29.1102 + depth--;
29.1103 + bout.setBlockDataMode(oldMode);
29.1104 + }
29.1105 + }
29.1106 +
29.1107 + /**
29.1108 + * Writes null code to stream.
29.1109 + */
29.1110 + private void writeNull() throws IOException {
29.1111 + bout.writeByte(TC_NULL);
29.1112 + }
29.1113 +
29.1114 + /**
29.1115 + * Writes given object handle to stream.
29.1116 + */
29.1117 + private void writeHandle(int handle) throws IOException {
29.1118 + bout.writeByte(TC_REFERENCE);
29.1119 + bout.writeInt(baseWireHandle + handle);
29.1120 + }
29.1121 +
29.1122 + /**
29.1123 + * Writes representation of given class to stream.
29.1124 + */
29.1125 + private void writeClass(Class cl, boolean unshared) throws IOException {
29.1126 + bout.writeByte(TC_CLASS);
29.1127 + writeClassDesc(ObjectStreamClass.lookup(cl, true), false);
29.1128 + handles.assign(unshared ? null : cl);
29.1129 + }
29.1130 +
29.1131 + /**
29.1132 + * Writes representation of given class descriptor to stream.
29.1133 + */
29.1134 + private void writeClassDesc(ObjectStreamClass desc, boolean unshared)
29.1135 + throws IOException
29.1136 + {
29.1137 + int handle;
29.1138 + if (desc == null) {
29.1139 + writeNull();
29.1140 + } else if (!unshared && (handle = handles.lookup(desc)) != -1) {
29.1141 + writeHandle(handle);
29.1142 + } else if (desc.isProxy()) {
29.1143 + writeProxyDesc(desc, unshared);
29.1144 + } else {
29.1145 + writeNonProxyDesc(desc, unshared);
29.1146 + }
29.1147 + }
29.1148 +
29.1149 + /**
29.1150 + * Writes class descriptor representing a dynamic proxy class to stream.
29.1151 + */
29.1152 + private void writeProxyDesc(ObjectStreamClass desc, boolean unshared)
29.1153 + throws IOException
29.1154 + {
29.1155 + bout.writeByte(TC_PROXYCLASSDESC);
29.1156 + handles.assign(unshared ? null : desc);
29.1157 +
29.1158 + Class cl = desc.forClass();
29.1159 + Class[] ifaces = cl.getInterfaces();
29.1160 + bout.writeInt(ifaces.length);
29.1161 + for (int i = 0; i < ifaces.length; i++) {
29.1162 + bout.writeUTF(ifaces[i].getName());
29.1163 + }
29.1164 +
29.1165 + bout.setBlockDataMode(true);
29.1166 + annotateProxyClass(cl);
29.1167 + bout.setBlockDataMode(false);
29.1168 + bout.writeByte(TC_ENDBLOCKDATA);
29.1169 +
29.1170 + writeClassDesc(desc.getSuperDesc(), false);
29.1171 + }
29.1172 +
29.1173 + /**
29.1174 + * Writes class descriptor representing a standard (i.e., not a dynamic
29.1175 + * proxy) class to stream.
29.1176 + */
29.1177 + private void writeNonProxyDesc(ObjectStreamClass desc, boolean unshared)
29.1178 + throws IOException
29.1179 + {
29.1180 + bout.writeByte(TC_CLASSDESC);
29.1181 + handles.assign(unshared ? null : desc);
29.1182 +
29.1183 + if (protocol == PROTOCOL_VERSION_1) {
29.1184 + // do not invoke class descriptor write hook with old protocol
29.1185 + desc.writeNonProxy(this);
29.1186 + } else {
29.1187 + writeClassDescriptor(desc);
29.1188 + }
29.1189 +
29.1190 + Class cl = desc.forClass();
29.1191 + bout.setBlockDataMode(true);
29.1192 + annotateClass(cl);
29.1193 + bout.setBlockDataMode(false);
29.1194 + bout.writeByte(TC_ENDBLOCKDATA);
29.1195 +
29.1196 + writeClassDesc(desc.getSuperDesc(), false);
29.1197 + }
29.1198 +
29.1199 + /**
29.1200 + * Writes given string to stream, using standard or long UTF format
29.1201 + * depending on string length.
29.1202 + */
29.1203 + private void writeString(String str, boolean unshared) throws IOException {
29.1204 + handles.assign(unshared ? null : str);
29.1205 + long utflen = bout.getUTFLength(str);
29.1206 + if (utflen <= 0xFFFF) {
29.1207 + bout.writeByte(TC_STRING);
29.1208 + bout.writeUTF(str, utflen);
29.1209 + } else {
29.1210 + bout.writeByte(TC_LONGSTRING);
29.1211 + bout.writeLongUTF(str, utflen);
29.1212 + }
29.1213 + }
29.1214 +
29.1215 + /**
29.1216 + * Writes given array object to stream.
29.1217 + */
29.1218 + private void writeArray(Object array,
29.1219 + ObjectStreamClass desc,
29.1220 + boolean unshared)
29.1221 + throws IOException
29.1222 + {
29.1223 + bout.writeByte(TC_ARRAY);
29.1224 + writeClassDesc(desc, false);
29.1225 + handles.assign(unshared ? null : array);
29.1226 +
29.1227 + Class ccl = desc.forClass().getComponentType();
29.1228 + if (ccl.isPrimitive()) {
29.1229 + if (ccl == Integer.TYPE) {
29.1230 + int[] ia = (int[]) array;
29.1231 + bout.writeInt(ia.length);
29.1232 + bout.writeInts(ia, 0, ia.length);
29.1233 + } else if (ccl == Byte.TYPE) {
29.1234 + byte[] ba = (byte[]) array;
29.1235 + bout.writeInt(ba.length);
29.1236 + bout.write(ba, 0, ba.length, true);
29.1237 + } else if (ccl == Long.TYPE) {
29.1238 + long[] ja = (long[]) array;
29.1239 + bout.writeInt(ja.length);
29.1240 + bout.writeLongs(ja, 0, ja.length);
29.1241 + } else if (ccl == Float.TYPE) {
29.1242 + float[] fa = (float[]) array;
29.1243 + bout.writeInt(fa.length);
29.1244 + bout.writeFloats(fa, 0, fa.length);
29.1245 + } else if (ccl == Double.TYPE) {
29.1246 + double[] da = (double[]) array;
29.1247 + bout.writeInt(da.length);
29.1248 + bout.writeDoubles(da, 0, da.length);
29.1249 + } else if (ccl == Short.TYPE) {
29.1250 + short[] sa = (short[]) array;
29.1251 + bout.writeInt(sa.length);
29.1252 + bout.writeShorts(sa, 0, sa.length);
29.1253 + } else if (ccl == Character.TYPE) {
29.1254 + char[] ca = (char[]) array;
29.1255 + bout.writeInt(ca.length);
29.1256 + bout.writeChars(ca, 0, ca.length);
29.1257 + } else if (ccl == Boolean.TYPE) {
29.1258 + boolean[] za = (boolean[]) array;
29.1259 + bout.writeInt(za.length);
29.1260 + bout.writeBooleans(za, 0, za.length);
29.1261 + } else {
29.1262 + throw new InternalError();
29.1263 + }
29.1264 + } else {
29.1265 + Object[] objs = (Object[]) array;
29.1266 + int len = objs.length;
29.1267 + bout.writeInt(len);
29.1268 + if (extendedDebugInfo) {
29.1269 + debugInfoStack.push(
29.1270 + "array (class \"" + array.getClass().getName() +
29.1271 + "\", size: " + len + ")");
29.1272 + }
29.1273 + try {
29.1274 + for (int i = 0; i < len; i++) {
29.1275 + if (extendedDebugInfo) {
29.1276 + debugInfoStack.push(
29.1277 + "element of array (index: " + i + ")");
29.1278 + }
29.1279 + try {
29.1280 + writeObject0(objs[i], false);
29.1281 + } finally {
29.1282 + if (extendedDebugInfo) {
29.1283 + debugInfoStack.pop();
29.1284 + }
29.1285 + }
29.1286 + }
29.1287 + } finally {
29.1288 + if (extendedDebugInfo) {
29.1289 + debugInfoStack.pop();
29.1290 + }
29.1291 + }
29.1292 + }
29.1293 + }
29.1294 +
29.1295 + /**
29.1296 + * Writes given enum constant to stream.
29.1297 + */
29.1298 + private void writeEnum(Enum en,
29.1299 + ObjectStreamClass desc,
29.1300 + boolean unshared)
29.1301 + throws IOException
29.1302 + {
29.1303 + bout.writeByte(TC_ENUM);
29.1304 + ObjectStreamClass sdesc = desc.getSuperDesc();
29.1305 + writeClassDesc((sdesc.forClass() == Enum.class) ? desc : sdesc, false);
29.1306 + handles.assign(unshared ? null : en);
29.1307 + writeString(en.name(), false);
29.1308 + }
29.1309 +
29.1310 + /**
29.1311 + * Writes representation of a "ordinary" (i.e., not a String, Class,
29.1312 + * ObjectStreamClass, array, or enum constant) serializable object to the
29.1313 + * stream.
29.1314 + */
29.1315 + private void writeOrdinaryObject(Object obj,
29.1316 + ObjectStreamClass desc,
29.1317 + boolean unshared)
29.1318 + throws IOException
29.1319 + {
29.1320 + if (extendedDebugInfo) {
29.1321 + debugInfoStack.push(
29.1322 + (depth == 1 ? "root " : "") + "object (class \"" +
29.1323 + obj.getClass().getName() + "\", " + obj.toString() + ")");
29.1324 + }
29.1325 + try {
29.1326 + desc.checkSerialize();
29.1327 +
29.1328 + bout.writeByte(TC_OBJECT);
29.1329 + writeClassDesc(desc, false);
29.1330 + handles.assign(unshared ? null : obj);
29.1331 + if (desc.isExternalizable() && !desc.isProxy()) {
29.1332 + writeExternalData((Externalizable) obj);
29.1333 + } else {
29.1334 + writeSerialData(obj, desc);
29.1335 + }
29.1336 + } finally {
29.1337 + if (extendedDebugInfo) {
29.1338 + debugInfoStack.pop();
29.1339 + }
29.1340 + }
29.1341 + }
29.1342 +
29.1343 + /**
29.1344 + * Writes externalizable data of given object by invoking its
29.1345 + * writeExternal() method.
29.1346 + */
29.1347 + private void writeExternalData(Externalizable obj) throws IOException {
29.1348 + PutFieldImpl oldPut = curPut;
29.1349 + curPut = null;
29.1350 +
29.1351 + if (extendedDebugInfo) {
29.1352 + debugInfoStack.push("writeExternal data");
29.1353 + }
29.1354 + Object oldContext = curContext;
29.1355 + try {
29.1356 + curContext = null;
29.1357 + if (protocol == PROTOCOL_VERSION_1) {
29.1358 + obj.writeExternal(this);
29.1359 + } else {
29.1360 + bout.setBlockDataMode(true);
29.1361 + obj.writeExternal(this);
29.1362 + bout.setBlockDataMode(false);
29.1363 + bout.writeByte(TC_ENDBLOCKDATA);
29.1364 + }
29.1365 + } finally {
29.1366 + curContext = oldContext;
29.1367 + if (extendedDebugInfo) {
29.1368 + debugInfoStack.pop();
29.1369 + }
29.1370 + }
29.1371 +
29.1372 + curPut = oldPut;
29.1373 + }
29.1374 +
29.1375 + /**
29.1376 + * Writes instance data for each serializable class of given object, from
29.1377 + * superclass to subclass.
29.1378 + */
29.1379 + private void writeSerialData(Object obj, ObjectStreamClass desc)
29.1380 + throws IOException
29.1381 + {
29.1382 + ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
29.1383 + for (int i = 0; i < slots.length; i++) {
29.1384 + ObjectStreamClass slotDesc = slots[i].desc;
29.1385 + if (slotDesc.hasWriteObjectMethod()) {
29.1386 + PutFieldImpl oldPut = curPut;
29.1387 + curPut = null;
29.1388 + Object oldContext = curContext;
29.1389 +
29.1390 + if (extendedDebugInfo) {
29.1391 + debugInfoStack.push(
29.1392 + "custom writeObject data (class \"" +
29.1393 + slotDesc.getName() + "\")");
29.1394 + }
29.1395 + try {
29.1396 + curContext = new Object(); //new SerialCallbackContext(obj, slotDesc);
29.1397 + bout.setBlockDataMode(true);
29.1398 + slotDesc.invokeWriteObject(obj, this);
29.1399 + bout.setBlockDataMode(false);
29.1400 + bout.writeByte(TC_ENDBLOCKDATA);
29.1401 + } finally {
29.1402 + //curContext.setUsed();
29.1403 + curContext = oldContext;
29.1404 + if (extendedDebugInfo) {
29.1405 + debugInfoStack.pop();
29.1406 + }
29.1407 + }
29.1408 +
29.1409 + curPut = oldPut;
29.1410 + } else {
29.1411 + defaultWriteFields(obj, slotDesc);
29.1412 + }
29.1413 + }
29.1414 + }
29.1415 +
29.1416 + /**
29.1417 + * Fetches and writes values of serializable fields of given object to
29.1418 + * stream. The given class descriptor specifies which field values to
29.1419 + * write, and in which order they should be written.
29.1420 + */
29.1421 + private void defaultWriteFields(Object obj, ObjectStreamClass desc)
29.1422 + throws IOException
29.1423 + {
29.1424 + // REMIND: perform conservative isInstance check here?
29.1425 + desc.checkDefaultSerialize();
29.1426 +
29.1427 + int primDataSize = desc.getPrimDataSize();
29.1428 + if (primVals == null || primVals.length < primDataSize) {
29.1429 + primVals = new byte[primDataSize];
29.1430 + }
29.1431 + desc.getPrimFieldValues(obj, primVals);
29.1432 + bout.write(primVals, 0, primDataSize, false);
29.1433 +
29.1434 + ObjectStreamField[] fields = desc.getFields(false);
29.1435 + Object[] objVals = new Object[desc.getNumObjFields()];
29.1436 + int numPrimFields = fields.length - objVals.length;
29.1437 + desc.getObjFieldValues(obj, objVals);
29.1438 + for (int i = 0; i < objVals.length; i++) {
29.1439 + if (extendedDebugInfo) {
29.1440 + debugInfoStack.push(
29.1441 + "field (class \"" + desc.getName() + "\", name: \"" +
29.1442 + fields[numPrimFields + i].getName() + "\", type: \"" +
29.1443 + fields[numPrimFields + i].getType() + "\")");
29.1444 + }
29.1445 + try {
29.1446 + writeObject0(objVals[i],
29.1447 + fields[numPrimFields + i].isUnshared());
29.1448 + } finally {
29.1449 + if (extendedDebugInfo) {
29.1450 + debugInfoStack.pop();
29.1451 + }
29.1452 + }
29.1453 + }
29.1454 + }
29.1455 +
29.1456 + /**
29.1457 + * Attempts to write to stream fatal IOException that has caused
29.1458 + * serialization to abort.
29.1459 + */
29.1460 + private void writeFatalException(IOException ex) throws IOException {
29.1461 + /*
29.1462 + * Note: the serialization specification states that if a second
29.1463 + * IOException occurs while attempting to serialize the original fatal
29.1464 + * exception to the stream, then a StreamCorruptedException should be
29.1465 + * thrown (section 2.1). However, due to a bug in previous
29.1466 + * implementations of serialization, StreamCorruptedExceptions were
29.1467 + * rarely (if ever) actually thrown--the "root" exceptions from
29.1468 + * underlying streams were thrown instead. This historical behavior is
29.1469 + * followed here for consistency.
29.1470 + */
29.1471 + clear();
29.1472 + boolean oldMode = bout.setBlockDataMode(false);
29.1473 + try {
29.1474 + bout.writeByte(TC_EXCEPTION);
29.1475 + writeObject0(ex, false);
29.1476 + clear();
29.1477 + } finally {
29.1478 + bout.setBlockDataMode(oldMode);
29.1479 + }
29.1480 + }
29.1481 +
29.1482 + /**
29.1483 + * Converts specified span of float values into byte values.
29.1484 + */
29.1485 + // REMIND: remove once hotspot inlines Float.floatToIntBits
29.1486 + private static native void floatsToBytes(float[] src, int srcpos,
29.1487 + byte[] dst, int dstpos,
29.1488 + int nfloats);
29.1489 +
29.1490 + /**
29.1491 + * Converts specified span of double values into byte values.
29.1492 + */
29.1493 + // REMIND: remove once hotspot inlines Double.doubleToLongBits
29.1494 + private static native void doublesToBytes(double[] src, int srcpos,
29.1495 + byte[] dst, int dstpos,
29.1496 + int ndoubles);
29.1497 +
29.1498 + /**
29.1499 + * Default PutField implementation.
29.1500 + */
29.1501 + private class PutFieldImpl extends PutField {
29.1502 +
29.1503 + /** class descriptor describing serializable fields */
29.1504 + private final ObjectStreamClass desc;
29.1505 + /** primitive field values */
29.1506 + private final byte[] primVals;
29.1507 + /** object field values */
29.1508 + private final Object[] objVals;
29.1509 +
29.1510 + /**
29.1511 + * Creates PutFieldImpl object for writing fields defined in given
29.1512 + * class descriptor.
29.1513 + */
29.1514 + PutFieldImpl(ObjectStreamClass desc) {
29.1515 + this.desc = desc;
29.1516 + primVals = new byte[desc.getPrimDataSize()];
29.1517 + objVals = new Object[desc.getNumObjFields()];
29.1518 + }
29.1519 +
29.1520 + public void put(String name, boolean val) {
29.1521 + Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
29.1522 + }
29.1523 +
29.1524 + public void put(String name, byte val) {
29.1525 + primVals[getFieldOffset(name, Byte.TYPE)] = val;
29.1526 + }
29.1527 +
29.1528 + public void put(String name, char val) {
29.1529 + Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
29.1530 + }
29.1531 +
29.1532 + public void put(String name, short val) {
29.1533 + Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
29.1534 + }
29.1535 +
29.1536 + public void put(String name, int val) {
29.1537 + Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
29.1538 + }
29.1539 +
29.1540 + public void put(String name, float val) {
29.1541 + Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
29.1542 + }
29.1543 +
29.1544 + public void put(String name, long val) {
29.1545 + Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
29.1546 + }
29.1547 +
29.1548 + public void put(String name, double val) {
29.1549 + Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
29.1550 + }
29.1551 +
29.1552 + public void put(String name, Object val) {
29.1553 + objVals[getFieldOffset(name, Object.class)] = val;
29.1554 + }
29.1555 +
29.1556 + // deprecated in ObjectOutputStream.PutField
29.1557 + public void write(ObjectOutput out) throws IOException {
29.1558 + /*
29.1559 + * Applications should *not* use this method to write PutField
29.1560 + * data, as it will lead to stream corruption if the PutField
29.1561 + * object writes any primitive data (since block data mode is not
29.1562 + * unset/set properly, as is done in OOS.writeFields()). This
29.1563 + * broken implementation is being retained solely for behavioral
29.1564 + * compatibility, in order to support applications which use
29.1565 + * OOS.PutField.write() for writing only non-primitive data.
29.1566 + *
29.1567 + * Serialization of unshared objects is not implemented here since
29.1568 + * it is not necessary for backwards compatibility; also, unshared
29.1569 + * semantics may not be supported by the given ObjectOutput
29.1570 + * instance. Applications which write unshared objects using the
29.1571 + * PutField API must use OOS.writeFields().
29.1572 + */
29.1573 + if (ObjectOutputStream.this != out) {
29.1574 + throw new IllegalArgumentException("wrong stream");
29.1575 + }
29.1576 + out.write(primVals, 0, primVals.length);
29.1577 +
29.1578 + ObjectStreamField[] fields = desc.getFields(false);
29.1579 + int numPrimFields = fields.length - objVals.length;
29.1580 + // REMIND: warn if numPrimFields > 0?
29.1581 + for (int i = 0; i < objVals.length; i++) {
29.1582 + if (fields[numPrimFields + i].isUnshared()) {
29.1583 + throw new IOException("cannot write unshared object");
29.1584 + }
29.1585 + out.writeObject(objVals[i]);
29.1586 + }
29.1587 + }
29.1588 +
29.1589 + /**
29.1590 + * Writes buffered primitive data and object fields to stream.
29.1591 + */
29.1592 + void writeFields() throws IOException {
29.1593 + bout.write(primVals, 0, primVals.length, false);
29.1594 +
29.1595 + ObjectStreamField[] fields = desc.getFields(false);
29.1596 + int numPrimFields = fields.length - objVals.length;
29.1597 + for (int i = 0; i < objVals.length; i++) {
29.1598 + if (extendedDebugInfo) {
29.1599 + debugInfoStack.push(
29.1600 + "field (class \"" + desc.getName() + "\", name: \"" +
29.1601 + fields[numPrimFields + i].getName() + "\", type: \"" +
29.1602 + fields[numPrimFields + i].getType() + "\")");
29.1603 + }
29.1604 + try {
29.1605 + writeObject0(objVals[i],
29.1606 + fields[numPrimFields + i].isUnshared());
29.1607 + } finally {
29.1608 + if (extendedDebugInfo) {
29.1609 + debugInfoStack.pop();
29.1610 + }
29.1611 + }
29.1612 + }
29.1613 + }
29.1614 +
29.1615 + /**
29.1616 + * Returns offset of field with given name and type. A specified type
29.1617 + * of null matches all types, Object.class matches all non-primitive
29.1618 + * types, and any other non-null type matches assignable types only.
29.1619 + * Throws IllegalArgumentException if no matching field found.
29.1620 + */
29.1621 + private int getFieldOffset(String name, Class type) {
29.1622 + ObjectStreamField field = desc.getField(name, type);
29.1623 + if (field == null) {
29.1624 + throw new IllegalArgumentException("no such field " + name +
29.1625 + " with type " + type);
29.1626 + }
29.1627 + return field.getOffset();
29.1628 + }
29.1629 + }
29.1630 +
29.1631 + /**
29.1632 + * Buffered output stream with two modes: in default mode, outputs data in
29.1633 + * same format as DataOutputStream; in "block data" mode, outputs data
29.1634 + * bracketed by block data markers (see object serialization specification
29.1635 + * for details).
29.1636 + */
29.1637 + private static class BlockDataOutputStream
29.1638 + extends OutputStream implements DataOutput
29.1639 + {
29.1640 + /** maximum data block length */
29.1641 + private static final int MAX_BLOCK_SIZE = 1024;
29.1642 + /** maximum data block header length */
29.1643 + private static final int MAX_HEADER_SIZE = 5;
29.1644 + /** (tunable) length of char buffer (for writing strings) */
29.1645 + private static final int CHAR_BUF_SIZE = 256;
29.1646 +
29.1647 + /** buffer for writing general/block data */
29.1648 + private final byte[] buf = new byte[MAX_BLOCK_SIZE];
29.1649 + /** buffer for writing block data headers */
29.1650 + private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
29.1651 + /** char buffer for fast string writes */
29.1652 + private final char[] cbuf = new char[CHAR_BUF_SIZE];
29.1653 +
29.1654 + /** block data mode */
29.1655 + private boolean blkmode = false;
29.1656 + /** current offset into buf */
29.1657 + private int pos = 0;
29.1658 +
29.1659 + /** underlying output stream */
29.1660 + private final OutputStream out;
29.1661 + /** loopback stream (for data writes that span data blocks) */
29.1662 + private final DataOutputStream dout;
29.1663 +
29.1664 + /**
29.1665 + * Creates new BlockDataOutputStream on top of given underlying stream.
29.1666 + * Block data mode is turned off by default.
29.1667 + */
29.1668 + BlockDataOutputStream(OutputStream out) {
29.1669 + this.out = out;
29.1670 + dout = new DataOutputStream(this);
29.1671 + }
29.1672 +
29.1673 + /**
29.1674 + * Sets block data mode to the given mode (true == on, false == off)
29.1675 + * and returns the previous mode value. If the new mode is the same as
29.1676 + * the old mode, no action is taken. If the new mode differs from the
29.1677 + * old mode, any buffered data is flushed before switching to the new
29.1678 + * mode.
29.1679 + */
29.1680 + boolean setBlockDataMode(boolean mode) throws IOException {
29.1681 + if (blkmode == mode) {
29.1682 + return blkmode;
29.1683 + }
29.1684 + drain();
29.1685 + blkmode = mode;
29.1686 + return !blkmode;
29.1687 + }
29.1688 +
29.1689 + /**
29.1690 + * Returns true if the stream is currently in block data mode, false
29.1691 + * otherwise.
29.1692 + */
29.1693 + boolean getBlockDataMode() {
29.1694 + return blkmode;
29.1695 + }
29.1696 +
29.1697 + /* ----------------- generic output stream methods ----------------- */
29.1698 + /*
29.1699 + * The following methods are equivalent to their counterparts in
29.1700 + * OutputStream, except that they partition written data into data
29.1701 + * blocks when in block data mode.
29.1702 + */
29.1703 +
29.1704 + public void write(int b) throws IOException {
29.1705 + if (pos >= MAX_BLOCK_SIZE) {
29.1706 + drain();
29.1707 + }
29.1708 + buf[pos++] = (byte) b;
29.1709 + }
29.1710 +
29.1711 + public void write(byte[] b) throws IOException {
29.1712 + write(b, 0, b.length, false);
29.1713 + }
29.1714 +
29.1715 + public void write(byte[] b, int off, int len) throws IOException {
29.1716 + write(b, off, len, false);
29.1717 + }
29.1718 +
29.1719 + public void flush() throws IOException {
29.1720 + drain();
29.1721 + out.flush();
29.1722 + }
29.1723 +
29.1724 + public void close() throws IOException {
29.1725 + flush();
29.1726 + out.close();
29.1727 + }
29.1728 +
29.1729 + /**
29.1730 + * Writes specified span of byte values from given array. If copy is
29.1731 + * true, copies the values to an intermediate buffer before writing
29.1732 + * them to underlying stream (to avoid exposing a reference to the
29.1733 + * original byte array).
29.1734 + */
29.1735 + void write(byte[] b, int off, int len, boolean copy)
29.1736 + throws IOException
29.1737 + {
29.1738 + if (!(copy || blkmode)) { // write directly
29.1739 + drain();
29.1740 + out.write(b, off, len);
29.1741 + return;
29.1742 + }
29.1743 +
29.1744 + while (len > 0) {
29.1745 + if (pos >= MAX_BLOCK_SIZE) {
29.1746 + drain();
29.1747 + }
29.1748 + if (len >= MAX_BLOCK_SIZE && !copy && pos == 0) {
29.1749 + // avoid unnecessary copy
29.1750 + writeBlockHeader(MAX_BLOCK_SIZE);
29.1751 + out.write(b, off, MAX_BLOCK_SIZE);
29.1752 + off += MAX_BLOCK_SIZE;
29.1753 + len -= MAX_BLOCK_SIZE;
29.1754 + } else {
29.1755 + int wlen = Math.min(len, MAX_BLOCK_SIZE - pos);
29.1756 + System.arraycopy(b, off, buf, pos, wlen);
29.1757 + pos += wlen;
29.1758 + off += wlen;
29.1759 + len -= wlen;
29.1760 + }
29.1761 + }
29.1762 + }
29.1763 +
29.1764 + /**
29.1765 + * Writes all buffered data from this stream to the underlying stream,
29.1766 + * but does not flush underlying stream.
29.1767 + */
29.1768 + void drain() throws IOException {
29.1769 + if (pos == 0) {
29.1770 + return;
29.1771 + }
29.1772 + if (blkmode) {
29.1773 + writeBlockHeader(pos);
29.1774 + }
29.1775 + out.write(buf, 0, pos);
29.1776 + pos = 0;
29.1777 + }
29.1778 +
29.1779 + /**
29.1780 + * Writes block data header. Data blocks shorter than 256 bytes are
29.1781 + * prefixed with a 2-byte header; all others start with a 5-byte
29.1782 + * header.
29.1783 + */
29.1784 + private void writeBlockHeader(int len) throws IOException {
29.1785 + if (len <= 0xFF) {
29.1786 + hbuf[0] = TC_BLOCKDATA;
29.1787 + hbuf[1] = (byte) len;
29.1788 + out.write(hbuf, 0, 2);
29.1789 + } else {
29.1790 + hbuf[0] = TC_BLOCKDATALONG;
29.1791 + Bits.putInt(hbuf, 1, len);
29.1792 + out.write(hbuf, 0, 5);
29.1793 + }
29.1794 + }
29.1795 +
29.1796 +
29.1797 + /* ----------------- primitive data output methods ----------------- */
29.1798 + /*
29.1799 + * The following methods are equivalent to their counterparts in
29.1800 + * DataOutputStream, except that they partition written data into data
29.1801 + * blocks when in block data mode.
29.1802 + */
29.1803 +
29.1804 + public void writeBoolean(boolean v) throws IOException {
29.1805 + if (pos >= MAX_BLOCK_SIZE) {
29.1806 + drain();
29.1807 + }
29.1808 + Bits.putBoolean(buf, pos++, v);
29.1809 + }
29.1810 +
29.1811 + public void writeByte(int v) throws IOException {
29.1812 + if (pos >= MAX_BLOCK_SIZE) {
29.1813 + drain();
29.1814 + }
29.1815 + buf[pos++] = (byte) v;
29.1816 + }
29.1817 +
29.1818 + public void writeChar(int v) throws IOException {
29.1819 + if (pos + 2 <= MAX_BLOCK_SIZE) {
29.1820 + Bits.putChar(buf, pos, (char) v);
29.1821 + pos += 2;
29.1822 + } else {
29.1823 + dout.writeChar(v);
29.1824 + }
29.1825 + }
29.1826 +
29.1827 + public void writeShort(int v) throws IOException {
29.1828 + if (pos + 2 <= MAX_BLOCK_SIZE) {
29.1829 + Bits.putShort(buf, pos, (short) v);
29.1830 + pos += 2;
29.1831 + } else {
29.1832 + dout.writeShort(v);
29.1833 + }
29.1834 + }
29.1835 +
29.1836 + public void writeInt(int v) throws IOException {
29.1837 + if (pos + 4 <= MAX_BLOCK_SIZE) {
29.1838 + Bits.putInt(buf, pos, v);
29.1839 + pos += 4;
29.1840 + } else {
29.1841 + dout.writeInt(v);
29.1842 + }
29.1843 + }
29.1844 +
29.1845 + public void writeFloat(float v) throws IOException {
29.1846 + if (pos + 4 <= MAX_BLOCK_SIZE) {
29.1847 + Bits.putFloat(buf, pos, v);
29.1848 + pos += 4;
29.1849 + } else {
29.1850 + dout.writeFloat(v);
29.1851 + }
29.1852 + }
29.1853 +
29.1854 + public void writeLong(long v) throws IOException {
29.1855 + if (pos + 8 <= MAX_BLOCK_SIZE) {
29.1856 + Bits.putLong(buf, pos, v);
29.1857 + pos += 8;
29.1858 + } else {
29.1859 + dout.writeLong(v);
29.1860 + }
29.1861 + }
29.1862 +
29.1863 + public void writeDouble(double v) throws IOException {
29.1864 + if (pos + 8 <= MAX_BLOCK_SIZE) {
29.1865 + Bits.putDouble(buf, pos, v);
29.1866 + pos += 8;
29.1867 + } else {
29.1868 + dout.writeDouble(v);
29.1869 + }
29.1870 + }
29.1871 +
29.1872 + public void writeBytes(String s) throws IOException {
29.1873 + int endoff = s.length();
29.1874 + int cpos = 0;
29.1875 + int csize = 0;
29.1876 + for (int off = 0; off < endoff; ) {
29.1877 + if (cpos >= csize) {
29.1878 + cpos = 0;
29.1879 + csize = Math.min(endoff - off, CHAR_BUF_SIZE);
29.1880 + s.getChars(off, off + csize, cbuf, 0);
29.1881 + }
29.1882 + if (pos >= MAX_BLOCK_SIZE) {
29.1883 + drain();
29.1884 + }
29.1885 + int n = Math.min(csize - cpos, MAX_BLOCK_SIZE - pos);
29.1886 + int stop = pos + n;
29.1887 + while (pos < stop) {
29.1888 + buf[pos++] = (byte) cbuf[cpos++];
29.1889 + }
29.1890 + off += n;
29.1891 + }
29.1892 + }
29.1893 +
29.1894 + public void writeChars(String s) throws IOException {
29.1895 + int endoff = s.length();
29.1896 + for (int off = 0; off < endoff; ) {
29.1897 + int csize = Math.min(endoff - off, CHAR_BUF_SIZE);
29.1898 + s.getChars(off, off + csize, cbuf, 0);
29.1899 + writeChars(cbuf, 0, csize);
29.1900 + off += csize;
29.1901 + }
29.1902 + }
29.1903 +
29.1904 + public void writeUTF(String s) throws IOException {
29.1905 + writeUTF(s, getUTFLength(s));
29.1906 + }
29.1907 +
29.1908 +
29.1909 + /* -------------- primitive data array output methods -------------- */
29.1910 + /*
29.1911 + * The following methods write out spans of primitive data values.
29.1912 + * Though equivalent to calling the corresponding primitive write
29.1913 + * methods repeatedly, these methods are optimized for writing groups
29.1914 + * of primitive data values more efficiently.
29.1915 + */
29.1916 +
29.1917 + void writeBooleans(boolean[] v, int off, int len) throws IOException {
29.1918 + int endoff = off + len;
29.1919 + while (off < endoff) {
29.1920 + if (pos >= MAX_BLOCK_SIZE) {
29.1921 + drain();
29.1922 + }
29.1923 + int stop = Math.min(endoff, off + (MAX_BLOCK_SIZE - pos));
29.1924 + while (off < stop) {
29.1925 + Bits.putBoolean(buf, pos++, v[off++]);
29.1926 + }
29.1927 + }
29.1928 + }
29.1929 +
29.1930 + void writeChars(char[] v, int off, int len) throws IOException {
29.1931 + int limit = MAX_BLOCK_SIZE - 2;
29.1932 + int endoff = off + len;
29.1933 + while (off < endoff) {
29.1934 + if (pos <= limit) {
29.1935 + int avail = (MAX_BLOCK_SIZE - pos) >> 1;
29.1936 + int stop = Math.min(endoff, off + avail);
29.1937 + while (off < stop) {
29.1938 + Bits.putChar(buf, pos, v[off++]);
29.1939 + pos += 2;
29.1940 + }
29.1941 + } else {
29.1942 + dout.writeChar(v[off++]);
29.1943 + }
29.1944 + }
29.1945 + }
29.1946 +
29.1947 + void writeShorts(short[] v, int off, int len) throws IOException {
29.1948 + int limit = MAX_BLOCK_SIZE - 2;
29.1949 + int endoff = off + len;
29.1950 + while (off < endoff) {
29.1951 + if (pos <= limit) {
29.1952 + int avail = (MAX_BLOCK_SIZE - pos) >> 1;
29.1953 + int stop = Math.min(endoff, off + avail);
29.1954 + while (off < stop) {
29.1955 + Bits.putShort(buf, pos, v[off++]);
29.1956 + pos += 2;
29.1957 + }
29.1958 + } else {
29.1959 + dout.writeShort(v[off++]);
29.1960 + }
29.1961 + }
29.1962 + }
29.1963 +
29.1964 + void writeInts(int[] v, int off, int len) throws IOException {
29.1965 + int limit = MAX_BLOCK_SIZE - 4;
29.1966 + int endoff = off + len;
29.1967 + while (off < endoff) {
29.1968 + if (pos <= limit) {
29.1969 + int avail = (MAX_BLOCK_SIZE - pos) >> 2;
29.1970 + int stop = Math.min(endoff, off + avail);
29.1971 + while (off < stop) {
29.1972 + Bits.putInt(buf, pos, v[off++]);
29.1973 + pos += 4;
29.1974 + }
29.1975 + } else {
29.1976 + dout.writeInt(v[off++]);
29.1977 + }
29.1978 + }
29.1979 + }
29.1980 +
29.1981 + void writeFloats(float[] v, int off, int len) throws IOException {
29.1982 + int limit = MAX_BLOCK_SIZE - 4;
29.1983 + int endoff = off + len;
29.1984 + while (off < endoff) {
29.1985 + if (pos <= limit) {
29.1986 + int avail = (MAX_BLOCK_SIZE - pos) >> 2;
29.1987 + int chunklen = Math.min(endoff - off, avail);
29.1988 + floatsToBytes(v, off, buf, pos, chunklen);
29.1989 + off += chunklen;
29.1990 + pos += chunklen << 2;
29.1991 + } else {
29.1992 + dout.writeFloat(v[off++]);
29.1993 + }
29.1994 + }
29.1995 + }
29.1996 +
29.1997 + void writeLongs(long[] v, int off, int len) throws IOException {
29.1998 + int limit = MAX_BLOCK_SIZE - 8;
29.1999 + int endoff = off + len;
29.2000 + while (off < endoff) {
29.2001 + if (pos <= limit) {
29.2002 + int avail = (MAX_BLOCK_SIZE - pos) >> 3;
29.2003 + int stop = Math.min(endoff, off + avail);
29.2004 + while (off < stop) {
29.2005 + Bits.putLong(buf, pos, v[off++]);
29.2006 + pos += 8;
29.2007 + }
29.2008 + } else {
29.2009 + dout.writeLong(v[off++]);
29.2010 + }
29.2011 + }
29.2012 + }
29.2013 +
29.2014 + void writeDoubles(double[] v, int off, int len) throws IOException {
29.2015 + int limit = MAX_BLOCK_SIZE - 8;
29.2016 + int endoff = off + len;
29.2017 + while (off < endoff) {
29.2018 + if (pos <= limit) {
29.2019 + int avail = (MAX_BLOCK_SIZE - pos) >> 3;
29.2020 + int chunklen = Math.min(endoff - off, avail);
29.2021 + doublesToBytes(v, off, buf, pos, chunklen);
29.2022 + off += chunklen;
29.2023 + pos += chunklen << 3;
29.2024 + } else {
29.2025 + dout.writeDouble(v[off++]);
29.2026 + }
29.2027 + }
29.2028 + }
29.2029 +
29.2030 + /**
29.2031 + * Returns the length in bytes of the UTF encoding of the given string.
29.2032 + */
29.2033 + long getUTFLength(String s) {
29.2034 + int len = s.length();
29.2035 + long utflen = 0;
29.2036 + for (int off = 0; off < len; ) {
29.2037 + int csize = Math.min(len - off, CHAR_BUF_SIZE);
29.2038 + s.getChars(off, off + csize, cbuf, 0);
29.2039 + for (int cpos = 0; cpos < csize; cpos++) {
29.2040 + char c = cbuf[cpos];
29.2041 + if (c >= 0x0001 && c <= 0x007F) {
29.2042 + utflen++;
29.2043 + } else if (c > 0x07FF) {
29.2044 + utflen += 3;
29.2045 + } else {
29.2046 + utflen += 2;
29.2047 + }
29.2048 + }
29.2049 + off += csize;
29.2050 + }
29.2051 + return utflen;
29.2052 + }
29.2053 +
29.2054 + /**
29.2055 + * Writes the given string in UTF format. This method is used in
29.2056 + * situations where the UTF encoding length of the string is already
29.2057 + * known; specifying it explicitly avoids a prescan of the string to
29.2058 + * determine its UTF length.
29.2059 + */
29.2060 + void writeUTF(String s, long utflen) throws IOException {
29.2061 + if (utflen > 0xFFFFL) {
29.2062 + throw new UTFDataFormatException();
29.2063 + }
29.2064 + writeShort((int) utflen);
29.2065 + if (utflen == (long) s.length()) {
29.2066 + writeBytes(s);
29.2067 + } else {
29.2068 + writeUTFBody(s);
29.2069 + }
29.2070 + }
29.2071 +
29.2072 + /**
29.2073 + * Writes given string in "long" UTF format. "Long" UTF format is
29.2074 + * identical to standard UTF, except that it uses an 8 byte header
29.2075 + * (instead of the standard 2 bytes) to convey the UTF encoding length.
29.2076 + */
29.2077 + void writeLongUTF(String s) throws IOException {
29.2078 + writeLongUTF(s, getUTFLength(s));
29.2079 + }
29.2080 +
29.2081 + /**
29.2082 + * Writes given string in "long" UTF format, where the UTF encoding
29.2083 + * length of the string is already known.
29.2084 + */
29.2085 + void writeLongUTF(String s, long utflen) throws IOException {
29.2086 + writeLong(utflen);
29.2087 + if (utflen == (long) s.length()) {
29.2088 + writeBytes(s);
29.2089 + } else {
29.2090 + writeUTFBody(s);
29.2091 + }
29.2092 + }
29.2093 +
29.2094 + /**
29.2095 + * Writes the "body" (i.e., the UTF representation minus the 2-byte or
29.2096 + * 8-byte length header) of the UTF encoding for the given string.
29.2097 + */
29.2098 + private void writeUTFBody(String s) throws IOException {
29.2099 + int limit = MAX_BLOCK_SIZE - 3;
29.2100 + int len = s.length();
29.2101 + for (int off = 0; off < len; ) {
29.2102 + int csize = Math.min(len - off, CHAR_BUF_SIZE);
29.2103 + s.getChars(off, off + csize, cbuf, 0);
29.2104 + for (int cpos = 0; cpos < csize; cpos++) {
29.2105 + char c = cbuf[cpos];
29.2106 + if (pos <= limit) {
29.2107 + if (c <= 0x007F && c != 0) {
29.2108 + buf[pos++] = (byte) c;
29.2109 + } else if (c > 0x07FF) {
29.2110 + buf[pos + 2] = (byte) (0x80 | ((c >> 0) & 0x3F));
29.2111 + buf[pos + 1] = (byte) (0x80 | ((c >> 6) & 0x3F));
29.2112 + buf[pos + 0] = (byte) (0xE0 | ((c >> 12) & 0x0F));
29.2113 + pos += 3;
29.2114 + } else {
29.2115 + buf[pos + 1] = (byte) (0x80 | ((c >> 0) & 0x3F));
29.2116 + buf[pos + 0] = (byte) (0xC0 | ((c >> 6) & 0x1F));
29.2117 + pos += 2;
29.2118 + }
29.2119 + } else { // write one byte at a time to normalize block
29.2120 + if (c <= 0x007F && c != 0) {
29.2121 + write(c);
29.2122 + } else if (c > 0x07FF) {
29.2123 + write(0xE0 | ((c >> 12) & 0x0F));
29.2124 + write(0x80 | ((c >> 6) & 0x3F));
29.2125 + write(0x80 | ((c >> 0) & 0x3F));
29.2126 + } else {
29.2127 + write(0xC0 | ((c >> 6) & 0x1F));
29.2128 + write(0x80 | ((c >> 0) & 0x3F));
29.2129 + }
29.2130 + }
29.2131 + }
29.2132 + off += csize;
29.2133 + }
29.2134 + }
29.2135 + }
29.2136 +
29.2137 + /**
29.2138 + * Lightweight identity hash table which maps objects to integer handles,
29.2139 + * assigned in ascending order.
29.2140 + */
29.2141 + private static class HandleTable {
29.2142 +
29.2143 + /* number of mappings in table/next available handle */
29.2144 + private int size;
29.2145 + /* size threshold determining when to expand hash spine */
29.2146 + private int threshold;
29.2147 + /* factor for computing size threshold */
29.2148 + private final float loadFactor;
29.2149 + /* maps hash value -> candidate handle value */
29.2150 + private int[] spine;
29.2151 + /* maps handle value -> next candidate handle value */
29.2152 + private int[] next;
29.2153 + /* maps handle value -> associated object */
29.2154 + private Object[] objs;
29.2155 +
29.2156 + /**
29.2157 + * Creates new HandleTable with given capacity and load factor.
29.2158 + */
29.2159 + HandleTable(int initialCapacity, float loadFactor) {
29.2160 + this.loadFactor = loadFactor;
29.2161 + spine = new int[initialCapacity];
29.2162 + next = new int[initialCapacity];
29.2163 + objs = new Object[initialCapacity];
29.2164 + threshold = (int) (initialCapacity * loadFactor);
29.2165 + clear();
29.2166 + }
29.2167 +
29.2168 + /**
29.2169 + * Assigns next available handle to given object, and returns handle
29.2170 + * value. Handles are assigned in ascending order starting at 0.
29.2171 + */
29.2172 + int assign(Object obj) {
29.2173 + if (size >= next.length) {
29.2174 + growEntries();
29.2175 + }
29.2176 + if (size >= threshold) {
29.2177 + growSpine();
29.2178 + }
29.2179 + insert(obj, size);
29.2180 + return size++;
29.2181 + }
29.2182 +
29.2183 + /**
29.2184 + * Looks up and returns handle associated with given object, or -1 if
29.2185 + * no mapping found.
29.2186 + */
29.2187 + int lookup(Object obj) {
29.2188 + if (size == 0) {
29.2189 + return -1;
29.2190 + }
29.2191 + int index = hash(obj) % spine.length;
29.2192 + for (int i = spine[index]; i >= 0; i = next[i]) {
29.2193 + if (objs[i] == obj) {
29.2194 + return i;
29.2195 + }
29.2196 + }
29.2197 + return -1;
29.2198 + }
29.2199 +
29.2200 + /**
29.2201 + * Resets table to its initial (empty) state.
29.2202 + */
29.2203 + void clear() {
29.2204 + Arrays.fill(spine, -1);
29.2205 + Arrays.fill(objs, 0, size, null);
29.2206 + size = 0;
29.2207 + }
29.2208 +
29.2209 + /**
29.2210 + * Returns the number of mappings currently in table.
29.2211 + */
29.2212 + int size() {
29.2213 + return size;
29.2214 + }
29.2215 +
29.2216 + /**
29.2217 + * Inserts mapping object -> handle mapping into table. Assumes table
29.2218 + * is large enough to accommodate new mapping.
29.2219 + */
29.2220 + private void insert(Object obj, int handle) {
29.2221 + int index = hash(obj) % spine.length;
29.2222 + objs[handle] = obj;
29.2223 + next[handle] = spine[index];
29.2224 + spine[index] = handle;
29.2225 + }
29.2226 +
29.2227 + /**
29.2228 + * Expands the hash "spine" -- equivalent to increasing the number of
29.2229 + * buckets in a conventional hash table.
29.2230 + */
29.2231 + private void growSpine() {
29.2232 + spine = new int[(spine.length << 1) + 1];
29.2233 + threshold = (int) (spine.length * loadFactor);
29.2234 + Arrays.fill(spine, -1);
29.2235 + for (int i = 0; i < size; i++) {
29.2236 + insert(objs[i], i);
29.2237 + }
29.2238 + }
29.2239 +
29.2240 + /**
29.2241 + * Increases hash table capacity by lengthening entry arrays.
29.2242 + */
29.2243 + private void growEntries() {
29.2244 + int newLength = (next.length << 1) + 1;
29.2245 + int[] newNext = new int[newLength];
29.2246 + System.arraycopy(next, 0, newNext, 0, size);
29.2247 + next = newNext;
29.2248 +
29.2249 + Object[] newObjs = new Object[newLength];
29.2250 + System.arraycopy(objs, 0, newObjs, 0, size);
29.2251 + objs = newObjs;
29.2252 + }
29.2253 +
29.2254 + /**
29.2255 + * Returns hash value for given object.
29.2256 + */
29.2257 + private int hash(Object obj) {
29.2258 + return System.identityHashCode(obj) & 0x7FFFFFFF;
29.2259 + }
29.2260 + }
29.2261 +
29.2262 + /**
29.2263 + * Lightweight identity hash table which maps objects to replacement
29.2264 + * objects.
29.2265 + */
29.2266 + private static class ReplaceTable {
29.2267 +
29.2268 + /* maps object -> index */
29.2269 + private final HandleTable htab;
29.2270 + /* maps index -> replacement object */
29.2271 + private Object[] reps;
29.2272 +
29.2273 + /**
29.2274 + * Creates new ReplaceTable with given capacity and load factor.
29.2275 + */
29.2276 + ReplaceTable(int initialCapacity, float loadFactor) {
29.2277 + htab = new HandleTable(initialCapacity, loadFactor);
29.2278 + reps = new Object[initialCapacity];
29.2279 + }
29.2280 +
29.2281 + /**
29.2282 + * Enters mapping from object to replacement object.
29.2283 + */
29.2284 + void assign(Object obj, Object rep) {
29.2285 + int index = htab.assign(obj);
29.2286 + while (index >= reps.length) {
29.2287 + grow();
29.2288 + }
29.2289 + reps[index] = rep;
29.2290 + }
29.2291 +
29.2292 + /**
29.2293 + * Looks up and returns replacement for given object. If no
29.2294 + * replacement is found, returns the lookup object itself.
29.2295 + */
29.2296 + Object lookup(Object obj) {
29.2297 + int index = htab.lookup(obj);
29.2298 + return (index >= 0) ? reps[index] : obj;
29.2299 + }
29.2300 +
29.2301 + /**
29.2302 + * Resets table to its initial (empty) state.
29.2303 + */
29.2304 + void clear() {
29.2305 + Arrays.fill(reps, 0, htab.size(), null);
29.2306 + htab.clear();
29.2307 + }
29.2308 +
29.2309 + /**
29.2310 + * Returns the number of mappings currently in table.
29.2311 + */
29.2312 + int size() {
29.2313 + return htab.size();
29.2314 + }
29.2315 +
29.2316 + /**
29.2317 + * Increases table capacity.
29.2318 + */
29.2319 + private void grow() {
29.2320 + Object[] newReps = new Object[(reps.length << 1) + 1];
29.2321 + System.arraycopy(reps, 0, newReps, 0, reps.length);
29.2322 + reps = newReps;
29.2323 + }
29.2324 + }
29.2325 +
29.2326 + /**
29.2327 + * Stack to keep debug information about the state of the
29.2328 + * serialization process, for embedding in exception messages.
29.2329 + */
29.2330 + private static class DebugTraceInfoStack {
29.2331 + private final List<String> stack;
29.2332 +
29.2333 + DebugTraceInfoStack() {
29.2334 + stack = new ArrayList<>();
29.2335 + }
29.2336 +
29.2337 + /**
29.2338 + * Removes all of the elements from enclosed list.
29.2339 + */
29.2340 + void clear() {
29.2341 + stack.clear();
29.2342 + }
29.2343 +
29.2344 + /**
29.2345 + * Removes the object at the top of enclosed list.
29.2346 + */
29.2347 + void pop() {
29.2348 + stack.remove(stack.size()-1);
29.2349 + }
29.2350 +
29.2351 + /**
29.2352 + * Pushes a String onto the top of enclosed list.
29.2353 + */
29.2354 + void push(String entry) {
29.2355 + stack.add("\t- " + entry);
29.2356 + }
29.2357 +
29.2358 + /**
29.2359 + * Returns a string representation of this object
29.2360 + */
29.2361 + public String toString() {
29.2362 + StringBuilder buffer = new StringBuilder();
29.2363 + if (!stack.isEmpty()) {
29.2364 + for(int i = stack.size(); i > 0; i-- ) {
29.2365 + buffer.append(stack.get(i-1) + ((i != 1) ? "\n" : ""));
29.2366 + }
29.2367 + }
29.2368 + return buffer.toString();
29.2369 + }
29.2370 + }
29.2371 +
29.2372 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamClass.java Tue Feb 05 17:04:22 2013 +0100
30.3 @@ -0,0 +1,1396 @@
30.4 +/*
30.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.7 + *
30.8 + * This code is free software; you can redistribute it and/or modify it
30.9 + * under the terms of the GNU General Public License version 2 only, as
30.10 + * published by the Free Software Foundation. Oracle designates this
30.11 + * particular file as subject to the "Classpath" exception as provided
30.12 + * by Oracle in the LICENSE file that accompanied this code.
30.13 + *
30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30.17 + * version 2 for more details (a copy is included in the LICENSE file that
30.18 + * accompanied this code).
30.19 + *
30.20 + * You should have received a copy of the GNU General Public License version
30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30.23 + *
30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
30.25 + * or visit www.oracle.com if you need additional information or have any
30.26 + * questions.
30.27 + */
30.28 +
30.29 +package java.io;
30.30 +
30.31 +import java.lang.ref.Reference;
30.32 +import java.lang.ref.ReferenceQueue;
30.33 +import java.lang.ref.SoftReference;
30.34 +import java.lang.ref.WeakReference;
30.35 +import java.lang.reflect.Constructor;
30.36 +import java.lang.reflect.Field;
30.37 +import java.lang.reflect.InvocationTargetException;
30.38 +import java.lang.reflect.Member;
30.39 +import java.lang.reflect.Method;
30.40 +import java.lang.reflect.Modifier;
30.41 +import java.lang.reflect.Proxy;
30.42 +import java.util.ArrayList;
30.43 +import java.util.Arrays;
30.44 +import java.util.Collections;
30.45 +import java.util.Comparator;
30.46 +import java.util.HashSet;
30.47 +import java.util.Set;
30.48 +
30.49 +/**
30.50 + * Serialization's descriptor for classes. It contains the name and
30.51 + * serialVersionUID of the class. The ObjectStreamClass for a specific class
30.52 + * loaded in this Java VM can be found/created using the lookup method.
30.53 + *
30.54 + * <p>The algorithm to compute the SerialVersionUID is described in
30.55 + * <a href="../../../platform/serialization/spec/class.html#4100">Object
30.56 + * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
30.57 + *
30.58 + * @author Mike Warres
30.59 + * @author Roger Riggs
30.60 + * @see ObjectStreamField
30.61 + * @see <a href="../../../platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
30.62 + * @since JDK1.1
30.63 + */
30.64 +public class ObjectStreamClass implements Serializable {
30.65 +
30.66 + /** serialPersistentFields value indicating no serializable fields */
30.67 + public static final ObjectStreamField[] NO_FIELDS =
30.68 + new ObjectStreamField[0];
30.69 +
30.70 + private static final long serialVersionUID = -6120832682080437368L;
30.71 + private static final ObjectStreamField[] serialPersistentFields =
30.72 + NO_FIELDS;
30.73 +
30.74 +
30.75 + /** class associated with this descriptor (if any) */
30.76 + private Class<?> cl;
30.77 + /** name of class represented by this descriptor */
30.78 + private String name;
30.79 + /** serialVersionUID of represented class (null if not computed yet) */
30.80 + private volatile Long suid;
30.81 +
30.82 + /** true if represents dynamic proxy class */
30.83 + private boolean isProxy;
30.84 + /** true if represents enum type */
30.85 + private boolean isEnum;
30.86 + /** true if represented class implements Serializable */
30.87 + private boolean serializable;
30.88 + /** true if represented class implements Externalizable */
30.89 + private boolean externalizable;
30.90 + /** true if desc has data written by class-defined writeObject method */
30.91 + private boolean hasWriteObjectData;
30.92 + /**
30.93 + * true if desc has externalizable data written in block data format; this
30.94 + * must be true by default to accommodate ObjectInputStream subclasses which
30.95 + * override readClassDescriptor() to return class descriptors obtained from
30.96 + * ObjectStreamClass.lookup() (see 4461737)
30.97 + */
30.98 + private boolean hasBlockExternalData = true;
30.99 +
30.100 + /** exception (if any) thrown while attempting to resolve class */
30.101 + private ClassNotFoundException resolveEx;
30.102 + /** exception (if any) to throw if non-enum deserialization attempted */
30.103 + private InvalidClassException deserializeEx;
30.104 + /** exception (if any) to throw if non-enum serialization attempted */
30.105 + private InvalidClassException serializeEx;
30.106 + /** exception (if any) to throw if default serialization attempted */
30.107 + private InvalidClassException defaultSerializeEx;
30.108 +
30.109 + /** serializable fields */
30.110 + private ObjectStreamField[] fields;
30.111 + /** aggregate marshalled size of primitive fields */
30.112 + private int primDataSize;
30.113 + /** number of non-primitive fields */
30.114 + private int numObjFields;
30.115 + /** reflector for setting/getting serializable field values */
30.116 +// private FieldReflector fieldRefl;
30.117 + /** data layout of serialized objects described by this class desc */
30.118 + private volatile ClassDataSlot[] dataLayout;
30.119 +
30.120 + /** serialization-appropriate constructor, or null if none */
30.121 + private Constructor cons;
30.122 + /** class-defined writeObject method, or null if none */
30.123 + private Method writeObjectMethod;
30.124 + /** class-defined readObject method, or null if none */
30.125 + private Method readObjectMethod;
30.126 + /** class-defined readObjectNoData method, or null if none */
30.127 + private Method readObjectNoDataMethod;
30.128 + /** class-defined writeReplace method, or null if none */
30.129 + private Method writeReplaceMethod;
30.130 + /** class-defined readResolve method, or null if none */
30.131 + private Method readResolveMethod;
30.132 +
30.133 + /** local class descriptor for represented class (may point to self) */
30.134 + private ObjectStreamClass localDesc;
30.135 + /** superclass descriptor appearing in stream */
30.136 + private ObjectStreamClass superDesc;
30.137 +
30.138 + /**
30.139 + * Initializes native code.
30.140 + */
30.141 + private static native void initNative();
30.142 + static {
30.143 + initNative();
30.144 + }
30.145 +
30.146 + /**
30.147 + * Find the descriptor for a class that can be serialized. Creates an
30.148 + * ObjectStreamClass instance if one does not exist yet for class. Null is
30.149 + * returned if the specified class does not implement java.io.Serializable
30.150 + * or java.io.Externalizable.
30.151 + *
30.152 + * @param cl class for which to get the descriptor
30.153 + * @return the class descriptor for the specified class
30.154 + */
30.155 + public static ObjectStreamClass lookup(Class<?> cl) {
30.156 + return lookup(cl, false);
30.157 + }
30.158 +
30.159 + /**
30.160 + * Returns the descriptor for any class, regardless of whether it
30.161 + * implements {@link Serializable}.
30.162 + *
30.163 + * @param cl class for which to get the descriptor
30.164 + * @return the class descriptor for the specified class
30.165 + * @since 1.6
30.166 + */
30.167 + public static ObjectStreamClass lookupAny(Class<?> cl) {
30.168 + return lookup(cl, true);
30.169 + }
30.170 +
30.171 + /**
30.172 + * Returns the name of the class described by this descriptor.
30.173 + * This method returns the name of the class in the format that
30.174 + * is used by the {@link Class#getName} method.
30.175 + *
30.176 + * @return a string representing the name of the class
30.177 + */
30.178 + public String getName() {
30.179 + return name;
30.180 + }
30.181 +
30.182 + /**
30.183 + * Return the serialVersionUID for this class. The serialVersionUID
30.184 + * defines a set of classes all with the same name that have evolved from a
30.185 + * common root class and agree to be serialized and deserialized using a
30.186 + * common format. NonSerializable classes have a serialVersionUID of 0L.
30.187 + *
30.188 + * @return the SUID of the class described by this descriptor
30.189 + */
30.190 + public long getSerialVersionUID() {
30.191 + // REMIND: synchronize instead of relying on volatile?
30.192 + if (suid == null) {
30.193 + return computeDefaultSUID(cl);
30.194 + }
30.195 + return suid.longValue();
30.196 + }
30.197 +
30.198 + /**
30.199 + * Return the class in the local VM that this version is mapped to. Null
30.200 + * is returned if there is no corresponding local class.
30.201 + *
30.202 + * @return the <code>Class</code> instance that this descriptor represents
30.203 + */
30.204 + public Class<?> forClass() {
30.205 + return cl;
30.206 + }
30.207 +
30.208 + /**
30.209 + * Return an array of the fields of this serializable class.
30.210 + *
30.211 + * @return an array containing an element for each persistent field of
30.212 + * this class. Returns an array of length zero if there are no
30.213 + * fields.
30.214 + * @since 1.2
30.215 + */
30.216 + public ObjectStreamField[] getFields() {
30.217 + return getFields(true);
30.218 + }
30.219 +
30.220 + /**
30.221 + * Get the field of this class by name.
30.222 + *
30.223 + * @param name the name of the data field to look for
30.224 + * @return The ObjectStreamField object of the named field or null if
30.225 + * there is no such named field.
30.226 + */
30.227 + public ObjectStreamField getField(String name) {
30.228 + return getField(name, null);
30.229 + }
30.230 +
30.231 + /**
30.232 + * Return a string describing this ObjectStreamClass.
30.233 + */
30.234 + public String toString() {
30.235 + return name + ": static final long serialVersionUID = " +
30.236 + getSerialVersionUID() + "L;";
30.237 + }
30.238 +
30.239 + /**
30.240 + * Looks up and returns class descriptor for given class, or null if class
30.241 + * is non-serializable and "all" is set to false.
30.242 + *
30.243 + * @param cl class to look up
30.244 + * @param all if true, return descriptors for all classes; if false, only
30.245 + * return descriptors for serializable classes
30.246 + */
30.247 + static ObjectStreamClass lookup(Class<?> cl, boolean all) {
30.248 + if (!(all || Serializable.class.isAssignableFrom(cl))) {
30.249 + return null;
30.250 + }
30.251 + Object entry = null;
30.252 + EntryFuture future = null;
30.253 + if (entry == null) {
30.254 + EntryFuture newEntry = new EntryFuture();
30.255 + Reference<?> newRef = new SoftReference<>(newEntry);
30.256 + if (entry == null) {
30.257 + future = newEntry;
30.258 + }
30.259 + }
30.260 +
30.261 + if (entry instanceof ObjectStreamClass) { // check common case first
30.262 + return (ObjectStreamClass) entry;
30.263 + }
30.264 + if (entry instanceof EntryFuture) {
30.265 + future = (EntryFuture) entry;
30.266 + if (true) {
30.267 + /*
30.268 + * Handle nested call situation described by 4803747: waiting
30.269 + * for future value to be set by a lookup() call further up the
30.270 + * stack will result in deadlock, so calculate and set the
30.271 + * future value here instead.
30.272 + */
30.273 + entry = null;
30.274 + } else {
30.275 + entry = future.get();
30.276 + }
30.277 + }
30.278 + if (entry == null) {
30.279 + try {
30.280 + entry = new ObjectStreamClass(cl);
30.281 + } catch (Throwable th) {
30.282 + entry = th;
30.283 + }
30.284 + // nested lookup call already set future
30.285 + entry = future.get();
30.286 + }
30.287 +
30.288 + if (entry instanceof ObjectStreamClass) {
30.289 + return (ObjectStreamClass) entry;
30.290 + } else if (entry instanceof RuntimeException) {
30.291 + throw (RuntimeException) entry;
30.292 + } else if (entry instanceof Error) {
30.293 + throw (Error) entry;
30.294 + } else {
30.295 + throw new InternalError("unexpected entry: " + entry);
30.296 + }
30.297 + }
30.298 +
30.299 + /**
30.300 + * Placeholder used in class descriptor and field reflector lookup tables
30.301 + * for an entry in the process of being initialized. (Internal) callers
30.302 + * which receive an EntryFuture belonging to another thread as the result
30.303 + * of a lookup should call the get() method of the EntryFuture; this will
30.304 + * return the actual entry once it is ready for use and has been set(). To
30.305 + * conserve objects, EntryFutures synchronize on themselves.
30.306 + */
30.307 + private static class EntryFuture {
30.308 +
30.309 + private static final Object unset = new Object();
30.310 + private Object entry = unset;
30.311 +
30.312 + /**
30.313 + * Attempts to set the value contained by this EntryFuture. If the
30.314 + * EntryFuture's value has not been set already, then the value is
30.315 + * saved, any callers blocked in the get() method are notified, and
30.316 + * true is returned. If the value has already been set, then no saving
30.317 + * or notification occurs, and false is returned.
30.318 + */
30.319 + synchronized boolean set(Object entry) {
30.320 + if (this.entry != unset) {
30.321 + return false;
30.322 + }
30.323 + this.entry = entry;
30.324 + notifyAll();
30.325 + return true;
30.326 + }
30.327 +
30.328 + /**
30.329 + * Returns the value contained by this EntryFuture, blocking if
30.330 + * necessary until a value is set.
30.331 + */
30.332 + synchronized Object get() {
30.333 + boolean interrupted = false;
30.334 + while (entry == unset) {
30.335 + try {
30.336 + wait();
30.337 + } catch (InterruptedException ex) {
30.338 + interrupted = true;
30.339 + }
30.340 + }
30.341 + return entry;
30.342 + }
30.343 + }
30.344 +
30.345 + /**
30.346 + * Creates local class descriptor representing given class.
30.347 + */
30.348 + private ObjectStreamClass(final Class<?> cl) {
30.349 + this.cl = cl;
30.350 + name = cl.getName();
30.351 + isProxy = Proxy.isProxyClass(cl);
30.352 + isEnum = Enum.class.isAssignableFrom(cl);
30.353 + serializable = Serializable.class.isAssignableFrom(cl);
30.354 + externalizable = Externalizable.class.isAssignableFrom(cl);
30.355 +
30.356 + Class<?> superCl = cl.getSuperclass();
30.357 + superDesc = (superCl != null) ? lookup(superCl, false) : null;
30.358 + localDesc = this;
30.359 +
30.360 + suid = Long.valueOf(0);
30.361 + fields = NO_FIELDS;
30.362 +
30.363 +
30.364 + if (deserializeEx == null) {
30.365 + if (isEnum) {
30.366 + deserializeEx = new InvalidClassException(name, "enum type");
30.367 + } else if (cons == null) {
30.368 + deserializeEx = new InvalidClassException(
30.369 + name, "no valid constructor");
30.370 + }
30.371 + }
30.372 + for (int i = 0; i < fields.length; i++) {
30.373 + if (fields[i].getField() == null) {
30.374 + defaultSerializeEx = new InvalidClassException(
30.375 + name, "unmatched serializable field(s) declared");
30.376 + }
30.377 + }
30.378 + }
30.379 +
30.380 + /**
30.381 + * Creates blank class descriptor which should be initialized via a
30.382 + * subsequent call to initProxy(), initNonProxy() or readNonProxy().
30.383 + */
30.384 + ObjectStreamClass() {
30.385 + }
30.386 +
30.387 + /**
30.388 + * Initializes class descriptor representing a proxy class.
30.389 + */
30.390 + void initProxy(Class<?> cl,
30.391 + ClassNotFoundException resolveEx,
30.392 + ObjectStreamClass superDesc)
30.393 + throws InvalidClassException
30.394 + {
30.395 + this.cl = cl;
30.396 + this.resolveEx = resolveEx;
30.397 + this.superDesc = superDesc;
30.398 + isProxy = true;
30.399 + serializable = true;
30.400 + suid = Long.valueOf(0);
30.401 + fields = NO_FIELDS;
30.402 +
30.403 + if (cl != null) {
30.404 + localDesc = lookup(cl, true);
30.405 + if (!localDesc.isProxy) {
30.406 + throw new InvalidClassException(
30.407 + "cannot bind proxy descriptor to a non-proxy class");
30.408 + }
30.409 + name = localDesc.name;
30.410 + externalizable = localDesc.externalizable;
30.411 + cons = localDesc.cons;
30.412 + writeReplaceMethod = localDesc.writeReplaceMethod;
30.413 + readResolveMethod = localDesc.readResolveMethod;
30.414 + deserializeEx = localDesc.deserializeEx;
30.415 + }
30.416 + }
30.417 +
30.418 + /**
30.419 + * Initializes class descriptor representing a non-proxy class.
30.420 + */
30.421 + void initNonProxy(ObjectStreamClass model,
30.422 + Class<?> cl,
30.423 + ClassNotFoundException resolveEx,
30.424 + ObjectStreamClass superDesc)
30.425 + throws InvalidClassException
30.426 + {
30.427 + this.cl = cl;
30.428 + this.resolveEx = resolveEx;
30.429 + this.superDesc = superDesc;
30.430 + name = model.name;
30.431 + suid = Long.valueOf(model.getSerialVersionUID());
30.432 + isProxy = false;
30.433 + isEnum = model.isEnum;
30.434 + serializable = model.serializable;
30.435 + externalizable = model.externalizable;
30.436 + hasBlockExternalData = model.hasBlockExternalData;
30.437 + hasWriteObjectData = model.hasWriteObjectData;
30.438 + fields = model.fields;
30.439 + primDataSize = model.primDataSize;
30.440 + numObjFields = model.numObjFields;
30.441 +
30.442 + if (cl != null) {
30.443 + localDesc = lookup(cl, true);
30.444 + if (localDesc.isProxy) {
30.445 + throw new InvalidClassException(
30.446 + "cannot bind non-proxy descriptor to a proxy class");
30.447 + }
30.448 + if (isEnum != localDesc.isEnum) {
30.449 + throw new InvalidClassException(isEnum ?
30.450 + "cannot bind enum descriptor to a non-enum class" :
30.451 + "cannot bind non-enum descriptor to an enum class");
30.452 + }
30.453 +
30.454 + if (serializable == localDesc.serializable &&
30.455 + !cl.isArray() &&
30.456 + suid.longValue() != localDesc.getSerialVersionUID())
30.457 + {
30.458 + throw new InvalidClassException(localDesc.name,
30.459 + "local class incompatible: " +
30.460 + "stream classdesc serialVersionUID = " + suid +
30.461 + ", local class serialVersionUID = " +
30.462 + localDesc.getSerialVersionUID());
30.463 + }
30.464 +
30.465 + if (!classNamesEqual(name, localDesc.name)) {
30.466 + throw new InvalidClassException(localDesc.name,
30.467 + "local class name incompatible with stream class " +
30.468 + "name \"" + name + "\"");
30.469 + }
30.470 +
30.471 + if (!isEnum) {
30.472 + if ((serializable == localDesc.serializable) &&
30.473 + (externalizable != localDesc.externalizable))
30.474 + {
30.475 + throw new InvalidClassException(localDesc.name,
30.476 + "Serializable incompatible with Externalizable");
30.477 + }
30.478 +
30.479 + if ((serializable != localDesc.serializable) ||
30.480 + (externalizable != localDesc.externalizable) ||
30.481 + !(serializable || externalizable))
30.482 + {
30.483 + deserializeEx = new InvalidClassException(localDesc.name,
30.484 + "class invalid for deserialization");
30.485 + }
30.486 + }
30.487 +
30.488 + cons = localDesc.cons;
30.489 + writeObjectMethod = localDesc.writeObjectMethod;
30.490 + readObjectMethod = localDesc.readObjectMethod;
30.491 + readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
30.492 + writeReplaceMethod = localDesc.writeReplaceMethod;
30.493 + readResolveMethod = localDesc.readResolveMethod;
30.494 + if (deserializeEx == null) {
30.495 + deserializeEx = localDesc.deserializeEx;
30.496 + }
30.497 + }
30.498 + // reassign to matched fields so as to reflect local unshared settings
30.499 + fields = null;
30.500 + }
30.501 +
30.502 + /**
30.503 + * Reads non-proxy class descriptor information from given input stream.
30.504 + * The resulting class descriptor is not fully functional; it can only be
30.505 + * used as input to the ObjectInputStream.resolveClass() and
30.506 + * ObjectStreamClass.initNonProxy() methods.
30.507 + */
30.508 + void readNonProxy(ObjectInputStream in)
30.509 + throws IOException, ClassNotFoundException
30.510 + {
30.511 + name = in.readUTF();
30.512 + suid = Long.valueOf(in.readLong());
30.513 + isProxy = false;
30.514 +
30.515 + byte flags = in.readByte();
30.516 + hasWriteObjectData =
30.517 + ((flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0);
30.518 + hasBlockExternalData =
30.519 + ((flags & ObjectStreamConstants.SC_BLOCK_DATA) != 0);
30.520 + externalizable =
30.521 + ((flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0);
30.522 + boolean sflag =
30.523 + ((flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0);
30.524 + if (externalizable && sflag) {
30.525 + throw new InvalidClassException(
30.526 + name, "serializable and externalizable flags conflict");
30.527 + }
30.528 + serializable = externalizable || sflag;
30.529 + isEnum = ((flags & ObjectStreamConstants.SC_ENUM) != 0);
30.530 + if (isEnum && suid.longValue() != 0L) {
30.531 + throw new InvalidClassException(name,
30.532 + "enum descriptor has non-zero serialVersionUID: " + suid);
30.533 + }
30.534 +
30.535 + int numFields = in.readShort();
30.536 + if (isEnum && numFields != 0) {
30.537 + throw new InvalidClassException(name,
30.538 + "enum descriptor has non-zero field count: " + numFields);
30.539 + }
30.540 + fields = (numFields > 0) ?
30.541 + new ObjectStreamField[numFields] : NO_FIELDS;
30.542 + for (int i = 0; i < numFields; i++) {
30.543 + char tcode = (char) in.readByte();
30.544 + String fname = in.readUTF();
30.545 + String signature = ((tcode == 'L') || (tcode == '[')) ?
30.546 + in.readTypeString() : new String(new char[] { tcode });
30.547 + try {
30.548 + fields[i] = new ObjectStreamField(fname, signature, false);
30.549 + } catch (RuntimeException e) {
30.550 + throw (IOException) new InvalidClassException(name,
30.551 + "invalid descriptor for field " + fname).initCause(e);
30.552 + }
30.553 + }
30.554 + computeFieldOffsets();
30.555 + }
30.556 +
30.557 + /**
30.558 + * Writes non-proxy class descriptor information to given output stream.
30.559 + */
30.560 + void writeNonProxy(ObjectOutputStream out) throws IOException {
30.561 + out.writeUTF(name);
30.562 + out.writeLong(getSerialVersionUID());
30.563 +
30.564 + byte flags = 0;
30.565 + if (externalizable) {
30.566 + flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
30.567 + int protocol = out.getProtocolVersion();
30.568 + if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) {
30.569 + flags |= ObjectStreamConstants.SC_BLOCK_DATA;
30.570 + }
30.571 + } else if (serializable) {
30.572 + flags |= ObjectStreamConstants.SC_SERIALIZABLE;
30.573 + }
30.574 + if (hasWriteObjectData) {
30.575 + flags |= ObjectStreamConstants.SC_WRITE_METHOD;
30.576 + }
30.577 + if (isEnum) {
30.578 + flags |= ObjectStreamConstants.SC_ENUM;
30.579 + }
30.580 + out.writeByte(flags);
30.581 +
30.582 + out.writeShort(fields.length);
30.583 + for (int i = 0; i < fields.length; i++) {
30.584 + ObjectStreamField f = fields[i];
30.585 + out.writeByte(f.getTypeCode());
30.586 + out.writeUTF(f.getName());
30.587 + if (!f.isPrimitive()) {
30.588 + out.writeTypeString(f.getTypeString());
30.589 + }
30.590 + }
30.591 + }
30.592 +
30.593 + /**
30.594 + * Returns ClassNotFoundException (if any) thrown while attempting to
30.595 + * resolve local class corresponding to this class descriptor.
30.596 + */
30.597 + ClassNotFoundException getResolveException() {
30.598 + return resolveEx;
30.599 + }
30.600 +
30.601 + /**
30.602 + * Throws an InvalidClassException if object instances referencing this
30.603 + * class descriptor should not be allowed to deserialize. This method does
30.604 + * not apply to deserialization of enum constants.
30.605 + */
30.606 + void checkDeserialize() throws InvalidClassException {
30.607 + if (deserializeEx != null) {
30.608 + InvalidClassException ice =
30.609 + new InvalidClassException(deserializeEx.classname,
30.610 + deserializeEx.getMessage());
30.611 + ice.initCause(deserializeEx);
30.612 + throw ice;
30.613 + }
30.614 + }
30.615 +
30.616 + /**
30.617 + * Throws an InvalidClassException if objects whose class is represented by
30.618 + * this descriptor should not be allowed to serialize. This method does
30.619 + * not apply to serialization of enum constants.
30.620 + */
30.621 + void checkSerialize() throws InvalidClassException {
30.622 + if (serializeEx != null) {
30.623 + InvalidClassException ice =
30.624 + new InvalidClassException(serializeEx.classname,
30.625 + serializeEx.getMessage());
30.626 + ice.initCause(serializeEx);
30.627 + throw ice;
30.628 + }
30.629 + }
30.630 +
30.631 + /**
30.632 + * Throws an InvalidClassException if objects whose class is represented by
30.633 + * this descriptor should not be permitted to use default serialization
30.634 + * (e.g., if the class declares serializable fields that do not correspond
30.635 + * to actual fields, and hence must use the GetField API). This method
30.636 + * does not apply to deserialization of enum constants.
30.637 + */
30.638 + void checkDefaultSerialize() throws InvalidClassException {
30.639 + if (defaultSerializeEx != null) {
30.640 + InvalidClassException ice =
30.641 + new InvalidClassException(defaultSerializeEx.classname,
30.642 + defaultSerializeEx.getMessage());
30.643 + ice.initCause(defaultSerializeEx);
30.644 + throw ice;
30.645 + }
30.646 + }
30.647 +
30.648 + /**
30.649 + * Returns superclass descriptor. Note that on the receiving side, the
30.650 + * superclass descriptor may be bound to a class that is not a superclass
30.651 + * of the subclass descriptor's bound class.
30.652 + */
30.653 + ObjectStreamClass getSuperDesc() {
30.654 + return superDesc;
30.655 + }
30.656 +
30.657 + /**
30.658 + * Returns the "local" class descriptor for the class associated with this
30.659 + * class descriptor (i.e., the result of
30.660 + * ObjectStreamClass.lookup(this.forClass())) or null if there is no class
30.661 + * associated with this descriptor.
30.662 + */
30.663 + ObjectStreamClass getLocalDesc() {
30.664 + return localDesc;
30.665 + }
30.666 +
30.667 + /**
30.668 + * Returns arrays of ObjectStreamFields representing the serializable
30.669 + * fields of the represented class. If copy is true, a clone of this class
30.670 + * descriptor's field array is returned, otherwise the array itself is
30.671 + * returned.
30.672 + */
30.673 + ObjectStreamField[] getFields(boolean copy) {
30.674 + return copy ? fields.clone() : fields;
30.675 + }
30.676 +
30.677 + /**
30.678 + * Looks up a serializable field of the represented class by name and type.
30.679 + * A specified type of null matches all types, Object.class matches all
30.680 + * non-primitive types, and any other non-null type matches assignable
30.681 + * types only. Returns matching field, or null if no match found.
30.682 + */
30.683 + ObjectStreamField getField(String name, Class<?> type) {
30.684 + for (int i = 0; i < fields.length; i++) {
30.685 + ObjectStreamField f = fields[i];
30.686 + if (f.getName().equals(name)) {
30.687 + if (type == null ||
30.688 + (type == Object.class && !f.isPrimitive()))
30.689 + {
30.690 + return f;
30.691 + }
30.692 + Class<?> ftype = f.getType();
30.693 + if (ftype != null && type.isAssignableFrom(ftype)) {
30.694 + return f;
30.695 + }
30.696 + }
30.697 + }
30.698 + return null;
30.699 + }
30.700 +
30.701 + /**
30.702 + * Returns true if class descriptor represents a dynamic proxy class, false
30.703 + * otherwise.
30.704 + */
30.705 + boolean isProxy() {
30.706 + return isProxy;
30.707 + }
30.708 +
30.709 + /**
30.710 + * Returns true if class descriptor represents an enum type, false
30.711 + * otherwise.
30.712 + */
30.713 + boolean isEnum() {
30.714 + return isEnum;
30.715 + }
30.716 +
30.717 + /**
30.718 + * Returns true if represented class implements Externalizable, false
30.719 + * otherwise.
30.720 + */
30.721 + boolean isExternalizable() {
30.722 + return externalizable;
30.723 + }
30.724 +
30.725 + /**
30.726 + * Returns true if represented class implements Serializable, false
30.727 + * otherwise.
30.728 + */
30.729 + boolean isSerializable() {
30.730 + return serializable;
30.731 + }
30.732 +
30.733 + /**
30.734 + * Returns true if class descriptor represents externalizable class that
30.735 + * has written its data in 1.2 (block data) format, false otherwise.
30.736 + */
30.737 + boolean hasBlockExternalData() {
30.738 + return hasBlockExternalData;
30.739 + }
30.740 +
30.741 + /**
30.742 + * Returns true if class descriptor represents serializable (but not
30.743 + * externalizable) class which has written its data via a custom
30.744 + * writeObject() method, false otherwise.
30.745 + */
30.746 + boolean hasWriteObjectData() {
30.747 + return hasWriteObjectData;
30.748 + }
30.749 +
30.750 + /**
30.751 + * Returns true if represented class is serializable/externalizable and can
30.752 + * be instantiated by the serialization runtime--i.e., if it is
30.753 + * externalizable and defines a public no-arg constructor, or if it is
30.754 + * non-externalizable and its first non-serializable superclass defines an
30.755 + * accessible no-arg constructor. Otherwise, returns false.
30.756 + */
30.757 + boolean isInstantiable() {
30.758 + return (cons != null);
30.759 + }
30.760 +
30.761 + /**
30.762 + * Returns true if represented class is serializable (but not
30.763 + * externalizable) and defines a conformant writeObject method. Otherwise,
30.764 + * returns false.
30.765 + */
30.766 + boolean hasWriteObjectMethod() {
30.767 + return (writeObjectMethod != null);
30.768 + }
30.769 +
30.770 + /**
30.771 + * Returns true if represented class is serializable (but not
30.772 + * externalizable) and defines a conformant readObject method. Otherwise,
30.773 + * returns false.
30.774 + */
30.775 + boolean hasReadObjectMethod() {
30.776 + return (readObjectMethod != null);
30.777 + }
30.778 +
30.779 + /**
30.780 + * Returns true if represented class is serializable (but not
30.781 + * externalizable) and defines a conformant readObjectNoData method.
30.782 + * Otherwise, returns false.
30.783 + */
30.784 + boolean hasReadObjectNoDataMethod() {
30.785 + return (readObjectNoDataMethod != null);
30.786 + }
30.787 +
30.788 + /**
30.789 + * Returns true if represented class is serializable or externalizable and
30.790 + * defines a conformant writeReplace method. Otherwise, returns false.
30.791 + */
30.792 + boolean hasWriteReplaceMethod() {
30.793 + return (writeReplaceMethod != null);
30.794 + }
30.795 +
30.796 + /**
30.797 + * Returns true if represented class is serializable or externalizable and
30.798 + * defines a conformant readResolve method. Otherwise, returns false.
30.799 + */
30.800 + boolean hasReadResolveMethod() {
30.801 + return (readResolveMethod != null);
30.802 + }
30.803 +
30.804 + /**
30.805 + * Creates a new instance of the represented class. If the class is
30.806 + * externalizable, invokes its public no-arg constructor; otherwise, if the
30.807 + * class is serializable, invokes the no-arg constructor of the first
30.808 + * non-serializable superclass. Throws UnsupportedOperationException if
30.809 + * this class descriptor is not associated with a class, if the associated
30.810 + * class is non-serializable or if the appropriate no-arg constructor is
30.811 + * inaccessible/unavailable.
30.812 + */
30.813 + Object newInstance()
30.814 + throws InstantiationException, InvocationTargetException,
30.815 + UnsupportedOperationException
30.816 + {
30.817 + if (cons != null) {
30.818 + try {
30.819 + return cons.newInstance();
30.820 + } catch (IllegalAccessException ex) {
30.821 + // should not occur, as access checks have been suppressed
30.822 + throw new InternalError();
30.823 + }
30.824 + } else {
30.825 + throw new UnsupportedOperationException();
30.826 + }
30.827 + }
30.828 +
30.829 + /**
30.830 + * Invokes the writeObject method of the represented serializable class.
30.831 + * Throws UnsupportedOperationException if this class descriptor is not
30.832 + * associated with a class, or if the class is externalizable,
30.833 + * non-serializable or does not define writeObject.
30.834 + */
30.835 + void invokeWriteObject(Object obj, ObjectOutputStream out)
30.836 + throws IOException, UnsupportedOperationException
30.837 + {
30.838 + if (writeObjectMethod != null) {
30.839 + try {
30.840 + writeObjectMethod.invoke(obj, new Object[]{ out });
30.841 + } catch (InvocationTargetException ex) {
30.842 + Throwable th = ex.getTargetException();
30.843 + if (th instanceof IOException) {
30.844 + throw (IOException) th;
30.845 + } else {
30.846 + throwMiscException(th);
30.847 + }
30.848 + } catch (IllegalAccessException ex) {
30.849 + // should not occur, as access checks have been suppressed
30.850 + throw new InternalError();
30.851 + }
30.852 + } else {
30.853 + throw new UnsupportedOperationException();
30.854 + }
30.855 + }
30.856 +
30.857 + /**
30.858 + * Invokes the readObject method of the represented serializable class.
30.859 + * Throws UnsupportedOperationException if this class descriptor is not
30.860 + * associated with a class, or if the class is externalizable,
30.861 + * non-serializable or does not define readObject.
30.862 + */
30.863 + void invokeReadObject(Object obj, ObjectInputStream in)
30.864 + throws ClassNotFoundException, IOException,
30.865 + UnsupportedOperationException
30.866 + {
30.867 + if (readObjectMethod != null) {
30.868 + try {
30.869 + readObjectMethod.invoke(obj, new Object[]{ in });
30.870 + } catch (InvocationTargetException ex) {
30.871 + Throwable th = ex.getTargetException();
30.872 + if (th instanceof ClassNotFoundException) {
30.873 + throw (ClassNotFoundException) th;
30.874 + } else if (th instanceof IOException) {
30.875 + throw (IOException) th;
30.876 + } else {
30.877 + throwMiscException(th);
30.878 + }
30.879 + } catch (IllegalAccessException ex) {
30.880 + // should not occur, as access checks have been suppressed
30.881 + throw new InternalError();
30.882 + }
30.883 + } else {
30.884 + throw new UnsupportedOperationException();
30.885 + }
30.886 + }
30.887 +
30.888 + /**
30.889 + * Invokes the readObjectNoData method of the represented serializable
30.890 + * class. Throws UnsupportedOperationException if this class descriptor is
30.891 + * not associated with a class, or if the class is externalizable,
30.892 + * non-serializable or does not define readObjectNoData.
30.893 + */
30.894 + void invokeReadObjectNoData(Object obj)
30.895 + throws IOException, UnsupportedOperationException
30.896 + {
30.897 + if (readObjectNoDataMethod != null) {
30.898 + try {
30.899 + readObjectNoDataMethod.invoke(obj, (Object[]) null);
30.900 + } catch (InvocationTargetException ex) {
30.901 + Throwable th = ex.getTargetException();
30.902 + if (th instanceof ObjectStreamException) {
30.903 + throw (ObjectStreamException) th;
30.904 + } else {
30.905 + throwMiscException(th);
30.906 + }
30.907 + } catch (IllegalAccessException ex) {
30.908 + // should not occur, as access checks have been suppressed
30.909 + throw new InternalError();
30.910 + }
30.911 + } else {
30.912 + throw new UnsupportedOperationException();
30.913 + }
30.914 + }
30.915 +
30.916 + /**
30.917 + * Invokes the writeReplace method of the represented serializable class and
30.918 + * returns the result. Throws UnsupportedOperationException if this class
30.919 + * descriptor is not associated with a class, or if the class is
30.920 + * non-serializable or does not define writeReplace.
30.921 + */
30.922 + Object invokeWriteReplace(Object obj)
30.923 + throws IOException, UnsupportedOperationException
30.924 + {
30.925 + if (writeReplaceMethod != null) {
30.926 + try {
30.927 + return writeReplaceMethod.invoke(obj, (Object[]) null);
30.928 + } catch (InvocationTargetException ex) {
30.929 + Throwable th = ex.getTargetException();
30.930 + if (th instanceof ObjectStreamException) {
30.931 + throw (ObjectStreamException) th;
30.932 + } else {
30.933 + throwMiscException(th);
30.934 + throw new InternalError(); // never reached
30.935 + }
30.936 + } catch (IllegalAccessException ex) {
30.937 + // should not occur, as access checks have been suppressed
30.938 + throw new InternalError();
30.939 + }
30.940 + } else {
30.941 + throw new UnsupportedOperationException();
30.942 + }
30.943 + }
30.944 +
30.945 + /**
30.946 + * Invokes the readResolve method of the represented serializable class and
30.947 + * returns the result. Throws UnsupportedOperationException if this class
30.948 + * descriptor is not associated with a class, or if the class is
30.949 + * non-serializable or does not define readResolve.
30.950 + */
30.951 + Object invokeReadResolve(Object obj)
30.952 + throws IOException, UnsupportedOperationException
30.953 + {
30.954 + if (readResolveMethod != null) {
30.955 + try {
30.956 + return readResolveMethod.invoke(obj, (Object[]) null);
30.957 + } catch (InvocationTargetException ex) {
30.958 + Throwable th = ex.getTargetException();
30.959 + if (th instanceof ObjectStreamException) {
30.960 + throw (ObjectStreamException) th;
30.961 + } else {
30.962 + throwMiscException(th);
30.963 + throw new InternalError(); // never reached
30.964 + }
30.965 + } catch (IllegalAccessException ex) {
30.966 + // should not occur, as access checks have been suppressed
30.967 + throw new InternalError();
30.968 + }
30.969 + } else {
30.970 + throw new UnsupportedOperationException();
30.971 + }
30.972 + }
30.973 +
30.974 + /**
30.975 + * Class representing the portion of an object's serialized form allotted
30.976 + * to data described by a given class descriptor. If "hasData" is false,
30.977 + * the object's serialized form does not contain data associated with the
30.978 + * class descriptor.
30.979 + */
30.980 + static class ClassDataSlot {
30.981 +
30.982 + /** class descriptor "occupying" this slot */
30.983 + final ObjectStreamClass desc;
30.984 + /** true if serialized form includes data for this slot's descriptor */
30.985 + final boolean hasData;
30.986 +
30.987 + ClassDataSlot(ObjectStreamClass desc, boolean hasData) {
30.988 + this.desc = desc;
30.989 + this.hasData = hasData;
30.990 + }
30.991 + }
30.992 +
30.993 + /**
30.994 + * Returns array of ClassDataSlot instances representing the data layout
30.995 + * (including superclass data) for serialized objects described by this
30.996 + * class descriptor. ClassDataSlots are ordered by inheritance with those
30.997 + * containing "higher" superclasses appearing first. The final
30.998 + * ClassDataSlot contains a reference to this descriptor.
30.999 + */
30.1000 + ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
30.1001 + // REMIND: synchronize instead of relying on volatile?
30.1002 + if (dataLayout == null) {
30.1003 + dataLayout = getClassDataLayout0();
30.1004 + }
30.1005 + return dataLayout;
30.1006 + }
30.1007 +
30.1008 + private ClassDataSlot[] getClassDataLayout0()
30.1009 + throws InvalidClassException
30.1010 + {
30.1011 + ArrayList<ClassDataSlot> slots = new ArrayList<>();
30.1012 + Class<?> start = cl, end = cl;
30.1013 +
30.1014 + // locate closest non-serializable superclass
30.1015 + while (end != null && Serializable.class.isAssignableFrom(end)) {
30.1016 + end = end.getSuperclass();
30.1017 + }
30.1018 +
30.1019 + for (ObjectStreamClass d = this; d != null; d = d.superDesc) {
30.1020 +
30.1021 + // search up inheritance hierarchy for class with matching name
30.1022 + String searchName = (d.cl != null) ? d.cl.getName() : d.name;
30.1023 + Class<?> match = null;
30.1024 + for (Class<?> c = start; c != end; c = c.getSuperclass()) {
30.1025 + if (searchName.equals(c.getName())) {
30.1026 + match = c;
30.1027 + break;
30.1028 + }
30.1029 + }
30.1030 +
30.1031 + // add "no data" slot for each unmatched class below match
30.1032 + if (match != null) {
30.1033 + for (Class<?> c = start; c != match; c = c.getSuperclass()) {
30.1034 + slots.add(new ClassDataSlot(
30.1035 + ObjectStreamClass.lookup(c, true), false));
30.1036 + }
30.1037 + start = match.getSuperclass();
30.1038 + }
30.1039 +
30.1040 + // record descriptor/class pairing
30.1041 + slots.add(new ClassDataSlot(d.getVariantFor(match), true));
30.1042 + }
30.1043 +
30.1044 + // add "no data" slot for any leftover unmatched classes
30.1045 + for (Class<?> c = start; c != end; c = c.getSuperclass()) {
30.1046 + slots.add(new ClassDataSlot(
30.1047 + ObjectStreamClass.lookup(c, true), false));
30.1048 + }
30.1049 +
30.1050 + // order slots from superclass -> subclass
30.1051 + Collections.reverse(slots);
30.1052 + return slots.toArray(new ClassDataSlot[slots.size()]);
30.1053 + }
30.1054 +
30.1055 + /**
30.1056 + * Returns aggregate size (in bytes) of marshalled primitive field values
30.1057 + * for represented class.
30.1058 + */
30.1059 + int getPrimDataSize() {
30.1060 + return primDataSize;
30.1061 + }
30.1062 +
30.1063 + /**
30.1064 + * Returns number of non-primitive serializable fields of represented
30.1065 + * class.
30.1066 + */
30.1067 + int getNumObjFields() {
30.1068 + return numObjFields;
30.1069 + }
30.1070 +
30.1071 + /**
30.1072 + * Fetches the serializable primitive field values of object obj and
30.1073 + * marshals them into byte array buf starting at offset 0. It is the
30.1074 + * responsibility of the caller to ensure that obj is of the proper type if
30.1075 + * non-null.
30.1076 + */
30.1077 + void getPrimFieldValues(Object obj, byte[] buf) {
30.1078 + }
30.1079 +
30.1080 + /**
30.1081 + * Sets the serializable primitive fields of object obj using values
30.1082 + * unmarshalled from byte array buf starting at offset 0. It is the
30.1083 + * responsibility of the caller to ensure that obj is of the proper type if
30.1084 + * non-null.
30.1085 + */
30.1086 + void setPrimFieldValues(Object obj, byte[] buf) {
30.1087 + }
30.1088 +
30.1089 + /**
30.1090 + * Fetches the serializable object field values of object obj and stores
30.1091 + * them in array vals starting at offset 0. It is the responsibility of
30.1092 + * the caller to ensure that obj is of the proper type if non-null.
30.1093 + */
30.1094 + void getObjFieldValues(Object obj, Object[] vals) {
30.1095 + }
30.1096 +
30.1097 + /**
30.1098 + * Sets the serializable object fields of object obj using values from
30.1099 + * array vals starting at offset 0. It is the responsibility of the caller
30.1100 + * to ensure that obj is of the proper type if non-null.
30.1101 + */
30.1102 + void setObjFieldValues(Object obj, Object[] vals) {
30.1103 + }
30.1104 +
30.1105 + /**
30.1106 + * Calculates and sets serializable field offsets, as well as primitive
30.1107 + * data size and object field count totals. Throws InvalidClassException
30.1108 + * if fields are illegally ordered.
30.1109 + */
30.1110 + private void computeFieldOffsets() throws InvalidClassException {
30.1111 + primDataSize = 0;
30.1112 + numObjFields = 0;
30.1113 + int firstObjIndex = -1;
30.1114 +
30.1115 + for (int i = 0; i < fields.length; i++) {
30.1116 + ObjectStreamField f = fields[i];
30.1117 + switch (f.getTypeCode()) {
30.1118 + case 'Z':
30.1119 + case 'B':
30.1120 + f.setOffset(primDataSize++);
30.1121 + break;
30.1122 +
30.1123 + case 'C':
30.1124 + case 'S':
30.1125 + f.setOffset(primDataSize);
30.1126 + primDataSize += 2;
30.1127 + break;
30.1128 +
30.1129 + case 'I':
30.1130 + case 'F':
30.1131 + f.setOffset(primDataSize);
30.1132 + primDataSize += 4;
30.1133 + break;
30.1134 +
30.1135 + case 'J':
30.1136 + case 'D':
30.1137 + f.setOffset(primDataSize);
30.1138 + primDataSize += 8;
30.1139 + break;
30.1140 +
30.1141 + case '[':
30.1142 + case 'L':
30.1143 + f.setOffset(numObjFields++);
30.1144 + if (firstObjIndex == -1) {
30.1145 + firstObjIndex = i;
30.1146 + }
30.1147 + break;
30.1148 +
30.1149 + default:
30.1150 + throw new InternalError();
30.1151 + }
30.1152 + }
30.1153 + if (firstObjIndex != -1 &&
30.1154 + firstObjIndex + numObjFields != fields.length)
30.1155 + {
30.1156 + throw new InvalidClassException(name, "illegal field order");
30.1157 + }
30.1158 + }
30.1159 +
30.1160 + /**
30.1161 + * If given class is the same as the class associated with this class
30.1162 + * descriptor, returns reference to this class descriptor. Otherwise,
30.1163 + * returns variant of this class descriptor bound to given class.
30.1164 + */
30.1165 + private ObjectStreamClass getVariantFor(Class<?> cl)
30.1166 + throws InvalidClassException
30.1167 + {
30.1168 + if (this.cl == cl) {
30.1169 + return this;
30.1170 + }
30.1171 + ObjectStreamClass desc = new ObjectStreamClass();
30.1172 + if (isProxy) {
30.1173 + desc.initProxy(cl, null, superDesc);
30.1174 + } else {
30.1175 + desc.initNonProxy(this, cl, null, superDesc);
30.1176 + }
30.1177 + return desc;
30.1178 + }
30.1179 +
30.1180 + /**
30.1181 + * Returns public no-arg constructor of given class, or null if none found.
30.1182 + * Access checks are disabled on the returned constructor (if any), since
30.1183 + * the defining class may still be non-public.
30.1184 + */
30.1185 + private static Constructor getExternalizableConstructor(Class<?> cl) {
30.1186 + throw new SecurityException();
30.1187 + }
30.1188 +
30.1189 + /**
30.1190 + * Returns subclass-accessible no-arg constructor of first non-serializable
30.1191 + * superclass, or null if none found. Access checks are disabled on the
30.1192 + * returned constructor (if any).
30.1193 + */
30.1194 + private static Constructor getSerializableConstructor(Class<?> cl) {
30.1195 + Class<?> initCl = cl;
30.1196 + while (Serializable.class.isAssignableFrom(initCl)) {
30.1197 + if ((initCl = initCl.getSuperclass()) == null) {
30.1198 + return null;
30.1199 + }
30.1200 + }
30.1201 + throw new SecurityException();
30.1202 + }
30.1203 +
30.1204 + /**
30.1205 + * Returns non-static, non-abstract method with given signature provided it
30.1206 + * is defined by or accessible (via inheritance) by the given class, or
30.1207 + * null if no match found. Access checks are disabled on the returned
30.1208 + * method (if any).
30.1209 + */
30.1210 + private static Method getInheritableMethod(Class<?> cl, String name,
30.1211 + Class<?>[] argTypes,
30.1212 + Class<?> returnType)
30.1213 + {
30.1214 + throw new SecurityException();
30.1215 + }
30.1216 +
30.1217 + /**
30.1218 + * Returns non-static private method with given signature defined by given
30.1219 + * class, or null if none found. Access checks are disabled on the
30.1220 + * returned method (if any).
30.1221 + */
30.1222 + private static Method getPrivateMethod(Class<?> cl, String name,
30.1223 + Class<?>[] argTypes,
30.1224 + Class<?> returnType)
30.1225 + {
30.1226 + throw new SecurityException();
30.1227 + }
30.1228 +
30.1229 + /**
30.1230 + * Returns true if classes are defined in the same runtime package, false
30.1231 + * otherwise.
30.1232 + */
30.1233 + private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
30.1234 + return (cl1.getClassLoader() == cl2.getClassLoader() &&
30.1235 + getPackageName(cl1).equals(getPackageName(cl2)));
30.1236 + }
30.1237 +
30.1238 + /**
30.1239 + * Returns package name of given class.
30.1240 + */
30.1241 + private static String getPackageName(Class<?> cl) {
30.1242 + String s = cl.getName();
30.1243 + int i = s.lastIndexOf('[');
30.1244 + if (i >= 0) {
30.1245 + s = s.substring(i + 2);
30.1246 + }
30.1247 + i = s.lastIndexOf('.');
30.1248 + return (i >= 0) ? s.substring(0, i) : "";
30.1249 + }
30.1250 +
30.1251 + /**
30.1252 + * Compares class names for equality, ignoring package names. Returns true
30.1253 + * if class names equal, false otherwise.
30.1254 + */
30.1255 + private static boolean classNamesEqual(String name1, String name2) {
30.1256 + name1 = name1.substring(name1.lastIndexOf('.') + 1);
30.1257 + name2 = name2.substring(name2.lastIndexOf('.') + 1);
30.1258 + return name1.equals(name2);
30.1259 + }
30.1260 +
30.1261 + /**
30.1262 + * Returns JVM type signature for given class.
30.1263 + */
30.1264 + private static String getClassSignature(Class<?> cl) {
30.1265 + StringBuilder sbuf = new StringBuilder();
30.1266 + while (cl.isArray()) {
30.1267 + sbuf.append('[');
30.1268 + cl = cl.getComponentType();
30.1269 + }
30.1270 + if (cl.isPrimitive()) {
30.1271 + if (cl == Integer.TYPE) {
30.1272 + sbuf.append('I');
30.1273 + } else if (cl == Byte.TYPE) {
30.1274 + sbuf.append('B');
30.1275 + } else if (cl == Long.TYPE) {
30.1276 + sbuf.append('J');
30.1277 + } else if (cl == Float.TYPE) {
30.1278 + sbuf.append('F');
30.1279 + } else if (cl == Double.TYPE) {
30.1280 + sbuf.append('D');
30.1281 + } else if (cl == Short.TYPE) {
30.1282 + sbuf.append('S');
30.1283 + } else if (cl == Character.TYPE) {
30.1284 + sbuf.append('C');
30.1285 + } else if (cl == Boolean.TYPE) {
30.1286 + sbuf.append('Z');
30.1287 + } else if (cl == Void.TYPE) {
30.1288 + sbuf.append('V');
30.1289 + } else {
30.1290 + throw new InternalError();
30.1291 + }
30.1292 + } else {
30.1293 + sbuf.append('L' + cl.getName().replace('.', '/') + ';');
30.1294 + }
30.1295 + return sbuf.toString();
30.1296 + }
30.1297 +
30.1298 + /**
30.1299 + * Returns JVM type signature for given list of parameters and return type.
30.1300 + */
30.1301 + private static String getMethodSignature(Class<?>[] paramTypes,
30.1302 + Class<?> retType)
30.1303 + {
30.1304 + StringBuilder sbuf = new StringBuilder();
30.1305 + sbuf.append('(');
30.1306 + for (int i = 0; i < paramTypes.length; i++) {
30.1307 + sbuf.append(getClassSignature(paramTypes[i]));
30.1308 + }
30.1309 + sbuf.append(')');
30.1310 + sbuf.append(getClassSignature(retType));
30.1311 + return sbuf.toString();
30.1312 + }
30.1313 +
30.1314 + /**
30.1315 + * Convenience method for throwing an exception that is either a
30.1316 + * RuntimeException, Error, or of some unexpected type (in which case it is
30.1317 + * wrapped inside an IOException).
30.1318 + */
30.1319 + private static void throwMiscException(Throwable th) throws IOException {
30.1320 + if (th instanceof RuntimeException) {
30.1321 + throw (RuntimeException) th;
30.1322 + } else if (th instanceof Error) {
30.1323 + throw (Error) th;
30.1324 + } else {
30.1325 + IOException ex = new IOException("unexpected exception type");
30.1326 + ex.initCause(th);
30.1327 + throw ex;
30.1328 + }
30.1329 + }
30.1330 +
30.1331 + /**
30.1332 + * Returns ObjectStreamField array describing the serializable fields of
30.1333 + * the given class. Serializable fields backed by an actual field of the
30.1334 + * class are represented by ObjectStreamFields with corresponding non-null
30.1335 + * Field objects. Throws InvalidClassException if the (explicitly
30.1336 + * declared) serializable fields are invalid.
30.1337 + */
30.1338 + private static ObjectStreamField[] getSerialFields(Class<?> cl)
30.1339 + throws InvalidClassException
30.1340 + {
30.1341 + ObjectStreamField[] fields;
30.1342 + if (Serializable.class.isAssignableFrom(cl) &&
30.1343 + !Externalizable.class.isAssignableFrom(cl) &&
30.1344 + !Proxy.isProxyClass(cl) &&
30.1345 + !cl.isInterface())
30.1346 + {
30.1347 + if ((fields = getDeclaredSerialFields(cl)) == null) {
30.1348 + fields = getDefaultSerialFields(cl);
30.1349 + }
30.1350 + Arrays.sort(fields);
30.1351 + } else {
30.1352 + fields = NO_FIELDS;
30.1353 + }
30.1354 + return fields;
30.1355 + }
30.1356 +
30.1357 + /**
30.1358 + * Returns serializable fields of given class as defined explicitly by a
30.1359 + * "serialPersistentFields" field, or null if no appropriate
30.1360 + * "serialPersistentFields" field is defined. Serializable fields backed
30.1361 + * by an actual field of the class are represented by ObjectStreamFields
30.1362 + * with corresponding non-null Field objects. For compatibility with past
30.1363 + * releases, a "serialPersistentFields" field with a null value is
30.1364 + * considered equivalent to not declaring "serialPersistentFields". Throws
30.1365 + * InvalidClassException if the declared serializable fields are
30.1366 + * invalid--e.g., if multiple fields share the same name.
30.1367 + */
30.1368 + private static ObjectStreamField[] getDeclaredSerialFields(Class<?> cl)
30.1369 + throws InvalidClassException
30.1370 + {
30.1371 + throw new SecurityException();
30.1372 + }
30.1373 +
30.1374 + /**
30.1375 + * Returns array of ObjectStreamFields corresponding to all non-static
30.1376 + * non-transient fields declared by given class. Each ObjectStreamField
30.1377 + * contains a Field object for the field it represents. If no default
30.1378 + * serializable fields exist, NO_FIELDS is returned.
30.1379 + */
30.1380 + private static ObjectStreamField[] getDefaultSerialFields(Class<?> cl) {
30.1381 + throw new SecurityException();
30.1382 + }
30.1383 +
30.1384 + /**
30.1385 + * Returns explicit serial version UID value declared by given class, or
30.1386 + * null if none.
30.1387 + */
30.1388 + private static Long getDeclaredSUID(Class<?> cl) {
30.1389 + return null;
30.1390 + }
30.1391 +
30.1392 + /**
30.1393 + * Computes the default serial version UID value for the given class.
30.1394 + */
30.1395 + private static long computeDefaultSUID(Class<?> cl) {
30.1396 + throw new SecurityException();
30.1397 + }
30.1398 +
30.1399 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamConstants.java Tue Feb 05 17:04:22 2013 +0100
31.3 @@ -0,0 +1,215 @@
31.4 +/*
31.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31.7 + *
31.8 + * This code is free software; you can redistribute it and/or modify it
31.9 + * under the terms of the GNU General Public License version 2 only, as
31.10 + * published by the Free Software Foundation. Oracle designates this
31.11 + * particular file as subject to the "Classpath" exception as provided
31.12 + * by Oracle in the LICENSE file that accompanied this code.
31.13 + *
31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31.17 + * version 2 for more details (a copy is included in the LICENSE file that
31.18 + * accompanied this code).
31.19 + *
31.20 + * You should have received a copy of the GNU General Public License version
31.21 + * 2 along with this work; if not, write to the Free Software Foundation,
31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
31.23 + *
31.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
31.25 + * or visit www.oracle.com if you need additional information or have any
31.26 + * questions.
31.27 + */
31.28 +
31.29 +package java.io;
31.30 +
31.31 +/**
31.32 + * Constants written into the Object Serialization Stream.
31.33 + *
31.34 + * @author unascribed
31.35 + * @since JDK 1.1
31.36 + */
31.37 +public interface ObjectStreamConstants {
31.38 +
31.39 + /**
31.40 + * Magic number that is written to the stream header.
31.41 + */
31.42 + final static short STREAM_MAGIC = (short)0xaced;
31.43 +
31.44 + /**
31.45 + * Version number that is written to the stream header.
31.46 + */
31.47 + final static short STREAM_VERSION = 5;
31.48 +
31.49 + /* Each item in the stream is preceded by a tag
31.50 + */
31.51 +
31.52 + /**
31.53 + * First tag value.
31.54 + */
31.55 + final static byte TC_BASE = 0x70;
31.56 +
31.57 + /**
31.58 + * Null object reference.
31.59 + */
31.60 + final static byte TC_NULL = (byte)0x70;
31.61 +
31.62 + /**
31.63 + * Reference to an object already written into the stream.
31.64 + */
31.65 + final static byte TC_REFERENCE = (byte)0x71;
31.66 +
31.67 + /**
31.68 + * new Class Descriptor.
31.69 + */
31.70 + final static byte TC_CLASSDESC = (byte)0x72;
31.71 +
31.72 + /**
31.73 + * new Object.
31.74 + */
31.75 + final static byte TC_OBJECT = (byte)0x73;
31.76 +
31.77 + /**
31.78 + * new String.
31.79 + */
31.80 + final static byte TC_STRING = (byte)0x74;
31.81 +
31.82 + /**
31.83 + * new Array.
31.84 + */
31.85 + final static byte TC_ARRAY = (byte)0x75;
31.86 +
31.87 + /**
31.88 + * Reference to Class.
31.89 + */
31.90 + final static byte TC_CLASS = (byte)0x76;
31.91 +
31.92 + /**
31.93 + * Block of optional data. Byte following tag indicates number
31.94 + * of bytes in this block data.
31.95 + */
31.96 + final static byte TC_BLOCKDATA = (byte)0x77;
31.97 +
31.98 + /**
31.99 + * End of optional block data blocks for an object.
31.100 + */
31.101 + final static byte TC_ENDBLOCKDATA = (byte)0x78;
31.102 +
31.103 + /**
31.104 + * Reset stream context. All handles written into stream are reset.
31.105 + */
31.106 + final static byte TC_RESET = (byte)0x79;
31.107 +
31.108 + /**
31.109 + * long Block data. The long following the tag indicates the
31.110 + * number of bytes in this block data.
31.111 + */
31.112 + final static byte TC_BLOCKDATALONG= (byte)0x7A;
31.113 +
31.114 + /**
31.115 + * Exception during write.
31.116 + */
31.117 + final static byte TC_EXCEPTION = (byte)0x7B;
31.118 +
31.119 + /**
31.120 + * Long string.
31.121 + */
31.122 + final static byte TC_LONGSTRING = (byte)0x7C;
31.123 +
31.124 + /**
31.125 + * new Proxy Class Descriptor.
31.126 + */
31.127 + final static byte TC_PROXYCLASSDESC = (byte)0x7D;
31.128 +
31.129 + /**
31.130 + * new Enum constant.
31.131 + * @since 1.5
31.132 + */
31.133 + final static byte TC_ENUM = (byte)0x7E;
31.134 +
31.135 + /**
31.136 + * Last tag value.
31.137 + */
31.138 + final static byte TC_MAX = (byte)0x7E;
31.139 +
31.140 + /**
31.141 + * First wire handle to be assigned.
31.142 + */
31.143 + final static int baseWireHandle = 0x7e0000;
31.144 +
31.145 +
31.146 + /******************************************************/
31.147 + /* Bit masks for ObjectStreamClass flag.*/
31.148 +
31.149 + /**
31.150 + * Bit mask for ObjectStreamClass flag. Indicates a Serializable class
31.151 + * defines its own writeObject method.
31.152 + */
31.153 + final static byte SC_WRITE_METHOD = 0x01;
31.154 +
31.155 + /**
31.156 + * Bit mask for ObjectStreamClass flag. Indicates Externalizable data
31.157 + * written in Block Data mode.
31.158 + * Added for PROTOCOL_VERSION_2.
31.159 + *
31.160 + * @see #PROTOCOL_VERSION_2
31.161 + * @since 1.2
31.162 + */
31.163 + final static byte SC_BLOCK_DATA = 0x08;
31.164 +
31.165 + /**
31.166 + * Bit mask for ObjectStreamClass flag. Indicates class is Serializable.
31.167 + */
31.168 + final static byte SC_SERIALIZABLE = 0x02;
31.169 +
31.170 + /**
31.171 + * Bit mask for ObjectStreamClass flag. Indicates class is Externalizable.
31.172 + */
31.173 + final static byte SC_EXTERNALIZABLE = 0x04;
31.174 +
31.175 + /**
31.176 + * Bit mask for ObjectStreamClass flag. Indicates class is an enum type.
31.177 + * @since 1.5
31.178 + */
31.179 + final static byte SC_ENUM = 0x10;
31.180 +
31.181 +
31.182 + /* *******************************************************************/
31.183 + /* Security permissions */
31.184 +
31.185 + /**
31.186 + * A Stream Protocol Version. <p>
31.187 + *
31.188 + * All externalizable data is written in JDK 1.1 external data
31.189 + * format after calling this method. This version is needed to write
31.190 + * streams containing Externalizable data that can be read by
31.191 + * pre-JDK 1.1.6 JVMs.
31.192 + *
31.193 + * @see java.io.ObjectOutputStream#useProtocolVersion(int)
31.194 + * @since 1.2
31.195 + */
31.196 + public final static int PROTOCOL_VERSION_1 = 1;
31.197 +
31.198 +
31.199 + /**
31.200 + * A Stream Protocol Version. <p>
31.201 + *
31.202 + * This protocol is written by JVM 1.2.
31.203 + *
31.204 + * Externalizable data is written in block data mode and is
31.205 + * terminated with TC_ENDBLOCKDATA. Externalizable classdescriptor
31.206 + * flags has SC_BLOCK_DATA enabled. JVM 1.1.6 and greater can
31.207 + * read this format change.
31.208 + *
31.209 + * Enables writing a nonSerializable class descriptor into the
31.210 + * stream. The serialVersionUID of a nonSerializable class is
31.211 + * set to 0L.
31.212 + *
31.213 + * @see java.io.ObjectOutputStream#useProtocolVersion(int)
31.214 + * @see #SC_BLOCK_DATA
31.215 + * @since 1.2
31.216 + */
31.217 + public final static int PROTOCOL_VERSION_2 = 2;
31.218 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamException.java Tue Feb 05 17:04:22 2013 +0100
32.3 @@ -0,0 +1,53 @@
32.4 +/*
32.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.7 + *
32.8 + * This code is free software; you can redistribute it and/or modify it
32.9 + * under the terms of the GNU General Public License version 2 only, as
32.10 + * published by the Free Software Foundation. Oracle designates this
32.11 + * particular file as subject to the "Classpath" exception as provided
32.12 + * by Oracle in the LICENSE file that accompanied this code.
32.13 + *
32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32.17 + * version 2 for more details (a copy is included in the LICENSE file that
32.18 + * accompanied this code).
32.19 + *
32.20 + * You should have received a copy of the GNU General Public License version
32.21 + * 2 along with this work; if not, write to the Free Software Foundation,
32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32.23 + *
32.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
32.25 + * or visit www.oracle.com if you need additional information or have any
32.26 + * questions.
32.27 + */
32.28 +
32.29 +package java.io;
32.30 +
32.31 +/**
32.32 + * Superclass of all exceptions specific to Object Stream classes.
32.33 + *
32.34 + * @author unascribed
32.35 + * @since JDK1.1
32.36 + */
32.37 +public abstract class ObjectStreamException extends IOException {
32.38 +
32.39 + private static final long serialVersionUID = 7260898174833392607L;
32.40 +
32.41 + /**
32.42 + * Create an ObjectStreamException with the specified argument.
32.43 + *
32.44 + * @param classname the detailed message for the exception
32.45 + */
32.46 + protected ObjectStreamException(String classname) {
32.47 + super(classname);
32.48 + }
32.49 +
32.50 + /**
32.51 + * Create an ObjectStreamException.
32.52 + */
32.53 + protected ObjectStreamException() {
32.54 + super();
32.55 + }
32.56 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamField.java Tue Feb 05 17:04:22 2013 +0100
33.3 @@ -0,0 +1,314 @@
33.4 +/*
33.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.7 + *
33.8 + * This code is free software; you can redistribute it and/or modify it
33.9 + * under the terms of the GNU General Public License version 2 only, as
33.10 + * published by the Free Software Foundation. Oracle designates this
33.11 + * particular file as subject to the "Classpath" exception as provided
33.12 + * by Oracle in the LICENSE file that accompanied this code.
33.13 + *
33.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
33.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33.17 + * version 2 for more details (a copy is included in the LICENSE file that
33.18 + * accompanied this code).
33.19 + *
33.20 + * You should have received a copy of the GNU General Public License version
33.21 + * 2 along with this work; if not, write to the Free Software Foundation,
33.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
33.23 + *
33.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
33.25 + * or visit www.oracle.com if you need additional information or have any
33.26 + * questions.
33.27 + */
33.28 +
33.29 +package java.io;
33.30 +
33.31 +import java.lang.reflect.Field;
33.32 +
33.33 +/**
33.34 + * A description of a Serializable field from a Serializable class. An array
33.35 + * of ObjectStreamFields is used to declare the Serializable fields of a class.
33.36 + *
33.37 + * @author Mike Warres
33.38 + * @author Roger Riggs
33.39 + * @see ObjectStreamClass
33.40 + * @since 1.2
33.41 + */
33.42 +public class ObjectStreamField
33.43 + implements Comparable<Object>
33.44 +{
33.45 +
33.46 + /** field name */
33.47 + private final String name;
33.48 + /** canonical JVM signature of field type */
33.49 + private final String signature;
33.50 + /** field type (Object.class if unknown non-primitive type) */
33.51 + private final Class<?> type;
33.52 + /** whether or not to (de)serialize field values as unshared */
33.53 + private final boolean unshared;
33.54 + /** corresponding reflective field object, if any */
33.55 + private final Field field;
33.56 + /** offset of field value in enclosing field group */
33.57 + private int offset = 0;
33.58 +
33.59 + /**
33.60 + * Create a Serializable field with the specified type. This field should
33.61 + * be documented with a <code>serialField</code> tag.
33.62 + *
33.63 + * @param name the name of the serializable field
33.64 + * @param type the <code>Class</code> object of the serializable field
33.65 + */
33.66 + public ObjectStreamField(String name, Class<?> type) {
33.67 + this(name, type, false);
33.68 + }
33.69 +
33.70 + /**
33.71 + * Creates an ObjectStreamField representing a serializable field with the
33.72 + * given name and type. If unshared is false, values of the represented
33.73 + * field are serialized and deserialized in the default manner--if the
33.74 + * field is non-primitive, object values are serialized and deserialized as
33.75 + * if they had been written and read by calls to writeObject and
33.76 + * readObject. If unshared is true, values of the represented field are
33.77 + * serialized and deserialized as if they had been written and read by
33.78 + * calls to writeUnshared and readUnshared.
33.79 + *
33.80 + * @param name field name
33.81 + * @param type field type
33.82 + * @param unshared if false, write/read field values in the same manner
33.83 + * as writeObject/readObject; if true, write/read in the same
33.84 + * manner as writeUnshared/readUnshared
33.85 + * @since 1.4
33.86 + */
33.87 + public ObjectStreamField(String name, Class<?> type, boolean unshared) {
33.88 + if (name == null) {
33.89 + throw new NullPointerException();
33.90 + }
33.91 + this.name = name;
33.92 + this.type = type;
33.93 + this.unshared = unshared;
33.94 + signature = getClassSignature(type).intern();
33.95 + field = null;
33.96 + }
33.97 +
33.98 + /**
33.99 + * Creates an ObjectStreamField representing a field with the given name,
33.100 + * signature and unshared setting.
33.101 + */
33.102 + ObjectStreamField(String name, String signature, boolean unshared) {
33.103 + if (name == null) {
33.104 + throw new NullPointerException();
33.105 + }
33.106 + this.name = name;
33.107 + this.signature = signature.intern();
33.108 + this.unshared = unshared;
33.109 + field = null;
33.110 +
33.111 + switch (signature.charAt(0)) {
33.112 + case 'Z': type = Boolean.TYPE; break;
33.113 + case 'B': type = Byte.TYPE; break;
33.114 + case 'C': type = Character.TYPE; break;
33.115 + case 'S': type = Short.TYPE; break;
33.116 + case 'I': type = Integer.TYPE; break;
33.117 + case 'J': type = Long.TYPE; break;
33.118 + case 'F': type = Float.TYPE; break;
33.119 + case 'D': type = Double.TYPE; break;
33.120 + case 'L':
33.121 + case '[': type = Object.class; break;
33.122 + default: throw new IllegalArgumentException("illegal signature");
33.123 + }
33.124 + }
33.125 +
33.126 + /**
33.127 + * Creates an ObjectStreamField representing the given field with the
33.128 + * specified unshared setting. For compatibility with the behavior of
33.129 + * earlier serialization implementations, a "showType" parameter is
33.130 + * necessary to govern whether or not a getType() call on this
33.131 + * ObjectStreamField (if non-primitive) will return Object.class (as
33.132 + * opposed to a more specific reference type).
33.133 + */
33.134 + ObjectStreamField(Field field, boolean unshared, boolean showType) {
33.135 + this.field = field;
33.136 + this.unshared = unshared;
33.137 + name = field.getName();
33.138 + Class<?> ftype = field.getType();
33.139 + type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
33.140 + signature = getClassSignature(ftype).intern();
33.141 + }
33.142 +
33.143 + /**
33.144 + * Get the name of this field.
33.145 + *
33.146 + * @return a <code>String</code> representing the name of the serializable
33.147 + * field
33.148 + */
33.149 + public String getName() {
33.150 + return name;
33.151 + }
33.152 +
33.153 + /**
33.154 + * Get the type of the field. If the type is non-primitive and this
33.155 + * <code>ObjectStreamField</code> was obtained from a deserialized {@link
33.156 + * ObjectStreamClass} instance, then <code>Object.class</code> is returned.
33.157 + * Otherwise, the <code>Class</code> object for the type of the field is
33.158 + * returned.
33.159 + *
33.160 + * @return a <code>Class</code> object representing the type of the
33.161 + * serializable field
33.162 + */
33.163 + public Class<?> getType() {
33.164 + return type;
33.165 + }
33.166 +
33.167 + /**
33.168 + * Returns character encoding of field type. The encoding is as follows:
33.169 + * <blockquote><pre>
33.170 + * B byte
33.171 + * C char
33.172 + * D double
33.173 + * F float
33.174 + * I int
33.175 + * J long
33.176 + * L class or interface
33.177 + * S short
33.178 + * Z boolean
33.179 + * [ array
33.180 + * </pre></blockquote>
33.181 + *
33.182 + * @return the typecode of the serializable field
33.183 + */
33.184 + // REMIND: deprecate?
33.185 + public char getTypeCode() {
33.186 + return signature.charAt(0);
33.187 + }
33.188 +
33.189 + /**
33.190 + * Return the JVM type signature.
33.191 + *
33.192 + * @return null if this field has a primitive type.
33.193 + */
33.194 + // REMIND: deprecate?
33.195 + public String getTypeString() {
33.196 + return isPrimitive() ? null : signature;
33.197 + }
33.198 +
33.199 + /**
33.200 + * Offset of field within instance data.
33.201 + *
33.202 + * @return the offset of this field
33.203 + * @see #setOffset
33.204 + */
33.205 + // REMIND: deprecate?
33.206 + public int getOffset() {
33.207 + return offset;
33.208 + }
33.209 +
33.210 + /**
33.211 + * Offset within instance data.
33.212 + *
33.213 + * @param offset the offset of the field
33.214 + * @see #getOffset
33.215 + */
33.216 + // REMIND: deprecate?
33.217 + protected void setOffset(int offset) {
33.218 + this.offset = offset;
33.219 + }
33.220 +
33.221 + /**
33.222 + * Return true if this field has a primitive type.
33.223 + *
33.224 + * @return true if and only if this field corresponds to a primitive type
33.225 + */
33.226 + // REMIND: deprecate?
33.227 + public boolean isPrimitive() {
33.228 + char tcode = signature.charAt(0);
33.229 + return ((tcode != 'L') && (tcode != '['));
33.230 + }
33.231 +
33.232 + /**
33.233 + * Returns boolean value indicating whether or not the serializable field
33.234 + * represented by this ObjectStreamField instance is unshared.
33.235 + *
33.236 + * @since 1.4
33.237 + */
33.238 + public boolean isUnshared() {
33.239 + return unshared;
33.240 + }
33.241 +
33.242 + /**
33.243 + * Compare this field with another <code>ObjectStreamField</code>. Return
33.244 + * -1 if this is smaller, 0 if equal, 1 if greater. Types that are
33.245 + * primitives are "smaller" than object types. If equal, the field names
33.246 + * are compared.
33.247 + */
33.248 + // REMIND: deprecate?
33.249 + public int compareTo(Object obj) {
33.250 + ObjectStreamField other = (ObjectStreamField) obj;
33.251 + boolean isPrim = isPrimitive();
33.252 + if (isPrim != other.isPrimitive()) {
33.253 + return isPrim ? -1 : 1;
33.254 + }
33.255 + return name.compareTo(other.name);
33.256 + }
33.257 +
33.258 + /**
33.259 + * Return a string that describes this field.
33.260 + */
33.261 + public String toString() {
33.262 + return signature + ' ' + name;
33.263 + }
33.264 +
33.265 + /**
33.266 + * Returns field represented by this ObjectStreamField, or null if
33.267 + * ObjectStreamField is not associated with an actual field.
33.268 + */
33.269 + Field getField() {
33.270 + return field;
33.271 + }
33.272 +
33.273 + /**
33.274 + * Returns JVM type signature of field (similar to getTypeString, except
33.275 + * that signature strings are returned for primitive fields as well).
33.276 + */
33.277 + String getSignature() {
33.278 + return signature;
33.279 + }
33.280 +
33.281 + /**
33.282 + * Returns JVM type signature for given class.
33.283 + */
33.284 + private static String getClassSignature(Class<?> cl) {
33.285 + StringBuilder sbuf = new StringBuilder();
33.286 + while (cl.isArray()) {
33.287 + sbuf.append('[');
33.288 + cl = cl.getComponentType();
33.289 + }
33.290 + if (cl.isPrimitive()) {
33.291 + if (cl == Integer.TYPE) {
33.292 + sbuf.append('I');
33.293 + } else if (cl == Byte.TYPE) {
33.294 + sbuf.append('B');
33.295 + } else if (cl == Long.TYPE) {
33.296 + sbuf.append('J');
33.297 + } else if (cl == Float.TYPE) {
33.298 + sbuf.append('F');
33.299 + } else if (cl == Double.TYPE) {
33.300 + sbuf.append('D');
33.301 + } else if (cl == Short.TYPE) {
33.302 + sbuf.append('S');
33.303 + } else if (cl == Character.TYPE) {
33.304 + sbuf.append('C');
33.305 + } else if (cl == Boolean.TYPE) {
33.306 + sbuf.append('Z');
33.307 + } else if (cl == Void.TYPE) {
33.308 + sbuf.append('V');
33.309 + } else {
33.310 + throw new InternalError();
33.311 + }
33.312 + } else {
33.313 + sbuf.append('L' + cl.getName().replace('.', '/') + ';');
33.314 + }
33.315 + return sbuf.toString();
33.316 + }
33.317 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/emul/compact/src/main/java/java/io/OptionalDataException.java Tue Feb 05 17:04:22 2013 +0100
34.3 @@ -0,0 +1,83 @@
34.4 +/*
34.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
34.7 + *
34.8 + * This code is free software; you can redistribute it and/or modify it
34.9 + * under the terms of the GNU General Public License version 2 only, as
34.10 + * published by the Free Software Foundation. Oracle designates this
34.11 + * particular file as subject to the "Classpath" exception as provided
34.12 + * by Oracle in the LICENSE file that accompanied this code.
34.13 + *
34.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
34.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34.17 + * version 2 for more details (a copy is included in the LICENSE file that
34.18 + * accompanied this code).
34.19 + *
34.20 + * You should have received a copy of the GNU General Public License version
34.21 + * 2 along with this work; if not, write to the Free Software Foundation,
34.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
34.23 + *
34.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
34.25 + * or visit www.oracle.com if you need additional information or have any
34.26 + * questions.
34.27 + */
34.28 +package java.io;
34.29 +
34.30 +/**
34.31 + * Exception indicating the failure of an object read operation due to
34.32 + * unread primitive data, or the end of data belonging to a serialized
34.33 + * object in the stream. This exception may be thrown in two cases:
34.34 + *
34.35 + * <ul>
34.36 + * <li>An attempt was made to read an object when the next element in the
34.37 + * stream is primitive data. In this case, the OptionalDataException's
34.38 + * length field is set to the number of bytes of primitive data
34.39 + * immediately readable from the stream, and the eof field is set to
34.40 + * false.
34.41 + *
34.42 + * <li>An attempt was made to read past the end of data consumable by a
34.43 + * class-defined readObject or readExternal method. In this case, the
34.44 + * OptionalDataException's eof field is set to true, and the length field
34.45 + * is set to 0.
34.46 + * </ul>
34.47 + *
34.48 + * @author unascribed
34.49 + * @since JDK1.1
34.50 + */
34.51 +public class OptionalDataException extends ObjectStreamException {
34.52 +
34.53 + private static final long serialVersionUID = -8011121865681257820L;
34.54 +
34.55 + /*
34.56 + * Create an <code>OptionalDataException</code> with a length.
34.57 + */
34.58 + OptionalDataException(int len) {
34.59 + eof = false;
34.60 + length = len;
34.61 + }
34.62 +
34.63 + /*
34.64 + * Create an <code>OptionalDataException</code> signifying no
34.65 + * more primitive data is available.
34.66 + */
34.67 + OptionalDataException(boolean end) {
34.68 + length = 0;
34.69 + eof = end;
34.70 + }
34.71 +
34.72 + /**
34.73 + * The number of bytes of primitive data available to be read
34.74 + * in the current buffer.
34.75 + *
34.76 + * @serial
34.77 + */
34.78 + public int length;
34.79 +
34.80 + /**
34.81 + * True if there is no more data in the buffered part of the stream.
34.82 + *
34.83 + * @serial
34.84 + */
34.85 + public boolean eof;
34.86 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/emul/compact/src/main/java/java/io/OutputStream.java Tue Feb 05 17:04:22 2013 +0100
35.3 @@ -0,0 +1,154 @@
35.4 +/*
35.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.7 + *
35.8 + * This code is free software; you can redistribute it and/or modify it
35.9 + * under the terms of the GNU General Public License version 2 only, as
35.10 + * published by the Free Software Foundation. Oracle designates this
35.11 + * particular file as subject to the "Classpath" exception as provided
35.12 + * by Oracle in the LICENSE file that accompanied this code.
35.13 + *
35.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
35.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35.17 + * version 2 for more details (a copy is included in the LICENSE file that
35.18 + * accompanied this code).
35.19 + *
35.20 + * You should have received a copy of the GNU General Public License version
35.21 + * 2 along with this work; if not, write to the Free Software Foundation,
35.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35.23 + *
35.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
35.25 + * or visit www.oracle.com if you need additional information or have any
35.26 + * questions.
35.27 + */
35.28 +
35.29 +package java.io;
35.30 +
35.31 +/**
35.32 + * This abstract class is the superclass of all classes representing
35.33 + * an output stream of bytes. An output stream accepts output bytes
35.34 + * and sends them to some sink.
35.35 + * <p>
35.36 + * Applications that need to define a subclass of
35.37 + * <code>OutputStream</code> must always provide at least a method
35.38 + * that writes one byte of output.
35.39 + *
35.40 + * @author Arthur van Hoff
35.41 + * @see java.io.BufferedOutputStream
35.42 + * @see java.io.ByteArrayOutputStream
35.43 + * @see java.io.DataOutputStream
35.44 + * @see java.io.FilterOutputStream
35.45 + * @see java.io.InputStream
35.46 + * @see java.io.OutputStream#write(int)
35.47 + * @since JDK1.0
35.48 + */
35.49 +public abstract class OutputStream implements Closeable, Flushable {
35.50 + /**
35.51 + * Writes the specified byte to this output stream. The general
35.52 + * contract for <code>write</code> is that one byte is written
35.53 + * to the output stream. The byte to be written is the eight
35.54 + * low-order bits of the argument <code>b</code>. The 24
35.55 + * high-order bits of <code>b</code> are ignored.
35.56 + * <p>
35.57 + * Subclasses of <code>OutputStream</code> must provide an
35.58 + * implementation for this method.
35.59 + *
35.60 + * @param b the <code>byte</code>.
35.61 + * @exception IOException if an I/O error occurs. In particular,
35.62 + * an <code>IOException</code> may be thrown if the
35.63 + * output stream has been closed.
35.64 + */
35.65 + public abstract void write(int b) throws IOException;
35.66 +
35.67 + /**
35.68 + * Writes <code>b.length</code> bytes from the specified byte array
35.69 + * to this output stream. The general contract for <code>write(b)</code>
35.70 + * is that it should have exactly the same effect as the call
35.71 + * <code>write(b, 0, b.length)</code>.
35.72 + *
35.73 + * @param b the data.
35.74 + * @exception IOException if an I/O error occurs.
35.75 + * @see java.io.OutputStream#write(byte[], int, int)
35.76 + */
35.77 + public void write(byte b[]) throws IOException {
35.78 + write(b, 0, b.length);
35.79 + }
35.80 +
35.81 + /**
35.82 + * Writes <code>len</code> bytes from the specified byte array
35.83 + * starting at offset <code>off</code> to this output stream.
35.84 + * The general contract for <code>write(b, off, len)</code> is that
35.85 + * some of the bytes in the array <code>b</code> are written to the
35.86 + * output stream in order; element <code>b[off]</code> is the first
35.87 + * byte written and <code>b[off+len-1]</code> is the last byte written
35.88 + * by this operation.
35.89 + * <p>
35.90 + * The <code>write</code> method of <code>OutputStream</code> calls
35.91 + * the write method of one argument on each of the bytes to be
35.92 + * written out. Subclasses are encouraged to override this method and
35.93 + * provide a more efficient implementation.
35.94 + * <p>
35.95 + * If <code>b</code> is <code>null</code>, a
35.96 + * <code>NullPointerException</code> is thrown.
35.97 + * <p>
35.98 + * If <code>off</code> is negative, or <code>len</code> is negative, or
35.99 + * <code>off+len</code> is greater than the length of the array
35.100 + * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown.
35.101 + *
35.102 + * @param b the data.
35.103 + * @param off the start offset in the data.
35.104 + * @param len the number of bytes to write.
35.105 + * @exception IOException if an I/O error occurs. In particular,
35.106 + * an <code>IOException</code> is thrown if the output
35.107 + * stream is closed.
35.108 + */
35.109 + public void write(byte b[], int off, int len) throws IOException {
35.110 + if (b == null) {
35.111 + throw new NullPointerException();
35.112 + } else if ((off < 0) || (off > b.length) || (len < 0) ||
35.113 + ((off + len) > b.length) || ((off + len) < 0)) {
35.114 + throw new IndexOutOfBoundsException();
35.115 + } else if (len == 0) {
35.116 + return;
35.117 + }
35.118 + for (int i = 0 ; i < len ; i++) {
35.119 + write(b[off + i]);
35.120 + }
35.121 + }
35.122 +
35.123 + /**
35.124 + * Flushes this output stream and forces any buffered output bytes
35.125 + * to be written out. The general contract of <code>flush</code> is
35.126 + * that calling it is an indication that, if any bytes previously
35.127 + * written have been buffered by the implementation of the output
35.128 + * stream, such bytes should immediately be written to their
35.129 + * intended destination.
35.130 + * <p>
35.131 + * If the intended destination of this stream is an abstraction provided by
35.132 + * the underlying operating system, for example a file, then flushing the
35.133 + * stream guarantees only that bytes previously written to the stream are
35.134 + * passed to the operating system for writing; it does not guarantee that
35.135 + * they are actually written to a physical device such as a disk drive.
35.136 + * <p>
35.137 + * The <code>flush</code> method of <code>OutputStream</code> does nothing.
35.138 + *
35.139 + * @exception IOException if an I/O error occurs.
35.140 + */
35.141 + public void flush() throws IOException {
35.142 + }
35.143 +
35.144 + /**
35.145 + * Closes this output stream and releases any system resources
35.146 + * associated with this stream. The general contract of <code>close</code>
35.147 + * is that it closes the output stream. A closed stream cannot perform
35.148 + * output operations and cannot be reopened.
35.149 + * <p>
35.150 + * The <code>close</code> method of <code>OutputStream</code> does nothing.
35.151 + *
35.152 + * @exception IOException if an I/O error occurs.
35.153 + */
35.154 + public void close() throws IOException {
35.155 + }
35.156 +
35.157 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/emul/compact/src/main/java/java/io/StreamCorruptedException.java Tue Feb 05 17:04:22 2013 +0100
36.3 @@ -0,0 +1,54 @@
36.4 +/*
36.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
36.7 + *
36.8 + * This code is free software; you can redistribute it and/or modify it
36.9 + * under the terms of the GNU General Public License version 2 only, as
36.10 + * published by the Free Software Foundation. Oracle designates this
36.11 + * particular file as subject to the "Classpath" exception as provided
36.12 + * by Oracle in the LICENSE file that accompanied this code.
36.13 + *
36.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
36.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36.17 + * version 2 for more details (a copy is included in the LICENSE file that
36.18 + * accompanied this code).
36.19 + *
36.20 + * You should have received a copy of the GNU General Public License version
36.21 + * 2 along with this work; if not, write to the Free Software Foundation,
36.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
36.23 + *
36.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
36.25 + * or visit www.oracle.com if you need additional information or have any
36.26 + * questions.
36.27 + */
36.28 +
36.29 +package java.io;
36.30 +
36.31 +/**
36.32 + * Thrown when control information that was read from an object stream
36.33 + * violates internal consistency checks.
36.34 + *
36.35 + * @author unascribed
36.36 + * @since JDK1.1
36.37 + */
36.38 +public class StreamCorruptedException extends ObjectStreamException {
36.39 +
36.40 + private static final long serialVersionUID = 8983558202217591746L;
36.41 +
36.42 + /**
36.43 + * Create a StreamCorruptedException and list a reason why thrown.
36.44 + *
36.45 + * @param reason String describing the reason for the exception.
36.46 + */
36.47 + public StreamCorruptedException(String reason) {
36.48 + super(reason);
36.49 + }
36.50 +
36.51 + /**
36.52 + * Create a StreamCorruptedException and list no reason why thrown.
36.53 + */
36.54 + public StreamCorruptedException() {
36.55 + super();
36.56 + }
36.57 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/emul/compact/src/main/java/java/io/WriteAbortedException.java Tue Feb 05 17:04:22 2013 +0100
37.3 @@ -0,0 +1,93 @@
37.4 +/*
37.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37.7 + *
37.8 + * This code is free software; you can redistribute it and/or modify it
37.9 + * under the terms of the GNU General Public License version 2 only, as
37.10 + * published by the Free Software Foundation. Oracle designates this
37.11 + * particular file as subject to the "Classpath" exception as provided
37.12 + * by Oracle in the LICENSE file that accompanied this code.
37.13 + *
37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37.17 + * version 2 for more details (a copy is included in the LICENSE file that
37.18 + * accompanied this code).
37.19 + *
37.20 + * You should have received a copy of the GNU General Public License version
37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37.23 + *
37.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
37.25 + * or visit www.oracle.com if you need additional information or have any
37.26 + * questions.
37.27 + */
37.28 +
37.29 +package java.io;
37.30 +
37.31 +/**
37.32 + * Signals that one of the ObjectStreamExceptions was thrown during a
37.33 + * write operation. Thrown during a read operation when one of the
37.34 + * ObjectStreamExceptions was thrown during a write operation. The
37.35 + * exception that terminated the write can be found in the detail
37.36 + * field. The stream is reset to it's initial state and all references
37.37 + * to objects already deserialized are discarded.
37.38 + *
37.39 + * <p>As of release 1.4, this exception has been retrofitted to conform to
37.40 + * the general purpose exception-chaining mechanism. The "exception causing
37.41 + * the abort" that is provided at construction time and
37.42 + * accessed via the public {@link #detail} field is now known as the
37.43 + * <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
37.44 + * method, as well as the aforementioned "legacy field."
37.45 + *
37.46 + * @author unascribed
37.47 + * @since JDK1.1
37.48 + */
37.49 +public class WriteAbortedException extends ObjectStreamException {
37.50 + private static final long serialVersionUID = -3326426625597282442L;
37.51 +
37.52 + /**
37.53 + * Exception that was caught while writing the ObjectStream.
37.54 + *
37.55 + * <p>This field predates the general-purpose exception chaining facility.
37.56 + * The {@link Throwable#getCause()} method is now the preferred means of
37.57 + * obtaining this information.
37.58 + *
37.59 + * @serial
37.60 + */
37.61 + public Exception detail;
37.62 +
37.63 + /**
37.64 + * Constructs a WriteAbortedException with a string describing
37.65 + * the exception and the exception causing the abort.
37.66 + * @param s String describing the exception.
37.67 + * @param ex Exception causing the abort.
37.68 + */
37.69 + public WriteAbortedException(String s, Exception ex) {
37.70 + super(s);
37.71 + initCause(null); // Disallow subsequent initCause
37.72 + detail = ex;
37.73 + }
37.74 +
37.75 + /**
37.76 + * Produce the message and include the message from the nested
37.77 + * exception, if there is one.
37.78 + */
37.79 + public String getMessage() {
37.80 + if (detail == null)
37.81 + return super.getMessage();
37.82 + else
37.83 + return super.getMessage() + "; " + detail.toString();
37.84 + }
37.85 +
37.86 + /**
37.87 + * Returns the exception that terminated the operation (the <i>cause</i>).
37.88 + *
37.89 + * @return the exception that terminated the operation (the <i>cause</i>),
37.90 + * which may be null.
37.91 + * @since 1.4
37.92 + */
37.93 + public Throwable getCause() {
37.94 + return detail;
37.95 + }
37.96 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/emul/compact/src/main/java/java/lang/AbstractMethodError.java Tue Feb 05 17:04:22 2013 +0100
38.3 @@ -0,0 +1,58 @@
38.4 +/*
38.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
38.7 + *
38.8 + * This code is free software; you can redistribute it and/or modify it
38.9 + * under the terms of the GNU General Public License version 2 only, as
38.10 + * published by the Free Software Foundation. Oracle designates this
38.11 + * particular file as subject to the "Classpath" exception as provided
38.12 + * by Oracle in the LICENSE file that accompanied this code.
38.13 + *
38.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
38.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38.17 + * version 2 for more details (a copy is included in the LICENSE file that
38.18 + * accompanied this code).
38.19 + *
38.20 + * You should have received a copy of the GNU General Public License version
38.21 + * 2 along with this work; if not, write to the Free Software Foundation,
38.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
38.23 + *
38.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
38.25 + * or visit www.oracle.com if you need additional information or have any
38.26 + * questions.
38.27 + */
38.28 +
38.29 +package java.lang;
38.30 +
38.31 +/**
38.32 + * Thrown when an application tries to call an abstract method.
38.33 + * Normally, this error is caught by the compiler; this error can
38.34 + * only occur at run time if the definition of some class has
38.35 + * incompatibly changed since the currently executing method was last
38.36 + * compiled.
38.37 + *
38.38 + * @author unascribed
38.39 + * @since JDK1.0
38.40 + */
38.41 +public
38.42 +class AbstractMethodError extends IncompatibleClassChangeError {
38.43 + private static final long serialVersionUID = -1654391082989018462L;
38.44 +
38.45 + /**
38.46 + * Constructs an <code>AbstractMethodError</code> with no detail message.
38.47 + */
38.48 + public AbstractMethodError() {
38.49 + super();
38.50 + }
38.51 +
38.52 + /**
38.53 + * Constructs an <code>AbstractMethodError</code> with the specified
38.54 + * detail message.
38.55 + *
38.56 + * @param s the detail message.
38.57 + */
38.58 + public AbstractMethodError(String s) {
38.59 + super(s);
38.60 + }
38.61 +}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/emul/compact/src/main/java/java/lang/IncompatibleClassChangeError.java Tue Feb 05 17:04:22 2013 +0100
39.3 @@ -0,0 +1,57 @@
39.4 +/*
39.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
39.7 + *
39.8 + * This code is free software; you can redistribute it and/or modify it
39.9 + * under the terms of the GNU General Public License version 2 only, as
39.10 + * published by the Free Software Foundation. Oracle designates this
39.11 + * particular file as subject to the "Classpath" exception as provided
39.12 + * by Oracle in the LICENSE file that accompanied this code.
39.13 + *
39.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
39.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
39.17 + * version 2 for more details (a copy is included in the LICENSE file that
39.18 + * accompanied this code).
39.19 + *
39.20 + * You should have received a copy of the GNU General Public License version
39.21 + * 2 along with this work; if not, write to the Free Software Foundation,
39.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
39.23 + *
39.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
39.25 + * or visit www.oracle.com if you need additional information or have any
39.26 + * questions.
39.27 + */
39.28 +
39.29 +package java.lang;
39.30 +
39.31 +/**
39.32 + * Thrown when an incompatible class change has occurred to some class
39.33 + * definition. The definition of some class, on which the currently
39.34 + * executing method depends, has since changed.
39.35 + *
39.36 + * @author unascribed
39.37 + * @since JDK1.0
39.38 + */
39.39 +public
39.40 +class IncompatibleClassChangeError extends LinkageError {
39.41 + private static final long serialVersionUID = -4914975503642802119L;
39.42 +
39.43 + /**
39.44 + * Constructs an <code>IncompatibleClassChangeError</code> with no
39.45 + * detail message.
39.46 + */
39.47 + public IncompatibleClassChangeError () {
39.48 + super();
39.49 + }
39.50 +
39.51 + /**
39.52 + * Constructs an <code>IncompatibleClassChangeError</code> with the
39.53 + * specified detail message.
39.54 + *
39.55 + * @param s the detail message.
39.56 + */
39.57 + public IncompatibleClassChangeError(String s) {
39.58 + super(s);
39.59 + }
39.60 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/emul/compact/src/main/java/java/lang/NoSuchFieldError.java Tue Feb 05 17:04:22 2013 +0100
40.3 @@ -0,0 +1,59 @@
40.4 +/*
40.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
40.7 + *
40.8 + * This code is free software; you can redistribute it and/or modify it
40.9 + * under the terms of the GNU General Public License version 2 only, as
40.10 + * published by the Free Software Foundation. Oracle designates this
40.11 + * particular file as subject to the "Classpath" exception as provided
40.12 + * by Oracle in the LICENSE file that accompanied this code.
40.13 + *
40.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
40.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40.17 + * version 2 for more details (a copy is included in the LICENSE file that
40.18 + * accompanied this code).
40.19 + *
40.20 + * You should have received a copy of the GNU General Public License version
40.21 + * 2 along with this work; if not, write to the Free Software Foundation,
40.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
40.23 + *
40.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
40.25 + * or visit www.oracle.com if you need additional information or have any
40.26 + * questions.
40.27 + */
40.28 +
40.29 +package java.lang;
40.30 +
40.31 +/**
40.32 + * Thrown if an application tries to access or modify a specified
40.33 + * field of an object, and that object no longer has that field.
40.34 + * <p>
40.35 + * Normally, this error is caught by the compiler; this error can
40.36 + * only occur at run time if the definition of a class has
40.37 + * incompatibly changed.
40.38 + *
40.39 + * @author unascribed
40.40 + * @since JDK1.0
40.41 + */
40.42 +public
40.43 +class NoSuchFieldError extends IncompatibleClassChangeError {
40.44 + private static final long serialVersionUID = -3456430195886129035L;
40.45 +
40.46 + /**
40.47 + * Constructs a <code>NoSuchFieldError</code> with no detail message.
40.48 + */
40.49 + public NoSuchFieldError() {
40.50 + super();
40.51 + }
40.52 +
40.53 + /**
40.54 + * Constructs a <code>NoSuchFieldError</code> with the specified
40.55 + * detail message.
40.56 + *
40.57 + * @param s the detail message.
40.58 + */
40.59 + public NoSuchFieldError(String s) {
40.60 + super(s);
40.61 + }
40.62 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/emul/compact/src/main/java/java/lang/System.java Tue Feb 05 17:04:22 2013 +0100
41.3 @@ -0,0 +1,36 @@
41.4 +/**
41.5 + * Back 2 Browser Bytecode Translator
41.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
41.7 + *
41.8 + * This program is free software: you can redistribute it and/or modify
41.9 + * it under the terms of the GNU General Public License as published by
41.10 + * the Free Software Foundation, version 2 of the License.
41.11 + *
41.12 + * This program is distributed in the hope that it will be useful,
41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.15 + * GNU General Public License for more details.
41.16 + *
41.17 + * You should have received a copy of the GNU General Public License
41.18 + * along with this program. Look for COPYING file in the top folder.
41.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
41.20 + */
41.21 +package java.lang;
41.22 +
41.23 +/** Poor man's re-implementation of most important System methods.
41.24 + *
41.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
41.26 + */
41.27 +public class System {
41.28 + private System() {
41.29 + }
41.30 +
41.31 + public static void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count) {
41.32 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(value, srcBegin, dst, dstBegin, count);
41.33 + }
41.34 +
41.35 + public static long currentTimeMillis() {
41.36 + return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis();
41.37 + }
41.38 +
41.39 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/emul/compact/src/main/java/java/lang/ref/PhantomReference.java Tue Feb 05 17:04:22 2013 +0100
42.3 @@ -0,0 +1,83 @@
42.4 +/*
42.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
42.7 + *
42.8 + * This code is free software; you can redistribute it and/or modify it
42.9 + * under the terms of the GNU General Public License version 2 only, as
42.10 + * published by the Free Software Foundation. Oracle designates this
42.11 + * particular file as subject to the "Classpath" exception as provided
42.12 + * by Oracle in the LICENSE file that accompanied this code.
42.13 + *
42.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
42.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42.17 + * version 2 for more details (a copy is included in the LICENSE file that
42.18 + * accompanied this code).
42.19 + *
42.20 + * You should have received a copy of the GNU General Public License version
42.21 + * 2 along with this work; if not, write to the Free Software Foundation,
42.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
42.23 + *
42.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
42.25 + * or visit www.oracle.com if you need additional information or have any
42.26 + * questions.
42.27 + */
42.28 +
42.29 +package java.lang.ref;
42.30 +
42.31 +
42.32 +/**
42.33 + * Phantom reference objects, which are enqueued after the collector
42.34 + * determines that their referents may otherwise be reclaimed. Phantom
42.35 + * references are most often used for scheduling pre-mortem cleanup actions in
42.36 + * a more flexible way than is possible with the Java finalization mechanism.
42.37 + *
42.38 + * <p> If the garbage collector determines at a certain point in time that the
42.39 + * referent of a phantom reference is <a
42.40 + * href="package-summary.html#reachability">phantom reachable</a>, then at that
42.41 + * time or at some later time it will enqueue the reference.
42.42 + *
42.43 + * <p> In order to ensure that a reclaimable object remains so, the referent of
42.44 + * a phantom reference may not be retrieved: The <code>get</code> method of a
42.45 + * phantom reference always returns <code>null</code>.
42.46 + *
42.47 + * <p> Unlike soft and weak references, phantom references are not
42.48 + * automatically cleared by the garbage collector as they are enqueued. An
42.49 + * object that is reachable via phantom references will remain so until all
42.50 + * such references are cleared or themselves become unreachable.
42.51 + *
42.52 + * @author Mark Reinhold
42.53 + * @since 1.2
42.54 + */
42.55 +
42.56 +public class PhantomReference<T> extends Reference<T> {
42.57 +
42.58 + /**
42.59 + * Returns this reference object's referent. Because the referent of a
42.60 + * phantom reference is always inaccessible, this method always returns
42.61 + * <code>null</code>.
42.62 + *
42.63 + * @return <code>null</code>
42.64 + */
42.65 + public T get() {
42.66 + return null;
42.67 + }
42.68 +
42.69 + /**
42.70 + * Creates a new phantom reference that refers to the given object and
42.71 + * is registered with the given queue.
42.72 + *
42.73 + * <p> It is possible to create a phantom reference with a <tt>null</tt>
42.74 + * queue, but such a reference is completely useless: Its <tt>get</tt>
42.75 + * method will always return null and, since it does not have a queue, it
42.76 + * will never be enqueued.
42.77 + *
42.78 + * @param referent the object the new phantom reference will refer to
42.79 + * @param q the queue with which the reference is to be registered,
42.80 + * or <tt>null</tt> if registration is not required
42.81 + */
42.82 + public PhantomReference(T referent, ReferenceQueue<? super T> q) {
42.83 + super(referent, q);
42.84 + }
42.85 +
42.86 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/emul/compact/src/main/java/java/lang/ref/Reference.java Tue Feb 05 17:04:22 2013 +0100
43.3 @@ -0,0 +1,185 @@
43.4 +/*
43.5 + * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
43.7 + *
43.8 + * This code is free software; you can redistribute it and/or modify it
43.9 + * under the terms of the GNU General Public License version 2 only, as
43.10 + * published by the Free Software Foundation. Oracle designates this
43.11 + * particular file as subject to the "Classpath" exception as provided
43.12 + * by Oracle in the LICENSE file that accompanied this code.
43.13 + *
43.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
43.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43.17 + * version 2 for more details (a copy is included in the LICENSE file that
43.18 + * accompanied this code).
43.19 + *
43.20 + * You should have received a copy of the GNU General Public License version
43.21 + * 2 along with this work; if not, write to the Free Software Foundation,
43.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
43.23 + *
43.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
43.25 + * or visit www.oracle.com if you need additional information or have any
43.26 + * questions.
43.27 + */
43.28 +
43.29 +package java.lang.ref;
43.30 +
43.31 +
43.32 +/**
43.33 + * Abstract base class for reference objects. This class defines the
43.34 + * operations common to all reference objects. Because reference objects are
43.35 + * implemented in close cooperation with the garbage collector, this class may
43.36 + * not be subclassed directly.
43.37 + *
43.38 + * @author Mark Reinhold
43.39 + * @since 1.2
43.40 + */
43.41 +
43.42 +public abstract class Reference<T> {
43.43 +
43.44 + /* A Reference instance is in one of four possible internal states:
43.45 + *
43.46 + * Active: Subject to special treatment by the garbage collector. Some
43.47 + * time after the collector detects that the reachability of the
43.48 + * referent has changed to the appropriate state, it changes the
43.49 + * instance's state to either Pending or Inactive, depending upon
43.50 + * whether or not the instance was registered with a queue when it was
43.51 + * created. In the former case it also adds the instance to the
43.52 + * pending-Reference list. Newly-created instances are Active.
43.53 + *
43.54 + * Pending: An element of the pending-Reference list, waiting to be
43.55 + * enqueued by the Reference-handler thread. Unregistered instances
43.56 + * are never in this state.
43.57 + *
43.58 + * Enqueued: An element of the queue with which the instance was
43.59 + * registered when it was created. When an instance is removed from
43.60 + * its ReferenceQueue, it is made Inactive. Unregistered instances are
43.61 + * never in this state.
43.62 + *
43.63 + * Inactive: Nothing more to do. Once an instance becomes Inactive its
43.64 + * state will never change again.
43.65 + *
43.66 + * The state is encoded in the queue and next fields as follows:
43.67 + *
43.68 + * Active: queue = ReferenceQueue with which instance is registered, or
43.69 + * ReferenceQueue.NULL if it was not registered with a queue; next =
43.70 + * null.
43.71 + *
43.72 + * Pending: queue = ReferenceQueue with which instance is registered;
43.73 + * next = Following instance in queue, or this if at end of list.
43.74 + *
43.75 + * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
43.76 + * in queue, or this if at end of list.
43.77 + *
43.78 + * Inactive: queue = ReferenceQueue.NULL; next = this.
43.79 + *
43.80 + * With this scheme the collector need only examine the next field in order
43.81 + * to determine whether a Reference instance requires special treatment: If
43.82 + * the next field is null then the instance is active; if it is non-null,
43.83 + * then the collector should treat the instance normally.
43.84 + *
43.85 + * To ensure that concurrent collector can discover active Reference
43.86 + * objects without interfering with application threads that may apply
43.87 + * the enqueue() method to those objects, collectors should link
43.88 + * discovered objects through the discovered field.
43.89 + */
43.90 +
43.91 + private T referent; /* Treated specially by GC */
43.92 +
43.93 + ReferenceQueue<? super T> queue;
43.94 +
43.95 + Reference next;
43.96 + transient private Reference<T> discovered; /* used by VM */
43.97 +
43.98 +
43.99 + /* Object used to synchronize with the garbage collector. The collector
43.100 + * must acquire this lock at the beginning of each collection cycle. It is
43.101 + * therefore critical that any code holding this lock complete as quickly
43.102 + * as possible, allocate no new objects, and avoid calling user code.
43.103 + */
43.104 + static private class Lock { };
43.105 + private static Lock lock = new Lock();
43.106 +
43.107 +
43.108 + /* List of References waiting to be enqueued. The collector adds
43.109 + * References to this list, while the Reference-handler thread removes
43.110 + * them. This list is protected by the above lock object.
43.111 + */
43.112 + private static Reference pending = null;
43.113 +
43.114 +
43.115 +
43.116 + /* -- Referent accessor and setters -- */
43.117 +
43.118 + /**
43.119 + * Returns this reference object's referent. If this reference object has
43.120 + * been cleared, either by the program or by the garbage collector, then
43.121 + * this method returns <code>null</code>.
43.122 + *
43.123 + * @return The object to which this reference refers, or
43.124 + * <code>null</code> if this reference object has been cleared
43.125 + */
43.126 + public T get() {
43.127 + return this.referent;
43.128 + }
43.129 +
43.130 + /**
43.131 + * Clears this reference object. Invoking this method will not cause this
43.132 + * object to be enqueued.
43.133 + *
43.134 + * <p> This method is invoked only by Java code; when the garbage collector
43.135 + * clears references it does so directly, without invoking this method.
43.136 + */
43.137 + public void clear() {
43.138 + this.referent = null;
43.139 + }
43.140 +
43.141 +
43.142 + /* -- Queue operations -- */
43.143 +
43.144 + /**
43.145 + * Tells whether or not this reference object has been enqueued, either by
43.146 + * the program or by the garbage collector. If this reference object was
43.147 + * not registered with a queue when it was created, then this method will
43.148 + * always return <code>false</code>.
43.149 + *
43.150 + * @return <code>true</code> if and only if this reference object has
43.151 + * been enqueued
43.152 + */
43.153 + public boolean isEnqueued() {
43.154 + /* In terms of the internal states, this predicate actually tests
43.155 + whether the instance is either Pending or Enqueued */
43.156 + synchronized (this) {
43.157 + return (this.queue != ReferenceQueue.NULL) && (this.next != null);
43.158 + }
43.159 + }
43.160 +
43.161 + /**
43.162 + * Adds this reference object to the queue with which it is registered,
43.163 + * if any.
43.164 + *
43.165 + * <p> This method is invoked only by Java code; when the garbage collector
43.166 + * enqueues references it does so directly, without invoking this method.
43.167 + *
43.168 + * @return <code>true</code> if this reference object was successfully
43.169 + * enqueued; <code>false</code> if it was already enqueued or if
43.170 + * it was not registered with a queue when it was created
43.171 + */
43.172 + public boolean enqueue() {
43.173 + return this.queue.enqueue(this);
43.174 + }
43.175 +
43.176 +
43.177 + /* -- Constructors -- */
43.178 +
43.179 + Reference(T referent) {
43.180 + this(referent, null);
43.181 + }
43.182 +
43.183 + Reference(T referent, ReferenceQueue<? super T> queue) {
43.184 + this.referent = referent;
43.185 + this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
43.186 + }
43.187 +
43.188 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java Tue Feb 05 17:04:22 2013 +0100
44.3 @@ -0,0 +1,148 @@
44.4 +/*
44.5 + * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44.7 + *
44.8 + * This code is free software; you can redistribute it and/or modify it
44.9 + * under the terms of the GNU General Public License version 2 only, as
44.10 + * published by the Free Software Foundation. Oracle designates this
44.11 + * particular file as subject to the "Classpath" exception as provided
44.12 + * by Oracle in the LICENSE file that accompanied this code.
44.13 + *
44.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
44.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
44.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44.17 + * version 2 for more details (a copy is included in the LICENSE file that
44.18 + * accompanied this code).
44.19 + *
44.20 + * You should have received a copy of the GNU General Public License version
44.21 + * 2 along with this work; if not, write to the Free Software Foundation,
44.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
44.23 + *
44.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
44.25 + * or visit www.oracle.com if you need additional information or have any
44.26 + * questions.
44.27 + */
44.28 +
44.29 +package java.lang.ref;
44.30 +
44.31 +/**
44.32 + * Reference queues, to which registered reference objects are appended by the
44.33 + * garbage collector after the appropriate reachability changes are detected.
44.34 + *
44.35 + * @author Mark Reinhold
44.36 + * @since 1.2
44.37 + */
44.38 +
44.39 +public class ReferenceQueue<T> {
44.40 +
44.41 + /**
44.42 + * Constructs a new reference-object queue.
44.43 + */
44.44 + public ReferenceQueue() { }
44.45 +
44.46 + private static class Null extends ReferenceQueue {
44.47 + boolean enqueue(Reference r) {
44.48 + return false;
44.49 + }
44.50 + }
44.51 +
44.52 + static ReferenceQueue NULL = new Null();
44.53 + static ReferenceQueue ENQUEUED = new Null();
44.54 +
44.55 + static private class Lock { };
44.56 + private Lock lock = new Lock();
44.57 + private volatile Reference<? extends T> head = null;
44.58 + private long queueLength = 0;
44.59 +
44.60 + boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
44.61 + synchronized (r) {
44.62 + if (r.queue == ENQUEUED) return false;
44.63 + synchronized (lock) {
44.64 + r.queue = ENQUEUED;
44.65 + r.next = (head == null) ? r : head;
44.66 + head = r;
44.67 + queueLength++;
44.68 + lock.notifyAll();
44.69 + return true;
44.70 + }
44.71 + }
44.72 + }
44.73 +
44.74 + private Reference<? extends T> reallyPoll() { /* Must hold lock */
44.75 + if (head != null) {
44.76 + Reference<? extends T> r = head;
44.77 + head = (r.next == r) ? null : r.next;
44.78 + r.queue = NULL;
44.79 + r.next = r;
44.80 + queueLength--;
44.81 + return r;
44.82 + }
44.83 + return null;
44.84 + }
44.85 +
44.86 + /**
44.87 + * Polls this queue to see if a reference object is available. If one is
44.88 + * available without further delay then it is removed from the queue and
44.89 + * returned. Otherwise this method immediately returns <tt>null</tt>.
44.90 + *
44.91 + * @return A reference object, if one was immediately available,
44.92 + * otherwise <code>null</code>
44.93 + */
44.94 + public Reference<? extends T> poll() {
44.95 + if (head == null)
44.96 + return null;
44.97 + synchronized (lock) {
44.98 + return reallyPoll();
44.99 + }
44.100 + }
44.101 +
44.102 + /**
44.103 + * Removes the next reference object in this queue, blocking until either
44.104 + * one becomes available or the given timeout period expires.
44.105 + *
44.106 + * <p> This method does not offer real-time guarantees: It schedules the
44.107 + * timeout as if by invoking the {@link Object#wait(long)} method.
44.108 + *
44.109 + * @param timeout If positive, block for up to <code>timeout</code>
44.110 + * milliseconds while waiting for a reference to be
44.111 + * added to this queue. If zero, block indefinitely.
44.112 + *
44.113 + * @return A reference object, if one was available within the specified
44.114 + * timeout period, otherwise <code>null</code>
44.115 + *
44.116 + * @throws IllegalArgumentException
44.117 + * If the value of the timeout argument is negative
44.118 + *
44.119 + * @throws InterruptedException
44.120 + * If the timeout wait is interrupted
44.121 + */
44.122 + public Reference<? extends T> remove(long timeout)
44.123 + throws IllegalArgumentException, InterruptedException
44.124 + {
44.125 + if (timeout < 0) {
44.126 + throw new IllegalArgumentException("Negative timeout value");
44.127 + }
44.128 + synchronized (lock) {
44.129 + Reference<? extends T> r = reallyPoll();
44.130 + if (r != null) return r;
44.131 + for (;;) {
44.132 + lock.wait(timeout);
44.133 + r = reallyPoll();
44.134 + if (r != null) return r;
44.135 + if (timeout != 0) return null;
44.136 + }
44.137 + }
44.138 + }
44.139 +
44.140 + /**
44.141 + * Removes the next reference object in this queue, blocking until one
44.142 + * becomes available.
44.143 + *
44.144 + * @return A reference object, blocking until one becomes available
44.145 + * @throws InterruptedException If the wait is interrupted
44.146 + */
44.147 + public Reference<? extends T> remove() throws InterruptedException {
44.148 + return remove(0);
44.149 + }
44.150 +
44.151 +}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/emul/compact/src/main/java/java/lang/ref/SoftReference.java Tue Feb 05 17:04:22 2013 +0100
45.3 @@ -0,0 +1,118 @@
45.4 +/*
45.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45.7 + *
45.8 + * This code is free software; you can redistribute it and/or modify it
45.9 + * under the terms of the GNU General Public License version 2 only, as
45.10 + * published by the Free Software Foundation. Oracle designates this
45.11 + * particular file as subject to the "Classpath" exception as provided
45.12 + * by Oracle in the LICENSE file that accompanied this code.
45.13 + *
45.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
45.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
45.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45.17 + * version 2 for more details (a copy is included in the LICENSE file that
45.18 + * accompanied this code).
45.19 + *
45.20 + * You should have received a copy of the GNU General Public License version
45.21 + * 2 along with this work; if not, write to the Free Software Foundation,
45.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
45.23 + *
45.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
45.25 + * or visit www.oracle.com if you need additional information or have any
45.26 + * questions.
45.27 + */
45.28 +
45.29 +package java.lang.ref;
45.30 +
45.31 +
45.32 +/**
45.33 + * Soft reference objects, which are cleared at the discretion of the garbage
45.34 + * collector in response to memory demand. Soft references are most often used
45.35 + * to implement memory-sensitive caches.
45.36 + *
45.37 + * <p> Suppose that the garbage collector determines at a certain point in time
45.38 + * that an object is <a href="package-summary.html#reachability">softly
45.39 + * reachable</a>. At that time it may choose to clear atomically all soft
45.40 + * references to that object and all soft references to any other
45.41 + * softly-reachable objects from which that object is reachable through a chain
45.42 + * of strong references. At the same time or at some later time it will
45.43 + * enqueue those newly-cleared soft references that are registered with
45.44 + * reference queues.
45.45 + *
45.46 + * <p> All soft references to softly-reachable objects are guaranteed to have
45.47 + * been cleared before the virtual machine throws an
45.48 + * <code>OutOfMemoryError</code>. Otherwise no constraints are placed upon the
45.49 + * time at which a soft reference will be cleared or the order in which a set
45.50 + * of such references to different objects will be cleared. Virtual machine
45.51 + * implementations are, however, encouraged to bias against clearing
45.52 + * recently-created or recently-used soft references.
45.53 + *
45.54 + * <p> Direct instances of this class may be used to implement simple caches;
45.55 + * this class or derived subclasses may also be used in larger data structures
45.56 + * to implement more sophisticated caches. As long as the referent of a soft
45.57 + * reference is strongly reachable, that is, is actually in use, the soft
45.58 + * reference will not be cleared. Thus a sophisticated cache can, for example,
45.59 + * prevent its most recently used entries from being discarded by keeping
45.60 + * strong referents to those entries, leaving the remaining entries to be
45.61 + * discarded at the discretion of the garbage collector.
45.62 + *
45.63 + * @author Mark Reinhold
45.64 + * @since 1.2
45.65 + */
45.66 +
45.67 +public class SoftReference<T> extends Reference<T> {
45.68 +
45.69 + /**
45.70 + * Timestamp clock, updated by the garbage collector
45.71 + */
45.72 + static private long clock;
45.73 +
45.74 + /**
45.75 + * Timestamp updated by each invocation of the get method. The VM may use
45.76 + * this field when selecting soft references to be cleared, but it is not
45.77 + * required to do so.
45.78 + */
45.79 + private long timestamp;
45.80 +
45.81 + /**
45.82 + * Creates a new soft reference that refers to the given object. The new
45.83 + * reference is not registered with any queue.
45.84 + *
45.85 + * @param referent object the new soft reference will refer to
45.86 + */
45.87 + public SoftReference(T referent) {
45.88 + super(referent);
45.89 + this.timestamp = clock;
45.90 + }
45.91 +
45.92 + /**
45.93 + * Creates a new soft reference that refers to the given object and is
45.94 + * registered with the given queue.
45.95 + *
45.96 + * @param referent object the new soft reference will refer to
45.97 + * @param q the queue with which the reference is to be registered,
45.98 + * or <tt>null</tt> if registration is not required
45.99 + *
45.100 + */
45.101 + public SoftReference(T referent, ReferenceQueue<? super T> q) {
45.102 + super(referent, q);
45.103 + this.timestamp = clock;
45.104 + }
45.105 +
45.106 + /**
45.107 + * Returns this reference object's referent. If this reference object has
45.108 + * been cleared, either by the program or by the garbage collector, then
45.109 + * this method returns <code>null</code>.
45.110 + *
45.111 + * @return The object to which this reference refers, or
45.112 + * <code>null</code> if this reference object has been cleared
45.113 + */
45.114 + public T get() {
45.115 + T o = super.get();
45.116 + if (o != null && this.timestamp != clock)
45.117 + this.timestamp = clock;
45.118 + return o;
45.119 + }
45.120 +
45.121 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/emul/compact/src/main/java/java/lang/ref/WeakReference.java Tue Feb 05 17:04:22 2013 +0100
46.3 @@ -0,0 +1,72 @@
46.4 +/*
46.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
46.7 + *
46.8 + * This code is free software; you can redistribute it and/or modify it
46.9 + * under the terms of the GNU General Public License version 2 only, as
46.10 + * published by the Free Software Foundation. Oracle designates this
46.11 + * particular file as subject to the "Classpath" exception as provided
46.12 + * by Oracle in the LICENSE file that accompanied this code.
46.13 + *
46.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
46.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
46.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46.17 + * version 2 for more details (a copy is included in the LICENSE file that
46.18 + * accompanied this code).
46.19 + *
46.20 + * You should have received a copy of the GNU General Public License version
46.21 + * 2 along with this work; if not, write to the Free Software Foundation,
46.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
46.23 + *
46.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
46.25 + * or visit www.oracle.com if you need additional information or have any
46.26 + * questions.
46.27 + */
46.28 +
46.29 +package java.lang.ref;
46.30 +
46.31 +
46.32 +/**
46.33 + * Weak reference objects, which do not prevent their referents from being
46.34 + * made finalizable, finalized, and then reclaimed. Weak references are most
46.35 + * often used to implement canonicalizing mappings.
46.36 + *
46.37 + * <p> Suppose that the garbage collector determines at a certain point in time
46.38 + * that an object is <a href="package-summary.html#reachability">weakly
46.39 + * reachable</a>. At that time it will atomically clear all weak references to
46.40 + * that object and all weak references to any other weakly-reachable objects
46.41 + * from which that object is reachable through a chain of strong and soft
46.42 + * references. At the same time it will declare all of the formerly
46.43 + * weakly-reachable objects to be finalizable. At the same time or at some
46.44 + * later time it will enqueue those newly-cleared weak references that are
46.45 + * registered with reference queues.
46.46 + *
46.47 + * @author Mark Reinhold
46.48 + * @since 1.2
46.49 + */
46.50 +
46.51 +public class WeakReference<T> extends Reference<T> {
46.52 +
46.53 + /**
46.54 + * Creates a new weak reference that refers to the given object. The new
46.55 + * reference is not registered with any queue.
46.56 + *
46.57 + * @param referent object the new weak reference will refer to
46.58 + */
46.59 + public WeakReference(T referent) {
46.60 + super(referent);
46.61 + }
46.62 +
46.63 + /**
46.64 + * Creates a new weak reference that refers to the given object and is
46.65 + * registered with the given queue.
46.66 + *
46.67 + * @param referent object the new weak reference will refer to
46.68 + * @param q the queue with which the reference is to be registered,
46.69 + * or <tt>null</tt> if registration is not required
46.70 + */
46.71 + public WeakReference(T referent, ReferenceQueue<? super T> q) {
46.72 + super(referent, q);
46.73 + }
46.74 +
46.75 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/emul/compact/src/main/java/java/lang/ref/package.html Tue Feb 05 17:04:22 2013 +0100
47.3 @@ -0,0 +1,147 @@
47.4 +<!--
47.5 + Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
47.6 + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47.7 +
47.8 + This code is free software; you can redistribute it and/or modify it
47.9 + under the terms of the GNU General Public License version 2 only, as
47.10 + published by the Free Software Foundation. Oracle designates this
47.11 + particular file as subject to the "Classpath" exception as provided
47.12 + by Oracle in the LICENSE file that accompanied this code.
47.13 +
47.14 + This code is distributed in the hope that it will be useful, but WITHOUT
47.15 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
47.16 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47.17 + version 2 for more details (a copy is included in the LICENSE file that
47.18 + accompanied this code).
47.19 +
47.20 + You should have received a copy of the GNU General Public License version
47.21 + 2 along with this work; if not, write to the Free Software Foundation,
47.22 + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
47.23 +
47.24 + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
47.25 + or visit www.oracle.com if you need additional information or have any
47.26 + questions.
47.27 +-->
47.28 +
47.29 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
47.30 +<html>
47.31 +<body bgcolor="white">
47.32 +
47.33 +
47.34 +Provides reference-object classes, which support a limited degree of
47.35 +interaction with the garbage collector. A program may use a reference object
47.36 +to maintain a reference to some other object in such a way that the latter
47.37 +object may still be reclaimed by the collector. A program may also arrange to
47.38 +be notified some time after the collector has determined that the reachability
47.39 +of a given object has changed.
47.40 +
47.41 +
47.42 +<h2>Package Specification</h2>
47.43 +
47.44 +A <em>reference object</em> encapsulates a reference to some other object so
47.45 +that the reference itself may be examined and manipulated like any other
47.46 +object. Three types of reference objects are provided, each weaker than the
47.47 +last: <em>soft</em>, <em>weak</em>, and <em>phantom</em>. Each type
47.48 +corresponds to a different level of reachability, as defined below. Soft
47.49 +references are for implementing memory-sensitive caches, weak references are
47.50 +for implementing canonicalizing mappings that do not prevent their keys (or
47.51 +values) from being reclaimed, and phantom references are for scheduling
47.52 +pre-mortem cleanup actions in a more flexible way than is possible with the
47.53 +Java finalization mechanism.
47.54 +
47.55 +<p> Each reference-object type is implemented by a subclass of the abstract
47.56 +base <code>{@link java.lang.ref.Reference}</code> class. An instance of one of
47.57 +these subclasses encapsulates a single reference to a particular object, called
47.58 +the <em>referent</em>. Every reference object provides methods for getting and
47.59 +clearing the reference. Aside from the clearing operation reference objects
47.60 +are otherwise immutable, so no <code>set</code> operation is provided. A
47.61 +program may further subclass these subclasses, adding whatever fields and
47.62 +methods are required for its purposes, or it may use these subclasses without
47.63 +change.
47.64 +
47.65 +
47.66 +<h3>Notification</h3>
47.67 +
47.68 +A program may request to be notified of changes in an object's reachability by
47.69 +<em>registering</em> an appropriate reference object with a <em>reference
47.70 +queue</em> at the time the reference object is created. Some time after the
47.71 +garbage collector determines that the reachability of the referent has changed
47.72 +to the value corresponding to the type of the reference, it will add the
47.73 +reference to the associated queue. At this point, the reference is considered
47.74 +to be <em>enqueued</em>. The program may remove references from a queue either
47.75 +by polling or by blocking until a reference becomes available. Reference
47.76 +queues are implemented by the <code>{@link java.lang.ref.ReferenceQueue}</code>
47.77 +class.
47.78 +
47.79 +<p> The relationship between a registered reference object and its queue is
47.80 +one-sided. That is, a queue does not keep track of the references that are
47.81 +registered with it. If a registered reference becomes unreachable itself, then
47.82 +it will never be enqueued. It is the responsibility of the program using
47.83 +reference objects to ensure that the objects remain reachable for as long as
47.84 +the program is interested in their referents.
47.85 +
47.86 +<p> While some programs will choose to dedicate a thread to removing reference
47.87 +objects from one or more queues and processing them, this is by no means
47.88 +necessary. A tactic that often works well is to examine a reference queue in
47.89 +the course of performing some other fairly-frequent action. For example, a
47.90 +hashtable that uses weak references to implement weak keys could poll its
47.91 +reference queue each time the table is accessed. This is how the <code>{@link
47.92 +java.util.WeakHashMap}</code> class works. Because the <code>{@link
47.93 +java.lang.ref.ReferenceQueue#poll ReferenceQueue.poll}</code> method simply
47.94 +checks an internal data structure, this check will add little overhead to the
47.95 +hashtable access methods.
47.96 +
47.97 +
47.98 +<h3>Automatically-cleared references</h3>
47.99 +
47.100 +Soft and weak references are automatically cleared by the collector before
47.101 +being added to the queues with which they are registered, if any. Therefore
47.102 +soft and weak references need not be registered with a queue in order to be
47.103 +useful, while phantom references do. An object that is reachable via phantom
47.104 +references will remain so until all such references are cleared or themselves
47.105 +become unreachable.
47.106 +
47.107 +
47.108 +<a name="reachability"></a>
47.109 +<h3>Reachability</h3>
47.110 +
47.111 +Going from strongest to weakest, the different levels of reachability reflect
47.112 +the life cycle of an object. They are operationally defined as follows:
47.113 +
47.114 +<ul>
47.115 +
47.116 +<li> An object is <em>strongly reachable</em> if it can be reached by some
47.117 +thread without traversing any reference objects. A newly-created object is
47.118 +strongly reachable by the thread that created it.
47.119 +
47.120 +<li> An object is <em>softly reachable</em> if it is not strongly reachable but
47.121 +can be reached by traversing a soft reference.
47.122 +
47.123 +<li> An object is <em>weakly reachable</em> if it is neither strongly nor
47.124 +softly reachable but can be reached by traversing a weak reference. When the
47.125 +weak references to a weakly-reachable object are cleared, the object becomes
47.126 +eligible for finalization.
47.127 +
47.128 +<li> An object is <em>phantom reachable</em> if it is neither strongly, softly,
47.129 +nor weakly reachable, it has been finalized, and some phantom reference refers
47.130 +to it.
47.131 +
47.132 +<li> Finally, an object is <em>unreachable</em>, and therefore eligible for
47.133 +reclamation, when it is not reachable in any of the above ways.
47.134 +
47.135 +</ul>
47.136 +
47.137 +
47.138 +@author Mark Reinhold
47.139 +@since 1.2
47.140 +
47.141 +<!--
47.142 +<h2>Related Documentation</h2>
47.143 +
47.144 +For overviews, tutorials, examples, guides, and tool documentation, please see:
47.145 +<ul>
47.146 + <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
47.147 +</ul>
47.148 +-->
47.149 +</body>
47.150 +</html>
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/emul/compact/src/main/java/java/util/AbstractQueue.java Tue Feb 05 17:04:22 2013 +0100
48.3 @@ -0,0 +1,192 @@
48.4 +/*
48.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
48.6 + *
48.7 + * This code is free software; you can redistribute it and/or modify it
48.8 + * under the terms of the GNU General Public License version 2 only, as
48.9 + * published by the Free Software Foundation. Oracle designates this
48.10 + * particular file as subject to the "Classpath" exception as provided
48.11 + * by Oracle in the LICENSE file that accompanied this code.
48.12 + *
48.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
48.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48.16 + * version 2 for more details (a copy is included in the LICENSE file that
48.17 + * accompanied this code).
48.18 + *
48.19 + * You should have received a copy of the GNU General Public License version
48.20 + * 2 along with this work; if not, write to the Free Software Foundation,
48.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
48.22 + *
48.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
48.24 + * or visit www.oracle.com if you need additional information or have any
48.25 + * questions.
48.26 + */
48.27 +
48.28 +/*
48.29 + * This file is available under and governed by the GNU General Public
48.30 + * License version 2 only, as published by the Free Software Foundation.
48.31 + * However, the following notice accompanied the original version of this
48.32 + * file:
48.33 + *
48.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
48.35 + * Expert Group and released to the public domain, as explained at
48.36 + * http://creativecommons.org/publicdomain/zero/1.0/
48.37 + */
48.38 +
48.39 +package java.util;
48.40 +
48.41 +/**
48.42 + * This class provides skeletal implementations of some {@link Queue}
48.43 + * operations. The implementations in this class are appropriate when
48.44 + * the base implementation does <em>not</em> allow <tt>null</tt>
48.45 + * elements. Methods {@link #add add}, {@link #remove remove}, and
48.46 + * {@link #element element} are based on {@link #offer offer}, {@link
48.47 + * #poll poll}, and {@link #peek peek}, respectively, but throw
48.48 + * exceptions instead of indicating failure via <tt>false</tt> or
48.49 + * <tt>null</tt> returns.
48.50 + *
48.51 + * <p>A <tt>Queue</tt> implementation that extends this class must
48.52 + * minimally define a method {@link Queue#offer} which does not permit
48.53 + * insertion of <tt>null</tt> elements, along with methods {@link
48.54 + * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and
48.55 + * {@link Collection#iterator}. Typically, additional methods will be
48.56 + * overridden as well. If these requirements cannot be met, consider
48.57 + * instead subclassing {@link AbstractCollection}.
48.58 + *
48.59 + * <p>This class is a member of the
48.60 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
48.61 + * Java Collections Framework</a>.
48.62 + *
48.63 + * @since 1.5
48.64 + * @author Doug Lea
48.65 + * @param <E> the type of elements held in this collection
48.66 + */
48.67 +public abstract class AbstractQueue<E>
48.68 + extends AbstractCollection<E>
48.69 + implements Queue<E> {
48.70 +
48.71 + /**
48.72 + * Constructor for use by subclasses.
48.73 + */
48.74 + protected AbstractQueue() {
48.75 + }
48.76 +
48.77 + /**
48.78 + * Inserts the specified element into this queue if it is possible to do so
48.79 + * immediately without violating capacity restrictions, returning
48.80 + * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
48.81 + * if no space is currently available.
48.82 + *
48.83 + * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds,
48.84 + * else throws an <tt>IllegalStateException</tt>.
48.85 + *
48.86 + * @param e the element to add
48.87 + * @return <tt>true</tt> (as specified by {@link Collection#add})
48.88 + * @throws IllegalStateException if the element cannot be added at this
48.89 + * time due to capacity restrictions
48.90 + * @throws ClassCastException if the class of the specified element
48.91 + * prevents it from being added to this queue
48.92 + * @throws NullPointerException if the specified element is null and
48.93 + * this queue does not permit null elements
48.94 + * @throws IllegalArgumentException if some property of this element
48.95 + * prevents it from being added to this queue
48.96 + */
48.97 + public boolean add(E e) {
48.98 + if (offer(e))
48.99 + return true;
48.100 + else
48.101 + throw new IllegalStateException("Queue full");
48.102 + }
48.103 +
48.104 + /**
48.105 + * Retrieves and removes the head of this queue. This method differs
48.106 + * from {@link #poll poll} only in that it throws an exception if this
48.107 + * queue is empty.
48.108 + *
48.109 + * <p>This implementation returns the result of <tt>poll</tt>
48.110 + * unless the queue is empty.
48.111 + *
48.112 + * @return the head of this queue
48.113 + * @throws NoSuchElementException if this queue is empty
48.114 + */
48.115 + public E remove() {
48.116 + E x = poll();
48.117 + if (x != null)
48.118 + return x;
48.119 + else
48.120 + throw new NoSuchElementException();
48.121 + }
48.122 +
48.123 + /**
48.124 + * Retrieves, but does not remove, the head of this queue. This method
48.125 + * differs from {@link #peek peek} only in that it throws an exception if
48.126 + * this queue is empty.
48.127 + *
48.128 + * <p>This implementation returns the result of <tt>peek</tt>
48.129 + * unless the queue is empty.
48.130 + *
48.131 + * @return the head of this queue
48.132 + * @throws NoSuchElementException if this queue is empty
48.133 + */
48.134 + public E element() {
48.135 + E x = peek();
48.136 + if (x != null)
48.137 + return x;
48.138 + else
48.139 + throw new NoSuchElementException();
48.140 + }
48.141 +
48.142 + /**
48.143 + * Removes all of the elements from this queue.
48.144 + * The queue will be empty after this call returns.
48.145 + *
48.146 + * <p>This implementation repeatedly invokes {@link #poll poll} until it
48.147 + * returns <tt>null</tt>.
48.148 + */
48.149 + public void clear() {
48.150 + while (poll() != null)
48.151 + ;
48.152 + }
48.153 +
48.154 + /**
48.155 + * Adds all of the elements in the specified collection to this
48.156 + * queue. Attempts to addAll of a queue to itself result in
48.157 + * <tt>IllegalArgumentException</tt>. Further, the behavior of
48.158 + * this operation is undefined if the specified collection is
48.159 + * modified while the operation is in progress.
48.160 + *
48.161 + * <p>This implementation iterates over the specified collection,
48.162 + * and adds each element returned by the iterator to this
48.163 + * queue, in turn. A runtime exception encountered while
48.164 + * trying to add an element (including, in particular, a
48.165 + * <tt>null</tt> element) may result in only some of the elements
48.166 + * having been successfully added when the associated exception is
48.167 + * thrown.
48.168 + *
48.169 + * @param c collection containing elements to be added to this queue
48.170 + * @return <tt>true</tt> if this queue changed as a result of the call
48.171 + * @throws ClassCastException if the class of an element of the specified
48.172 + * collection prevents it from being added to this queue
48.173 + * @throws NullPointerException if the specified collection contains a
48.174 + * null element and this queue does not permit null elements,
48.175 + * or if the specified collection is null
48.176 + * @throws IllegalArgumentException if some property of an element of the
48.177 + * specified collection prevents it from being added to this
48.178 + * queue, or if the specified collection is this queue
48.179 + * @throws IllegalStateException if not all the elements can be added at
48.180 + * this time due to insertion restrictions
48.181 + * @see #add(Object)
48.182 + */
48.183 + public boolean addAll(Collection<? extends E> c) {
48.184 + if (c == null)
48.185 + throw new NullPointerException();
48.186 + if (c == this)
48.187 + throw new IllegalArgumentException();
48.188 + boolean modified = false;
48.189 + for (E e : c)
48.190 + if (add(e))
48.191 + modified = true;
48.192 + return modified;
48.193 + }
48.194 +
48.195 +}
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/emul/compact/src/main/java/java/util/AbstractSequentialList.java Tue Feb 05 17:04:22 2013 +0100
49.3 @@ -0,0 +1,253 @@
49.4 +/*
49.5 + * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
49.7 + *
49.8 + * This code is free software; you can redistribute it and/or modify it
49.9 + * under the terms of the GNU General Public License version 2 only, as
49.10 + * published by the Free Software Foundation. Oracle designates this
49.11 + * particular file as subject to the "Classpath" exception as provided
49.12 + * by Oracle in the LICENSE file that accompanied this code.
49.13 + *
49.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
49.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49.17 + * version 2 for more details (a copy is included in the LICENSE file that
49.18 + * accompanied this code).
49.19 + *
49.20 + * You should have received a copy of the GNU General Public License version
49.21 + * 2 along with this work; if not, write to the Free Software Foundation,
49.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
49.23 + *
49.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
49.25 + * or visit www.oracle.com if you need additional information or have any
49.26 + * questions.
49.27 + */
49.28 +
49.29 +package java.util;
49.30 +
49.31 +/**
49.32 + * This class provides a skeletal implementation of the <tt>List</tt>
49.33 + * interface to minimize the effort required to implement this interface
49.34 + * backed by a "sequential access" data store (such as a linked list). For
49.35 + * random access data (such as an array), <tt>AbstractList</tt> should be used
49.36 + * in preference to this class.<p>
49.37 + *
49.38 + * This class is the opposite of the <tt>AbstractList</tt> class in the sense
49.39 + * that it implements the "random access" methods (<tt>get(int index)</tt>,
49.40 + * <tt>set(int index, E element)</tt>, <tt>add(int index, E element)</tt> and
49.41 + * <tt>remove(int index)</tt>) on top of the list's list iterator, instead of
49.42 + * the other way around.<p>
49.43 + *
49.44 + * To implement a list the programmer needs only to extend this class and
49.45 + * provide implementations for the <tt>listIterator</tt> and <tt>size</tt>
49.46 + * methods. For an unmodifiable list, the programmer need only implement the
49.47 + * list iterator's <tt>hasNext</tt>, <tt>next</tt>, <tt>hasPrevious</tt>,
49.48 + * <tt>previous</tt> and <tt>index</tt> methods.<p>
49.49 + *
49.50 + * For a modifiable list the programmer should additionally implement the list
49.51 + * iterator's <tt>set</tt> method. For a variable-size list the programmer
49.52 + * should additionally implement the list iterator's <tt>remove</tt> and
49.53 + * <tt>add</tt> methods.<p>
49.54 + *
49.55 + * The programmer should generally provide a void (no argument) and collection
49.56 + * constructor, as per the recommendation in the <tt>Collection</tt> interface
49.57 + * specification.<p>
49.58 + *
49.59 + * This class is a member of the
49.60 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
49.61 + * Java Collections Framework</a>.
49.62 + *
49.63 + * @author Josh Bloch
49.64 + * @author Neal Gafter
49.65 + * @see Collection
49.66 + * @see List
49.67 + * @see AbstractList
49.68 + * @see AbstractCollection
49.69 + * @since 1.2
49.70 + */
49.71 +
49.72 +public abstract class AbstractSequentialList<E> extends AbstractList<E> {
49.73 + /**
49.74 + * Sole constructor. (For invocation by subclass constructors, typically
49.75 + * implicit.)
49.76 + */
49.77 + protected AbstractSequentialList() {
49.78 + }
49.79 +
49.80 + /**
49.81 + * Returns the element at the specified position in this list.
49.82 + *
49.83 + * <p>This implementation first gets a list iterator pointing to the
49.84 + * indexed element (with <tt>listIterator(index)</tt>). Then, it gets
49.85 + * the element using <tt>ListIterator.next</tt> and returns it.
49.86 + *
49.87 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.88 + */
49.89 + public E get(int index) {
49.90 + try {
49.91 + return listIterator(index).next();
49.92 + } catch (NoSuchElementException exc) {
49.93 + throw new IndexOutOfBoundsException("Index: "+index);
49.94 + }
49.95 + }
49.96 +
49.97 + /**
49.98 + * Replaces the element at the specified position in this list with the
49.99 + * specified element (optional operation).
49.100 + *
49.101 + * <p>This implementation first gets a list iterator pointing to the
49.102 + * indexed element (with <tt>listIterator(index)</tt>). Then, it gets
49.103 + * the current element using <tt>ListIterator.next</tt> and replaces it
49.104 + * with <tt>ListIterator.set</tt>.
49.105 + *
49.106 + * <p>Note that this implementation will throw an
49.107 + * <tt>UnsupportedOperationException</tt> if the list iterator does not
49.108 + * implement the <tt>set</tt> operation.
49.109 + *
49.110 + * @throws UnsupportedOperationException {@inheritDoc}
49.111 + * @throws ClassCastException {@inheritDoc}
49.112 + * @throws NullPointerException {@inheritDoc}
49.113 + * @throws IllegalArgumentException {@inheritDoc}
49.114 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.115 + */
49.116 + public E set(int index, E element) {
49.117 + try {
49.118 + ListIterator<E> e = listIterator(index);
49.119 + E oldVal = e.next();
49.120 + e.set(element);
49.121 + return oldVal;
49.122 + } catch (NoSuchElementException exc) {
49.123 + throw new IndexOutOfBoundsException("Index: "+index);
49.124 + }
49.125 + }
49.126 +
49.127 + /**
49.128 + * Inserts the specified element at the specified position in this list
49.129 + * (optional operation). Shifts the element currently at that position
49.130 + * (if any) and any subsequent elements to the right (adds one to their
49.131 + * indices).
49.132 + *
49.133 + * <p>This implementation first gets a list iterator pointing to the
49.134 + * indexed element (with <tt>listIterator(index)</tt>). Then, it
49.135 + * inserts the specified element with <tt>ListIterator.add</tt>.
49.136 + *
49.137 + * <p>Note that this implementation will throw an
49.138 + * <tt>UnsupportedOperationException</tt> if the list iterator does not
49.139 + * implement the <tt>add</tt> operation.
49.140 + *
49.141 + * @throws UnsupportedOperationException {@inheritDoc}
49.142 + * @throws ClassCastException {@inheritDoc}
49.143 + * @throws NullPointerException {@inheritDoc}
49.144 + * @throws IllegalArgumentException {@inheritDoc}
49.145 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.146 + */
49.147 + public void add(int index, E element) {
49.148 + try {
49.149 + listIterator(index).add(element);
49.150 + } catch (NoSuchElementException exc) {
49.151 + throw new IndexOutOfBoundsException("Index: "+index);
49.152 + }
49.153 + }
49.154 +
49.155 + /**
49.156 + * Removes the element at the specified position in this list (optional
49.157 + * operation). Shifts any subsequent elements to the left (subtracts one
49.158 + * from their indices). Returns the element that was removed from the
49.159 + * list.
49.160 + *
49.161 + * <p>This implementation first gets a list iterator pointing to the
49.162 + * indexed element (with <tt>listIterator(index)</tt>). Then, it removes
49.163 + * the element with <tt>ListIterator.remove</tt>.
49.164 + *
49.165 + * <p>Note that this implementation will throw an
49.166 + * <tt>UnsupportedOperationException</tt> if the list iterator does not
49.167 + * implement the <tt>remove</tt> operation.
49.168 + *
49.169 + * @throws UnsupportedOperationException {@inheritDoc}
49.170 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.171 + */
49.172 + public E remove(int index) {
49.173 + try {
49.174 + ListIterator<E> e = listIterator(index);
49.175 + E outCast = e.next();
49.176 + e.remove();
49.177 + return outCast;
49.178 + } catch (NoSuchElementException exc) {
49.179 + throw new IndexOutOfBoundsException("Index: "+index);
49.180 + }
49.181 + }
49.182 +
49.183 +
49.184 + // Bulk Operations
49.185 +
49.186 + /**
49.187 + * Inserts all of the elements in the specified collection into this
49.188 + * list at the specified position (optional operation). Shifts the
49.189 + * element currently at that position (if any) and any subsequent
49.190 + * elements to the right (increases their indices). The new elements
49.191 + * will appear in this list in the order that they are returned by the
49.192 + * specified collection's iterator. The behavior of this operation is
49.193 + * undefined if the specified collection is modified while the
49.194 + * operation is in progress. (Note that this will occur if the specified
49.195 + * collection is this list, and it's nonempty.)
49.196 + *
49.197 + * <p>This implementation gets an iterator over the specified collection and
49.198 + * a list iterator over this list pointing to the indexed element (with
49.199 + * <tt>listIterator(index)</tt>). Then, it iterates over the specified
49.200 + * collection, inserting the elements obtained from the iterator into this
49.201 + * list, one at a time, using <tt>ListIterator.add</tt> followed by
49.202 + * <tt>ListIterator.next</tt> (to skip over the added element).
49.203 + *
49.204 + * <p>Note that this implementation will throw an
49.205 + * <tt>UnsupportedOperationException</tt> if the list iterator returned by
49.206 + * the <tt>listIterator</tt> method does not implement the <tt>add</tt>
49.207 + * operation.
49.208 + *
49.209 + * @throws UnsupportedOperationException {@inheritDoc}
49.210 + * @throws ClassCastException {@inheritDoc}
49.211 + * @throws NullPointerException {@inheritDoc}
49.212 + * @throws IllegalArgumentException {@inheritDoc}
49.213 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.214 + */
49.215 + public boolean addAll(int index, Collection<? extends E> c) {
49.216 + try {
49.217 + boolean modified = false;
49.218 + ListIterator<E> e1 = listIterator(index);
49.219 + Iterator<? extends E> e2 = c.iterator();
49.220 + while (e2.hasNext()) {
49.221 + e1.add(e2.next());
49.222 + modified = true;
49.223 + }
49.224 + return modified;
49.225 + } catch (NoSuchElementException exc) {
49.226 + throw new IndexOutOfBoundsException("Index: "+index);
49.227 + }
49.228 + }
49.229 +
49.230 +
49.231 + // Iterators
49.232 +
49.233 + /**
49.234 + * Returns an iterator over the elements in this list (in proper
49.235 + * sequence).<p>
49.236 + *
49.237 + * This implementation merely returns a list iterator over the list.
49.238 + *
49.239 + * @return an iterator over the elements in this list (in proper sequence)
49.240 + */
49.241 + public Iterator<E> iterator() {
49.242 + return listIterator();
49.243 + }
49.244 +
49.245 + /**
49.246 + * Returns a list iterator over the elements in this list (in proper
49.247 + * sequence).
49.248 + *
49.249 + * @param index index of first element to be returned from the list
49.250 + * iterator (by a call to the <code>next</code> method)
49.251 + * @return a list iterator over the elements in this list (in proper
49.252 + * sequence)
49.253 + * @throws IndexOutOfBoundsException {@inheritDoc}
49.254 + */
49.255 + public abstract ListIterator<E> listIterator(int index);
49.256 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/emul/compact/src/main/java/java/util/ArrayDeque.java Tue Feb 05 17:04:22 2013 +0100
50.3 @@ -0,0 +1,830 @@
50.4 +/*
50.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
50.6 + *
50.7 + * This code is free software; you can redistribute it and/or modify it
50.8 + * under the terms of the GNU General Public License version 2 only, as
50.9 + * published by the Free Software Foundation. Oracle designates this
50.10 + * particular file as subject to the "Classpath" exception as provided
50.11 + * by Oracle in the LICENSE file that accompanied this code.
50.12 + *
50.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
50.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
50.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50.16 + * version 2 for more details (a copy is included in the LICENSE file that
50.17 + * accompanied this code).
50.18 + *
50.19 + * You should have received a copy of the GNU General Public License version
50.20 + * 2 along with this work; if not, write to the Free Software Foundation,
50.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
50.22 + *
50.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
50.24 + * or visit www.oracle.com if you need additional information or have any
50.25 + * questions.
50.26 + */
50.27 +
50.28 +/*
50.29 + * This file is available under and governed by the GNU General Public
50.30 + * License version 2 only, as published by the Free Software Foundation.
50.31 + * However, the following notice accompanied the original version of this
50.32 + * file:
50.33 + *
50.34 + * Written by Josh Bloch of Google Inc. and released to the public domain,
50.35 + * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
50.36 + */
50.37 +
50.38 +package java.util;
50.39 +import java.io.*;
50.40 +
50.41 +/**
50.42 + * Resizable-array implementation of the {@link Deque} interface. Array
50.43 + * deques have no capacity restrictions; they grow as necessary to support
50.44 + * usage. They are not thread-safe; in the absence of external
50.45 + * synchronization, they do not support concurrent access by multiple threads.
50.46 + * Null elements are prohibited. This class is likely to be faster than
50.47 + * {@link Stack} when used as a stack, and faster than {@link LinkedList}
50.48 + * when used as a queue.
50.49 + *
50.50 + * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
50.51 + * Exceptions include {@link #remove(Object) remove}, {@link
50.52 + * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
50.53 + * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
50.54 + * iterator.remove()}, and the bulk operations, all of which run in linear
50.55 + * time.
50.56 + *
50.57 + * <p>The iterators returned by this class's <tt>iterator</tt> method are
50.58 + * <i>fail-fast</i>: If the deque is modified at any time after the iterator
50.59 + * is created, in any way except through the iterator's own <tt>remove</tt>
50.60 + * method, the iterator will generally throw a {@link
50.61 + * ConcurrentModificationException}. Thus, in the face of concurrent
50.62 + * modification, the iterator fails quickly and cleanly, rather than risking
50.63 + * arbitrary, non-deterministic behavior at an undetermined time in the
50.64 + * future.
50.65 + *
50.66 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
50.67 + * as it is, generally speaking, impossible to make any hard guarantees in the
50.68 + * presence of unsynchronized concurrent modification. Fail-fast iterators
50.69 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
50.70 + * Therefore, it would be wrong to write a program that depended on this
50.71 + * exception for its correctness: <i>the fail-fast behavior of iterators
50.72 + * should be used only to detect bugs.</i>
50.73 + *
50.74 + * <p>This class and its iterator implement all of the
50.75 + * <em>optional</em> methods of the {@link Collection} and {@link
50.76 + * Iterator} interfaces.
50.77 + *
50.78 + * <p>This class is a member of the
50.79 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
50.80 + * Java Collections Framework</a>.
50.81 + *
50.82 + * @author Josh Bloch and Doug Lea
50.83 + * @since 1.6
50.84 + * @param <E> the type of elements held in this collection
50.85 + */
50.86 +public class ArrayDeque<E> extends AbstractCollection<E>
50.87 + implements Deque<E>, Cloneable, Serializable
50.88 +{
50.89 + /**
50.90 + * The array in which the elements of the deque are stored.
50.91 + * The capacity of the deque is the length of this array, which is
50.92 + * always a power of two. The array is never allowed to become
50.93 + * full, except transiently within an addX method where it is
50.94 + * resized (see doubleCapacity) immediately upon becoming full,
50.95 + * thus avoiding head and tail wrapping around to equal each
50.96 + * other. We also guarantee that all array cells not holding
50.97 + * deque elements are always null.
50.98 + */
50.99 + private transient E[] elements;
50.100 +
50.101 + /**
50.102 + * The index of the element at the head of the deque (which is the
50.103 + * element that would be removed by remove() or pop()); or an
50.104 + * arbitrary number equal to tail if the deque is empty.
50.105 + */
50.106 + private transient int head;
50.107 +
50.108 + /**
50.109 + * The index at which the next element would be added to the tail
50.110 + * of the deque (via addLast(E), add(E), or push(E)).
50.111 + */
50.112 + private transient int tail;
50.113 +
50.114 + /**
50.115 + * The minimum capacity that we'll use for a newly created deque.
50.116 + * Must be a power of 2.
50.117 + */
50.118 + private static final int MIN_INITIAL_CAPACITY = 8;
50.119 +
50.120 + // ****** Array allocation and resizing utilities ******
50.121 +
50.122 + /**
50.123 + * Allocate empty array to hold the given number of elements.
50.124 + *
50.125 + * @param numElements the number of elements to hold
50.126 + */
50.127 + private void allocateElements(int numElements) {
50.128 + int initialCapacity = MIN_INITIAL_CAPACITY;
50.129 + // Find the best power of two to hold elements.
50.130 + // Tests "<=" because arrays aren't kept full.
50.131 + if (numElements >= initialCapacity) {
50.132 + initialCapacity = numElements;
50.133 + initialCapacity |= (initialCapacity >>> 1);
50.134 + initialCapacity |= (initialCapacity >>> 2);
50.135 + initialCapacity |= (initialCapacity >>> 4);
50.136 + initialCapacity |= (initialCapacity >>> 8);
50.137 + initialCapacity |= (initialCapacity >>> 16);
50.138 + initialCapacity++;
50.139 +
50.140 + if (initialCapacity < 0) // Too many elements, must back off
50.141 + initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
50.142 + }
50.143 + elements = (E[]) new Object[initialCapacity];
50.144 + }
50.145 +
50.146 + /**
50.147 + * Double the capacity of this deque. Call only when full, i.e.,
50.148 + * when head and tail have wrapped around to become equal.
50.149 + */
50.150 + private void doubleCapacity() {
50.151 + assert head == tail;
50.152 + int p = head;
50.153 + int n = elements.length;
50.154 + int r = n - p; // number of elements to the right of p
50.155 + int newCapacity = n << 1;
50.156 + if (newCapacity < 0)
50.157 + throw new IllegalStateException("Sorry, deque too big");
50.158 + Object[] a = new Object[newCapacity];
50.159 + System.arraycopy(elements, p, a, 0, r);
50.160 + System.arraycopy(elements, 0, a, r, p);
50.161 + elements = (E[])a;
50.162 + head = 0;
50.163 + tail = n;
50.164 + }
50.165 +
50.166 + /**
50.167 + * Copies the elements from our element array into the specified array,
50.168 + * in order (from first to last element in the deque). It is assumed
50.169 + * that the array is large enough to hold all elements in the deque.
50.170 + *
50.171 + * @return its argument
50.172 + */
50.173 + private <T> T[] copyElements(T[] a) {
50.174 + if (head < tail) {
50.175 + System.arraycopy(elements, head, a, 0, size());
50.176 + } else if (head > tail) {
50.177 + int headPortionLen = elements.length - head;
50.178 + System.arraycopy(elements, head, a, 0, headPortionLen);
50.179 + System.arraycopy(elements, 0, a, headPortionLen, tail);
50.180 + }
50.181 + return a;
50.182 + }
50.183 +
50.184 + /**
50.185 + * Constructs an empty array deque with an initial capacity
50.186 + * sufficient to hold 16 elements.
50.187 + */
50.188 + public ArrayDeque() {
50.189 + elements = (E[]) new Object[16];
50.190 + }
50.191 +
50.192 + /**
50.193 + * Constructs an empty array deque with an initial capacity
50.194 + * sufficient to hold the specified number of elements.
50.195 + *
50.196 + * @param numElements lower bound on initial capacity of the deque
50.197 + */
50.198 + public ArrayDeque(int numElements) {
50.199 + allocateElements(numElements);
50.200 + }
50.201 +
50.202 + /**
50.203 + * Constructs a deque containing the elements of the specified
50.204 + * collection, in the order they are returned by the collection's
50.205 + * iterator. (The first element returned by the collection's
50.206 + * iterator becomes the first element, or <i>front</i> of the
50.207 + * deque.)
50.208 + *
50.209 + * @param c the collection whose elements are to be placed into the deque
50.210 + * @throws NullPointerException if the specified collection is null
50.211 + */
50.212 + public ArrayDeque(Collection<? extends E> c) {
50.213 + allocateElements(c.size());
50.214 + addAll(c);
50.215 + }
50.216 +
50.217 + // The main insertion and extraction methods are addFirst,
50.218 + // addLast, pollFirst, pollLast. The other methods are defined in
50.219 + // terms of these.
50.220 +
50.221 + /**
50.222 + * Inserts the specified element at the front of this deque.
50.223 + *
50.224 + * @param e the element to add
50.225 + * @throws NullPointerException if the specified element is null
50.226 + */
50.227 + public void addFirst(E e) {
50.228 + if (e == null)
50.229 + throw new NullPointerException();
50.230 + elements[head = (head - 1) & (elements.length - 1)] = e;
50.231 + if (head == tail)
50.232 + doubleCapacity();
50.233 + }
50.234 +
50.235 + /**
50.236 + * Inserts the specified element at the end of this deque.
50.237 + *
50.238 + * <p>This method is equivalent to {@link #add}.
50.239 + *
50.240 + * @param e the element to add
50.241 + * @throws NullPointerException if the specified element is null
50.242 + */
50.243 + public void addLast(E e) {
50.244 + if (e == null)
50.245 + throw new NullPointerException();
50.246 + elements[tail] = e;
50.247 + if ( (tail = (tail + 1) & (elements.length - 1)) == head)
50.248 + doubleCapacity();
50.249 + }
50.250 +
50.251 + /**
50.252 + * Inserts the specified element at the front of this deque.
50.253 + *
50.254 + * @param e the element to add
50.255 + * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
50.256 + * @throws NullPointerException if the specified element is null
50.257 + */
50.258 + public boolean offerFirst(E e) {
50.259 + addFirst(e);
50.260 + return true;
50.261 + }
50.262 +
50.263 + /**
50.264 + * Inserts the specified element at the end of this deque.
50.265 + *
50.266 + * @param e the element to add
50.267 + * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
50.268 + * @throws NullPointerException if the specified element is null
50.269 + */
50.270 + public boolean offerLast(E e) {
50.271 + addLast(e);
50.272 + return true;
50.273 + }
50.274 +
50.275 + /**
50.276 + * @throws NoSuchElementException {@inheritDoc}
50.277 + */
50.278 + public E removeFirst() {
50.279 + E x = pollFirst();
50.280 + if (x == null)
50.281 + throw new NoSuchElementException();
50.282 + return x;
50.283 + }
50.284 +
50.285 + /**
50.286 + * @throws NoSuchElementException {@inheritDoc}
50.287 + */
50.288 + public E removeLast() {
50.289 + E x = pollLast();
50.290 + if (x == null)
50.291 + throw new NoSuchElementException();
50.292 + return x;
50.293 + }
50.294 +
50.295 + public E pollFirst() {
50.296 + int h = head;
50.297 + E result = elements[h]; // Element is null if deque empty
50.298 + if (result == null)
50.299 + return null;
50.300 + elements[h] = null; // Must null out slot
50.301 + head = (h + 1) & (elements.length - 1);
50.302 + return result;
50.303 + }
50.304 +
50.305 + public E pollLast() {
50.306 + int t = (tail - 1) & (elements.length - 1);
50.307 + E result = elements[t];
50.308 + if (result == null)
50.309 + return null;
50.310 + elements[t] = null;
50.311 + tail = t;
50.312 + return result;
50.313 + }
50.314 +
50.315 + /**
50.316 + * @throws NoSuchElementException {@inheritDoc}
50.317 + */
50.318 + public E getFirst() {
50.319 + E x = elements[head];
50.320 + if (x == null)
50.321 + throw new NoSuchElementException();
50.322 + return x;
50.323 + }
50.324 +
50.325 + /**
50.326 + * @throws NoSuchElementException {@inheritDoc}
50.327 + */
50.328 + public E getLast() {
50.329 + E x = elements[(tail - 1) & (elements.length - 1)];
50.330 + if (x == null)
50.331 + throw new NoSuchElementException();
50.332 + return x;
50.333 + }
50.334 +
50.335 + public E peekFirst() {
50.336 + return elements[head]; // elements[head] is null if deque empty
50.337 + }
50.338 +
50.339 + public E peekLast() {
50.340 + return elements[(tail - 1) & (elements.length - 1)];
50.341 + }
50.342 +
50.343 + /**
50.344 + * Removes the first occurrence of the specified element in this
50.345 + * deque (when traversing the deque from head to tail).
50.346 + * If the deque does not contain the element, it is unchanged.
50.347 + * More formally, removes the first element <tt>e</tt> such that
50.348 + * <tt>o.equals(e)</tt> (if such an element exists).
50.349 + * Returns <tt>true</tt> if this deque contained the specified element
50.350 + * (or equivalently, if this deque changed as a result of the call).
50.351 + *
50.352 + * @param o element to be removed from this deque, if present
50.353 + * @return <tt>true</tt> if the deque contained the specified element
50.354 + */
50.355 + public boolean removeFirstOccurrence(Object o) {
50.356 + if (o == null)
50.357 + return false;
50.358 + int mask = elements.length - 1;
50.359 + int i = head;
50.360 + E x;
50.361 + while ( (x = elements[i]) != null) {
50.362 + if (o.equals(x)) {
50.363 + delete(i);
50.364 + return true;
50.365 + }
50.366 + i = (i + 1) & mask;
50.367 + }
50.368 + return false;
50.369 + }
50.370 +
50.371 + /**
50.372 + * Removes the last occurrence of the specified element in this
50.373 + * deque (when traversing the deque from head to tail).
50.374 + * If the deque does not contain the element, it is unchanged.
50.375 + * More formally, removes the last element <tt>e</tt> such that
50.376 + * <tt>o.equals(e)</tt> (if such an element exists).
50.377 + * Returns <tt>true</tt> if this deque contained the specified element
50.378 + * (or equivalently, if this deque changed as a result of the call).
50.379 + *
50.380 + * @param o element to be removed from this deque, if present
50.381 + * @return <tt>true</tt> if the deque contained the specified element
50.382 + */
50.383 + public boolean removeLastOccurrence(Object o) {
50.384 + if (o == null)
50.385 + return false;
50.386 + int mask = elements.length - 1;
50.387 + int i = (tail - 1) & mask;
50.388 + E x;
50.389 + while ( (x = elements[i]) != null) {
50.390 + if (o.equals(x)) {
50.391 + delete(i);
50.392 + return true;
50.393 + }
50.394 + i = (i - 1) & mask;
50.395 + }
50.396 + return false;
50.397 + }
50.398 +
50.399 + // *** Queue methods ***
50.400 +
50.401 + /**
50.402 + * Inserts the specified element at the end of this deque.
50.403 + *
50.404 + * <p>This method is equivalent to {@link #addLast}.
50.405 + *
50.406 + * @param e the element to add
50.407 + * @return <tt>true</tt> (as specified by {@link Collection#add})
50.408 + * @throws NullPointerException if the specified element is null
50.409 + */
50.410 + public boolean add(E e) {
50.411 + addLast(e);
50.412 + return true;
50.413 + }
50.414 +
50.415 + /**
50.416 + * Inserts the specified element at the end of this deque.
50.417 + *
50.418 + * <p>This method is equivalent to {@link #offerLast}.
50.419 + *
50.420 + * @param e the element to add
50.421 + * @return <tt>true</tt> (as specified by {@link Queue#offer})
50.422 + * @throws NullPointerException if the specified element is null
50.423 + */
50.424 + public boolean offer(E e) {
50.425 + return offerLast(e);
50.426 + }
50.427 +
50.428 + /**
50.429 + * Retrieves and removes the head of the queue represented by this deque.
50.430 + *
50.431 + * This method differs from {@link #poll poll} only in that it throws an
50.432 + * exception if this deque is empty.
50.433 + *
50.434 + * <p>This method is equivalent to {@link #removeFirst}.
50.435 + *
50.436 + * @return the head of the queue represented by this deque
50.437 + * @throws NoSuchElementException {@inheritDoc}
50.438 + */
50.439 + public E remove() {
50.440 + return removeFirst();
50.441 + }
50.442 +
50.443 + /**
50.444 + * Retrieves and removes the head of the queue represented by this deque
50.445 + * (in other words, the first element of this deque), or returns
50.446 + * <tt>null</tt> if this deque is empty.
50.447 + *
50.448 + * <p>This method is equivalent to {@link #pollFirst}.
50.449 + *
50.450 + * @return the head of the queue represented by this deque, or
50.451 + * <tt>null</tt> if this deque is empty
50.452 + */
50.453 + public E poll() {
50.454 + return pollFirst();
50.455 + }
50.456 +
50.457 + /**
50.458 + * Retrieves, but does not remove, the head of the queue represented by
50.459 + * this deque. This method differs from {@link #peek peek} only in
50.460 + * that it throws an exception if this deque is empty.
50.461 + *
50.462 + * <p>This method is equivalent to {@link #getFirst}.
50.463 + *
50.464 + * @return the head of the queue represented by this deque
50.465 + * @throws NoSuchElementException {@inheritDoc}
50.466 + */
50.467 + public E element() {
50.468 + return getFirst();
50.469 + }
50.470 +
50.471 + /**
50.472 + * Retrieves, but does not remove, the head of the queue represented by
50.473 + * this deque, or returns <tt>null</tt> if this deque is empty.
50.474 + *
50.475 + * <p>This method is equivalent to {@link #peekFirst}.
50.476 + *
50.477 + * @return the head of the queue represented by this deque, or
50.478 + * <tt>null</tt> if this deque is empty
50.479 + */
50.480 + public E peek() {
50.481 + return peekFirst();
50.482 + }
50.483 +
50.484 + // *** Stack methods ***
50.485 +
50.486 + /**
50.487 + * Pushes an element onto the stack represented by this deque. In other
50.488 + * words, inserts the element at the front of this deque.
50.489 + *
50.490 + * <p>This method is equivalent to {@link #addFirst}.
50.491 + *
50.492 + * @param e the element to push
50.493 + * @throws NullPointerException if the specified element is null
50.494 + */
50.495 + public void push(E e) {
50.496 + addFirst(e);
50.497 + }
50.498 +
50.499 + /**
50.500 + * Pops an element from the stack represented by this deque. In other
50.501 + * words, removes and returns the first element of this deque.
50.502 + *
50.503 + * <p>This method is equivalent to {@link #removeFirst()}.
50.504 + *
50.505 + * @return the element at the front of this deque (which is the top
50.506 + * of the stack represented by this deque)
50.507 + * @throws NoSuchElementException {@inheritDoc}
50.508 + */
50.509 + public E pop() {
50.510 + return removeFirst();
50.511 + }
50.512 +
50.513 + private void checkInvariants() {
50.514 + assert elements[tail] == null;
50.515 + assert head == tail ? elements[head] == null :
50.516 + (elements[head] != null &&
50.517 + elements[(tail - 1) & (elements.length - 1)] != null);
50.518 + assert elements[(head - 1) & (elements.length - 1)] == null;
50.519 + }
50.520 +
50.521 + /**
50.522 + * Removes the element at the specified position in the elements array,
50.523 + * adjusting head and tail as necessary. This can result in motion of
50.524 + * elements backwards or forwards in the array.
50.525 + *
50.526 + * <p>This method is called delete rather than remove to emphasize
50.527 + * that its semantics differ from those of {@link List#remove(int)}.
50.528 + *
50.529 + * @return true if elements moved backwards
50.530 + */
50.531 + private boolean delete(int i) {
50.532 + checkInvariants();
50.533 + final E[] elements = this.elements;
50.534 + final int mask = elements.length - 1;
50.535 + final int h = head;
50.536 + final int t = tail;
50.537 + final int front = (i - h) & mask;
50.538 + final int back = (t - i) & mask;
50.539 +
50.540 + // Invariant: head <= i < tail mod circularity
50.541 + if (front >= ((t - h) & mask))
50.542 + throw new ConcurrentModificationException();
50.543 +
50.544 + // Optimize for least element motion
50.545 + if (front < back) {
50.546 + if (h <= i) {
50.547 + System.arraycopy(elements, h, elements, h + 1, front);
50.548 + } else { // Wrap around
50.549 + System.arraycopy(elements, 0, elements, 1, i);
50.550 + elements[0] = elements[mask];
50.551 + System.arraycopy(elements, h, elements, h + 1, mask - h);
50.552 + }
50.553 + elements[h] = null;
50.554 + head = (h + 1) & mask;
50.555 + return false;
50.556 + } else {
50.557 + if (i < t) { // Copy the null tail as well
50.558 + System.arraycopy(elements, i + 1, elements, i, back);
50.559 + tail = t - 1;
50.560 + } else { // Wrap around
50.561 + System.arraycopy(elements, i + 1, elements, i, mask - i);
50.562 + elements[mask] = elements[0];
50.563 + System.arraycopy(elements, 1, elements, 0, t);
50.564 + tail = (t - 1) & mask;
50.565 + }
50.566 + return true;
50.567 + }
50.568 + }
50.569 +
50.570 + // *** Collection Methods ***
50.571 +
50.572 + /**
50.573 + * Returns the number of elements in this deque.
50.574 + *
50.575 + * @return the number of elements in this deque
50.576 + */
50.577 + public int size() {
50.578 + return (tail - head) & (elements.length - 1);
50.579 + }
50.580 +
50.581 + /**
50.582 + * Returns <tt>true</tt> if this deque contains no elements.
50.583 + *
50.584 + * @return <tt>true</tt> if this deque contains no elements
50.585 + */
50.586 + public boolean isEmpty() {
50.587 + return head == tail;
50.588 + }
50.589 +
50.590 + /**
50.591 + * Returns an iterator over the elements in this deque. The elements
50.592 + * will be ordered from first (head) to last (tail). This is the same
50.593 + * order that elements would be dequeued (via successive calls to
50.594 + * {@link #remove} or popped (via successive calls to {@link #pop}).
50.595 + *
50.596 + * @return an iterator over the elements in this deque
50.597 + */
50.598 + public Iterator<E> iterator() {
50.599 + return new DeqIterator();
50.600 + }
50.601 +
50.602 + public Iterator<E> descendingIterator() {
50.603 + return new DescendingIterator();
50.604 + }
50.605 +
50.606 + private class DeqIterator implements Iterator<E> {
50.607 + /**
50.608 + * Index of element to be returned by subsequent call to next.
50.609 + */
50.610 + private int cursor = head;
50.611 +
50.612 + /**
50.613 + * Tail recorded at construction (also in remove), to stop
50.614 + * iterator and also to check for comodification.
50.615 + */
50.616 + private int fence = tail;
50.617 +
50.618 + /**
50.619 + * Index of element returned by most recent call to next.
50.620 + * Reset to -1 if element is deleted by a call to remove.
50.621 + */
50.622 + private int lastRet = -1;
50.623 +
50.624 + public boolean hasNext() {
50.625 + return cursor != fence;
50.626 + }
50.627 +
50.628 + public E next() {
50.629 + if (cursor == fence)
50.630 + throw new NoSuchElementException();
50.631 + E result = elements[cursor];
50.632 + // This check doesn't catch all possible comodifications,
50.633 + // but does catch the ones that corrupt traversal
50.634 + if (tail != fence || result == null)
50.635 + throw new ConcurrentModificationException();
50.636 + lastRet = cursor;
50.637 + cursor = (cursor + 1) & (elements.length - 1);
50.638 + return result;
50.639 + }
50.640 +
50.641 + public void remove() {
50.642 + if (lastRet < 0)
50.643 + throw new IllegalStateException();
50.644 + if (delete(lastRet)) { // if left-shifted, undo increment in next()
50.645 + cursor = (cursor - 1) & (elements.length - 1);
50.646 + fence = tail;
50.647 + }
50.648 + lastRet = -1;
50.649 + }
50.650 + }
50.651 +
50.652 + private class DescendingIterator implements Iterator<E> {
50.653 + /*
50.654 + * This class is nearly a mirror-image of DeqIterator, using
50.655 + * tail instead of head for initial cursor, and head instead of
50.656 + * tail for fence.
50.657 + */
50.658 + private int cursor = tail;
50.659 + private int fence = head;
50.660 + private int lastRet = -1;
50.661 +
50.662 + public boolean hasNext() {
50.663 + return cursor != fence;
50.664 + }
50.665 +
50.666 + public E next() {
50.667 + if (cursor == fence)
50.668 + throw new NoSuchElementException();
50.669 + cursor = (cursor - 1) & (elements.length - 1);
50.670 + E result = elements[cursor];
50.671 + if (head != fence || result == null)
50.672 + throw new ConcurrentModificationException();
50.673 + lastRet = cursor;
50.674 + return result;
50.675 + }
50.676 +
50.677 + public void remove() {
50.678 + if (lastRet < 0)
50.679 + throw new IllegalStateException();
50.680 + if (!delete(lastRet)) {
50.681 + cursor = (cursor + 1) & (elements.length - 1);
50.682 + fence = head;
50.683 + }
50.684 + lastRet = -1;
50.685 + }
50.686 + }
50.687 +
50.688 + /**
50.689 + * Returns <tt>true</tt> if this deque contains the specified element.
50.690 + * More formally, returns <tt>true</tt> if and only if this deque contains
50.691 + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
50.692 + *
50.693 + * @param o object to be checked for containment in this deque
50.694 + * @return <tt>true</tt> if this deque contains the specified element
50.695 + */
50.696 + public boolean contains(Object o) {
50.697 + if (o == null)
50.698 + return false;
50.699 + int mask = elements.length - 1;
50.700 + int i = head;
50.701 + E x;
50.702 + while ( (x = elements[i]) != null) {
50.703 + if (o.equals(x))
50.704 + return true;
50.705 + i = (i + 1) & mask;
50.706 + }
50.707 + return false;
50.708 + }
50.709 +
50.710 + /**
50.711 + * Removes a single instance of the specified element from this deque.
50.712 + * If the deque does not contain the element, it is unchanged.
50.713 + * More formally, removes the first element <tt>e</tt> such that
50.714 + * <tt>o.equals(e)</tt> (if such an element exists).
50.715 + * Returns <tt>true</tt> if this deque contained the specified element
50.716 + * (or equivalently, if this deque changed as a result of the call).
50.717 + *
50.718 + * <p>This method is equivalent to {@link #removeFirstOccurrence}.
50.719 + *
50.720 + * @param o element to be removed from this deque, if present
50.721 + * @return <tt>true</tt> if this deque contained the specified element
50.722 + */
50.723 + public boolean remove(Object o) {
50.724 + return removeFirstOccurrence(o);
50.725 + }
50.726 +
50.727 + /**
50.728 + * Removes all of the elements from this deque.
50.729 + * The deque will be empty after this call returns.
50.730 + */
50.731 + public void clear() {
50.732 + int h = head;
50.733 + int t = tail;
50.734 + if (h != t) { // clear all cells
50.735 + head = tail = 0;
50.736 + int i = h;
50.737 + int mask = elements.length - 1;
50.738 + do {
50.739 + elements[i] = null;
50.740 + i = (i + 1) & mask;
50.741 + } while (i != t);
50.742 + }
50.743 + }
50.744 +
50.745 + /**
50.746 + * Returns an array containing all of the elements in this deque
50.747 + * in proper sequence (from first to last element).
50.748 + *
50.749 + * <p>The returned array will be "safe" in that no references to it are
50.750 + * maintained by this deque. (In other words, this method must allocate
50.751 + * a new array). The caller is thus free to modify the returned array.
50.752 + *
50.753 + * <p>This method acts as bridge between array-based and collection-based
50.754 + * APIs.
50.755 + *
50.756 + * @return an array containing all of the elements in this deque
50.757 + */
50.758 + public Object[] toArray() {
50.759 + return copyElements(new Object[size()]);
50.760 + }
50.761 +
50.762 + /**
50.763 + * Returns an array containing all of the elements in this deque in
50.764 + * proper sequence (from first to last element); the runtime type of the
50.765 + * returned array is that of the specified array. If the deque fits in
50.766 + * the specified array, it is returned therein. Otherwise, a new array
50.767 + * is allocated with the runtime type of the specified array and the
50.768 + * size of this deque.
50.769 + *
50.770 + * <p>If this deque fits in the specified array with room to spare
50.771 + * (i.e., the array has more elements than this deque), the element in
50.772 + * the array immediately following the end of the deque is set to
50.773 + * <tt>null</tt>.
50.774 + *
50.775 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
50.776 + * array-based and collection-based APIs. Further, this method allows
50.777 + * precise control over the runtime type of the output array, and may,
50.778 + * under certain circumstances, be used to save allocation costs.
50.779 + *
50.780 + * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
50.781 + * The following code can be used to dump the deque into a newly
50.782 + * allocated array of <tt>String</tt>:
50.783 + *
50.784 + * <pre>
50.785 + * String[] y = x.toArray(new String[0]);</pre>
50.786 + *
50.787 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
50.788 + * <tt>toArray()</tt>.
50.789 + *
50.790 + * @param a the array into which the elements of the deque are to
50.791 + * be stored, if it is big enough; otherwise, a new array of the
50.792 + * same runtime type is allocated for this purpose
50.793 + * @return an array containing all of the elements in this deque
50.794 + * @throws ArrayStoreException if the runtime type of the specified array
50.795 + * is not a supertype of the runtime type of every element in
50.796 + * this deque
50.797 + * @throws NullPointerException if the specified array is null
50.798 + */
50.799 + public <T> T[] toArray(T[] a) {
50.800 + int size = size();
50.801 + if (a.length < size)
50.802 + a = (T[])java.lang.reflect.Array.newInstance(
50.803 + a.getClass().getComponentType(), size);
50.804 + copyElements(a);
50.805 + if (a.length > size)
50.806 + a[size] = null;
50.807 + return a;
50.808 + }
50.809 +
50.810 + // *** Object methods ***
50.811 +
50.812 + /**
50.813 + * Returns a copy of this deque.
50.814 + *
50.815 + * @return a copy of this deque
50.816 + */
50.817 + public ArrayDeque<E> clone() {
50.818 + try {
50.819 + ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
50.820 + result.elements = Arrays.copyOf(elements, elements.length);
50.821 + return result;
50.822 +
50.823 + } catch (CloneNotSupportedException e) {
50.824 + throw new AssertionError();
50.825 + }
50.826 + }
50.827 +
50.828 + /**
50.829 + * Appease the serialization gods.
50.830 + */
50.831 + private static final long serialVersionUID = 2340985798034038923L;
50.832 +
50.833 +}
51.1 --- a/emul/compact/src/main/java/java/util/ArrayList.java Tue Feb 05 16:40:01 2013 +0100
51.2 +++ b/emul/compact/src/main/java/java/util/ArrayList.java Tue Feb 05 17:04:22 2013 +0100
51.3 @@ -25,7 +25,6 @@
51.4
51.5 package java.util;
51.6
51.7 -import org.apidesign.bck2brwsr.emul.lang.System;
51.8
51.9 /**
51.10 * Resizable-array implementation of the <tt>List</tt> interface. Implements
52.1 --- a/emul/compact/src/main/java/java/util/Arrays.java Tue Feb 05 16:40:01 2013 +0100
52.2 +++ b/emul/compact/src/main/java/java/util/Arrays.java Tue Feb 05 17:04:22 2013 +0100
52.3 @@ -26,7 +26,6 @@
52.4 package java.util;
52.5
52.6 import java.lang.reflect.*;
52.7 -import org.apidesign.bck2brwsr.emul.lang.System;
52.8
52.9 /**
52.10 * This class contains various methods for manipulating arrays (such as
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/emul/compact/src/main/java/java/util/Collections.java Tue Feb 05 17:04:22 2013 +0100
53.3 @@ -0,0 +1,3953 @@
53.4 +/*
53.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
53.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
53.7 + *
53.8 + * This code is free software; you can redistribute it and/or modify it
53.9 + * under the terms of the GNU General Public License version 2 only, as
53.10 + * published by the Free Software Foundation. Oracle designates this
53.11 + * particular file as subject to the "Classpath" exception as provided
53.12 + * by Oracle in the LICENSE file that accompanied this code.
53.13 + *
53.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
53.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
53.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
53.17 + * version 2 for more details (a copy is included in the LICENSE file that
53.18 + * accompanied this code).
53.19 + *
53.20 + * You should have received a copy of the GNU General Public License version
53.21 + * 2 along with this work; if not, write to the Free Software Foundation,
53.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
53.23 + *
53.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
53.25 + * or visit www.oracle.com if you need additional information or have any
53.26 + * questions.
53.27 + */
53.28 +
53.29 +package java.util;
53.30 +import java.io.Serializable;
53.31 +import java.io.IOException;
53.32 +import java.lang.reflect.Array;
53.33 +
53.34 +/**
53.35 + * This class consists exclusively of static methods that operate on or return
53.36 + * collections. It contains polymorphic algorithms that operate on
53.37 + * collections, "wrappers", which return a new collection backed by a
53.38 + * specified collection, and a few other odds and ends.
53.39 + *
53.40 + * <p>The methods of this class all throw a <tt>NullPointerException</tt>
53.41 + * if the collections or class objects provided to them are null.
53.42 + *
53.43 + * <p>The documentation for the polymorphic algorithms contained in this class
53.44 + * generally includes a brief description of the <i>implementation</i>. Such
53.45 + * descriptions should be regarded as <i>implementation notes</i>, rather than
53.46 + * parts of the <i>specification</i>. Implementors should feel free to
53.47 + * substitute other algorithms, so long as the specification itself is adhered
53.48 + * to. (For example, the algorithm used by <tt>sort</tt> does not have to be
53.49 + * a mergesort, but it does have to be <i>stable</i>.)
53.50 + *
53.51 + * <p>The "destructive" algorithms contained in this class, that is, the
53.52 + * algorithms that modify the collection on which they operate, are specified
53.53 + * to throw <tt>UnsupportedOperationException</tt> if the collection does not
53.54 + * support the appropriate mutation primitive(s), such as the <tt>set</tt>
53.55 + * method. These algorithms may, but are not required to, throw this
53.56 + * exception if an invocation would have no effect on the collection. For
53.57 + * example, invoking the <tt>sort</tt> method on an unmodifiable list that is
53.58 + * already sorted may or may not throw <tt>UnsupportedOperationException</tt>.
53.59 + *
53.60 + * <p>This class is a member of the
53.61 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
53.62 + * Java Collections Framework</a>.
53.63 + *
53.64 + * @author Josh Bloch
53.65 + * @author Neal Gafter
53.66 + * @see Collection
53.67 + * @see Set
53.68 + * @see List
53.69 + * @see Map
53.70 + * @since 1.2
53.71 + */
53.72 +
53.73 +public class Collections {
53.74 + // Suppresses default constructor, ensuring non-instantiability.
53.75 + private Collections() {
53.76 + }
53.77 +
53.78 + // Algorithms
53.79 +
53.80 + /*
53.81 + * Tuning parameters for algorithms - Many of the List algorithms have
53.82 + * two implementations, one of which is appropriate for RandomAccess
53.83 + * lists, the other for "sequential." Often, the random access variant
53.84 + * yields better performance on small sequential access lists. The
53.85 + * tuning parameters below determine the cutoff point for what constitutes
53.86 + * a "small" sequential access list for each algorithm. The values below
53.87 + * were empirically determined to work well for LinkedList. Hopefully
53.88 + * they should be reasonable for other sequential access List
53.89 + * implementations. Those doing performance work on this code would
53.90 + * do well to validate the values of these parameters from time to time.
53.91 + * (The first word of each tuning parameter name is the algorithm to which
53.92 + * it applies.)
53.93 + */
53.94 + private static final int BINARYSEARCH_THRESHOLD = 5000;
53.95 + private static final int REVERSE_THRESHOLD = 18;
53.96 + private static final int SHUFFLE_THRESHOLD = 5;
53.97 + private static final int FILL_THRESHOLD = 25;
53.98 + private static final int ROTATE_THRESHOLD = 100;
53.99 + private static final int COPY_THRESHOLD = 10;
53.100 + private static final int REPLACEALL_THRESHOLD = 11;
53.101 + private static final int INDEXOFSUBLIST_THRESHOLD = 35;
53.102 +
53.103 + /**
53.104 + * Sorts the specified list into ascending order, according to the
53.105 + * {@linkplain Comparable natural ordering} of its elements.
53.106 + * All elements in the list must implement the {@link Comparable}
53.107 + * interface. Furthermore, all elements in the list must be
53.108 + * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}
53.109 + * must not throw a {@code ClassCastException} for any elements
53.110 + * {@code e1} and {@code e2} in the list).
53.111 + *
53.112 + * <p>This sort is guaranteed to be <i>stable</i>: equal elements will
53.113 + * not be reordered as a result of the sort.
53.114 + *
53.115 + * <p>The specified list must be modifiable, but need not be resizable.
53.116 + *
53.117 + * <p>Implementation note: This implementation is a stable, adaptive,
53.118 + * iterative mergesort that requires far fewer than n lg(n) comparisons
53.119 + * when the input array is partially sorted, while offering the
53.120 + * performance of a traditional mergesort when the input array is
53.121 + * randomly ordered. If the input array is nearly sorted, the
53.122 + * implementation requires approximately n comparisons. Temporary
53.123 + * storage requirements vary from a small constant for nearly sorted
53.124 + * input arrays to n/2 object references for randomly ordered input
53.125 + * arrays.
53.126 + *
53.127 + * <p>The implementation takes equal advantage of ascending and
53.128 + * descending order in its input array, and can take advantage of
53.129 + * ascending and descending order in different parts of the same
53.130 + * input array. It is well-suited to merging two or more sorted arrays:
53.131 + * simply concatenate the arrays and sort the resulting array.
53.132 + *
53.133 + * <p>The implementation was adapted from Tim Peters's list sort for Python
53.134 + * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
53.135 + * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic
53.136 + * Sorting and Information Theoretic Complexity", in Proceedings of the
53.137 + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
53.138 + * January 1993.
53.139 + *
53.140 + * <p>This implementation dumps the specified list into an array, sorts
53.141 + * the array, and iterates over the list resetting each element
53.142 + * from the corresponding position in the array. This avoids the
53.143 + * n<sup>2</sup> log(n) performance that would result from attempting
53.144 + * to sort a linked list in place.
53.145 + *
53.146 + * @param list the list to be sorted.
53.147 + * @throws ClassCastException if the list contains elements that are not
53.148 + * <i>mutually comparable</i> (for example, strings and integers).
53.149 + * @throws UnsupportedOperationException if the specified list's
53.150 + * list-iterator does not support the {@code set} operation.
53.151 + * @throws IllegalArgumentException (optional) if the implementation
53.152 + * detects that the natural ordering of the list elements is
53.153 + * found to violate the {@link Comparable} contract
53.154 + */
53.155 + public static <T extends Comparable<? super T>> void sort(List<T> list) {
53.156 + Object[] a = list.toArray();
53.157 + Arrays.sort(a);
53.158 + ListIterator<T> i = list.listIterator();
53.159 + for (int j=0; j<a.length; j++) {
53.160 + i.next();
53.161 + i.set((T)a[j]);
53.162 + }
53.163 + }
53.164 +
53.165 + /**
53.166 + * Sorts the specified list according to the order induced by the
53.167 + * specified comparator. All elements in the list must be <i>mutually
53.168 + * comparable</i> using the specified comparator (that is,
53.169 + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException}
53.170 + * for any elements {@code e1} and {@code e2} in the list).
53.171 + *
53.172 + * <p>This sort is guaranteed to be <i>stable</i>: equal elements will
53.173 + * not be reordered as a result of the sort.
53.174 + *
53.175 + * <p>The specified list must be modifiable, but need not be resizable.
53.176 + *
53.177 + * <p>Implementation note: This implementation is a stable, adaptive,
53.178 + * iterative mergesort that requires far fewer than n lg(n) comparisons
53.179 + * when the input array is partially sorted, while offering the
53.180 + * performance of a traditional mergesort when the input array is
53.181 + * randomly ordered. If the input array is nearly sorted, the
53.182 + * implementation requires approximately n comparisons. Temporary
53.183 + * storage requirements vary from a small constant for nearly sorted
53.184 + * input arrays to n/2 object references for randomly ordered input
53.185 + * arrays.
53.186 + *
53.187 + * <p>The implementation takes equal advantage of ascending and
53.188 + * descending order in its input array, and can take advantage of
53.189 + * ascending and descending order in different parts of the same
53.190 + * input array. It is well-suited to merging two or more sorted arrays:
53.191 + * simply concatenate the arrays and sort the resulting array.
53.192 + *
53.193 + * <p>The implementation was adapted from Tim Peters's list sort for Python
53.194 + * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
53.195 + * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic
53.196 + * Sorting and Information Theoretic Complexity", in Proceedings of the
53.197 + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
53.198 + * January 1993.
53.199 + *
53.200 + * <p>This implementation dumps the specified list into an array, sorts
53.201 + * the array, and iterates over the list resetting each element
53.202 + * from the corresponding position in the array. This avoids the
53.203 + * n<sup>2</sup> log(n) performance that would result from attempting
53.204 + * to sort a linked list in place.
53.205 + *
53.206 + * @param list the list to be sorted.
53.207 + * @param c the comparator to determine the order of the list. A
53.208 + * {@code null} value indicates that the elements' <i>natural
53.209 + * ordering</i> should be used.
53.210 + * @throws ClassCastException if the list contains elements that are not
53.211 + * <i>mutually comparable</i> using the specified comparator.
53.212 + * @throws UnsupportedOperationException if the specified list's
53.213 + * list-iterator does not support the {@code set} operation.
53.214 + * @throws IllegalArgumentException (optional) if the comparator is
53.215 + * found to violate the {@link Comparator} contract
53.216 + */
53.217 + public static <T> void sort(List<T> list, Comparator<? super T> c) {
53.218 + Object[] a = list.toArray();
53.219 + Arrays.sort(a, (Comparator)c);
53.220 + ListIterator i = list.listIterator();
53.221 + for (int j=0; j<a.length; j++) {
53.222 + i.next();
53.223 + i.set(a[j]);
53.224 + }
53.225 + }
53.226 +
53.227 +
53.228 + /**
53.229 + * Searches the specified list for the specified object using the binary
53.230 + * search algorithm. The list must be sorted into ascending order
53.231 + * according to the {@linkplain Comparable natural ordering} of its
53.232 + * elements (as by the {@link #sort(List)} method) prior to making this
53.233 + * call. If it is not sorted, the results are undefined. If the list
53.234 + * contains multiple elements equal to the specified object, there is no
53.235 + * guarantee which one will be found.
53.236 + *
53.237 + * <p>This method runs in log(n) time for a "random access" list (which
53.238 + * provides near-constant-time positional access). If the specified list
53.239 + * does not implement the {@link RandomAccess} interface and is large,
53.240 + * this method will do an iterator-based binary search that performs
53.241 + * O(n) link traversals and O(log n) element comparisons.
53.242 + *
53.243 + * @param list the list to be searched.
53.244 + * @param key the key to be searched for.
53.245 + * @return the index of the search key, if it is contained in the list;
53.246 + * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
53.247 + * <i>insertion point</i> is defined as the point at which the
53.248 + * key would be inserted into the list: the index of the first
53.249 + * element greater than the key, or <tt>list.size()</tt> if all
53.250 + * elements in the list are less than the specified key. Note
53.251 + * that this guarantees that the return value will be >= 0 if
53.252 + * and only if the key is found.
53.253 + * @throws ClassCastException if the list contains elements that are not
53.254 + * <i>mutually comparable</i> (for example, strings and
53.255 + * integers), or the search key is not mutually comparable
53.256 + * with the elements of the list.
53.257 + */
53.258 + public static <T>
53.259 + int binarySearch(List<? extends Comparable<? super T>> list, T key) {
53.260 + if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
53.261 + return Collections.indexedBinarySearch(list, key);
53.262 + else
53.263 + return Collections.iteratorBinarySearch(list, key);
53.264 + }
53.265 +
53.266 + private static <T>
53.267 + int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)
53.268 + {
53.269 + int low = 0;
53.270 + int high = list.size()-1;
53.271 +
53.272 + while (low <= high) {
53.273 + int mid = (low + high) >>> 1;
53.274 + Comparable<? super T> midVal = list.get(mid);
53.275 + int cmp = midVal.compareTo(key);
53.276 +
53.277 + if (cmp < 0)
53.278 + low = mid + 1;
53.279 + else if (cmp > 0)
53.280 + high = mid - 1;
53.281 + else
53.282 + return mid; // key found
53.283 + }
53.284 + return -(low + 1); // key not found
53.285 + }
53.286 +
53.287 + private static <T>
53.288 + int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
53.289 + {
53.290 + int low = 0;
53.291 + int high = list.size()-1;
53.292 + ListIterator<? extends Comparable<? super T>> i = list.listIterator();
53.293 +
53.294 + while (low <= high) {
53.295 + int mid = (low + high) >>> 1;
53.296 + Comparable<? super T> midVal = get(i, mid);
53.297 + int cmp = midVal.compareTo(key);
53.298 +
53.299 + if (cmp < 0)
53.300 + low = mid + 1;
53.301 + else if (cmp > 0)
53.302 + high = mid - 1;
53.303 + else
53.304 + return mid; // key found
53.305 + }
53.306 + return -(low + 1); // key not found
53.307 + }
53.308 +
53.309 + /**
53.310 + * Gets the ith element from the given list by repositioning the specified
53.311 + * list listIterator.
53.312 + */
53.313 + private static <T> T get(ListIterator<? extends T> i, int index) {
53.314 + T obj = null;
53.315 + int pos = i.nextIndex();
53.316 + if (pos <= index) {
53.317 + do {
53.318 + obj = i.next();
53.319 + } while (pos++ < index);
53.320 + } else {
53.321 + do {
53.322 + obj = i.previous();
53.323 + } while (--pos > index);
53.324 + }
53.325 + return obj;
53.326 + }
53.327 +
53.328 + /**
53.329 + * Searches the specified list for the specified object using the binary
53.330 + * search algorithm. The list must be sorted into ascending order
53.331 + * according to the specified comparator (as by the
53.332 + * {@link #sort(List, Comparator) sort(List, Comparator)}
53.333 + * method), prior to making this call. If it is
53.334 + * not sorted, the results are undefined. If the list contains multiple
53.335 + * elements equal to the specified object, there is no guarantee which one
53.336 + * will be found.
53.337 + *
53.338 + * <p>This method runs in log(n) time for a "random access" list (which
53.339 + * provides near-constant-time positional access). If the specified list
53.340 + * does not implement the {@link RandomAccess} interface and is large,
53.341 + * this method will do an iterator-based binary search that performs
53.342 + * O(n) link traversals and O(log n) element comparisons.
53.343 + *
53.344 + * @param list the list to be searched.
53.345 + * @param key the key to be searched for.
53.346 + * @param c the comparator by which the list is ordered.
53.347 + * A <tt>null</tt> value indicates that the elements'
53.348 + * {@linkplain Comparable natural ordering} should be used.
53.349 + * @return the index of the search key, if it is contained in the list;
53.350 + * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
53.351 + * <i>insertion point</i> is defined as the point at which the
53.352 + * key would be inserted into the list: the index of the first
53.353 + * element greater than the key, or <tt>list.size()</tt> if all
53.354 + * elements in the list are less than the specified key. Note
53.355 + * that this guarantees that the return value will be >= 0 if
53.356 + * and only if the key is found.
53.357 + * @throws ClassCastException if the list contains elements that are not
53.358 + * <i>mutually comparable</i> using the specified comparator,
53.359 + * or the search key is not mutually comparable with the
53.360 + * elements of the list using this comparator.
53.361 + */
53.362 + public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
53.363 + if (c==null)
53.364 + return binarySearch((List) list, key);
53.365 +
53.366 + if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
53.367 + return Collections.indexedBinarySearch(list, key, c);
53.368 + else
53.369 + return Collections.iteratorBinarySearch(list, key, c);
53.370 + }
53.371 +
53.372 + private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
53.373 + int low = 0;
53.374 + int high = l.size()-1;
53.375 +
53.376 + while (low <= high) {
53.377 + int mid = (low + high) >>> 1;
53.378 + T midVal = l.get(mid);
53.379 + int cmp = c.compare(midVal, key);
53.380 +
53.381 + if (cmp < 0)
53.382 + low = mid + 1;
53.383 + else if (cmp > 0)
53.384 + high = mid - 1;
53.385 + else
53.386 + return mid; // key found
53.387 + }
53.388 + return -(low + 1); // key not found
53.389 + }
53.390 +
53.391 + private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
53.392 + int low = 0;
53.393 + int high = l.size()-1;
53.394 + ListIterator<? extends T> i = l.listIterator();
53.395 +
53.396 + while (low <= high) {
53.397 + int mid = (low + high) >>> 1;
53.398 + T midVal = get(i, mid);
53.399 + int cmp = c.compare(midVal, key);
53.400 +
53.401 + if (cmp < 0)
53.402 + low = mid + 1;
53.403 + else if (cmp > 0)
53.404 + high = mid - 1;
53.405 + else
53.406 + return mid; // key found
53.407 + }
53.408 + return -(low + 1); // key not found
53.409 + }
53.410 +
53.411 + private interface SelfComparable extends Comparable<SelfComparable> {}
53.412 +
53.413 +
53.414 + /**
53.415 + * Reverses the order of the elements in the specified list.<p>
53.416 + *
53.417 + * This method runs in linear time.
53.418 + *
53.419 + * @param list the list whose elements are to be reversed.
53.420 + * @throws UnsupportedOperationException if the specified list or
53.421 + * its list-iterator does not support the <tt>set</tt> operation.
53.422 + */
53.423 + public static void reverse(List<?> list) {
53.424 + int size = list.size();
53.425 + if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
53.426 + for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
53.427 + swap(list, i, j);
53.428 + } else {
53.429 + ListIterator fwd = list.listIterator();
53.430 + ListIterator rev = list.listIterator(size);
53.431 + for (int i=0, mid=list.size()>>1; i<mid; i++) {
53.432 + Object tmp = fwd.next();
53.433 + fwd.set(rev.previous());
53.434 + rev.set(tmp);
53.435 + }
53.436 + }
53.437 + }
53.438 +
53.439 + /**
53.440 + * Randomly permutes the specified list using a default source of
53.441 + * randomness. All permutations occur with approximately equal
53.442 + * likelihood.<p>
53.443 + *
53.444 + * The hedge "approximately" is used in the foregoing description because
53.445 + * default source of randomness is only approximately an unbiased source
53.446 + * of independently chosen bits. If it were a perfect source of randomly
53.447 + * chosen bits, then the algorithm would choose permutations with perfect
53.448 + * uniformity.<p>
53.449 + *
53.450 + * This implementation traverses the list backwards, from the last element
53.451 + * up to the second, repeatedly swapping a randomly selected element into
53.452 + * the "current position". Elements are randomly selected from the
53.453 + * portion of the list that runs from the first element to the current
53.454 + * position, inclusive.<p>
53.455 + *
53.456 + * This method runs in linear time. If the specified list does not
53.457 + * implement the {@link RandomAccess} interface and is large, this
53.458 + * implementation dumps the specified list into an array before shuffling
53.459 + * it, and dumps the shuffled array back into the list. This avoids the
53.460 + * quadratic behavior that would result from shuffling a "sequential
53.461 + * access" list in place.
53.462 + *
53.463 + * @param list the list to be shuffled.
53.464 + * @throws UnsupportedOperationException if the specified list or
53.465 + * its list-iterator does not support the <tt>set</tt> operation.
53.466 + */
53.467 + public static void shuffle(List<?> list) {
53.468 + Random rnd = r;
53.469 + if (rnd == null)
53.470 + r = rnd = new Random();
53.471 + shuffle(list, rnd);
53.472 + }
53.473 + private static Random r;
53.474 +
53.475 + /**
53.476 + * Randomly permute the specified list using the specified source of
53.477 + * randomness. All permutations occur with equal likelihood
53.478 + * assuming that the source of randomness is fair.<p>
53.479 + *
53.480 + * This implementation traverses the list backwards, from the last element
53.481 + * up to the second, repeatedly swapping a randomly selected element into
53.482 + * the "current position". Elements are randomly selected from the
53.483 + * portion of the list that runs from the first element to the current
53.484 + * position, inclusive.<p>
53.485 + *
53.486 + * This method runs in linear time. If the specified list does not
53.487 + * implement the {@link RandomAccess} interface and is large, this
53.488 + * implementation dumps the specified list into an array before shuffling
53.489 + * it, and dumps the shuffled array back into the list. This avoids the
53.490 + * quadratic behavior that would result from shuffling a "sequential
53.491 + * access" list in place.
53.492 + *
53.493 + * @param list the list to be shuffled.
53.494 + * @param rnd the source of randomness to use to shuffle the list.
53.495 + * @throws UnsupportedOperationException if the specified list or its
53.496 + * list-iterator does not support the <tt>set</tt> operation.
53.497 + */
53.498 + public static void shuffle(List<?> list, Random rnd) {
53.499 + int size = list.size();
53.500 + if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
53.501 + for (int i=size; i>1; i--)
53.502 + swap(list, i-1, rnd.nextInt(i));
53.503 + } else {
53.504 + Object arr[] = list.toArray();
53.505 +
53.506 + // Shuffle array
53.507 + for (int i=size; i>1; i--)
53.508 + swap(arr, i-1, rnd.nextInt(i));
53.509 +
53.510 + // Dump array back into list
53.511 + ListIterator it = list.listIterator();
53.512 + for (int i=0; i<arr.length; i++) {
53.513 + it.next();
53.514 + it.set(arr[i]);
53.515 + }
53.516 + }
53.517 + }
53.518 +
53.519 + /**
53.520 + * Swaps the elements at the specified positions in the specified list.
53.521 + * (If the specified positions are equal, invoking this method leaves
53.522 + * the list unchanged.)
53.523 + *
53.524 + * @param list The list in which to swap elements.
53.525 + * @param i the index of one element to be swapped.
53.526 + * @param j the index of the other element to be swapped.
53.527 + * @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt>
53.528 + * is out of range (i < 0 || i >= list.size()
53.529 + * || j < 0 || j >= list.size()).
53.530 + * @since 1.4
53.531 + */
53.532 + public static void swap(List<?> list, int i, int j) {
53.533 + final List l = list;
53.534 + l.set(i, l.set(j, l.get(i)));
53.535 + }
53.536 +
53.537 + /**
53.538 + * Swaps the two specified elements in the specified array.
53.539 + */
53.540 + private static void swap(Object[] arr, int i, int j) {
53.541 + Object tmp = arr[i];
53.542 + arr[i] = arr[j];
53.543 + arr[j] = tmp;
53.544 + }
53.545 +
53.546 + /**
53.547 + * Replaces all of the elements of the specified list with the specified
53.548 + * element. <p>
53.549 + *
53.550 + * This method runs in linear time.
53.551 + *
53.552 + * @param list the list to be filled with the specified element.
53.553 + * @param obj The element with which to fill the specified list.
53.554 + * @throws UnsupportedOperationException if the specified list or its
53.555 + * list-iterator does not support the <tt>set</tt> operation.
53.556 + */
53.557 + public static <T> void fill(List<? super T> list, T obj) {
53.558 + int size = list.size();
53.559 +
53.560 + if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
53.561 + for (int i=0; i<size; i++)
53.562 + list.set(i, obj);
53.563 + } else {
53.564 + ListIterator<? super T> itr = list.listIterator();
53.565 + for (int i=0; i<size; i++) {
53.566 + itr.next();
53.567 + itr.set(obj);
53.568 + }
53.569 + }
53.570 + }
53.571 +
53.572 + /**
53.573 + * Copies all of the elements from one list into another. After the
53.574 + * operation, the index of each copied element in the destination list
53.575 + * will be identical to its index in the source list. The destination
53.576 + * list must be at least as long as the source list. If it is longer, the
53.577 + * remaining elements in the destination list are unaffected. <p>
53.578 + *
53.579 + * This method runs in linear time.
53.580 + *
53.581 + * @param dest The destination list.
53.582 + * @param src The source list.
53.583 + * @throws IndexOutOfBoundsException if the destination list is too small
53.584 + * to contain the entire source List.
53.585 + * @throws UnsupportedOperationException if the destination list's
53.586 + * list-iterator does not support the <tt>set</tt> operation.
53.587 + */
53.588 + public static <T> void copy(List<? super T> dest, List<? extends T> src) {
53.589 + int srcSize = src.size();
53.590 + if (srcSize > dest.size())
53.591 + throw new IndexOutOfBoundsException("Source does not fit in dest");
53.592 +
53.593 + if (srcSize < COPY_THRESHOLD ||
53.594 + (src instanceof RandomAccess && dest instanceof RandomAccess)) {
53.595 + for (int i=0; i<srcSize; i++)
53.596 + dest.set(i, src.get(i));
53.597 + } else {
53.598 + ListIterator<? super T> di=dest.listIterator();
53.599 + ListIterator<? extends T> si=src.listIterator();
53.600 + for (int i=0; i<srcSize; i++) {
53.601 + di.next();
53.602 + di.set(si.next());
53.603 + }
53.604 + }
53.605 + }
53.606 +
53.607 + /**
53.608 + * Returns the minimum element of the given collection, according to the
53.609 + * <i>natural ordering</i> of its elements. All elements in the
53.610 + * collection must implement the <tt>Comparable</tt> interface.
53.611 + * Furthermore, all elements in the collection must be <i>mutually
53.612 + * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
53.613 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
53.614 + * <tt>e2</tt> in the collection).<p>
53.615 + *
53.616 + * This method iterates over the entire collection, hence it requires
53.617 + * time proportional to the size of the collection.
53.618 + *
53.619 + * @param coll the collection whose minimum element is to be determined.
53.620 + * @return the minimum element of the given collection, according
53.621 + * to the <i>natural ordering</i> of its elements.
53.622 + * @throws ClassCastException if the collection contains elements that are
53.623 + * not <i>mutually comparable</i> (for example, strings and
53.624 + * integers).
53.625 + * @throws NoSuchElementException if the collection is empty.
53.626 + * @see Comparable
53.627 + */
53.628 + public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
53.629 + Iterator<? extends T> i = coll.iterator();
53.630 + T candidate = i.next();
53.631 +
53.632 + while (i.hasNext()) {
53.633 + T next = i.next();
53.634 + if (next.compareTo(candidate) < 0)
53.635 + candidate = next;
53.636 + }
53.637 + return candidate;
53.638 + }
53.639 +
53.640 + /**
53.641 + * Returns the minimum element of the given collection, according to the
53.642 + * order induced by the specified comparator. All elements in the
53.643 + * collection must be <i>mutually comparable</i> by the specified
53.644 + * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
53.645 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
53.646 + * <tt>e2</tt> in the collection).<p>
53.647 + *
53.648 + * This method iterates over the entire collection, hence it requires
53.649 + * time proportional to the size of the collection.
53.650 + *
53.651 + * @param coll the collection whose minimum element is to be determined.
53.652 + * @param comp the comparator with which to determine the minimum element.
53.653 + * A <tt>null</tt> value indicates that the elements' <i>natural
53.654 + * ordering</i> should be used.
53.655 + * @return the minimum element of the given collection, according
53.656 + * to the specified comparator.
53.657 + * @throws ClassCastException if the collection contains elements that are
53.658 + * not <i>mutually comparable</i> using the specified comparator.
53.659 + * @throws NoSuchElementException if the collection is empty.
53.660 + * @see Comparable
53.661 + */
53.662 + public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
53.663 + if (comp==null)
53.664 + return (T)min((Collection<SelfComparable>) (Collection) coll);
53.665 +
53.666 + Iterator<? extends T> i = coll.iterator();
53.667 + T candidate = i.next();
53.668 +
53.669 + while (i.hasNext()) {
53.670 + T next = i.next();
53.671 + if (comp.compare(next, candidate) < 0)
53.672 + candidate = next;
53.673 + }
53.674 + return candidate;
53.675 + }
53.676 +
53.677 + /**
53.678 + * Returns the maximum element of the given collection, according to the
53.679 + * <i>natural ordering</i> of its elements. All elements in the
53.680 + * collection must implement the <tt>Comparable</tt> interface.
53.681 + * Furthermore, all elements in the collection must be <i>mutually
53.682 + * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
53.683 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
53.684 + * <tt>e2</tt> in the collection).<p>
53.685 + *
53.686 + * This method iterates over the entire collection, hence it requires
53.687 + * time proportional to the size of the collection.
53.688 + *
53.689 + * @param coll the collection whose maximum element is to be determined.
53.690 + * @return the maximum element of the given collection, according
53.691 + * to the <i>natural ordering</i> of its elements.
53.692 + * @throws ClassCastException if the collection contains elements that are
53.693 + * not <i>mutually comparable</i> (for example, strings and
53.694 + * integers).
53.695 + * @throws NoSuchElementException if the collection is empty.
53.696 + * @see Comparable
53.697 + */
53.698 + public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
53.699 + Iterator<? extends T> i = coll.iterator();
53.700 + T candidate = i.next();
53.701 +
53.702 + while (i.hasNext()) {
53.703 + T next = i.next();
53.704 + if (next.compareTo(candidate) > 0)
53.705 + candidate = next;
53.706 + }
53.707 + return candidate;
53.708 + }
53.709 +
53.710 + /**
53.711 + * Returns the maximum element of the given collection, according to the
53.712 + * order induced by the specified comparator. All elements in the
53.713 + * collection must be <i>mutually comparable</i> by the specified
53.714 + * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
53.715 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
53.716 + * <tt>e2</tt> in the collection).<p>
53.717 + *
53.718 + * This method iterates over the entire collection, hence it requires
53.719 + * time proportional to the size of the collection.
53.720 + *
53.721 + * @param coll the collection whose maximum element is to be determined.
53.722 + * @param comp the comparator with which to determine the maximum element.
53.723 + * A <tt>null</tt> value indicates that the elements' <i>natural
53.724 + * ordering</i> should be used.
53.725 + * @return the maximum element of the given collection, according
53.726 + * to the specified comparator.
53.727 + * @throws ClassCastException if the collection contains elements that are
53.728 + * not <i>mutually comparable</i> using the specified comparator.
53.729 + * @throws NoSuchElementException if the collection is empty.
53.730 + * @see Comparable
53.731 + */
53.732 + public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
53.733 + if (comp==null)
53.734 + return (T)max((Collection<SelfComparable>) (Collection) coll);
53.735 +
53.736 + Iterator<? extends T> i = coll.iterator();
53.737 + T candidate = i.next();
53.738 +
53.739 + while (i.hasNext()) {
53.740 + T next = i.next();
53.741 + if (comp.compare(next, candidate) > 0)
53.742 + candidate = next;
53.743 + }
53.744 + return candidate;
53.745 + }
53.746 +
53.747 + /**
53.748 + * Rotates the elements in the specified list by the specified distance.
53.749 + * After calling this method, the element at index <tt>i</tt> will be
53.750 + * the element previously at index <tt>(i - distance)</tt> mod
53.751 + * <tt>list.size()</tt>, for all values of <tt>i</tt> between <tt>0</tt>
53.752 + * and <tt>list.size()-1</tt>, inclusive. (This method has no effect on
53.753 + * the size of the list.)
53.754 + *
53.755 + * <p>For example, suppose <tt>list</tt> comprises<tt> [t, a, n, k, s]</tt>.
53.756 + * After invoking <tt>Collections.rotate(list, 1)</tt> (or
53.757 + * <tt>Collections.rotate(list, -4)</tt>), <tt>list</tt> will comprise
53.758 + * <tt>[s, t, a, n, k]</tt>.
53.759 + *
53.760 + * <p>Note that this method can usefully be applied to sublists to
53.761 + * move one or more elements within a list while preserving the
53.762 + * order of the remaining elements. For example, the following idiom
53.763 + * moves the element at index <tt>j</tt> forward to position
53.764 + * <tt>k</tt> (which must be greater than or equal to <tt>j</tt>):
53.765 + * <pre>
53.766 + * Collections.rotate(list.subList(j, k+1), -1);
53.767 + * </pre>
53.768 + * To make this concrete, suppose <tt>list</tt> comprises
53.769 + * <tt>[a, b, c, d, e]</tt>. To move the element at index <tt>1</tt>
53.770 + * (<tt>b</tt>) forward two positions, perform the following invocation:
53.771 + * <pre>
53.772 + * Collections.rotate(l.subList(1, 4), -1);
53.773 + * </pre>
53.774 + * The resulting list is <tt>[a, c, d, b, e]</tt>.
53.775 + *
53.776 + * <p>To move more than one element forward, increase the absolute value
53.777 + * of the rotation distance. To move elements backward, use a positive
53.778 + * shift distance.
53.779 + *
53.780 + * <p>If the specified list is small or implements the {@link
53.781 + * RandomAccess} interface, this implementation exchanges the first
53.782 + * element into the location it should go, and then repeatedly exchanges
53.783 + * the displaced element into the location it should go until a displaced
53.784 + * element is swapped into the first element. If necessary, the process
53.785 + * is repeated on the second and successive elements, until the rotation
53.786 + * is complete. If the specified list is large and doesn't implement the
53.787 + * <tt>RandomAccess</tt> interface, this implementation breaks the
53.788 + * list into two sublist views around index <tt>-distance mod size</tt>.
53.789 + * Then the {@link #reverse(List)} method is invoked on each sublist view,
53.790 + * and finally it is invoked on the entire list. For a more complete
53.791 + * description of both algorithms, see Section 2.3 of Jon Bentley's
53.792 + * <i>Programming Pearls</i> (Addison-Wesley, 1986).
53.793 + *
53.794 + * @param list the list to be rotated.
53.795 + * @param distance the distance to rotate the list. There are no
53.796 + * constraints on this value; it may be zero, negative, or
53.797 + * greater than <tt>list.size()</tt>.
53.798 + * @throws UnsupportedOperationException if the specified list or
53.799 + * its list-iterator does not support the <tt>set</tt> operation.
53.800 + * @since 1.4
53.801 + */
53.802 + public static void rotate(List<?> list, int distance) {
53.803 + if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
53.804 + rotate1(list, distance);
53.805 + else
53.806 + rotate2(list, distance);
53.807 + }
53.808 +
53.809 + private static <T> void rotate1(List<T> list, int distance) {
53.810 + int size = list.size();
53.811 + if (size == 0)
53.812 + return;
53.813 + distance = distance % size;
53.814 + if (distance < 0)
53.815 + distance += size;
53.816 + if (distance == 0)
53.817 + return;
53.818 +
53.819 + for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
53.820 + T displaced = list.get(cycleStart);
53.821 + int i = cycleStart;
53.822 + do {
53.823 + i += distance;
53.824 + if (i >= size)
53.825 + i -= size;
53.826 + displaced = list.set(i, displaced);
53.827 + nMoved ++;
53.828 + } while (i != cycleStart);
53.829 + }
53.830 + }
53.831 +
53.832 + private static void rotate2(List<?> list, int distance) {
53.833 + int size = list.size();
53.834 + if (size == 0)
53.835 + return;
53.836 + int mid = -distance % size;
53.837 + if (mid < 0)
53.838 + mid += size;
53.839 + if (mid == 0)
53.840 + return;
53.841 +
53.842 + reverse(list.subList(0, mid));
53.843 + reverse(list.subList(mid, size));
53.844 + reverse(list);
53.845 + }
53.846 +
53.847 + /**
53.848 + * Replaces all occurrences of one specified value in a list with another.
53.849 + * More formally, replaces with <tt>newVal</tt> each element <tt>e</tt>
53.850 + * in <tt>list</tt> such that
53.851 + * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>.
53.852 + * (This method has no effect on the size of the list.)
53.853 + *
53.854 + * @param list the list in which replacement is to occur.
53.855 + * @param oldVal the old value to be replaced.
53.856 + * @param newVal the new value with which <tt>oldVal</tt> is to be
53.857 + * replaced.
53.858 + * @return <tt>true</tt> if <tt>list</tt> contained one or more elements
53.859 + * <tt>e</tt> such that
53.860 + * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>.
53.861 + * @throws UnsupportedOperationException if the specified list or
53.862 + * its list-iterator does not support the <tt>set</tt> operation.
53.863 + * @since 1.4
53.864 + */
53.865 + public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {
53.866 + boolean result = false;
53.867 + int size = list.size();
53.868 + if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {
53.869 + if (oldVal==null) {
53.870 + for (int i=0; i<size; i++) {
53.871 + if (list.get(i)==null) {
53.872 + list.set(i, newVal);
53.873 + result = true;
53.874 + }
53.875 + }
53.876 + } else {
53.877 + for (int i=0; i<size; i++) {
53.878 + if (oldVal.equals(list.get(i))) {
53.879 + list.set(i, newVal);
53.880 + result = true;
53.881 + }
53.882 + }
53.883 + }
53.884 + } else {
53.885 + ListIterator<T> itr=list.listIterator();
53.886 + if (oldVal==null) {
53.887 + for (int i=0; i<size; i++) {
53.888 + if (itr.next()==null) {
53.889 + itr.set(newVal);
53.890 + result = true;
53.891 + }
53.892 + }
53.893 + } else {
53.894 + for (int i=0; i<size; i++) {
53.895 + if (oldVal.equals(itr.next())) {
53.896 + itr.set(newVal);
53.897 + result = true;
53.898 + }
53.899 + }
53.900 + }
53.901 + }
53.902 + return result;
53.903 + }
53.904 +
53.905 + /**
53.906 + * Returns the starting position of the first occurrence of the specified
53.907 + * target list within the specified source list, or -1 if there is no
53.908 + * such occurrence. More formally, returns the lowest index <tt>i</tt>
53.909 + * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
53.910 + * or -1 if there is no such index. (Returns -1 if
53.911 + * <tt>target.size() > source.size()</tt>.)
53.912 + *
53.913 + * <p>This implementation uses the "brute force" technique of scanning
53.914 + * over the source list, looking for a match with the target at each
53.915 + * location in turn.
53.916 + *
53.917 + * @param source the list in which to search for the first occurrence
53.918 + * of <tt>target</tt>.
53.919 + * @param target the list to search for as a subList of <tt>source</tt>.
53.920 + * @return the starting position of the first occurrence of the specified
53.921 + * target list within the specified source list, or -1 if there
53.922 + * is no such occurrence.
53.923 + * @since 1.4
53.924 + */
53.925 + public static int indexOfSubList(List<?> source, List<?> target) {
53.926 + int sourceSize = source.size();
53.927 + int targetSize = target.size();
53.928 + int maxCandidate = sourceSize - targetSize;
53.929 +
53.930 + if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
53.931 + (source instanceof RandomAccess&&target instanceof RandomAccess)) {
53.932 + nextCand:
53.933 + for (int candidate = 0; candidate <= maxCandidate; candidate++) {
53.934 + for (int i=0, j=candidate; i<targetSize; i++, j++)
53.935 + if (!eq(target.get(i), source.get(j)))
53.936 + continue nextCand; // Element mismatch, try next cand
53.937 + return candidate; // All elements of candidate matched target
53.938 + }
53.939 + } else { // Iterator version of above algorithm
53.940 + ListIterator<?> si = source.listIterator();
53.941 + nextCand:
53.942 + for (int candidate = 0; candidate <= maxCandidate; candidate++) {
53.943 + ListIterator<?> ti = target.listIterator();
53.944 + for (int i=0; i<targetSize; i++) {
53.945 + if (!eq(ti.next(), si.next())) {
53.946 + // Back up source iterator to next candidate
53.947 + for (int j=0; j<i; j++)
53.948 + si.previous();
53.949 + continue nextCand;
53.950 + }
53.951 + }
53.952 + return candidate;
53.953 + }
53.954 + }
53.955 + return -1; // No candidate matched the target
53.956 + }
53.957 +
53.958 + /**
53.959 + * Returns the starting position of the last occurrence of the specified
53.960 + * target list within the specified source list, or -1 if there is no such
53.961 + * occurrence. More formally, returns the highest index <tt>i</tt>
53.962 + * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
53.963 + * or -1 if there is no such index. (Returns -1 if
53.964 + * <tt>target.size() > source.size()</tt>.)
53.965 + *
53.966 + * <p>This implementation uses the "brute force" technique of iterating
53.967 + * over the source list, looking for a match with the target at each
53.968 + * location in turn.
53.969 + *
53.970 + * @param source the list in which to search for the last occurrence
53.971 + * of <tt>target</tt>.
53.972 + * @param target the list to search for as a subList of <tt>source</tt>.
53.973 + * @return the starting position of the last occurrence of the specified
53.974 + * target list within the specified source list, or -1 if there
53.975 + * is no such occurrence.
53.976 + * @since 1.4
53.977 + */
53.978 + public static int lastIndexOfSubList(List<?> source, List<?> target) {
53.979 + int sourceSize = source.size();
53.980 + int targetSize = target.size();
53.981 + int maxCandidate = sourceSize - targetSize;
53.982 +
53.983 + if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
53.984 + source instanceof RandomAccess) { // Index access version
53.985 + nextCand:
53.986 + for (int candidate = maxCandidate; candidate >= 0; candidate--) {
53.987 + for (int i=0, j=candidate; i<targetSize; i++, j++)
53.988 + if (!eq(target.get(i), source.get(j)))
53.989 + continue nextCand; // Element mismatch, try next cand
53.990 + return candidate; // All elements of candidate matched target
53.991 + }
53.992 + } else { // Iterator version of above algorithm
53.993 + if (maxCandidate < 0)
53.994 + return -1;
53.995 + ListIterator<?> si = source.listIterator(maxCandidate);
53.996 + nextCand:
53.997 + for (int candidate = maxCandidate; candidate >= 0; candidate--) {
53.998 + ListIterator<?> ti = target.listIterator();
53.999 + for (int i=0; i<targetSize; i++) {
53.1000 + if (!eq(ti.next(), si.next())) {
53.1001 + if (candidate != 0) {
53.1002 + // Back up source iterator to next candidate
53.1003 + for (int j=0; j<=i+1; j++)
53.1004 + si.previous();
53.1005 + }
53.1006 + continue nextCand;
53.1007 + }
53.1008 + }
53.1009 + return candidate;
53.1010 + }
53.1011 + }
53.1012 + return -1; // No candidate matched the target
53.1013 + }
53.1014 +
53.1015 +
53.1016 + // Unmodifiable Wrappers
53.1017 +
53.1018 + /**
53.1019 + * Returns an unmodifiable view of the specified collection. This method
53.1020 + * allows modules to provide users with "read-only" access to internal
53.1021 + * collections. Query operations on the returned collection "read through"
53.1022 + * to the specified collection, and attempts to modify the returned
53.1023 + * collection, whether direct or via its iterator, result in an
53.1024 + * <tt>UnsupportedOperationException</tt>.<p>
53.1025 + *
53.1026 + * The returned collection does <i>not</i> pass the hashCode and equals
53.1027 + * operations through to the backing collection, but relies on
53.1028 + * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods. This
53.1029 + * is necessary to preserve the contracts of these operations in the case
53.1030 + * that the backing collection is a set or a list.<p>
53.1031 + *
53.1032 + * The returned collection will be serializable if the specified collection
53.1033 + * is serializable.
53.1034 + *
53.1035 + * @param c the collection for which an unmodifiable view is to be
53.1036 + * returned.
53.1037 + * @return an unmodifiable view of the specified collection.
53.1038 + */
53.1039 + public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
53.1040 + return new UnmodifiableCollection<>(c);
53.1041 + }
53.1042 +
53.1043 + /**
53.1044 + * @serial include
53.1045 + */
53.1046 + static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
53.1047 + private static final long serialVersionUID = 1820017752578914078L;
53.1048 +
53.1049 + final Collection<? extends E> c;
53.1050 +
53.1051 + UnmodifiableCollection(Collection<? extends E> c) {
53.1052 + if (c==null)
53.1053 + throw new NullPointerException();
53.1054 + this.c = c;
53.1055 + }
53.1056 +
53.1057 + public int size() {return c.size();}
53.1058 + public boolean isEmpty() {return c.isEmpty();}
53.1059 + public boolean contains(Object o) {return c.contains(o);}
53.1060 + public Object[] toArray() {return c.toArray();}
53.1061 + public <T> T[] toArray(T[] a) {return c.toArray(a);}
53.1062 + public String toString() {return c.toString();}
53.1063 +
53.1064 + public Iterator<E> iterator() {
53.1065 + return new Iterator<E>() {
53.1066 + private final Iterator<? extends E> i = c.iterator();
53.1067 +
53.1068 + public boolean hasNext() {return i.hasNext();}
53.1069 + public E next() {return i.next();}
53.1070 + public void remove() {
53.1071 + throw new UnsupportedOperationException();
53.1072 + }
53.1073 + };
53.1074 + }
53.1075 +
53.1076 + public boolean add(E e) {
53.1077 + throw new UnsupportedOperationException();
53.1078 + }
53.1079 + public boolean remove(Object o) {
53.1080 + throw new UnsupportedOperationException();
53.1081 + }
53.1082 +
53.1083 + public boolean containsAll(Collection<?> coll) {
53.1084 + return c.containsAll(coll);
53.1085 + }
53.1086 + public boolean addAll(Collection<? extends E> coll) {
53.1087 + throw new UnsupportedOperationException();
53.1088 + }
53.1089 + public boolean removeAll(Collection<?> coll) {
53.1090 + throw new UnsupportedOperationException();
53.1091 + }
53.1092 + public boolean retainAll(Collection<?> coll) {
53.1093 + throw new UnsupportedOperationException();
53.1094 + }
53.1095 + public void clear() {
53.1096 + throw new UnsupportedOperationException();
53.1097 + }
53.1098 + }
53.1099 +
53.1100 + /**
53.1101 + * Returns an unmodifiable view of the specified set. This method allows
53.1102 + * modules to provide users with "read-only" access to internal sets.
53.1103 + * Query operations on the returned set "read through" to the specified
53.1104 + * set, and attempts to modify the returned set, whether direct or via its
53.1105 + * iterator, result in an <tt>UnsupportedOperationException</tt>.<p>
53.1106 + *
53.1107 + * The returned set will be serializable if the specified set
53.1108 + * is serializable.
53.1109 + *
53.1110 + * @param s the set for which an unmodifiable view is to be returned.
53.1111 + * @return an unmodifiable view of the specified set.
53.1112 + */
53.1113 + public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
53.1114 + return new UnmodifiableSet<>(s);
53.1115 + }
53.1116 +
53.1117 + /**
53.1118 + * @serial include
53.1119 + */
53.1120 + static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
53.1121 + implements Set<E>, Serializable {
53.1122 + private static final long serialVersionUID = -9215047833775013803L;
53.1123 +
53.1124 + UnmodifiableSet(Set<? extends E> s) {super(s);}
53.1125 + public boolean equals(Object o) {return o == this || c.equals(o);}
53.1126 + public int hashCode() {return c.hashCode();}
53.1127 + }
53.1128 +
53.1129 + /**
53.1130 + * Returns an unmodifiable view of the specified sorted set. This method
53.1131 + * allows modules to provide users with "read-only" access to internal
53.1132 + * sorted sets. Query operations on the returned sorted set "read
53.1133 + * through" to the specified sorted set. Attempts to modify the returned
53.1134 + * sorted set, whether direct, via its iterator, or via its
53.1135 + * <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in
53.1136 + * an <tt>UnsupportedOperationException</tt>.<p>
53.1137 + *
53.1138 + * The returned sorted set will be serializable if the specified sorted set
53.1139 + * is serializable.
53.1140 + *
53.1141 + * @param s the sorted set for which an unmodifiable view is to be
53.1142 + * returned.
53.1143 + * @return an unmodifiable view of the specified sorted set.
53.1144 + */
53.1145 + public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
53.1146 + return new UnmodifiableSortedSet<>(s);
53.1147 + }
53.1148 +
53.1149 + /**
53.1150 + * @serial include
53.1151 + */
53.1152 + static class UnmodifiableSortedSet<E>
53.1153 + extends UnmodifiableSet<E>
53.1154 + implements SortedSet<E>, Serializable {
53.1155 + private static final long serialVersionUID = -4929149591599911165L;
53.1156 + private final SortedSet<E> ss;
53.1157 +
53.1158 + UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
53.1159 +
53.1160 + public Comparator<? super E> comparator() {return ss.comparator();}
53.1161 +
53.1162 + public SortedSet<E> subSet(E fromElement, E toElement) {
53.1163 + return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement));
53.1164 + }
53.1165 + public SortedSet<E> headSet(E toElement) {
53.1166 + return new UnmodifiableSortedSet<>(ss.headSet(toElement));
53.1167 + }
53.1168 + public SortedSet<E> tailSet(E fromElement) {
53.1169 + return new UnmodifiableSortedSet<>(ss.tailSet(fromElement));
53.1170 + }
53.1171 +
53.1172 + public E first() {return ss.first();}
53.1173 + public E last() {return ss.last();}
53.1174 + }
53.1175 +
53.1176 + /**
53.1177 + * Returns an unmodifiable view of the specified list. This method allows
53.1178 + * modules to provide users with "read-only" access to internal
53.1179 + * lists. Query operations on the returned list "read through" to the
53.1180 + * specified list, and attempts to modify the returned list, whether
53.1181 + * direct or via its iterator, result in an
53.1182 + * <tt>UnsupportedOperationException</tt>.<p>
53.1183 + *
53.1184 + * The returned list will be serializable if the specified list
53.1185 + * is serializable. Similarly, the returned list will implement
53.1186 + * {@link RandomAccess} if the specified list does.
53.1187 + *
53.1188 + * @param list the list for which an unmodifiable view is to be returned.
53.1189 + * @return an unmodifiable view of the specified list.
53.1190 + */
53.1191 + public static <T> List<T> unmodifiableList(List<? extends T> list) {
53.1192 + return (list instanceof RandomAccess ?
53.1193 + new UnmodifiableRandomAccessList<>(list) :
53.1194 + new UnmodifiableList<>(list));
53.1195 + }
53.1196 +
53.1197 + /**
53.1198 + * @serial include
53.1199 + */
53.1200 + static class UnmodifiableList<E> extends UnmodifiableCollection<E>
53.1201 + implements List<E> {
53.1202 + private static final long serialVersionUID = -283967356065247728L;
53.1203 + final List<? extends E> list;
53.1204 +
53.1205 + UnmodifiableList(List<? extends E> list) {
53.1206 + super(list);
53.1207 + this.list = list;
53.1208 + }
53.1209 +
53.1210 + public boolean equals(Object o) {return o == this || list.equals(o);}
53.1211 + public int hashCode() {return list.hashCode();}
53.1212 +
53.1213 + public E get(int index) {return list.get(index);}
53.1214 + public E set(int index, E element) {
53.1215 + throw new UnsupportedOperationException();
53.1216 + }
53.1217 + public void add(int index, E element) {
53.1218 + throw new UnsupportedOperationException();
53.1219 + }
53.1220 + public E remove(int index) {
53.1221 + throw new UnsupportedOperationException();
53.1222 + }
53.1223 + public int indexOf(Object o) {return list.indexOf(o);}
53.1224 + public int lastIndexOf(Object o) {return list.lastIndexOf(o);}
53.1225 + public boolean addAll(int index, Collection<? extends E> c) {
53.1226 + throw new UnsupportedOperationException();
53.1227 + }
53.1228 + public ListIterator<E> listIterator() {return listIterator(0);}
53.1229 +
53.1230 + public ListIterator<E> listIterator(final int index) {
53.1231 + return new ListIterator<E>() {
53.1232 + private final ListIterator<? extends E> i
53.1233 + = list.listIterator(index);
53.1234 +
53.1235 + public boolean hasNext() {return i.hasNext();}
53.1236 + public E next() {return i.next();}
53.1237 + public boolean hasPrevious() {return i.hasPrevious();}
53.1238 + public E previous() {return i.previous();}
53.1239 + public int nextIndex() {return i.nextIndex();}
53.1240 + public int previousIndex() {return i.previousIndex();}
53.1241 +
53.1242 + public void remove() {
53.1243 + throw new UnsupportedOperationException();
53.1244 + }
53.1245 + public void set(E e) {
53.1246 + throw new UnsupportedOperationException();
53.1247 + }
53.1248 + public void add(E e) {
53.1249 + throw new UnsupportedOperationException();
53.1250 + }
53.1251 + };
53.1252 + }
53.1253 +
53.1254 + public List<E> subList(int fromIndex, int toIndex) {
53.1255 + return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
53.1256 + }
53.1257 +
53.1258 + /**
53.1259 + * UnmodifiableRandomAccessList instances are serialized as
53.1260 + * UnmodifiableList instances to allow them to be deserialized
53.1261 + * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).
53.1262 + * This method inverts the transformation. As a beneficial
53.1263 + * side-effect, it also grafts the RandomAccess marker onto
53.1264 + * UnmodifiableList instances that were serialized in pre-1.4 JREs.
53.1265 + *
53.1266 + * Note: Unfortunately, UnmodifiableRandomAccessList instances
53.1267 + * serialized in 1.4.1 and deserialized in 1.4 will become
53.1268 + * UnmodifiableList instances, as this method was missing in 1.4.
53.1269 + */
53.1270 + private Object readResolve() {
53.1271 + return (list instanceof RandomAccess
53.1272 + ? new UnmodifiableRandomAccessList<>(list)
53.1273 + : this);
53.1274 + }
53.1275 + }
53.1276 +
53.1277 + /**
53.1278 + * @serial include
53.1279 + */
53.1280 + static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
53.1281 + implements RandomAccess
53.1282 + {
53.1283 + UnmodifiableRandomAccessList(List<? extends E> list) {
53.1284 + super(list);
53.1285 + }
53.1286 +
53.1287 + public List<E> subList(int fromIndex, int toIndex) {
53.1288 + return new UnmodifiableRandomAccessList<>(
53.1289 + list.subList(fromIndex, toIndex));
53.1290 + }
53.1291 +
53.1292 + private static final long serialVersionUID = -2542308836966382001L;
53.1293 +
53.1294 + /**
53.1295 + * Allows instances to be deserialized in pre-1.4 JREs (which do
53.1296 + * not have UnmodifiableRandomAccessList). UnmodifiableList has
53.1297 + * a readResolve method that inverts this transformation upon
53.1298 + * deserialization.
53.1299 + */
53.1300 + private Object writeReplace() {
53.1301 + return new UnmodifiableList<>(list);
53.1302 + }
53.1303 + }
53.1304 +
53.1305 + /**
53.1306 + * Returns an unmodifiable view of the specified map. This method
53.1307 + * allows modules to provide users with "read-only" access to internal
53.1308 + * maps. Query operations on the returned map "read through"
53.1309 + * to the specified map, and attempts to modify the returned
53.1310 + * map, whether direct or via its collection views, result in an
53.1311 + * <tt>UnsupportedOperationException</tt>.<p>
53.1312 + *
53.1313 + * The returned map will be serializable if the specified map
53.1314 + * is serializable.
53.1315 + *
53.1316 + * @param m the map for which an unmodifiable view is to be returned.
53.1317 + * @return an unmodifiable view of the specified map.
53.1318 + */
53.1319 + public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
53.1320 + return new UnmodifiableMap<>(m);
53.1321 + }
53.1322 +
53.1323 + /**
53.1324 + * @serial include
53.1325 + */
53.1326 + private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
53.1327 + private static final long serialVersionUID = -1034234728574286014L;
53.1328 +
53.1329 + private final Map<? extends K, ? extends V> m;
53.1330 +
53.1331 + UnmodifiableMap(Map<? extends K, ? extends V> m) {
53.1332 + if (m==null)
53.1333 + throw new NullPointerException();
53.1334 + this.m = m;
53.1335 + }
53.1336 +
53.1337 + public int size() {return m.size();}
53.1338 + public boolean isEmpty() {return m.isEmpty();}
53.1339 + public boolean containsKey(Object key) {return m.containsKey(key);}
53.1340 + public boolean containsValue(Object val) {return m.containsValue(val);}
53.1341 + public V get(Object key) {return m.get(key);}
53.1342 +
53.1343 + public V put(K key, V value) {
53.1344 + throw new UnsupportedOperationException();
53.1345 + }
53.1346 + public V remove(Object key) {
53.1347 + throw new UnsupportedOperationException();
53.1348 + }
53.1349 + public void putAll(Map<? extends K, ? extends V> m) {
53.1350 + throw new UnsupportedOperationException();
53.1351 + }
53.1352 + public void clear() {
53.1353 + throw new UnsupportedOperationException();
53.1354 + }
53.1355 +
53.1356 + private transient Set<K> keySet = null;
53.1357 + private transient Set<Map.Entry<K,V>> entrySet = null;
53.1358 + private transient Collection<V> values = null;
53.1359 +
53.1360 + public Set<K> keySet() {
53.1361 + if (keySet==null)
53.1362 + keySet = unmodifiableSet(m.keySet());
53.1363 + return keySet;
53.1364 + }
53.1365 +
53.1366 + public Set<Map.Entry<K,V>> entrySet() {
53.1367 + if (entrySet==null)
53.1368 + entrySet = new UnmodifiableEntrySet<>(m.entrySet());
53.1369 + return entrySet;
53.1370 + }
53.1371 +
53.1372 + public Collection<V> values() {
53.1373 + if (values==null)
53.1374 + values = unmodifiableCollection(m.values());
53.1375 + return values;
53.1376 + }
53.1377 +
53.1378 + public boolean equals(Object o) {return o == this || m.equals(o);}
53.1379 + public int hashCode() {return m.hashCode();}
53.1380 + public String toString() {return m.toString();}
53.1381 +
53.1382 + /**
53.1383 + * We need this class in addition to UnmodifiableSet as
53.1384 + * Map.Entries themselves permit modification of the backing Map
53.1385 + * via their setValue operation. This class is subtle: there are
53.1386 + * many possible attacks that must be thwarted.
53.1387 + *
53.1388 + * @serial include
53.1389 + */
53.1390 + static class UnmodifiableEntrySet<K,V>
53.1391 + extends UnmodifiableSet<Map.Entry<K,V>> {
53.1392 + private static final long serialVersionUID = 7854390611657943733L;
53.1393 +
53.1394 + UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
53.1395 + super((Set)s);
53.1396 + }
53.1397 + public Iterator<Map.Entry<K,V>> iterator() {
53.1398 + return new Iterator<Map.Entry<K,V>>() {
53.1399 + private final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
53.1400 +
53.1401 + public boolean hasNext() {
53.1402 + return i.hasNext();
53.1403 + }
53.1404 + public Map.Entry<K,V> next() {
53.1405 + return new UnmodifiableEntry<>(i.next());
53.1406 + }
53.1407 + public void remove() {
53.1408 + throw new UnsupportedOperationException();
53.1409 + }
53.1410 + };
53.1411 + }
53.1412 +
53.1413 + public Object[] toArray() {
53.1414 + Object[] a = c.toArray();
53.1415 + for (int i=0; i<a.length; i++)
53.1416 + a[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)a[i]);
53.1417 + return a;
53.1418 + }
53.1419 +
53.1420 + public <T> T[] toArray(T[] a) {
53.1421 + // We don't pass a to c.toArray, to avoid window of
53.1422 + // vulnerability wherein an unscrupulous multithreaded client
53.1423 + // could get his hands on raw (unwrapped) Entries from c.
53.1424 + Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
53.1425 +
53.1426 + for (int i=0; i<arr.length; i++)
53.1427 + arr[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)arr[i]);
53.1428 +
53.1429 + if (arr.length > a.length)
53.1430 + return (T[])arr;
53.1431 +
53.1432 + System.arraycopy(arr, 0, a, 0, arr.length);
53.1433 + if (a.length > arr.length)
53.1434 + a[arr.length] = null;
53.1435 + return a;
53.1436 + }
53.1437 +
53.1438 + /**
53.1439 + * This method is overridden to protect the backing set against
53.1440 + * an object with a nefarious equals function that senses
53.1441 + * that the equality-candidate is Map.Entry and calls its
53.1442 + * setValue method.
53.1443 + */
53.1444 + public boolean contains(Object o) {
53.1445 + if (!(o instanceof Map.Entry))
53.1446 + return false;
53.1447 + return c.contains(
53.1448 + new UnmodifiableEntry<>((Map.Entry<?,?>) o));
53.1449 + }
53.1450 +
53.1451 + /**
53.1452 + * The next two methods are overridden to protect against
53.1453 + * an unscrupulous List whose contains(Object o) method senses
53.1454 + * when o is a Map.Entry, and calls o.setValue.
53.1455 + */
53.1456 + public boolean containsAll(Collection<?> coll) {
53.1457 + for (Object e : coll) {
53.1458 + if (!contains(e)) // Invokes safe contains() above
53.1459 + return false;
53.1460 + }
53.1461 + return true;
53.1462 + }
53.1463 + public boolean equals(Object o) {
53.1464 + if (o == this)
53.1465 + return true;
53.1466 +
53.1467 + if (!(o instanceof Set))
53.1468 + return false;
53.1469 + Set s = (Set) o;
53.1470 + if (s.size() != c.size())
53.1471 + return false;
53.1472 + return containsAll(s); // Invokes safe containsAll() above
53.1473 + }
53.1474 +
53.1475 + /**
53.1476 + * This "wrapper class" serves two purposes: it prevents
53.1477 + * the client from modifying the backing Map, by short-circuiting
53.1478 + * the setValue method, and it protects the backing Map against
53.1479 + * an ill-behaved Map.Entry that attempts to modify another
53.1480 + * Map Entry when asked to perform an equality check.
53.1481 + */
53.1482 + private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> {
53.1483 + private Map.Entry<? extends K, ? extends V> e;
53.1484 +
53.1485 + UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;}
53.1486 +
53.1487 + public K getKey() {return e.getKey();}
53.1488 + public V getValue() {return e.getValue();}
53.1489 + public V setValue(V value) {
53.1490 + throw new UnsupportedOperationException();
53.1491 + }
53.1492 + public int hashCode() {return e.hashCode();}
53.1493 + public boolean equals(Object o) {
53.1494 + if (!(o instanceof Map.Entry))
53.1495 + return false;
53.1496 + Map.Entry t = (Map.Entry)o;
53.1497 + return eq(e.getKey(), t.getKey()) &&
53.1498 + eq(e.getValue(), t.getValue());
53.1499 + }
53.1500 + public String toString() {return e.toString();}
53.1501 + }
53.1502 + }
53.1503 + }
53.1504 +
53.1505 + /**
53.1506 + * Returns an unmodifiable view of the specified sorted map. This method
53.1507 + * allows modules to provide users with "read-only" access to internal
53.1508 + * sorted maps. Query operations on the returned sorted map "read through"
53.1509 + * to the specified sorted map. Attempts to modify the returned
53.1510 + * sorted map, whether direct, via its collection views, or via its
53.1511 + * <tt>subMap</tt>, <tt>headMap</tt>, or <tt>tailMap</tt> views, result in
53.1512 + * an <tt>UnsupportedOperationException</tt>.<p>
53.1513 + *
53.1514 + * The returned sorted map will be serializable if the specified sorted map
53.1515 + * is serializable.
53.1516 + *
53.1517 + * @param m the sorted map for which an unmodifiable view is to be
53.1518 + * returned.
53.1519 + * @return an unmodifiable view of the specified sorted map.
53.1520 + */
53.1521 + public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
53.1522 + return new UnmodifiableSortedMap<>(m);
53.1523 + }
53.1524 +
53.1525 + /**
53.1526 + * @serial include
53.1527 + */
53.1528 + static class UnmodifiableSortedMap<K,V>
53.1529 + extends UnmodifiableMap<K,V>
53.1530 + implements SortedMap<K,V>, Serializable {
53.1531 + private static final long serialVersionUID = -8806743815996713206L;
53.1532 +
53.1533 + private final SortedMap<K, ? extends V> sm;
53.1534 +
53.1535 + UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m;}
53.1536 +
53.1537 + public Comparator<? super K> comparator() {return sm.comparator();}
53.1538 +
53.1539 + public SortedMap<K,V> subMap(K fromKey, K toKey) {
53.1540 + return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey));
53.1541 + }
53.1542 + public SortedMap<K,V> headMap(K toKey) {
53.1543 + return new UnmodifiableSortedMap<>(sm.headMap(toKey));
53.1544 + }
53.1545 + public SortedMap<K,V> tailMap(K fromKey) {
53.1546 + return new UnmodifiableSortedMap<>(sm.tailMap(fromKey));
53.1547 + }
53.1548 +
53.1549 + public K firstKey() {return sm.firstKey();}
53.1550 + public K lastKey() {return sm.lastKey();}
53.1551 + }
53.1552 +
53.1553 +
53.1554 + // Synch Wrappers
53.1555 +
53.1556 + /**
53.1557 + * Returns a synchronized (thread-safe) collection backed by the specified
53.1558 + * collection. In order to guarantee serial access, it is critical that
53.1559 + * <strong>all</strong> access to the backing collection is accomplished
53.1560 + * through the returned collection.<p>
53.1561 + *
53.1562 + * It is imperative that the user manually synchronize on the returned
53.1563 + * collection when iterating over it:
53.1564 + * <pre>
53.1565 + * Collection c = Collections.synchronizedCollection(myCollection);
53.1566 + * ...
53.1567 + * synchronized (c) {
53.1568 + * Iterator i = c.iterator(); // Must be in the synchronized block
53.1569 + * while (i.hasNext())
53.1570 + * foo(i.next());
53.1571 + * }
53.1572 + * </pre>
53.1573 + * Failure to follow this advice may result in non-deterministic behavior.
53.1574 + *
53.1575 + * <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt>
53.1576 + * and <tt>equals</tt> operations through to the backing collection, but
53.1577 + * relies on <tt>Object</tt>'s equals and hashCode methods. This is
53.1578 + * necessary to preserve the contracts of these operations in the case
53.1579 + * that the backing collection is a set or a list.<p>
53.1580 + *
53.1581 + * The returned collection will be serializable if the specified collection
53.1582 + * is serializable.
53.1583 + *
53.1584 + * @param c the collection to be "wrapped" in a synchronized collection.
53.1585 + * @return a synchronized view of the specified collection.
53.1586 + */
53.1587 + public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
53.1588 + return new SynchronizedCollection<>(c);
53.1589 + }
53.1590 +
53.1591 + static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
53.1592 + return new SynchronizedCollection<>(c, mutex);
53.1593 + }
53.1594 +
53.1595 + /**
53.1596 + * @serial include
53.1597 + */
53.1598 + static class SynchronizedCollection<E> implements Collection<E>, Serializable {
53.1599 + private static final long serialVersionUID = 3053995032091335093L;
53.1600 +
53.1601 + final Collection<E> c; // Backing Collection
53.1602 + final Object mutex; // Object on which to synchronize
53.1603 +
53.1604 + SynchronizedCollection(Collection<E> c) {
53.1605 + if (c==null)
53.1606 + throw new NullPointerException();
53.1607 + this.c = c;
53.1608 + mutex = this;
53.1609 + }
53.1610 + SynchronizedCollection(Collection<E> c, Object mutex) {
53.1611 + this.c = c;
53.1612 + this.mutex = mutex;
53.1613 + }
53.1614 +
53.1615 + public int size() {
53.1616 + synchronized (mutex) {return c.size();}
53.1617 + }
53.1618 + public boolean isEmpty() {
53.1619 + synchronized (mutex) {return c.isEmpty();}
53.1620 + }
53.1621 + public boolean contains(Object o) {
53.1622 + synchronized (mutex) {return c.contains(o);}
53.1623 + }
53.1624 + public Object[] toArray() {
53.1625 + synchronized (mutex) {return c.toArray();}
53.1626 + }
53.1627 + public <T> T[] toArray(T[] a) {
53.1628 + synchronized (mutex) {return c.toArray(a);}
53.1629 + }
53.1630 +
53.1631 + public Iterator<E> iterator() {
53.1632 + return c.iterator(); // Must be manually synched by user!
53.1633 + }
53.1634 +
53.1635 + public boolean add(E e) {
53.1636 + synchronized (mutex) {return c.add(e);}
53.1637 + }
53.1638 + public boolean remove(Object o) {
53.1639 + synchronized (mutex) {return c.remove(o);}
53.1640 + }
53.1641 +
53.1642 + public boolean containsAll(Collection<?> coll) {
53.1643 + synchronized (mutex) {return c.containsAll(coll);}
53.1644 + }
53.1645 + public boolean addAll(Collection<? extends E> coll) {
53.1646 + synchronized (mutex) {return c.addAll(coll);}
53.1647 + }
53.1648 + public boolean removeAll(Collection<?> coll) {
53.1649 + synchronized (mutex) {return c.removeAll(coll);}
53.1650 + }
53.1651 + public boolean retainAll(Collection<?> coll) {
53.1652 + synchronized (mutex) {return c.retainAll(coll);}
53.1653 + }
53.1654 + public void clear() {
53.1655 + synchronized (mutex) {c.clear();}
53.1656 + }
53.1657 + public String toString() {
53.1658 + synchronized (mutex) {return c.toString();}
53.1659 + }
53.1660 + }
53.1661 +
53.1662 + /**
53.1663 + * Returns a synchronized (thread-safe) set backed by the specified
53.1664 + * set. In order to guarantee serial access, it is critical that
53.1665 + * <strong>all</strong> access to the backing set is accomplished
53.1666 + * through the returned set.<p>
53.1667 + *
53.1668 + * It is imperative that the user manually synchronize on the returned
53.1669 + * set when iterating over it:
53.1670 + * <pre>
53.1671 + * Set s = Collections.synchronizedSet(new HashSet());
53.1672 + * ...
53.1673 + * synchronized (s) {
53.1674 + * Iterator i = s.iterator(); // Must be in the synchronized block
53.1675 + * while (i.hasNext())
53.1676 + * foo(i.next());
53.1677 + * }
53.1678 + * </pre>
53.1679 + * Failure to follow this advice may result in non-deterministic behavior.
53.1680 + *
53.1681 + * <p>The returned set will be serializable if the specified set is
53.1682 + * serializable.
53.1683 + *
53.1684 + * @param s the set to be "wrapped" in a synchronized set.
53.1685 + * @return a synchronized view of the specified set.
53.1686 + */
53.1687 + public static <T> Set<T> synchronizedSet(Set<T> s) {
53.1688 + return new SynchronizedSet<>(s);
53.1689 + }
53.1690 +
53.1691 + static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {
53.1692 + return new SynchronizedSet<>(s, mutex);
53.1693 + }
53.1694 +
53.1695 + /**
53.1696 + * @serial include
53.1697 + */
53.1698 + static class SynchronizedSet<E>
53.1699 + extends SynchronizedCollection<E>
53.1700 + implements Set<E> {
53.1701 + private static final long serialVersionUID = 487447009682186044L;
53.1702 +
53.1703 + SynchronizedSet(Set<E> s) {
53.1704 + super(s);
53.1705 + }
53.1706 + SynchronizedSet(Set<E> s, Object mutex) {
53.1707 + super(s, mutex);
53.1708 + }
53.1709 +
53.1710 + public boolean equals(Object o) {
53.1711 + synchronized (mutex) {return c.equals(o);}
53.1712 + }
53.1713 + public int hashCode() {
53.1714 + synchronized (mutex) {return c.hashCode();}
53.1715 + }
53.1716 + }
53.1717 +
53.1718 + /**
53.1719 + * Returns a synchronized (thread-safe) sorted set backed by the specified
53.1720 + * sorted set. In order to guarantee serial access, it is critical that
53.1721 + * <strong>all</strong> access to the backing sorted set is accomplished
53.1722 + * through the returned sorted set (or its views).<p>
53.1723 + *
53.1724 + * It is imperative that the user manually synchronize on the returned
53.1725 + * sorted set when iterating over it or any of its <tt>subSet</tt>,
53.1726 + * <tt>headSet</tt>, or <tt>tailSet</tt> views.
53.1727 + * <pre>
53.1728 + * SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
53.1729 + * ...
53.1730 + * synchronized (s) {
53.1731 + * Iterator i = s.iterator(); // Must be in the synchronized block
53.1732 + * while (i.hasNext())
53.1733 + * foo(i.next());
53.1734 + * }
53.1735 + * </pre>
53.1736 + * or:
53.1737 + * <pre>
53.1738 + * SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
53.1739 + * SortedSet s2 = s.headSet(foo);
53.1740 + * ...
53.1741 + * synchronized (s) { // Note: s, not s2!!!
53.1742 + * Iterator i = s2.iterator(); // Must be in the synchronized block
53.1743 + * while (i.hasNext())
53.1744 + * foo(i.next());
53.1745 + * }
53.1746 + * </pre>
53.1747 + * Failure to follow this advice may result in non-deterministic behavior.
53.1748 + *
53.1749 + * <p>The returned sorted set will be serializable if the specified
53.1750 + * sorted set is serializable.
53.1751 + *
53.1752 + * @param s the sorted set to be "wrapped" in a synchronized sorted set.
53.1753 + * @return a synchronized view of the specified sorted set.
53.1754 + */
53.1755 + public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {
53.1756 + return new SynchronizedSortedSet<>(s);
53.1757 + }
53.1758 +
53.1759 + /**
53.1760 + * @serial include
53.1761 + */
53.1762 + static class SynchronizedSortedSet<E>
53.1763 + extends SynchronizedSet<E>
53.1764 + implements SortedSet<E>
53.1765 + {
53.1766 + private static final long serialVersionUID = 8695801310862127406L;
53.1767 +
53.1768 + private final SortedSet<E> ss;
53.1769 +
53.1770 + SynchronizedSortedSet(SortedSet<E> s) {
53.1771 + super(s);
53.1772 + ss = s;
53.1773 + }
53.1774 + SynchronizedSortedSet(SortedSet<E> s, Object mutex) {
53.1775 + super(s, mutex);
53.1776 + ss = s;
53.1777 + }
53.1778 +
53.1779 + public Comparator<? super E> comparator() {
53.1780 + synchronized (mutex) {return ss.comparator();}
53.1781 + }
53.1782 +
53.1783 + public SortedSet<E> subSet(E fromElement, E toElement) {
53.1784 + synchronized (mutex) {
53.1785 + return new SynchronizedSortedSet<>(
53.1786 + ss.subSet(fromElement, toElement), mutex);
53.1787 + }
53.1788 + }
53.1789 + public SortedSet<E> headSet(E toElement) {
53.1790 + synchronized (mutex) {
53.1791 + return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
53.1792 + }
53.1793 + }
53.1794 + public SortedSet<E> tailSet(E fromElement) {
53.1795 + synchronized (mutex) {
53.1796 + return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex);
53.1797 + }
53.1798 + }
53.1799 +
53.1800 + public E first() {
53.1801 + synchronized (mutex) {return ss.first();}
53.1802 + }
53.1803 + public E last() {
53.1804 + synchronized (mutex) {return ss.last();}
53.1805 + }
53.1806 + }
53.1807 +
53.1808 + /**
53.1809 + * Returns a synchronized (thread-safe) list backed by the specified
53.1810 + * list. In order to guarantee serial access, it is critical that
53.1811 + * <strong>all</strong> access to the backing list is accomplished
53.1812 + * through the returned list.<p>
53.1813 + *
53.1814 + * It is imperative that the user manually synchronize on the returned
53.1815 + * list when iterating over it:
53.1816 + * <pre>
53.1817 + * List list = Collections.synchronizedList(new ArrayList());
53.1818 + * ...
53.1819 + * synchronized (list) {
53.1820 + * Iterator i = list.iterator(); // Must be in synchronized block
53.1821 + * while (i.hasNext())
53.1822 + * foo(i.next());
53.1823 + * }
53.1824 + * </pre>
53.1825 + * Failure to follow this advice may result in non-deterministic behavior.
53.1826 + *
53.1827 + * <p>The returned list will be serializable if the specified list is
53.1828 + * serializable.
53.1829 + *
53.1830 + * @param list the list to be "wrapped" in a synchronized list.
53.1831 + * @return a synchronized view of the specified list.
53.1832 + */
53.1833 + public static <T> List<T> synchronizedList(List<T> list) {
53.1834 + return (list instanceof RandomAccess ?
53.1835 + new SynchronizedRandomAccessList<>(list) :
53.1836 + new SynchronizedList<>(list));
53.1837 + }
53.1838 +
53.1839 + static <T> List<T> synchronizedList(List<T> list, Object mutex) {
53.1840 + return (list instanceof RandomAccess ?
53.1841 + new SynchronizedRandomAccessList<>(list, mutex) :
53.1842 + new SynchronizedList<>(list, mutex));
53.1843 + }
53.1844 +
53.1845 + /**
53.1846 + * @serial include
53.1847 + */
53.1848 + static class SynchronizedList<E>
53.1849 + extends SynchronizedCollection<E>
53.1850 + implements List<E> {
53.1851 + private static final long serialVersionUID = -7754090372962971524L;
53.1852 +
53.1853 + final List<E> list;
53.1854 +
53.1855 + SynchronizedList(List<E> list) {
53.1856 + super(list);
53.1857 + this.list = list;
53.1858 + }
53.1859 + SynchronizedList(List<E> list, Object mutex) {
53.1860 + super(list, mutex);
53.1861 + this.list = list;
53.1862 + }
53.1863 +
53.1864 + public boolean equals(Object o) {
53.1865 + synchronized (mutex) {return list.equals(o);}
53.1866 + }
53.1867 + public int hashCode() {
53.1868 + synchronized (mutex) {return list.hashCode();}
53.1869 + }
53.1870 +
53.1871 + public E get(int index) {
53.1872 + synchronized (mutex) {return list.get(index);}
53.1873 + }
53.1874 + public E set(int index, E element) {
53.1875 + synchronized (mutex) {return list.set(index, element);}
53.1876 + }
53.1877 + public void add(int index, E element) {
53.1878 + synchronized (mutex) {list.add(index, element);}
53.1879 + }
53.1880 + public E remove(int index) {
53.1881 + synchronized (mutex) {return list.remove(index);}
53.1882 + }
53.1883 +
53.1884 + public int indexOf(Object o) {
53.1885 + synchronized (mutex) {return list.indexOf(o);}
53.1886 + }
53.1887 + public int lastIndexOf(Object o) {
53.1888 + synchronized (mutex) {return list.lastIndexOf(o);}
53.1889 + }
53.1890 +
53.1891 + public boolean addAll(int index, Collection<? extends E> c) {
53.1892 + synchronized (mutex) {return list.addAll(index, c);}
53.1893 + }
53.1894 +
53.1895 + public ListIterator<E> listIterator() {
53.1896 + return list.listIterator(); // Must be manually synched by user
53.1897 + }
53.1898 +
53.1899 + public ListIterator<E> listIterator(int index) {
53.1900 + return list.listIterator(index); // Must be manually synched by user
53.1901 + }
53.1902 +
53.1903 + public List<E> subList(int fromIndex, int toIndex) {
53.1904 + synchronized (mutex) {
53.1905 + return new SynchronizedList<>(list.subList(fromIndex, toIndex),
53.1906 + mutex);
53.1907 + }
53.1908 + }
53.1909 +
53.1910 + /**
53.1911 + * SynchronizedRandomAccessList instances are serialized as
53.1912 + * SynchronizedList instances to allow them to be deserialized
53.1913 + * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList).
53.1914 + * This method inverts the transformation. As a beneficial
53.1915 + * side-effect, it also grafts the RandomAccess marker onto
53.1916 + * SynchronizedList instances that were serialized in pre-1.4 JREs.
53.1917 + *
53.1918 + * Note: Unfortunately, SynchronizedRandomAccessList instances
53.1919 + * serialized in 1.4.1 and deserialized in 1.4 will become
53.1920 + * SynchronizedList instances, as this method was missing in 1.4.
53.1921 + */
53.1922 + private Object readResolve() {
53.1923 + return (list instanceof RandomAccess
53.1924 + ? new SynchronizedRandomAccessList<>(list)
53.1925 + : this);
53.1926 + }
53.1927 + }
53.1928 +
53.1929 + /**
53.1930 + * @serial include
53.1931 + */
53.1932 + static class SynchronizedRandomAccessList<E>
53.1933 + extends SynchronizedList<E>
53.1934 + implements RandomAccess {
53.1935 +
53.1936 + SynchronizedRandomAccessList(List<E> list) {
53.1937 + super(list);
53.1938 + }
53.1939 +
53.1940 + SynchronizedRandomAccessList(List<E> list, Object mutex) {
53.1941 + super(list, mutex);
53.1942 + }
53.1943 +
53.1944 + public List<E> subList(int fromIndex, int toIndex) {
53.1945 + synchronized (mutex) {
53.1946 + return new SynchronizedRandomAccessList<>(
53.1947 + list.subList(fromIndex, toIndex), mutex);
53.1948 + }
53.1949 + }
53.1950 +
53.1951 + private static final long serialVersionUID = 1530674583602358482L;
53.1952 +
53.1953 + /**
53.1954 + * Allows instances to be deserialized in pre-1.4 JREs (which do
53.1955 + * not have SynchronizedRandomAccessList). SynchronizedList has
53.1956 + * a readResolve method that inverts this transformation upon
53.1957 + * deserialization.
53.1958 + */
53.1959 + private Object writeReplace() {
53.1960 + return new SynchronizedList<>(list);
53.1961 + }
53.1962 + }
53.1963 +
53.1964 + /**
53.1965 + * Returns a synchronized (thread-safe) map backed by the specified
53.1966 + * map. In order to guarantee serial access, it is critical that
53.1967 + * <strong>all</strong> access to the backing map is accomplished
53.1968 + * through the returned map.<p>
53.1969 + *
53.1970 + * It is imperative that the user manually synchronize on the returned
53.1971 + * map when iterating over any of its collection views:
53.1972 + * <pre>
53.1973 + * Map m = Collections.synchronizedMap(new HashMap());
53.1974 + * ...
53.1975 + * Set s = m.keySet(); // Needn't be in synchronized block
53.1976 + * ...
53.1977 + * synchronized (m) { // Synchronizing on m, not s!
53.1978 + * Iterator i = s.iterator(); // Must be in synchronized block
53.1979 + * while (i.hasNext())
53.1980 + * foo(i.next());
53.1981 + * }
53.1982 + * </pre>
53.1983 + * Failure to follow this advice may result in non-deterministic behavior.
53.1984 + *
53.1985 + * <p>The returned map will be serializable if the specified map is
53.1986 + * serializable.
53.1987 + *
53.1988 + * @param m the map to be "wrapped" in a synchronized map.
53.1989 + * @return a synchronized view of the specified map.
53.1990 + */
53.1991 + public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
53.1992 + return new SynchronizedMap<>(m);
53.1993 + }
53.1994 +
53.1995 + /**
53.1996 + * @serial include
53.1997 + */
53.1998 + private static class SynchronizedMap<K,V>
53.1999 + implements Map<K,V>, Serializable {
53.2000 + private static final long serialVersionUID = 1978198479659022715L;
53.2001 +
53.2002 + private final Map<K,V> m; // Backing Map
53.2003 + final Object mutex; // Object on which to synchronize
53.2004 +
53.2005 + SynchronizedMap(Map<K,V> m) {
53.2006 + if (m==null)
53.2007 + throw new NullPointerException();
53.2008 + this.m = m;
53.2009 + mutex = this;
53.2010 + }
53.2011 +
53.2012 + SynchronizedMap(Map<K,V> m, Object mutex) {
53.2013 + this.m = m;
53.2014 + this.mutex = mutex;
53.2015 + }
53.2016 +
53.2017 + public int size() {
53.2018 + synchronized (mutex) {return m.size();}
53.2019 + }
53.2020 + public boolean isEmpty() {
53.2021 + synchronized (mutex) {return m.isEmpty();}
53.2022 + }
53.2023 + public boolean containsKey(Object key) {
53.2024 + synchronized (mutex) {return m.containsKey(key);}
53.2025 + }
53.2026 + public boolean containsValue(Object value) {
53.2027 + synchronized (mutex) {return m.containsValue(value);}
53.2028 + }
53.2029 + public V get(Object key) {
53.2030 + synchronized (mutex) {return m.get(key);}
53.2031 + }
53.2032 +
53.2033 + public V put(K key, V value) {
53.2034 + synchronized (mutex) {return m.put(key, value);}
53.2035 + }
53.2036 + public V remove(Object key) {
53.2037 + synchronized (mutex) {return m.remove(key);}
53.2038 + }
53.2039 + public void putAll(Map<? extends K, ? extends V> map) {
53.2040 + synchronized (mutex) {m.putAll(map);}
53.2041 + }
53.2042 + public void clear() {
53.2043 + synchronized (mutex) {m.clear();}
53.2044 + }
53.2045 +
53.2046 + private transient Set<K> keySet = null;
53.2047 + private transient Set<Map.Entry<K,V>> entrySet = null;
53.2048 + private transient Collection<V> values = null;
53.2049 +
53.2050 + public Set<K> keySet() {
53.2051 + synchronized (mutex) {
53.2052 + if (keySet==null)
53.2053 + keySet = new SynchronizedSet<>(m.keySet(), mutex);
53.2054 + return keySet;
53.2055 + }
53.2056 + }
53.2057 +
53.2058 + public Set<Map.Entry<K,V>> entrySet() {
53.2059 + synchronized (mutex) {
53.2060 + if (entrySet==null)
53.2061 + entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
53.2062 + return entrySet;
53.2063 + }
53.2064 + }
53.2065 +
53.2066 + public Collection<V> values() {
53.2067 + synchronized (mutex) {
53.2068 + if (values==null)
53.2069 + values = new SynchronizedCollection<>(m.values(), mutex);
53.2070 + return values;
53.2071 + }
53.2072 + }
53.2073 +
53.2074 + public boolean equals(Object o) {
53.2075 + synchronized (mutex) {return m.equals(o);}
53.2076 + }
53.2077 + public int hashCode() {
53.2078 + synchronized (mutex) {return m.hashCode();}
53.2079 + }
53.2080 + public String toString() {
53.2081 + synchronized (mutex) {return m.toString();}
53.2082 + }
53.2083 + }
53.2084 +
53.2085 + /**
53.2086 + * Returns a synchronized (thread-safe) sorted map backed by the specified
53.2087 + * sorted map. In order to guarantee serial access, it is critical that
53.2088 + * <strong>all</strong> access to the backing sorted map is accomplished
53.2089 + * through the returned sorted map (or its views).<p>
53.2090 + *
53.2091 + * It is imperative that the user manually synchronize on the returned
53.2092 + * sorted map when iterating over any of its collection views, or the
53.2093 + * collections views of any of its <tt>subMap</tt>, <tt>headMap</tt> or
53.2094 + * <tt>tailMap</tt> views.
53.2095 + * <pre>
53.2096 + * SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
53.2097 + * ...
53.2098 + * Set s = m.keySet(); // Needn't be in synchronized block
53.2099 + * ...
53.2100 + * synchronized (m) { // Synchronizing on m, not s!
53.2101 + * Iterator i = s.iterator(); // Must be in synchronized block
53.2102 + * while (i.hasNext())
53.2103 + * foo(i.next());
53.2104 + * }
53.2105 + * </pre>
53.2106 + * or:
53.2107 + * <pre>
53.2108 + * SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
53.2109 + * SortedMap m2 = m.subMap(foo, bar);
53.2110 + * ...
53.2111 + * Set s2 = m2.keySet(); // Needn't be in synchronized block
53.2112 + * ...
53.2113 + * synchronized (m) { // Synchronizing on m, not m2 or s2!
53.2114 + * Iterator i = s.iterator(); // Must be in synchronized block
53.2115 + * while (i.hasNext())
53.2116 + * foo(i.next());
53.2117 + * }
53.2118 + * </pre>
53.2119 + * Failure to follow this advice may result in non-deterministic behavior.
53.2120 + *
53.2121 + * <p>The returned sorted map will be serializable if the specified
53.2122 + * sorted map is serializable.
53.2123 + *
53.2124 + * @param m the sorted map to be "wrapped" in a synchronized sorted map.
53.2125 + * @return a synchronized view of the specified sorted map.
53.2126 + */
53.2127 + public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) {
53.2128 + return new SynchronizedSortedMap<>(m);
53.2129 + }
53.2130 +
53.2131 +
53.2132 + /**
53.2133 + * @serial include
53.2134 + */
53.2135 + static class SynchronizedSortedMap<K,V>
53.2136 + extends SynchronizedMap<K,V>
53.2137 + implements SortedMap<K,V>
53.2138 + {
53.2139 + private static final long serialVersionUID = -8798146769416483793L;
53.2140 +
53.2141 + private final SortedMap<K,V> sm;
53.2142 +
53.2143 + SynchronizedSortedMap(SortedMap<K,V> m) {
53.2144 + super(m);
53.2145 + sm = m;
53.2146 + }
53.2147 + SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) {
53.2148 + super(m, mutex);
53.2149 + sm = m;
53.2150 + }
53.2151 +
53.2152 + public Comparator<? super K> comparator() {
53.2153 + synchronized (mutex) {return sm.comparator();}
53.2154 + }
53.2155 +
53.2156 + public SortedMap<K,V> subMap(K fromKey, K toKey) {
53.2157 + synchronized (mutex) {
53.2158 + return new SynchronizedSortedMap<>(
53.2159 + sm.subMap(fromKey, toKey), mutex);
53.2160 + }
53.2161 + }
53.2162 + public SortedMap<K,V> headMap(K toKey) {
53.2163 + synchronized (mutex) {
53.2164 + return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex);
53.2165 + }
53.2166 + }
53.2167 + public SortedMap<K,V> tailMap(K fromKey) {
53.2168 + synchronized (mutex) {
53.2169 + return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex);
53.2170 + }
53.2171 + }
53.2172 +
53.2173 + public K firstKey() {
53.2174 + synchronized (mutex) {return sm.firstKey();}
53.2175 + }
53.2176 + public K lastKey() {
53.2177 + synchronized (mutex) {return sm.lastKey();}
53.2178 + }
53.2179 + }
53.2180 +
53.2181 + // Dynamically typesafe collection wrappers
53.2182 +
53.2183 + /**
53.2184 + * Returns a dynamically typesafe view of the specified collection.
53.2185 + * Any attempt to insert an element of the wrong type will result in an
53.2186 + * immediate {@link ClassCastException}. Assuming a collection
53.2187 + * contains no incorrectly typed elements prior to the time a
53.2188 + * dynamically typesafe view is generated, and that all subsequent
53.2189 + * access to the collection takes place through the view, it is
53.2190 + * <i>guaranteed</i> that the collection cannot contain an incorrectly
53.2191 + * typed element.
53.2192 + *
53.2193 + * <p>The generics mechanism in the language provides compile-time
53.2194 + * (static) type checking, but it is possible to defeat this mechanism
53.2195 + * with unchecked casts. Usually this is not a problem, as the compiler
53.2196 + * issues warnings on all such unchecked operations. There are, however,
53.2197 + * times when static type checking alone is not sufficient. For example,
53.2198 + * suppose a collection is passed to a third-party library and it is
53.2199 + * imperative that the library code not corrupt the collection by
53.2200 + * inserting an element of the wrong type.
53.2201 + *
53.2202 + * <p>Another use of dynamically typesafe views is debugging. Suppose a
53.2203 + * program fails with a {@code ClassCastException}, indicating that an
53.2204 + * incorrectly typed element was put into a parameterized collection.
53.2205 + * Unfortunately, the exception can occur at any time after the erroneous
53.2206 + * element is inserted, so it typically provides little or no information
53.2207 + * as to the real source of the problem. If the problem is reproducible,
53.2208 + * one can quickly determine its source by temporarily modifying the
53.2209 + * program to wrap the collection with a dynamically typesafe view.
53.2210 + * For example, this declaration:
53.2211 + * <pre> {@code
53.2212 + * Collection<String> c = new HashSet<String>();
53.2213 + * }</pre>
53.2214 + * may be replaced temporarily by this one:
53.2215 + * <pre> {@code
53.2216 + * Collection<String> c = Collections.checkedCollection(
53.2217 + * new HashSet<String>(), String.class);
53.2218 + * }</pre>
53.2219 + * Running the program again will cause it to fail at the point where
53.2220 + * an incorrectly typed element is inserted into the collection, clearly
53.2221 + * identifying the source of the problem. Once the problem is fixed, the
53.2222 + * modified declaration may be reverted back to the original.
53.2223 + *
53.2224 + * <p>The returned collection does <i>not</i> pass the hashCode and equals
53.2225 + * operations through to the backing collection, but relies on
53.2226 + * {@code Object}'s {@code equals} and {@code hashCode} methods. This
53.2227 + * is necessary to preserve the contracts of these operations in the case
53.2228 + * that the backing collection is a set or a list.
53.2229 + *
53.2230 + * <p>The returned collection will be serializable if the specified
53.2231 + * collection is serializable.
53.2232 + *
53.2233 + * <p>Since {@code null} is considered to be a value of any reference
53.2234 + * type, the returned collection permits insertion of null elements
53.2235 + * whenever the backing collection does.
53.2236 + *
53.2237 + * @param c the collection for which a dynamically typesafe view is to be
53.2238 + * returned
53.2239 + * @param type the type of element that {@code c} is permitted to hold
53.2240 + * @return a dynamically typesafe view of the specified collection
53.2241 + * @since 1.5
53.2242 + */
53.2243 + public static <E> Collection<E> checkedCollection(Collection<E> c,
53.2244 + Class<E> type) {
53.2245 + return new CheckedCollection<>(c, type);
53.2246 + }
53.2247 +
53.2248 + @SuppressWarnings("unchecked")
53.2249 + static <T> T[] zeroLengthArray(Class<T> type) {
53.2250 + return (T[]) Array.newInstance(type, 0);
53.2251 + }
53.2252 +
53.2253 + /**
53.2254 + * @serial include
53.2255 + */
53.2256 + static class CheckedCollection<E> implements Collection<E>, Serializable {
53.2257 + private static final long serialVersionUID = 1578914078182001775L;
53.2258 +
53.2259 + final Collection<E> c;
53.2260 + final Class<E> type;
53.2261 +
53.2262 + void typeCheck(Object o) {
53.2263 + if (o != null && !type.isInstance(o))
53.2264 + throw new ClassCastException(badElementMsg(o));
53.2265 + }
53.2266 +
53.2267 + private String badElementMsg(Object o) {
53.2268 + return "Attempt to insert " + o.getClass() +
53.2269 + " element into collection with element type " + type;
53.2270 + }
53.2271 +
53.2272 + CheckedCollection(Collection<E> c, Class<E> type) {
53.2273 + if (c==null || type == null)
53.2274 + throw new NullPointerException();
53.2275 + this.c = c;
53.2276 + this.type = type;
53.2277 + }
53.2278 +
53.2279 + public int size() { return c.size(); }
53.2280 + public boolean isEmpty() { return c.isEmpty(); }
53.2281 + public boolean contains(Object o) { return c.contains(o); }
53.2282 + public Object[] toArray() { return c.toArray(); }
53.2283 + public <T> T[] toArray(T[] a) { return c.toArray(a); }
53.2284 + public String toString() { return c.toString(); }
53.2285 + public boolean remove(Object o) { return c.remove(o); }
53.2286 + public void clear() { c.clear(); }
53.2287 +
53.2288 + public boolean containsAll(Collection<?> coll) {
53.2289 + return c.containsAll(coll);
53.2290 + }
53.2291 + public boolean removeAll(Collection<?> coll) {
53.2292 + return c.removeAll(coll);
53.2293 + }
53.2294 + public boolean retainAll(Collection<?> coll) {
53.2295 + return c.retainAll(coll);
53.2296 + }
53.2297 +
53.2298 + public Iterator<E> iterator() {
53.2299 + final Iterator<E> it = c.iterator();
53.2300 + return new Iterator<E>() {
53.2301 + public boolean hasNext() { return it.hasNext(); }
53.2302 + public E next() { return it.next(); }
53.2303 + public void remove() { it.remove(); }};
53.2304 + }
53.2305 +
53.2306 + public boolean add(E e) {
53.2307 + typeCheck(e);
53.2308 + return c.add(e);
53.2309 + }
53.2310 +
53.2311 + private E[] zeroLengthElementArray = null; // Lazily initialized
53.2312 +
53.2313 + private E[] zeroLengthElementArray() {
53.2314 + return zeroLengthElementArray != null ? zeroLengthElementArray :
53.2315 + (zeroLengthElementArray = zeroLengthArray(type));
53.2316 + }
53.2317 +
53.2318 + @SuppressWarnings("unchecked")
53.2319 + Collection<E> checkedCopyOf(Collection<? extends E> coll) {
53.2320 + Object[] a = null;
53.2321 + try {
53.2322 + E[] z = zeroLengthElementArray();
53.2323 + a = coll.toArray(z);
53.2324 + // Defend against coll violating the toArray contract
53.2325 + if (a.getClass() != z.getClass())
53.2326 + a = Arrays.copyOf(a, a.length, z.getClass());
53.2327 + } catch (ArrayStoreException ignore) {
53.2328 + // To get better and consistent diagnostics,
53.2329 + // we call typeCheck explicitly on each element.
53.2330 + // We call clone() to defend against coll retaining a
53.2331 + // reference to the returned array and storing a bad
53.2332 + // element into it after it has been type checked.
53.2333 + a = coll.toArray().clone();
53.2334 + for (Object o : a)
53.2335 + typeCheck(o);
53.2336 + }
53.2337 + // A slight abuse of the type system, but safe here.
53.2338 + return (Collection<E>) Arrays.asList(a);
53.2339 + }
53.2340 +
53.2341 + public boolean addAll(Collection<? extends E> coll) {
53.2342 + // Doing things this way insulates us from concurrent changes
53.2343 + // in the contents of coll and provides all-or-nothing
53.2344 + // semantics (which we wouldn't get if we type-checked each
53.2345 + // element as we added it)
53.2346 + return c.addAll(checkedCopyOf(coll));
53.2347 + }
53.2348 + }
53.2349 +
53.2350 + /**
53.2351 + * Returns a dynamically typesafe view of the specified set.
53.2352 + * Any attempt to insert an element of the wrong type will result in
53.2353 + * an immediate {@link ClassCastException}. Assuming a set contains
53.2354 + * no incorrectly typed elements prior to the time a dynamically typesafe
53.2355 + * view is generated, and that all subsequent access to the set
53.2356 + * takes place through the view, it is <i>guaranteed</i> that the
53.2357 + * set cannot contain an incorrectly typed element.
53.2358 + *
53.2359 + * <p>A discussion of the use of dynamically typesafe views may be
53.2360 + * found in the documentation for the {@link #checkedCollection
53.2361 + * checkedCollection} method.
53.2362 + *
53.2363 + * <p>The returned set will be serializable if the specified set is
53.2364 + * serializable.
53.2365 + *
53.2366 + * <p>Since {@code null} is considered to be a value of any reference
53.2367 + * type, the returned set permits insertion of null elements whenever
53.2368 + * the backing set does.
53.2369 + *
53.2370 + * @param s the set for which a dynamically typesafe view is to be
53.2371 + * returned
53.2372 + * @param type the type of element that {@code s} is permitted to hold
53.2373 + * @return a dynamically typesafe view of the specified set
53.2374 + * @since 1.5
53.2375 + */
53.2376 + public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
53.2377 + return new CheckedSet<>(s, type);
53.2378 + }
53.2379 +
53.2380 + /**
53.2381 + * @serial include
53.2382 + */
53.2383 + static class CheckedSet<E> extends CheckedCollection<E>
53.2384 + implements Set<E>, Serializable
53.2385 + {
53.2386 + private static final long serialVersionUID = 4694047833775013803L;
53.2387 +
53.2388 + CheckedSet(Set<E> s, Class<E> elementType) { super(s, elementType); }
53.2389 +
53.2390 + public boolean equals(Object o) { return o == this || c.equals(o); }
53.2391 + public int hashCode() { return c.hashCode(); }
53.2392 + }
53.2393 +
53.2394 + /**
53.2395 + * Returns a dynamically typesafe view of the specified sorted set.
53.2396 + * Any attempt to insert an element of the wrong type will result in an
53.2397 + * immediate {@link ClassCastException}. Assuming a sorted set
53.2398 + * contains no incorrectly typed elements prior to the time a
53.2399 + * dynamically typesafe view is generated, and that all subsequent
53.2400 + * access to the sorted set takes place through the view, it is
53.2401 + * <i>guaranteed</i> that the sorted set cannot contain an incorrectly
53.2402 + * typed element.
53.2403 + *
53.2404 + * <p>A discussion of the use of dynamically typesafe views may be
53.2405 + * found in the documentation for the {@link #checkedCollection
53.2406 + * checkedCollection} method.
53.2407 + *
53.2408 + * <p>The returned sorted set will be serializable if the specified sorted
53.2409 + * set is serializable.
53.2410 + *
53.2411 + * <p>Since {@code null} is considered to be a value of any reference
53.2412 + * type, the returned sorted set permits insertion of null elements
53.2413 + * whenever the backing sorted set does.
53.2414 + *
53.2415 + * @param s the sorted set for which a dynamically typesafe view is to be
53.2416 + * returned
53.2417 + * @param type the type of element that {@code s} is permitted to hold
53.2418 + * @return a dynamically typesafe view of the specified sorted set
53.2419 + * @since 1.5
53.2420 + */
53.2421 + public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
53.2422 + Class<E> type) {
53.2423 + return new CheckedSortedSet<>(s, type);
53.2424 + }
53.2425 +
53.2426 + /**
53.2427 + * @serial include
53.2428 + */
53.2429 + static class CheckedSortedSet<E> extends CheckedSet<E>
53.2430 + implements SortedSet<E>, Serializable
53.2431 + {
53.2432 + private static final long serialVersionUID = 1599911165492914959L;
53.2433 + private final SortedSet<E> ss;
53.2434 +
53.2435 + CheckedSortedSet(SortedSet<E> s, Class<E> type) {
53.2436 + super(s, type);
53.2437 + ss = s;
53.2438 + }
53.2439 +
53.2440 + public Comparator<? super E> comparator() { return ss.comparator(); }
53.2441 + public E first() { return ss.first(); }
53.2442 + public E last() { return ss.last(); }
53.2443 +
53.2444 + public SortedSet<E> subSet(E fromElement, E toElement) {
53.2445 + return checkedSortedSet(ss.subSet(fromElement,toElement), type);
53.2446 + }
53.2447 + public SortedSet<E> headSet(E toElement) {
53.2448 + return checkedSortedSet(ss.headSet(toElement), type);
53.2449 + }
53.2450 + public SortedSet<E> tailSet(E fromElement) {
53.2451 + return checkedSortedSet(ss.tailSet(fromElement), type);
53.2452 + }
53.2453 + }
53.2454 +
53.2455 + /**
53.2456 + * Returns a dynamically typesafe view of the specified list.
53.2457 + * Any attempt to insert an element of the wrong type will result in
53.2458 + * an immediate {@link ClassCastException}. Assuming a list contains
53.2459 + * no incorrectly typed elements prior to the time a dynamically typesafe
53.2460 + * view is generated, and that all subsequent access to the list
53.2461 + * takes place through the view, it is <i>guaranteed</i> that the
53.2462 + * list cannot contain an incorrectly typed element.
53.2463 + *
53.2464 + * <p>A discussion of the use of dynamically typesafe views may be
53.2465 + * found in the documentation for the {@link #checkedCollection
53.2466 + * checkedCollection} method.
53.2467 + *
53.2468 + * <p>The returned list will be serializable if the specified list
53.2469 + * is serializable.
53.2470 + *
53.2471 + * <p>Since {@code null} is considered to be a value of any reference
53.2472 + * type, the returned list permits insertion of null elements whenever
53.2473 + * the backing list does.
53.2474 + *
53.2475 + * @param list the list for which a dynamically typesafe view is to be
53.2476 + * returned
53.2477 + * @param type the type of element that {@code list} is permitted to hold
53.2478 + * @return a dynamically typesafe view of the specified list
53.2479 + * @since 1.5
53.2480 + */
53.2481 + public static <E> List<E> checkedList(List<E> list, Class<E> type) {
53.2482 + return (list instanceof RandomAccess ?
53.2483 + new CheckedRandomAccessList<>(list, type) :
53.2484 + new CheckedList<>(list, type));
53.2485 + }
53.2486 +
53.2487 + /**
53.2488 + * @serial include
53.2489 + */
53.2490 + static class CheckedList<E>
53.2491 + extends CheckedCollection<E>
53.2492 + implements List<E>
53.2493 + {
53.2494 + private static final long serialVersionUID = 65247728283967356L;
53.2495 + final List<E> list;
53.2496 +
53.2497 + CheckedList(List<E> list, Class<E> type) {
53.2498 + super(list, type);
53.2499 + this.list = list;
53.2500 + }
53.2501 +
53.2502 + public boolean equals(Object o) { return o == this || list.equals(o); }
53.2503 + public int hashCode() { return list.hashCode(); }
53.2504 + public E get(int index) { return list.get(index); }
53.2505 + public E remove(int index) { return list.remove(index); }
53.2506 + public int indexOf(Object o) { return list.indexOf(o); }
53.2507 + public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
53.2508 +
53.2509 + public E set(int index, E element) {
53.2510 + typeCheck(element);
53.2511 + return list.set(index, element);
53.2512 + }
53.2513 +
53.2514 + public void add(int index, E element) {
53.2515 + typeCheck(element);
53.2516 + list.add(index, element);
53.2517 + }
53.2518 +
53.2519 + public boolean addAll(int index, Collection<? extends E> c) {
53.2520 + return list.addAll(index, checkedCopyOf(c));
53.2521 + }
53.2522 + public ListIterator<E> listIterator() { return listIterator(0); }
53.2523 +
53.2524 + public ListIterator<E> listIterator(final int index) {
53.2525 + final ListIterator<E> i = list.listIterator(index);
53.2526 +
53.2527 + return new ListIterator<E>() {
53.2528 + public boolean hasNext() { return i.hasNext(); }
53.2529 + public E next() { return i.next(); }
53.2530 + public boolean hasPrevious() { return i.hasPrevious(); }
53.2531 + public E previous() { return i.previous(); }
53.2532 + public int nextIndex() { return i.nextIndex(); }
53.2533 + public int previousIndex() { return i.previousIndex(); }
53.2534 + public void remove() { i.remove(); }
53.2535 +
53.2536 + public void set(E e) {
53.2537 + typeCheck(e);
53.2538 + i.set(e);
53.2539 + }
53.2540 +
53.2541 + public void add(E e) {
53.2542 + typeCheck(e);
53.2543 + i.add(e);
53.2544 + }
53.2545 + };
53.2546 + }
53.2547 +
53.2548 + public List<E> subList(int fromIndex, int toIndex) {
53.2549 + return new CheckedList<>(list.subList(fromIndex, toIndex), type);
53.2550 + }
53.2551 + }
53.2552 +
53.2553 + /**
53.2554 + * @serial include
53.2555 + */
53.2556 + static class CheckedRandomAccessList<E> extends CheckedList<E>
53.2557 + implements RandomAccess
53.2558 + {
53.2559 + private static final long serialVersionUID = 1638200125423088369L;
53.2560 +
53.2561 + CheckedRandomAccessList(List<E> list, Class<E> type) {
53.2562 + super(list, type);
53.2563 + }
53.2564 +
53.2565 + public List<E> subList(int fromIndex, int toIndex) {
53.2566 + return new CheckedRandomAccessList<>(
53.2567 + list.subList(fromIndex, toIndex), type);
53.2568 + }
53.2569 + }
53.2570 +
53.2571 + /**
53.2572 + * Returns a dynamically typesafe view of the specified map.
53.2573 + * Any attempt to insert a mapping whose key or value have the wrong
53.2574 + * type will result in an immediate {@link ClassCastException}.
53.2575 + * Similarly, any attempt to modify the value currently associated with
53.2576 + * a key will result in an immediate {@link ClassCastException},
53.2577 + * whether the modification is attempted directly through the map
53.2578 + * itself, or through a {@link Map.Entry} instance obtained from the
53.2579 + * map's {@link Map#entrySet() entry set} view.
53.2580 + *
53.2581 + * <p>Assuming a map contains no incorrectly typed keys or values
53.2582 + * prior to the time a dynamically typesafe view is generated, and
53.2583 + * that all subsequent access to the map takes place through the view
53.2584 + * (or one of its collection views), it is <i>guaranteed</i> that the
53.2585 + * map cannot contain an incorrectly typed key or value.
53.2586 + *
53.2587 + * <p>A discussion of the use of dynamically typesafe views may be
53.2588 + * found in the documentation for the {@link #checkedCollection
53.2589 + * checkedCollection} method.
53.2590 + *
53.2591 + * <p>The returned map will be serializable if the specified map is
53.2592 + * serializable.
53.2593 + *
53.2594 + * <p>Since {@code null} is considered to be a value of any reference
53.2595 + * type, the returned map permits insertion of null keys or values
53.2596 + * whenever the backing map does.
53.2597 + *
53.2598 + * @param m the map for which a dynamically typesafe view is to be
53.2599 + * returned
53.2600 + * @param keyType the type of key that {@code m} is permitted to hold
53.2601 + * @param valueType the type of value that {@code m} is permitted to hold
53.2602 + * @return a dynamically typesafe view of the specified map
53.2603 + * @since 1.5
53.2604 + */
53.2605 + public static <K, V> Map<K, V> checkedMap(Map<K, V> m,
53.2606 + Class<K> keyType,
53.2607 + Class<V> valueType) {
53.2608 + return new CheckedMap<>(m, keyType, valueType);
53.2609 + }
53.2610 +
53.2611 +
53.2612 + /**
53.2613 + * @serial include
53.2614 + */
53.2615 + private static class CheckedMap<K,V>
53.2616 + implements Map<K,V>, Serializable
53.2617 + {
53.2618 + private static final long serialVersionUID = 5742860141034234728L;
53.2619 +
53.2620 + private final Map<K, V> m;
53.2621 + final Class<K> keyType;
53.2622 + final Class<V> valueType;
53.2623 +
53.2624 + private void typeCheck(Object key, Object value) {
53.2625 + if (key != null && !keyType.isInstance(key))
53.2626 + throw new ClassCastException(badKeyMsg(key));
53.2627 +
53.2628 + if (value != null && !valueType.isInstance(value))
53.2629 + throw new ClassCastException(badValueMsg(value));
53.2630 + }
53.2631 +
53.2632 + private String badKeyMsg(Object key) {
53.2633 + return "Attempt to insert " + key.getClass() +
53.2634 + " key into map with key type " + keyType;
53.2635 + }
53.2636 +
53.2637 + private String badValueMsg(Object value) {
53.2638 + return "Attempt to insert " + value.getClass() +
53.2639 + " value into map with value type " + valueType;
53.2640 + }
53.2641 +
53.2642 + CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
53.2643 + if (m == null || keyType == null || valueType == null)
53.2644 + throw new NullPointerException();
53.2645 + this.m = m;
53.2646 + this.keyType = keyType;
53.2647 + this.valueType = valueType;
53.2648 + }
53.2649 +
53.2650 + public int size() { return m.size(); }
53.2651 + public boolean isEmpty() { return m.isEmpty(); }
53.2652 + public boolean containsKey(Object key) { return m.containsKey(key); }
53.2653 + public boolean containsValue(Object v) { return m.containsValue(v); }
53.2654 + public V get(Object key) { return m.get(key); }
53.2655 + public V remove(Object key) { return m.remove(key); }
53.2656 + public void clear() { m.clear(); }
53.2657 + public Set<K> keySet() { return m.keySet(); }
53.2658 + public Collection<V> values() { return m.values(); }
53.2659 + public boolean equals(Object o) { return o == this || m.equals(o); }
53.2660 + public int hashCode() { return m.hashCode(); }
53.2661 + public String toString() { return m.toString(); }
53.2662 +
53.2663 + public V put(K key, V value) {
53.2664 + typeCheck(key, value);
53.2665 + return m.put(key, value);
53.2666 + }
53.2667 +
53.2668 + @SuppressWarnings("unchecked")
53.2669 + public void putAll(Map<? extends K, ? extends V> t) {
53.2670 + // Satisfy the following goals:
53.2671 + // - good diagnostics in case of type mismatch
53.2672 + // - all-or-nothing semantics
53.2673 + // - protection from malicious t
53.2674 + // - correct behavior if t is a concurrent map
53.2675 + Object[] entries = t.entrySet().toArray();
53.2676 + List<Map.Entry<K,V>> checked = new ArrayList<>(entries.length);
53.2677 + for (Object o : entries) {
53.2678 + Map.Entry<?,?> e = (Map.Entry<?,?>) o;
53.2679 + Object k = e.getKey();
53.2680 + Object v = e.getValue();
53.2681 + typeCheck(k, v);
53.2682 + checked.add(
53.2683 + new AbstractMap.SimpleImmutableEntry<>((K) k, (V) v));
53.2684 + }
53.2685 + for (Map.Entry<K,V> e : checked)
53.2686 + m.put(e.getKey(), e.getValue());
53.2687 + }
53.2688 +
53.2689 + private transient Set<Map.Entry<K,V>> entrySet = null;
53.2690 +
53.2691 + public Set<Map.Entry<K,V>> entrySet() {
53.2692 + if (entrySet==null)
53.2693 + entrySet = new CheckedEntrySet<>(m.entrySet(), valueType);
53.2694 + return entrySet;
53.2695 + }
53.2696 +
53.2697 + /**
53.2698 + * We need this class in addition to CheckedSet as Map.Entry permits
53.2699 + * modification of the backing Map via the setValue operation. This
53.2700 + * class is subtle: there are many possible attacks that must be
53.2701 + * thwarted.
53.2702 + *
53.2703 + * @serial exclude
53.2704 + */
53.2705 + static class CheckedEntrySet<K,V> implements Set<Map.Entry<K,V>> {
53.2706 + private final Set<Map.Entry<K,V>> s;
53.2707 + private final Class<V> valueType;
53.2708 +
53.2709 + CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {
53.2710 + this.s = s;
53.2711 + this.valueType = valueType;
53.2712 + }
53.2713 +
53.2714 + public int size() { return s.size(); }
53.2715 + public boolean isEmpty() { return s.isEmpty(); }
53.2716 + public String toString() { return s.toString(); }
53.2717 + public int hashCode() { return s.hashCode(); }
53.2718 + public void clear() { s.clear(); }
53.2719 +
53.2720 + public boolean add(Map.Entry<K, V> e) {
53.2721 + throw new UnsupportedOperationException();
53.2722 + }
53.2723 + public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {
53.2724 + throw new UnsupportedOperationException();
53.2725 + }
53.2726 +
53.2727 + public Iterator<Map.Entry<K,V>> iterator() {
53.2728 + final Iterator<Map.Entry<K, V>> i = s.iterator();
53.2729 + final Class<V> valueType = this.valueType;
53.2730 +
53.2731 + return new Iterator<Map.Entry<K,V>>() {
53.2732 + public boolean hasNext() { return i.hasNext(); }
53.2733 + public void remove() { i.remove(); }
53.2734 +
53.2735 + public Map.Entry<K,V> next() {
53.2736 + return checkedEntry(i.next(), valueType);
53.2737 + }
53.2738 + };
53.2739 + }
53.2740 +
53.2741 + @SuppressWarnings("unchecked")
53.2742 + public Object[] toArray() {
53.2743 + Object[] source = s.toArray();
53.2744 +
53.2745 + /*
53.2746 + * Ensure that we don't get an ArrayStoreException even if
53.2747 + * s.toArray returns an array of something other than Object
53.2748 + */
53.2749 + Object[] dest = (CheckedEntry.class.isInstance(
53.2750 + source.getClass().getComponentType()) ? source :
53.2751 + new Object[source.length]);
53.2752 +
53.2753 + for (int i = 0; i < source.length; i++)
53.2754 + dest[i] = checkedEntry((Map.Entry<K,V>)source[i],
53.2755 + valueType);
53.2756 + return dest;
53.2757 + }
53.2758 +
53.2759 + @SuppressWarnings("unchecked")
53.2760 + public <T> T[] toArray(T[] a) {
53.2761 + // We don't pass a to s.toArray, to avoid window of
53.2762 + // vulnerability wherein an unscrupulous multithreaded client
53.2763 + // could get his hands on raw (unwrapped) Entries from s.
53.2764 + T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
53.2765 +
53.2766 + for (int i=0; i<arr.length; i++)
53.2767 + arr[i] = (T) checkedEntry((Map.Entry<K,V>)arr[i],
53.2768 + valueType);
53.2769 + if (arr.length > a.length)
53.2770 + return arr;
53.2771 +
53.2772 + System.arraycopy(arr, 0, a, 0, arr.length);
53.2773 + if (a.length > arr.length)
53.2774 + a[arr.length] = null;
53.2775 + return a;
53.2776 + }
53.2777 +
53.2778 + /**
53.2779 + * This method is overridden to protect the backing set against
53.2780 + * an object with a nefarious equals function that senses
53.2781 + * that the equality-candidate is Map.Entry and calls its
53.2782 + * setValue method.
53.2783 + */
53.2784 + public boolean contains(Object o) {
53.2785 + if (!(o instanceof Map.Entry))
53.2786 + return false;
53.2787 + Map.Entry<?,?> e = (Map.Entry<?,?>) o;
53.2788 + return s.contains(
53.2789 + (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType));
53.2790 + }
53.2791 +
53.2792 + /**
53.2793 + * The bulk collection methods are overridden to protect
53.2794 + * against an unscrupulous collection whose contains(Object o)
53.2795 + * method senses when o is a Map.Entry, and calls o.setValue.
53.2796 + */
53.2797 + public boolean containsAll(Collection<?> c) {
53.2798 + for (Object o : c)
53.2799 + if (!contains(o)) // Invokes safe contains() above
53.2800 + return false;
53.2801 + return true;
53.2802 + }
53.2803 +
53.2804 + public boolean remove(Object o) {
53.2805 + if (!(o instanceof Map.Entry))
53.2806 + return false;
53.2807 + return s.remove(new AbstractMap.SimpleImmutableEntry
53.2808 + <>((Map.Entry<?,?>)o));
53.2809 + }
53.2810 +
53.2811 + public boolean removeAll(Collection<?> c) {
53.2812 + return batchRemove(c, false);
53.2813 + }
53.2814 + public boolean retainAll(Collection<?> c) {
53.2815 + return batchRemove(c, true);
53.2816 + }
53.2817 + private boolean batchRemove(Collection<?> c, boolean complement) {
53.2818 + boolean modified = false;
53.2819 + Iterator<Map.Entry<K,V>> it = iterator();
53.2820 + while (it.hasNext()) {
53.2821 + if (c.contains(it.next()) != complement) {
53.2822 + it.remove();
53.2823 + modified = true;
53.2824 + }
53.2825 + }
53.2826 + return modified;
53.2827 + }
53.2828 +
53.2829 + public boolean equals(Object o) {
53.2830 + if (o == this)
53.2831 + return true;
53.2832 + if (!(o instanceof Set))
53.2833 + return false;
53.2834 + Set<?> that = (Set<?>) o;
53.2835 + return that.size() == s.size()
53.2836 + && containsAll(that); // Invokes safe containsAll() above
53.2837 + }
53.2838 +
53.2839 + static <K,V,T> CheckedEntry<K,V,T> checkedEntry(Map.Entry<K,V> e,
53.2840 + Class<T> valueType) {
53.2841 + return new CheckedEntry<>(e, valueType);
53.2842 + }
53.2843 +
53.2844 + /**
53.2845 + * This "wrapper class" serves two purposes: it prevents
53.2846 + * the client from modifying the backing Map, by short-circuiting
53.2847 + * the setValue method, and it protects the backing Map against
53.2848 + * an ill-behaved Map.Entry that attempts to modify another
53.2849 + * Map.Entry when asked to perform an equality check.
53.2850 + */
53.2851 + private static class CheckedEntry<K,V,T> implements Map.Entry<K,V> {
53.2852 + private final Map.Entry<K, V> e;
53.2853 + private final Class<T> valueType;
53.2854 +
53.2855 + CheckedEntry(Map.Entry<K, V> e, Class<T> valueType) {
53.2856 + this.e = e;
53.2857 + this.valueType = valueType;
53.2858 + }
53.2859 +
53.2860 + public K getKey() { return e.getKey(); }
53.2861 + public V getValue() { return e.getValue(); }
53.2862 + public int hashCode() { return e.hashCode(); }
53.2863 + public String toString() { return e.toString(); }
53.2864 +
53.2865 + public V setValue(V value) {
53.2866 + if (value != null && !valueType.isInstance(value))
53.2867 + throw new ClassCastException(badValueMsg(value));
53.2868 + return e.setValue(value);
53.2869 + }
53.2870 +
53.2871 + private String badValueMsg(Object value) {
53.2872 + return "Attempt to insert " + value.getClass() +
53.2873 + " value into map with value type " + valueType;
53.2874 + }
53.2875 +
53.2876 + public boolean equals(Object o) {
53.2877 + if (o == this)
53.2878 + return true;
53.2879 + if (!(o instanceof Map.Entry))
53.2880 + return false;
53.2881 + return e.equals(new AbstractMap.SimpleImmutableEntry
53.2882 + <>((Map.Entry<?,?>)o));
53.2883 + }
53.2884 + }
53.2885 + }
53.2886 + }
53.2887 +
53.2888 + /**
53.2889 + * Returns a dynamically typesafe view of the specified sorted map.
53.2890 + * Any attempt to insert a mapping whose key or value have the wrong
53.2891 + * type will result in an immediate {@link ClassCastException}.
53.2892 + * Similarly, any attempt to modify the value currently associated with
53.2893 + * a key will result in an immediate {@link ClassCastException},
53.2894 + * whether the modification is attempted directly through the map
53.2895 + * itself, or through a {@link Map.Entry} instance obtained from the
53.2896 + * map's {@link Map#entrySet() entry set} view.
53.2897 + *
53.2898 + * <p>Assuming a map contains no incorrectly typed keys or values
53.2899 + * prior to the time a dynamically typesafe view is generated, and
53.2900 + * that all subsequent access to the map takes place through the view
53.2901 + * (or one of its collection views), it is <i>guaranteed</i> that the
53.2902 + * map cannot contain an incorrectly typed key or value.
53.2903 + *
53.2904 + * <p>A discussion of the use of dynamically typesafe views may be
53.2905 + * found in the documentation for the {@link #checkedCollection
53.2906 + * checkedCollection} method.
53.2907 + *
53.2908 + * <p>The returned map will be serializable if the specified map is
53.2909 + * serializable.
53.2910 + *
53.2911 + * <p>Since {@code null} is considered to be a value of any reference
53.2912 + * type, the returned map permits insertion of null keys or values
53.2913 + * whenever the backing map does.
53.2914 + *
53.2915 + * @param m the map for which a dynamically typesafe view is to be
53.2916 + * returned
53.2917 + * @param keyType the type of key that {@code m} is permitted to hold
53.2918 + * @param valueType the type of value that {@code m} is permitted to hold
53.2919 + * @return a dynamically typesafe view of the specified map
53.2920 + * @since 1.5
53.2921 + */
53.2922 + public static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K, V> m,
53.2923 + Class<K> keyType,
53.2924 + Class<V> valueType) {
53.2925 + return new CheckedSortedMap<>(m, keyType, valueType);
53.2926 + }
53.2927 +
53.2928 + /**
53.2929 + * @serial include
53.2930 + */
53.2931 + static class CheckedSortedMap<K,V> extends CheckedMap<K,V>
53.2932 + implements SortedMap<K,V>, Serializable
53.2933 + {
53.2934 + private static final long serialVersionUID = 1599671320688067438L;
53.2935 +
53.2936 + private final SortedMap<K, V> sm;
53.2937 +
53.2938 + CheckedSortedMap(SortedMap<K, V> m,
53.2939 + Class<K> keyType, Class<V> valueType) {
53.2940 + super(m, keyType, valueType);
53.2941 + sm = m;
53.2942 + }
53.2943 +
53.2944 + public Comparator<? super K> comparator() { return sm.comparator(); }
53.2945 + public K firstKey() { return sm.firstKey(); }
53.2946 + public K lastKey() { return sm.lastKey(); }
53.2947 +
53.2948 + public SortedMap<K,V> subMap(K fromKey, K toKey) {
53.2949 + return checkedSortedMap(sm.subMap(fromKey, toKey),
53.2950 + keyType, valueType);
53.2951 + }
53.2952 + public SortedMap<K,V> headMap(K toKey) {
53.2953 + return checkedSortedMap(sm.headMap(toKey), keyType, valueType);
53.2954 + }
53.2955 + public SortedMap<K,V> tailMap(K fromKey) {
53.2956 + return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType);
53.2957 + }
53.2958 + }
53.2959 +
53.2960 + // Empty collections
53.2961 +
53.2962 + /**
53.2963 + * Returns an iterator that has no elements. More precisely,
53.2964 + *
53.2965 + * <ul compact>
53.2966 + *
53.2967 + * <li>{@link Iterator#hasNext hasNext} always returns {@code
53.2968 + * false}.
53.2969 + *
53.2970 + * <li>{@link Iterator#next next} always throws {@link
53.2971 + * NoSuchElementException}.
53.2972 + *
53.2973 + * <li>{@link Iterator#remove remove} always throws {@link
53.2974 + * IllegalStateException}.
53.2975 + *
53.2976 + * </ul>
53.2977 + *
53.2978 + * <p>Implementations of this method are permitted, but not
53.2979 + * required, to return the same object from multiple invocations.
53.2980 + *
53.2981 + * @return an empty iterator
53.2982 + * @since 1.7
53.2983 + */
53.2984 + @SuppressWarnings("unchecked")
53.2985 + public static <T> Iterator<T> emptyIterator() {
53.2986 + return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR;
53.2987 + }
53.2988 +
53.2989 + private static class EmptyIterator<E> implements Iterator<E> {
53.2990 + static final EmptyIterator<Object> EMPTY_ITERATOR
53.2991 + = new EmptyIterator<>();
53.2992 +
53.2993 + public boolean hasNext() { return false; }
53.2994 + public E next() { throw new NoSuchElementException(); }
53.2995 + public void remove() { throw new IllegalStateException(); }
53.2996 + }
53.2997 +
53.2998 + /**
53.2999 + * Returns a list iterator that has no elements. More precisely,
53.3000 + *
53.3001 + * <ul compact>
53.3002 + *
53.3003 + * <li>{@link Iterator#hasNext hasNext} and {@link
53.3004 + * ListIterator#hasPrevious hasPrevious} always return {@code
53.3005 + * false}.
53.3006 + *
53.3007 + * <li>{@link Iterator#next next} and {@link ListIterator#previous
53.3008 + * previous} always throw {@link NoSuchElementException}.
53.3009 + *
53.3010 + * <li>{@link Iterator#remove remove} and {@link ListIterator#set
53.3011 + * set} always throw {@link IllegalStateException}.
53.3012 + *
53.3013 + * <li>{@link ListIterator#add add} always throws {@link
53.3014 + * UnsupportedOperationException}.
53.3015 + *
53.3016 + * <li>{@link ListIterator#nextIndex nextIndex} always returns
53.3017 + * {@code 0} .
53.3018 + *
53.3019 + * <li>{@link ListIterator#previousIndex previousIndex} always
53.3020 + * returns {@code -1}.
53.3021 + *
53.3022 + * </ul>
53.3023 + *
53.3024 + * <p>Implementations of this method are permitted, but not
53.3025 + * required, to return the same object from multiple invocations.
53.3026 + *
53.3027 + * @return an empty list iterator
53.3028 + * @since 1.7
53.3029 + */
53.3030 + @SuppressWarnings("unchecked")
53.3031 + public static <T> ListIterator<T> emptyListIterator() {
53.3032 + return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR;
53.3033 + }
53.3034 +
53.3035 + private static class EmptyListIterator<E>
53.3036 + extends EmptyIterator<E>
53.3037 + implements ListIterator<E>
53.3038 + {
53.3039 + static final EmptyListIterator<Object> EMPTY_ITERATOR
53.3040 + = new EmptyListIterator<>();
53.3041 +
53.3042 + public boolean hasPrevious() { return false; }
53.3043 + public E previous() { throw new NoSuchElementException(); }
53.3044 + public int nextIndex() { return 0; }
53.3045 + public int previousIndex() { return -1; }
53.3046 + public void set(E e) { throw new IllegalStateException(); }
53.3047 + public void add(E e) { throw new UnsupportedOperationException(); }
53.3048 + }
53.3049 +
53.3050 + /**
53.3051 + * Returns an enumeration that has no elements. More precisely,
53.3052 + *
53.3053 + * <ul compact>
53.3054 + *
53.3055 + * <li>{@link Enumeration#hasMoreElements hasMoreElements} always
53.3056 + * returns {@code false}.
53.3057 + *
53.3058 + * <li> {@link Enumeration#nextElement nextElement} always throws
53.3059 + * {@link NoSuchElementException}.
53.3060 + *
53.3061 + * </ul>
53.3062 + *
53.3063 + * <p>Implementations of this method are permitted, but not
53.3064 + * required, to return the same object from multiple invocations.
53.3065 + *
53.3066 + * @return an empty enumeration
53.3067 + * @since 1.7
53.3068 + */
53.3069 + @SuppressWarnings("unchecked")
53.3070 + public static <T> Enumeration<T> emptyEnumeration() {
53.3071 + return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION;
53.3072 + }
53.3073 +
53.3074 + private static class EmptyEnumeration<E> implements Enumeration<E> {
53.3075 + static final EmptyEnumeration<Object> EMPTY_ENUMERATION
53.3076 + = new EmptyEnumeration<>();
53.3077 +
53.3078 + public boolean hasMoreElements() { return false; }
53.3079 + public E nextElement() { throw new NoSuchElementException(); }
53.3080 + }
53.3081 +
53.3082 + /**
53.3083 + * The empty set (immutable). This set is serializable.
53.3084 + *
53.3085 + * @see #emptySet()
53.3086 + */
53.3087 + @SuppressWarnings("unchecked")
53.3088 + public static final Set EMPTY_SET = new EmptySet<>();
53.3089 +
53.3090 + /**
53.3091 + * Returns the empty set (immutable). This set is serializable.
53.3092 + * Unlike the like-named field, this method is parameterized.
53.3093 + *
53.3094 + * <p>This example illustrates the type-safe way to obtain an empty set:
53.3095 + * <pre>
53.3096 + * Set<String> s = Collections.emptySet();
53.3097 + * </pre>
53.3098 + * Implementation note: Implementations of this method need not
53.3099 + * create a separate <tt>Set</tt> object for each call. Using this
53.3100 + * method is likely to have comparable cost to using the like-named
53.3101 + * field. (Unlike this method, the field does not provide type safety.)
53.3102 + *
53.3103 + * @see #EMPTY_SET
53.3104 + * @since 1.5
53.3105 + */
53.3106 + @SuppressWarnings("unchecked")
53.3107 + public static final <T> Set<T> emptySet() {
53.3108 + return (Set<T>) EMPTY_SET;
53.3109 + }
53.3110 +
53.3111 + /**
53.3112 + * @serial include
53.3113 + */
53.3114 + private static class EmptySet<E>
53.3115 + extends AbstractSet<E>
53.3116 + implements Serializable
53.3117 + {
53.3118 + private static final long serialVersionUID = 1582296315990362920L;
53.3119 +
53.3120 + public Iterator<E> iterator() { return emptyIterator(); }
53.3121 +
53.3122 + public int size() {return 0;}
53.3123 + public boolean isEmpty() {return true;}
53.3124 +
53.3125 + public boolean contains(Object obj) {return false;}
53.3126 + public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
53.3127 +
53.3128 + public Object[] toArray() { return new Object[0]; }
53.3129 +
53.3130 + public <T> T[] toArray(T[] a) {
53.3131 + if (a.length > 0)
53.3132 + a[0] = null;
53.3133 + return a;
53.3134 + }
53.3135 +
53.3136 + // Preserves singleton property
53.3137 + private Object readResolve() {
53.3138 + return EMPTY_SET;
53.3139 + }
53.3140 + }
53.3141 +
53.3142 + /**
53.3143 + * The empty list (immutable). This list is serializable.
53.3144 + *
53.3145 + * @see #emptyList()
53.3146 + */
53.3147 + @SuppressWarnings("unchecked")
53.3148 + public static final List EMPTY_LIST = new EmptyList<>();
53.3149 +
53.3150 + /**
53.3151 + * Returns the empty list (immutable). This list is serializable.
53.3152 + *
53.3153 + * <p>This example illustrates the type-safe way to obtain an empty list:
53.3154 + * <pre>
53.3155 + * List<String> s = Collections.emptyList();
53.3156 + * </pre>
53.3157 + * Implementation note: Implementations of this method need not
53.3158 + * create a separate <tt>List</tt> object for each call. Using this
53.3159 + * method is likely to have comparable cost to using the like-named
53.3160 + * field. (Unlike this method, the field does not provide type safety.)
53.3161 + *
53.3162 + * @see #EMPTY_LIST
53.3163 + * @since 1.5
53.3164 + */
53.3165 + @SuppressWarnings("unchecked")
53.3166 + public static final <T> List<T> emptyList() {
53.3167 + return (List<T>) EMPTY_LIST;
53.3168 + }
53.3169 +
53.3170 + /**
53.3171 + * @serial include
53.3172 + */
53.3173 + private static class EmptyList<E>
53.3174 + extends AbstractList<E>
53.3175 + implements RandomAccess, Serializable {
53.3176 + private static final long serialVersionUID = 8842843931221139166L;
53.3177 +
53.3178 + public Iterator<E> iterator() {
53.3179 + return emptyIterator();
53.3180 + }
53.3181 + public ListIterator<E> listIterator() {
53.3182 + return emptyListIterator();
53.3183 + }
53.3184 +
53.3185 + public int size() {return 0;}
53.3186 + public boolean isEmpty() {return true;}
53.3187 +
53.3188 + public boolean contains(Object obj) {return false;}
53.3189 + public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
53.3190 +
53.3191 + public Object[] toArray() { return new Object[0]; }
53.3192 +
53.3193 + public <T> T[] toArray(T[] a) {
53.3194 + if (a.length > 0)
53.3195 + a[0] = null;
53.3196 + return a;
53.3197 + }
53.3198 +
53.3199 + public E get(int index) {
53.3200 + throw new IndexOutOfBoundsException("Index: "+index);
53.3201 + }
53.3202 +
53.3203 + public boolean equals(Object o) {
53.3204 + return (o instanceof List) && ((List<?>)o).isEmpty();
53.3205 + }
53.3206 +
53.3207 + public int hashCode() { return 1; }
53.3208 +
53.3209 + // Preserves singleton property
53.3210 + private Object readResolve() {
53.3211 + return EMPTY_LIST;
53.3212 + }
53.3213 + }
53.3214 +
53.3215 + /**
53.3216 + * The empty map (immutable). This map is serializable.
53.3217 + *
53.3218 + * @see #emptyMap()
53.3219 + * @since 1.3
53.3220 + */
53.3221 + @SuppressWarnings("unchecked")
53.3222 + public static final Map EMPTY_MAP = new EmptyMap<>();
53.3223 +
53.3224 + /**
53.3225 + * Returns the empty map (immutable). This map is serializable.
53.3226 + *
53.3227 + * <p>This example illustrates the type-safe way to obtain an empty set:
53.3228 + * <pre>
53.3229 + * Map<String, Date> s = Collections.emptyMap();
53.3230 + * </pre>
53.3231 + * Implementation note: Implementations of this method need not
53.3232 + * create a separate <tt>Map</tt> object for each call. Using this
53.3233 + * method is likely to have comparable cost to using the like-named
53.3234 + * field. (Unlike this method, the field does not provide type safety.)
53.3235 + *
53.3236 + * @see #EMPTY_MAP
53.3237 + * @since 1.5
53.3238 + */
53.3239 + @SuppressWarnings("unchecked")
53.3240 + public static final <K,V> Map<K,V> emptyMap() {
53.3241 + return (Map<K,V>) EMPTY_MAP;
53.3242 + }
53.3243 +
53.3244 + /**
53.3245 + * @serial include
53.3246 + */
53.3247 + private static class EmptyMap<K,V>
53.3248 + extends AbstractMap<K,V>
53.3249 + implements Serializable
53.3250 + {
53.3251 + private static final long serialVersionUID = 6428348081105594320L;
53.3252 +
53.3253 + public int size() {return 0;}
53.3254 + public boolean isEmpty() {return true;}
53.3255 + public boolean containsKey(Object key) {return false;}
53.3256 + public boolean containsValue(Object value) {return false;}
53.3257 + public V get(Object key) {return null;}
53.3258 + public Set<K> keySet() {return emptySet();}
53.3259 + public Collection<V> values() {return emptySet();}
53.3260 + public Set<Map.Entry<K,V>> entrySet() {return emptySet();}
53.3261 +
53.3262 + public boolean equals(Object o) {
53.3263 + return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
53.3264 + }
53.3265 +
53.3266 + public int hashCode() {return 0;}
53.3267 +
53.3268 + // Preserves singleton property
53.3269 + private Object readResolve() {
53.3270 + return EMPTY_MAP;
53.3271 + }
53.3272 + }
53.3273 +
53.3274 + // Singleton collections
53.3275 +
53.3276 + /**
53.3277 + * Returns an immutable set containing only the specified object.
53.3278 + * The returned set is serializable.
53.3279 + *
53.3280 + * @param o the sole object to be stored in the returned set.
53.3281 + * @return an immutable set containing only the specified object.
53.3282 + */
53.3283 + public static <T> Set<T> singleton(T o) {
53.3284 + return new SingletonSet<>(o);
53.3285 + }
53.3286 +
53.3287 + static <E> Iterator<E> singletonIterator(final E e) {
53.3288 + return new Iterator<E>() {
53.3289 + private boolean hasNext = true;
53.3290 + public boolean hasNext() {
53.3291 + return hasNext;
53.3292 + }
53.3293 + public E next() {
53.3294 + if (hasNext) {
53.3295 + hasNext = false;
53.3296 + return e;
53.3297 + }
53.3298 + throw new NoSuchElementException();
53.3299 + }
53.3300 + public void remove() {
53.3301 + throw new UnsupportedOperationException();
53.3302 + }
53.3303 + };
53.3304 + }
53.3305 +
53.3306 + /**
53.3307 + * @serial include
53.3308 + */
53.3309 + private static class SingletonSet<E>
53.3310 + extends AbstractSet<E>
53.3311 + implements Serializable
53.3312 + {
53.3313 + private static final long serialVersionUID = 3193687207550431679L;
53.3314 +
53.3315 + private final E element;
53.3316 +
53.3317 + SingletonSet(E e) {element = e;}
53.3318 +
53.3319 + public Iterator<E> iterator() {
53.3320 + return singletonIterator(element);
53.3321 + }
53.3322 +
53.3323 + public int size() {return 1;}
53.3324 +
53.3325 + public boolean contains(Object o) {return eq(o, element);}
53.3326 + }
53.3327 +
53.3328 + /**
53.3329 + * Returns an immutable list containing only the specified object.
53.3330 + * The returned list is serializable.
53.3331 + *
53.3332 + * @param o the sole object to be stored in the returned list.
53.3333 + * @return an immutable list containing only the specified object.
53.3334 + * @since 1.3
53.3335 + */
53.3336 + public static <T> List<T> singletonList(T o) {
53.3337 + return new SingletonList<>(o);
53.3338 + }
53.3339 +
53.3340 + /**
53.3341 + * @serial include
53.3342 + */
53.3343 + private static class SingletonList<E>
53.3344 + extends AbstractList<E>
53.3345 + implements RandomAccess, Serializable {
53.3346 +
53.3347 + private static final long serialVersionUID = 3093736618740652951L;
53.3348 +
53.3349 + private final E element;
53.3350 +
53.3351 + SingletonList(E obj) {element = obj;}
53.3352 +
53.3353 + public Iterator<E> iterator() {
53.3354 + return singletonIterator(element);
53.3355 + }
53.3356 +
53.3357 + public int size() {return 1;}
53.3358 +
53.3359 + public boolean contains(Object obj) {return eq(obj, element);}
53.3360 +
53.3361 + public E get(int index) {
53.3362 + if (index != 0)
53.3363 + throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
53.3364 + return element;
53.3365 + }
53.3366 + }
53.3367 +
53.3368 + /**
53.3369 + * Returns an immutable map, mapping only the specified key to the
53.3370 + * specified value. The returned map is serializable.
53.3371 + *
53.3372 + * @param key the sole key to be stored in the returned map.
53.3373 + * @param value the value to which the returned map maps <tt>key</tt>.
53.3374 + * @return an immutable map containing only the specified key-value
53.3375 + * mapping.
53.3376 + * @since 1.3
53.3377 + */
53.3378 + public static <K,V> Map<K,V> singletonMap(K key, V value) {
53.3379 + return new SingletonMap<>(key, value);
53.3380 + }
53.3381 +
53.3382 + /**
53.3383 + * @serial include
53.3384 + */
53.3385 + private static class SingletonMap<K,V>
53.3386 + extends AbstractMap<K,V>
53.3387 + implements Serializable {
53.3388 + private static final long serialVersionUID = -6979724477215052911L;
53.3389 +
53.3390 + private final K k;
53.3391 + private final V v;
53.3392 +
53.3393 + SingletonMap(K key, V value) {
53.3394 + k = key;
53.3395 + v = value;
53.3396 + }
53.3397 +
53.3398 + public int size() {return 1;}
53.3399 +
53.3400 + public boolean isEmpty() {return false;}
53.3401 +
53.3402 + public boolean containsKey(Object key) {return eq(key, k);}
53.3403 +
53.3404 + public boolean containsValue(Object value) {return eq(value, v);}
53.3405 +
53.3406 + public V get(Object key) {return (eq(key, k) ? v : null);}
53.3407 +
53.3408 + private transient Set<K> keySet = null;
53.3409 + private transient Set<Map.Entry<K,V>> entrySet = null;
53.3410 + private transient Collection<V> values = null;
53.3411 +
53.3412 + public Set<K> keySet() {
53.3413 + if (keySet==null)
53.3414 + keySet = singleton(k);
53.3415 + return keySet;
53.3416 + }
53.3417 +
53.3418 + public Set<Map.Entry<K,V>> entrySet() {
53.3419 + if (entrySet==null)
53.3420 + entrySet = Collections.<Map.Entry<K,V>>singleton(
53.3421 + new SimpleImmutableEntry<>(k, v));
53.3422 + return entrySet;
53.3423 + }
53.3424 +
53.3425 + public Collection<V> values() {
53.3426 + if (values==null)
53.3427 + values = singleton(v);
53.3428 + return values;
53.3429 + }
53.3430 +
53.3431 + }
53.3432 +
53.3433 + // Miscellaneous
53.3434 +
53.3435 + /**
53.3436 + * Returns an immutable list consisting of <tt>n</tt> copies of the
53.3437 + * specified object. The newly allocated data object is tiny (it contains
53.3438 + * a single reference to the data object). This method is useful in
53.3439 + * combination with the <tt>List.addAll</tt> method to grow lists.
53.3440 + * The returned list is serializable.
53.3441 + *
53.3442 + * @param n the number of elements in the returned list.
53.3443 + * @param o the element to appear repeatedly in the returned list.
53.3444 + * @return an immutable list consisting of <tt>n</tt> copies of the
53.3445 + * specified object.
53.3446 + * @throws IllegalArgumentException if {@code n < 0}
53.3447 + * @see List#addAll(Collection)
53.3448 + * @see List#addAll(int, Collection)
53.3449 + */
53.3450 + public static <T> List<T> nCopies(int n, T o) {
53.3451 + if (n < 0)
53.3452 + throw new IllegalArgumentException("List length = " + n);
53.3453 + return new CopiesList<>(n, o);
53.3454 + }
53.3455 +
53.3456 + /**
53.3457 + * @serial include
53.3458 + */
53.3459 + private static class CopiesList<E>
53.3460 + extends AbstractList<E>
53.3461 + implements RandomAccess, Serializable
53.3462 + {
53.3463 + private static final long serialVersionUID = 2739099268398711800L;
53.3464 +
53.3465 + final int n;
53.3466 + final E element;
53.3467 +
53.3468 + CopiesList(int n, E e) {
53.3469 + assert n >= 0;
53.3470 + this.n = n;
53.3471 + element = e;
53.3472 + }
53.3473 +
53.3474 + public int size() {
53.3475 + return n;
53.3476 + }
53.3477 +
53.3478 + public boolean contains(Object obj) {
53.3479 + return n != 0 && eq(obj, element);
53.3480 + }
53.3481 +
53.3482 + public int indexOf(Object o) {
53.3483 + return contains(o) ? 0 : -1;
53.3484 + }
53.3485 +
53.3486 + public int lastIndexOf(Object o) {
53.3487 + return contains(o) ? n - 1 : -1;
53.3488 + }
53.3489 +
53.3490 + public E get(int index) {
53.3491 + if (index < 0 || index >= n)
53.3492 + throw new IndexOutOfBoundsException("Index: "+index+
53.3493 + ", Size: "+n);
53.3494 + return element;
53.3495 + }
53.3496 +
53.3497 + public Object[] toArray() {
53.3498 + final Object[] a = new Object[n];
53.3499 + if (element != null)
53.3500 + Arrays.fill(a, 0, n, element);
53.3501 + return a;
53.3502 + }
53.3503 +
53.3504 + public <T> T[] toArray(T[] a) {
53.3505 + final int n = this.n;
53.3506 + if (a.length < n) {
53.3507 + a = (T[])java.lang.reflect.Array
53.3508 + .newInstance(a.getClass().getComponentType(), n);
53.3509 + if (element != null)
53.3510 + Arrays.fill(a, 0, n, element);
53.3511 + } else {
53.3512 + Arrays.fill(a, 0, n, element);
53.3513 + if (a.length > n)
53.3514 + a[n] = null;
53.3515 + }
53.3516 + return a;
53.3517 + }
53.3518 +
53.3519 + public List<E> subList(int fromIndex, int toIndex) {
53.3520 + if (fromIndex < 0)
53.3521 + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
53.3522 + if (toIndex > n)
53.3523 + throw new IndexOutOfBoundsException("toIndex = " + toIndex);
53.3524 + if (fromIndex > toIndex)
53.3525 + throw new IllegalArgumentException("fromIndex(" + fromIndex +
53.3526 + ") > toIndex(" + toIndex + ")");
53.3527 + return new CopiesList<>(toIndex - fromIndex, element);
53.3528 + }
53.3529 + }
53.3530 +
53.3531 + /**
53.3532 + * Returns a comparator that imposes the reverse of the <em>natural
53.3533 + * ordering</em> on a collection of objects that implement the
53.3534 + * {@code Comparable} interface. (The natural ordering is the ordering
53.3535 + * imposed by the objects' own {@code compareTo} method.) This enables a
53.3536 + * simple idiom for sorting (or maintaining) collections (or arrays) of
53.3537 + * objects that implement the {@code Comparable} interface in
53.3538 + * reverse-natural-order. For example, suppose {@code a} is an array of
53.3539 + * strings. Then: <pre>
53.3540 + * Arrays.sort(a, Collections.reverseOrder());
53.3541 + * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
53.3542 + *
53.3543 + * The returned comparator is serializable.
53.3544 + *
53.3545 + * @return A comparator that imposes the reverse of the <i>natural
53.3546 + * ordering</i> on a collection of objects that implement
53.3547 + * the <tt>Comparable</tt> interface.
53.3548 + * @see Comparable
53.3549 + */
53.3550 + public static <T> Comparator<T> reverseOrder() {
53.3551 + return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
53.3552 + }
53.3553 +
53.3554 + /**
53.3555 + * @serial include
53.3556 + */
53.3557 + private static class ReverseComparator
53.3558 + implements Comparator<Comparable<Object>>, Serializable {
53.3559 +
53.3560 + private static final long serialVersionUID = 7207038068494060240L;
53.3561 +
53.3562 + static final ReverseComparator REVERSE_ORDER
53.3563 + = new ReverseComparator();
53.3564 +
53.3565 + public int compare(Comparable<Object> c1, Comparable<Object> c2) {
53.3566 + return c2.compareTo(c1);
53.3567 + }
53.3568 +
53.3569 + private Object readResolve() { return reverseOrder(); }
53.3570 + }
53.3571 +
53.3572 + /**
53.3573 + * Returns a comparator that imposes the reverse ordering of the specified
53.3574 + * comparator. If the specified comparator is {@code null}, this method is
53.3575 + * equivalent to {@link #reverseOrder()} (in other words, it returns a
53.3576 + * comparator that imposes the reverse of the <em>natural ordering</em> on
53.3577 + * a collection of objects that implement the Comparable interface).
53.3578 + *
53.3579 + * <p>The returned comparator is serializable (assuming the specified
53.3580 + * comparator is also serializable or {@code null}).
53.3581 + *
53.3582 + * @param cmp a comparator who's ordering is to be reversed by the returned
53.3583 + * comparator or {@code null}
53.3584 + * @return A comparator that imposes the reverse ordering of the
53.3585 + * specified comparator.
53.3586 + * @since 1.5
53.3587 + */
53.3588 + public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
53.3589 + if (cmp == null)
53.3590 + return reverseOrder();
53.3591 +
53.3592 + if (cmp instanceof ReverseComparator2)
53.3593 + return ((ReverseComparator2<T>)cmp).cmp;
53.3594 +
53.3595 + return new ReverseComparator2<>(cmp);
53.3596 + }
53.3597 +
53.3598 + /**
53.3599 + * @serial include
53.3600 + */
53.3601 + private static class ReverseComparator2<T> implements Comparator<T>,
53.3602 + Serializable
53.3603 + {
53.3604 + private static final long serialVersionUID = 4374092139857L;
53.3605 +
53.3606 + /**
53.3607 + * The comparator specified in the static factory. This will never
53.3608 + * be null, as the static factory returns a ReverseComparator
53.3609 + * instance if its argument is null.
53.3610 + *
53.3611 + * @serial
53.3612 + */
53.3613 + final Comparator<T> cmp;
53.3614 +
53.3615 + ReverseComparator2(Comparator<T> cmp) {
53.3616 + assert cmp != null;
53.3617 + this.cmp = cmp;
53.3618 + }
53.3619 +
53.3620 + public int compare(T t1, T t2) {
53.3621 + return cmp.compare(t2, t1);
53.3622 + }
53.3623 +
53.3624 + public boolean equals(Object o) {
53.3625 + return (o == this) ||
53.3626 + (o instanceof ReverseComparator2 &&
53.3627 + cmp.equals(((ReverseComparator2)o).cmp));
53.3628 + }
53.3629 +
53.3630 + public int hashCode() {
53.3631 + return cmp.hashCode() ^ Integer.MIN_VALUE;
53.3632 + }
53.3633 + }
53.3634 +
53.3635 + /**
53.3636 + * Returns an enumeration over the specified collection. This provides
53.3637 + * interoperability with legacy APIs that require an enumeration
53.3638 + * as input.
53.3639 + *
53.3640 + * @param c the collection for which an enumeration is to be returned.
53.3641 + * @return an enumeration over the specified collection.
53.3642 + * @see Enumeration
53.3643 + */
53.3644 + public static <T> Enumeration<T> enumeration(final Collection<T> c) {
53.3645 + return new Enumeration<T>() {
53.3646 + private final Iterator<T> i = c.iterator();
53.3647 +
53.3648 + public boolean hasMoreElements() {
53.3649 + return i.hasNext();
53.3650 + }
53.3651 +
53.3652 + public T nextElement() {
53.3653 + return i.next();
53.3654 + }
53.3655 + };
53.3656 + }
53.3657 +
53.3658 + /**
53.3659 + * Returns an array list containing the elements returned by the
53.3660 + * specified enumeration in the order they are returned by the
53.3661 + * enumeration. This method provides interoperability between
53.3662 + * legacy APIs that return enumerations and new APIs that require
53.3663 + * collections.
53.3664 + *
53.3665 + * @param e enumeration providing elements for the returned
53.3666 + * array list
53.3667 + * @return an array list containing the elements returned
53.3668 + * by the specified enumeration.
53.3669 + * @since 1.4
53.3670 + * @see Enumeration
53.3671 + * @see ArrayList
53.3672 + */
53.3673 + public static <T> ArrayList<T> list(Enumeration<T> e) {
53.3674 + ArrayList<T> l = new ArrayList<>();
53.3675 + while (e.hasMoreElements())
53.3676 + l.add(e.nextElement());
53.3677 + return l;
53.3678 + }
53.3679 +
53.3680 + /**
53.3681 + * Returns true if the specified arguments are equal, or both null.
53.3682 + */
53.3683 + static boolean eq(Object o1, Object o2) {
53.3684 + return o1==null ? o2==null : o1.equals(o2);
53.3685 + }
53.3686 +
53.3687 + /**
53.3688 + * Returns the number of elements in the specified collection equal to the
53.3689 + * specified object. More formally, returns the number of elements
53.3690 + * <tt>e</tt> in the collection such that
53.3691 + * <tt>(o == null ? e == null : o.equals(e))</tt>.
53.3692 + *
53.3693 + * @param c the collection in which to determine the frequency
53.3694 + * of <tt>o</tt>
53.3695 + * @param o the object whose frequency is to be determined
53.3696 + * @throws NullPointerException if <tt>c</tt> is null
53.3697 + * @since 1.5
53.3698 + */
53.3699 + public static int frequency(Collection<?> c, Object o) {
53.3700 + int result = 0;
53.3701 + if (o == null) {
53.3702 + for (Object e : c)
53.3703 + if (e == null)
53.3704 + result++;
53.3705 + } else {
53.3706 + for (Object e : c)
53.3707 + if (o.equals(e))
53.3708 + result++;
53.3709 + }
53.3710 + return result;
53.3711 + }
53.3712 +
53.3713 + /**
53.3714 + * Returns {@code true} if the two specified collections have no
53.3715 + * elements in common.
53.3716 + *
53.3717 + * <p>Care must be exercised if this method is used on collections that
53.3718 + * do not comply with the general contract for {@code Collection}.
53.3719 + * Implementations may elect to iterate over either collection and test
53.3720 + * for containment in the other collection (or to perform any equivalent
53.3721 + * computation). If either collection uses a nonstandard equality test
53.3722 + * (as does a {@link SortedSet} whose ordering is not <em>compatible with
53.3723 + * equals</em>, or the key set of an {@link IdentityHashMap}), both
53.3724 + * collections must use the same nonstandard equality test, or the
53.3725 + * result of this method is undefined.
53.3726 + *
53.3727 + * <p>Care must also be exercised when using collections that have
53.3728 + * restrictions on the elements that they may contain. Collection
53.3729 + * implementations are allowed to throw exceptions for any operation
53.3730 + * involving elements they deem ineligible. For absolute safety the
53.3731 + * specified collections should contain only elements which are
53.3732 + * eligible elements for both collections.
53.3733 + *
53.3734 + * <p>Note that it is permissible to pass the same collection in both
53.3735 + * parameters, in which case the method will return {@code true} if and
53.3736 + * only if the collection is empty.
53.3737 + *
53.3738 + * @param c1 a collection
53.3739 + * @param c2 a collection
53.3740 + * @return {@code true} if the two specified collections have no
53.3741 + * elements in common.
53.3742 + * @throws NullPointerException if either collection is {@code null}.
53.3743 + * @throws NullPointerException if one collection contains a {@code null}
53.3744 + * element and {@code null} is not an eligible element for the other collection.
53.3745 + * (<a href="Collection.html#optional-restrictions">optional</a>)
53.3746 + * @throws ClassCastException if one collection contains an element that is
53.3747 + * of a type which is ineligible for the other collection.
53.3748 + * (<a href="Collection.html#optional-restrictions">optional</a>)
53.3749 + * @since 1.5
53.3750 + */
53.3751 + public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
53.3752 + // The collection to be used for contains(). Preference is given to
53.3753 + // the collection who's contains() has lower O() complexity.
53.3754 + Collection<?> contains = c2;
53.3755 + // The collection to be iterated. If the collections' contains() impl
53.3756 + // are of different O() complexity, the collection with slower
53.3757 + // contains() will be used for iteration. For collections who's
53.3758 + // contains() are of the same complexity then best performance is
53.3759 + // achieved by iterating the smaller collection.
53.3760 + Collection<?> iterate = c1;
53.3761 +
53.3762 + // Performance optimization cases. The heuristics:
53.3763 + // 1. Generally iterate over c1.
53.3764 + // 2. If c1 is a Set then iterate over c2.
53.3765 + // 3. If either collection is empty then result is always true.
53.3766 + // 4. Iterate over the smaller Collection.
53.3767 + if (c1 instanceof Set) {
53.3768 + // Use c1 for contains as a Set's contains() is expected to perform
53.3769 + // better than O(N/2)
53.3770 + iterate = c2;
53.3771 + contains = c1;
53.3772 + } else if (!(c2 instanceof Set)) {
53.3773 + // Both are mere Collections. Iterate over smaller collection.
53.3774 + // Example: If c1 contains 3 elements and c2 contains 50 elements and
53.3775 + // assuming contains() requires ceiling(N/2) comparisons then
53.3776 + // checking for all c1 elements in c2 would require 75 comparisons
53.3777 + // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring
53.3778 + // 100 comparisons (50 * ceiling(3/2)).
53.3779 + int c1size = c1.size();
53.3780 + int c2size = c2.size();
53.3781 + if (c1size == 0 || c2size == 0) {
53.3782 + // At least one collection is empty. Nothing will match.
53.3783 + return true;
53.3784 + }
53.3785 +
53.3786 + if (c1size > c2size) {
53.3787 + iterate = c2;
53.3788 + contains = c1;
53.3789 + }
53.3790 + }
53.3791 +
53.3792 + for (Object e : iterate) {
53.3793 + if (contains.contains(e)) {
53.3794 + // Found a common element. Collections are not disjoint.
53.3795 + return false;
53.3796 + }
53.3797 + }
53.3798 +
53.3799 + // No common elements were found.
53.3800 + return true;
53.3801 + }
53.3802 +
53.3803 + /**
53.3804 + * Adds all of the specified elements to the specified collection.
53.3805 + * Elements to be added may be specified individually or as an array.
53.3806 + * The behavior of this convenience method is identical to that of
53.3807 + * <tt>c.addAll(Arrays.asList(elements))</tt>, but this method is likely
53.3808 + * to run significantly faster under most implementations.
53.3809 + *
53.3810 + * <p>When elements are specified individually, this method provides a
53.3811 + * convenient way to add a few elements to an existing collection:
53.3812 + * <pre>
53.3813 + * Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
53.3814 + * </pre>
53.3815 + *
53.3816 + * @param c the collection into which <tt>elements</tt> are to be inserted
53.3817 + * @param elements the elements to insert into <tt>c</tt>
53.3818 + * @return <tt>true</tt> if the collection changed as a result of the call
53.3819 + * @throws UnsupportedOperationException if <tt>c</tt> does not support
53.3820 + * the <tt>add</tt> operation
53.3821 + * @throws NullPointerException if <tt>elements</tt> contains one or more
53.3822 + * null values and <tt>c</tt> does not permit null elements, or
53.3823 + * if <tt>c</tt> or <tt>elements</tt> are <tt>null</tt>
53.3824 + * @throws IllegalArgumentException if some property of a value in
53.3825 + * <tt>elements</tt> prevents it from being added to <tt>c</tt>
53.3826 + * @see Collection#addAll(Collection)
53.3827 + * @since 1.5
53.3828 + */
53.3829 + @SafeVarargs
53.3830 + public static <T> boolean addAll(Collection<? super T> c, T... elements) {
53.3831 + boolean result = false;
53.3832 + for (T element : elements)
53.3833 + result |= c.add(element);
53.3834 + return result;
53.3835 + }
53.3836 +
53.3837 + /**
53.3838 + * Returns a set backed by the specified map. The resulting set displays
53.3839 + * the same ordering, concurrency, and performance characteristics as the
53.3840 + * backing map. In essence, this factory method provides a {@link Set}
53.3841 + * implementation corresponding to any {@link Map} implementation. There
53.3842 + * is no need to use this method on a {@link Map} implementation that
53.3843 + * already has a corresponding {@link Set} implementation (such as {@link
53.3844 + * HashMap} or {@link TreeMap}).
53.3845 + *
53.3846 + * <p>Each method invocation on the set returned by this method results in
53.3847 + * exactly one method invocation on the backing map or its <tt>keySet</tt>
53.3848 + * view, with one exception. The <tt>addAll</tt> method is implemented
53.3849 + * as a sequence of <tt>put</tt> invocations on the backing map.
53.3850 + *
53.3851 + * <p>The specified map must be empty at the time this method is invoked,
53.3852 + * and should not be accessed directly after this method returns. These
53.3853 + * conditions are ensured if the map is created empty, passed directly
53.3854 + * to this method, and no reference to the map is retained, as illustrated
53.3855 + * in the following code fragment:
53.3856 + * <pre>
53.3857 + * Set<Object> weakHashSet = Collections.newSetFromMap(
53.3858 + * new WeakHashMap<Object, Boolean>());
53.3859 + * </pre>
53.3860 + *
53.3861 + * @param map the backing map
53.3862 + * @return the set backed by the map
53.3863 + * @throws IllegalArgumentException if <tt>map</tt> is not empty
53.3864 + * @since 1.6
53.3865 + */
53.3866 + public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
53.3867 + return new SetFromMap<>(map);
53.3868 + }
53.3869 +
53.3870 + /**
53.3871 + * @serial include
53.3872 + */
53.3873 + private static class SetFromMap<E> extends AbstractSet<E>
53.3874 + implements Set<E>, Serializable
53.3875 + {
53.3876 + private final Map<E, Boolean> m; // The backing map
53.3877 + private transient Set<E> s; // Its keySet
53.3878 +
53.3879 + SetFromMap(Map<E, Boolean> map) {
53.3880 + if (!map.isEmpty())
53.3881 + throw new IllegalArgumentException("Map is non-empty");
53.3882 + m = map;
53.3883 + s = map.keySet();
53.3884 + }
53.3885 +
53.3886 + public void clear() { m.clear(); }
53.3887 + public int size() { return m.size(); }
53.3888 + public boolean isEmpty() { return m.isEmpty(); }
53.3889 + public boolean contains(Object o) { return m.containsKey(o); }
53.3890 + public boolean remove(Object o) { return m.remove(o) != null; }
53.3891 + public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
53.3892 + public Iterator<E> iterator() { return s.iterator(); }
53.3893 + public Object[] toArray() { return s.toArray(); }
53.3894 + public <T> T[] toArray(T[] a) { return s.toArray(a); }
53.3895 + public String toString() { return s.toString(); }
53.3896 + public int hashCode() { return s.hashCode(); }
53.3897 + public boolean equals(Object o) { return o == this || s.equals(o); }
53.3898 + public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
53.3899 + public boolean removeAll(Collection<?> c) {return s.removeAll(c);}
53.3900 + public boolean retainAll(Collection<?> c) {return s.retainAll(c);}
53.3901 + // addAll is the only inherited implementation
53.3902 +
53.3903 + private static final long serialVersionUID = 2454657854757543876L;
53.3904 +
53.3905 + }
53.3906 +
53.3907 + /**
53.3908 + * Returns a view of a {@link Deque} as a Last-in-first-out (Lifo)
53.3909 + * {@link Queue}. Method <tt>add</tt> is mapped to <tt>push</tt>,
53.3910 + * <tt>remove</tt> is mapped to <tt>pop</tt> and so on. This
53.3911 + * view can be useful when you would like to use a method
53.3912 + * requiring a <tt>Queue</tt> but you need Lifo ordering.
53.3913 + *
53.3914 + * <p>Each method invocation on the queue returned by this method
53.3915 + * results in exactly one method invocation on the backing deque, with
53.3916 + * one exception. The {@link Queue#addAll addAll} method is
53.3917 + * implemented as a sequence of {@link Deque#addFirst addFirst}
53.3918 + * invocations on the backing deque.
53.3919 + *
53.3920 + * @param deque the deque
53.3921 + * @return the queue
53.3922 + * @since 1.6
53.3923 + */
53.3924 + public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
53.3925 + return new AsLIFOQueue<>(deque);
53.3926 + }
53.3927 +
53.3928 + /**
53.3929 + * @serial include
53.3930 + */
53.3931 + static class AsLIFOQueue<E> extends AbstractQueue<E>
53.3932 + implements Queue<E>, Serializable {
53.3933 + private static final long serialVersionUID = 1802017725587941708L;
53.3934 + private final Deque<E> q;
53.3935 + AsLIFOQueue(Deque<E> q) { this.q = q; }
53.3936 + public boolean add(E e) { q.addFirst(e); return true; }
53.3937 + public boolean offer(E e) { return q.offerFirst(e); }
53.3938 + public E poll() { return q.pollFirst(); }
53.3939 + public E remove() { return q.removeFirst(); }
53.3940 + public E peek() { return q.peekFirst(); }
53.3941 + public E element() { return q.getFirst(); }
53.3942 + public void clear() { q.clear(); }
53.3943 + public int size() { return q.size(); }
53.3944 + public boolean isEmpty() { return q.isEmpty(); }
53.3945 + public boolean contains(Object o) { return q.contains(o); }
53.3946 + public boolean remove(Object o) { return q.remove(o); }
53.3947 + public Iterator<E> iterator() { return q.iterator(); }
53.3948 + public Object[] toArray() { return q.toArray(); }
53.3949 + public <T> T[] toArray(T[] a) { return q.toArray(a); }
53.3950 + public String toString() { return q.toString(); }
53.3951 + public boolean containsAll(Collection<?> c) {return q.containsAll(c);}
53.3952 + public boolean removeAll(Collection<?> c) {return q.removeAll(c);}
53.3953 + public boolean retainAll(Collection<?> c) {return q.retainAll(c);}
53.3954 + // We use inherited addAll; forwarding addAll would be wrong
53.3955 + }
53.3956 +}
54.1 --- a/emul/compact/src/main/java/java/util/ComparableTimSort.java Tue Feb 05 16:40:01 2013 +0100
54.2 +++ b/emul/compact/src/main/java/java/util/ComparableTimSort.java Tue Feb 05 17:04:22 2013 +0100
54.3 @@ -25,7 +25,6 @@
54.4
54.5 package java.util;
54.6
54.7 -import org.apidesign.bck2brwsr.emul.lang.System;
54.8
54.9 /**
54.10 * This is a near duplicate of {@link TimSort}, modified for use with
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/emul/compact/src/main/java/java/util/Deque.java Tue Feb 05 17:04:22 2013 +0100
55.3 @@ -0,0 +1,584 @@
55.4 +/*
55.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55.6 + *
55.7 + * This code is free software; you can redistribute it and/or modify it
55.8 + * under the terms of the GNU General Public License version 2 only, as
55.9 + * published by the Free Software Foundation. Oracle designates this
55.10 + * particular file as subject to the "Classpath" exception as provided
55.11 + * by Oracle in the LICENSE file that accompanied this code.
55.12 + *
55.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
55.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
55.16 + * version 2 for more details (a copy is included in the LICENSE file that
55.17 + * accompanied this code).
55.18 + *
55.19 + * You should have received a copy of the GNU General Public License version
55.20 + * 2 along with this work; if not, write to the Free Software Foundation,
55.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
55.22 + *
55.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
55.24 + * or visit www.oracle.com if you need additional information or have any
55.25 + * questions.
55.26 + */
55.27 +
55.28 +/*
55.29 + * This file is available under and governed by the GNU General Public
55.30 + * License version 2 only, as published by the Free Software Foundation.
55.31 + * However, the following notice accompanied the original version of this
55.32 + * file:
55.33 + *
55.34 + * Written by Doug Lea and Josh Bloch with assistance from members of
55.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
55.36 + * at http://creativecommons.org/publicdomain/zero/1.0/
55.37 + */
55.38 +
55.39 +package java.util;
55.40 +
55.41 +/**
55.42 + * A linear collection that supports element insertion and removal at
55.43 + * both ends. The name <i>deque</i> is short for "double ended queue"
55.44 + * and is usually pronounced "deck". Most <tt>Deque</tt>
55.45 + * implementations place no fixed limits on the number of elements
55.46 + * they may contain, but this interface supports capacity-restricted
55.47 + * deques as well as those with no fixed size limit.
55.48 + *
55.49 + * <p>This interface defines methods to access the elements at both
55.50 + * ends of the deque. Methods are provided to insert, remove, and
55.51 + * examine the element. Each of these methods exists in two forms:
55.52 + * one throws an exception if the operation fails, the other returns a
55.53 + * special value (either <tt>null</tt> or <tt>false</tt>, depending on
55.54 + * the operation). The latter form of the insert operation is
55.55 + * designed specifically for use with capacity-restricted
55.56 + * <tt>Deque</tt> implementations; in most implementations, insert
55.57 + * operations cannot fail.
55.58 + *
55.59 + * <p>The twelve methods described above are summarized in the
55.60 + * following table:
55.61 + *
55.62 + * <p>
55.63 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
55.64 + * <tr>
55.65 + * <td></td>
55.66 + * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
55.67 + * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
55.68 + * </tr>
55.69 + * <tr>
55.70 + * <td></td>
55.71 + * <td ALIGN=CENTER><em>Throws exception</em></td>
55.72 + * <td ALIGN=CENTER><em>Special value</em></td>
55.73 + * <td ALIGN=CENTER><em>Throws exception</em></td>
55.74 + * <td ALIGN=CENTER><em>Special value</em></td>
55.75 + * </tr>
55.76 + * <tr>
55.77 + * <td><b>Insert</b></td>
55.78 + * <td>{@link #addFirst addFirst(e)}</td>
55.79 + * <td>{@link #offerFirst offerFirst(e)}</td>
55.80 + * <td>{@link #addLast addLast(e)}</td>
55.81 + * <td>{@link #offerLast offerLast(e)}</td>
55.82 + * </tr>
55.83 + * <tr>
55.84 + * <td><b>Remove</b></td>
55.85 + * <td>{@link #removeFirst removeFirst()}</td>
55.86 + * <td>{@link #pollFirst pollFirst()}</td>
55.87 + * <td>{@link #removeLast removeLast()}</td>
55.88 + * <td>{@link #pollLast pollLast()}</td>
55.89 + * </tr>
55.90 + * <tr>
55.91 + * <td><b>Examine</b></td>
55.92 + * <td>{@link #getFirst getFirst()}</td>
55.93 + * <td>{@link #peekFirst peekFirst()}</td>
55.94 + * <td>{@link #getLast getLast()}</td>
55.95 + * <td>{@link #peekLast peekLast()}</td>
55.96 + * </tr>
55.97 + * </table>
55.98 + *
55.99 + * <p>This interface extends the {@link Queue} interface. When a deque is
55.100 + * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are
55.101 + * added at the end of the deque and removed from the beginning. The methods
55.102 + * inherited from the <tt>Queue</tt> interface are precisely equivalent to
55.103 + * <tt>Deque</tt> methods as indicated in the following table:
55.104 + *
55.105 + * <p>
55.106 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
55.107 + * <tr>
55.108 + * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
55.109 + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
55.110 + * </tr>
55.111 + * <tr>
55.112 + * <td>{@link java.util.Queue#add add(e)}</td>
55.113 + * <td>{@link #addLast addLast(e)}</td>
55.114 + * </tr>
55.115 + * <tr>
55.116 + * <td>{@link java.util.Queue#offer offer(e)}</td>
55.117 + * <td>{@link #offerLast offerLast(e)}</td>
55.118 + * </tr>
55.119 + * <tr>
55.120 + * <td>{@link java.util.Queue#remove remove()}</td>
55.121 + * <td>{@link #removeFirst removeFirst()}</td>
55.122 + * </tr>
55.123 + * <tr>
55.124 + * <td>{@link java.util.Queue#poll poll()}</td>
55.125 + * <td>{@link #pollFirst pollFirst()}</td>
55.126 + * </tr>
55.127 + * <tr>
55.128 + * <td>{@link java.util.Queue#element element()}</td>
55.129 + * <td>{@link #getFirst getFirst()}</td>
55.130 + * </tr>
55.131 + * <tr>
55.132 + * <td>{@link java.util.Queue#peek peek()}</td>
55.133 + * <td>{@link #peek peekFirst()}</td>
55.134 + * </tr>
55.135 + * </table>
55.136 + *
55.137 + * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This
55.138 + * interface should be used in preference to the legacy {@link Stack} class.
55.139 + * When a deque is used as a stack, elements are pushed and popped from the
55.140 + * beginning of the deque. Stack methods are precisely equivalent to
55.141 + * <tt>Deque</tt> methods as indicated in the table below:
55.142 + *
55.143 + * <p>
55.144 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
55.145 + * <tr>
55.146 + * <td ALIGN=CENTER> <b>Stack Method</b></td>
55.147 + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
55.148 + * </tr>
55.149 + * <tr>
55.150 + * <td>{@link #push push(e)}</td>
55.151 + * <td>{@link #addFirst addFirst(e)}</td>
55.152 + * </tr>
55.153 + * <tr>
55.154 + * <td>{@link #pop pop()}</td>
55.155 + * <td>{@link #removeFirst removeFirst()}</td>
55.156 + * </tr>
55.157 + * <tr>
55.158 + * <td>{@link #peek peek()}</td>
55.159 + * <td>{@link #peekFirst peekFirst()}</td>
55.160 + * </tr>
55.161 + * </table>
55.162 + *
55.163 + * <p>Note that the {@link #peek peek} method works equally well when
55.164 + * a deque is used as a queue or a stack; in either case, elements are
55.165 + * drawn from the beginning of the deque.
55.166 + *
55.167 + * <p>This interface provides two methods to remove interior
55.168 + * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and
55.169 + * {@link #removeLastOccurrence removeLastOccurrence}.
55.170 + *
55.171 + * <p>Unlike the {@link List} interface, this interface does not
55.172 + * provide support for indexed access to elements.
55.173 + *
55.174 + * <p>While <tt>Deque</tt> implementations are not strictly required
55.175 + * to prohibit the insertion of null elements, they are strongly
55.176 + * encouraged to do so. Users of any <tt>Deque</tt> implementations
55.177 + * that do allow null elements are strongly encouraged <i>not</i> to
55.178 + * take advantage of the ability to insert nulls. This is so because
55.179 + * <tt>null</tt> is used as a special return value by various methods
55.180 + * to indicated that the deque is empty.
55.181 + *
55.182 + * <p><tt>Deque</tt> implementations generally do not define
55.183 + * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt>
55.184 + * methods, but instead inherit the identity-based versions from class
55.185 + * <tt>Object</tt>.
55.186 + *
55.187 + * <p>This interface is a member of the <a
55.188 + * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections
55.189 + * Framework</a>.
55.190 + *
55.191 + * @author Doug Lea
55.192 + * @author Josh Bloch
55.193 + * @since 1.6
55.194 + * @param <E> the type of elements held in this collection
55.195 + */
55.196 +
55.197 +public interface Deque<E> extends Queue<E> {
55.198 + /**
55.199 + * Inserts the specified element at the front of this deque if it is
55.200 + * possible to do so immediately without violating capacity restrictions.
55.201 + * When using a capacity-restricted deque, it is generally preferable to
55.202 + * use method {@link #offerFirst}.
55.203 + *
55.204 + * @param e the element to add
55.205 + * @throws IllegalStateException if the element cannot be added at this
55.206 + * time due to capacity restrictions
55.207 + * @throws ClassCastException if the class of the specified element
55.208 + * prevents it from being added to this deque
55.209 + * @throws NullPointerException if the specified element is null and this
55.210 + * deque does not permit null elements
55.211 + * @throws IllegalArgumentException if some property of the specified
55.212 + * element prevents it from being added to this deque
55.213 + */
55.214 + void addFirst(E e);
55.215 +
55.216 + /**
55.217 + * Inserts the specified element at the end of this deque if it is
55.218 + * possible to do so immediately without violating capacity restrictions.
55.219 + * When using a capacity-restricted deque, it is generally preferable to
55.220 + * use method {@link #offerLast}.
55.221 + *
55.222 + * <p>This method is equivalent to {@link #add}.
55.223 + *
55.224 + * @param e the element to add
55.225 + * @throws IllegalStateException if the element cannot be added at this
55.226 + * time due to capacity restrictions
55.227 + * @throws ClassCastException if the class of the specified element
55.228 + * prevents it from being added to this deque
55.229 + * @throws NullPointerException if the specified element is null and this
55.230 + * deque does not permit null elements
55.231 + * @throws IllegalArgumentException if some property of the specified
55.232 + * element prevents it from being added to this deque
55.233 + */
55.234 + void addLast(E e);
55.235 +
55.236 + /**
55.237 + * Inserts the specified element at the front of this deque unless it would
55.238 + * violate capacity restrictions. When using a capacity-restricted deque,
55.239 + * this method is generally preferable to the {@link #addFirst} method,
55.240 + * which can fail to insert an element only by throwing an exception.
55.241 + *
55.242 + * @param e the element to add
55.243 + * @return <tt>true</tt> if the element was added to this deque, else
55.244 + * <tt>false</tt>
55.245 + * @throws ClassCastException if the class of the specified element
55.246 + * prevents it from being added to this deque
55.247 + * @throws NullPointerException if the specified element is null and this
55.248 + * deque does not permit null elements
55.249 + * @throws IllegalArgumentException if some property of the specified
55.250 + * element prevents it from being added to this deque
55.251 + */
55.252 + boolean offerFirst(E e);
55.253 +
55.254 + /**
55.255 + * Inserts the specified element at the end of this deque unless it would
55.256 + * violate capacity restrictions. When using a capacity-restricted deque,
55.257 + * this method is generally preferable to the {@link #addLast} method,
55.258 + * which can fail to insert an element only by throwing an exception.
55.259 + *
55.260 + * @param e the element to add
55.261 + * @return <tt>true</tt> if the element was added to this deque, else
55.262 + * <tt>false</tt>
55.263 + * @throws ClassCastException if the class of the specified element
55.264 + * prevents it from being added to this deque
55.265 + * @throws NullPointerException if the specified element is null and this
55.266 + * deque does not permit null elements
55.267 + * @throws IllegalArgumentException if some property of the specified
55.268 + * element prevents it from being added to this deque
55.269 + */
55.270 + boolean offerLast(E e);
55.271 +
55.272 + /**
55.273 + * Retrieves and removes the first element of this deque. This method
55.274 + * differs from {@link #pollFirst pollFirst} only in that it throws an
55.275 + * exception if this deque is empty.
55.276 + *
55.277 + * @return the head of this deque
55.278 + * @throws NoSuchElementException if this deque is empty
55.279 + */
55.280 + E removeFirst();
55.281 +
55.282 + /**
55.283 + * Retrieves and removes the last element of this deque. This method
55.284 + * differs from {@link #pollLast pollLast} only in that it throws an
55.285 + * exception if this deque is empty.
55.286 + *
55.287 + * @return the tail of this deque
55.288 + * @throws NoSuchElementException if this deque is empty
55.289 + */
55.290 + E removeLast();
55.291 +
55.292 + /**
55.293 + * Retrieves and removes the first element of this deque,
55.294 + * or returns <tt>null</tt> if this deque is empty.
55.295 + *
55.296 + * @return the head of this deque, or <tt>null</tt> if this deque is empty
55.297 + */
55.298 + E pollFirst();
55.299 +
55.300 + /**
55.301 + * Retrieves and removes the last element of this deque,
55.302 + * or returns <tt>null</tt> if this deque is empty.
55.303 + *
55.304 + * @return the tail of this deque, or <tt>null</tt> if this deque is empty
55.305 + */
55.306 + E pollLast();
55.307 +
55.308 + /**
55.309 + * Retrieves, but does not remove, the first element of this deque.
55.310 + *
55.311 + * This method differs from {@link #peekFirst peekFirst} only in that it
55.312 + * throws an exception if this deque is empty.
55.313 + *
55.314 + * @return the head of this deque
55.315 + * @throws NoSuchElementException if this deque is empty
55.316 + */
55.317 + E getFirst();
55.318 +
55.319 + /**
55.320 + * Retrieves, but does not remove, the last element of this deque.
55.321 + * This method differs from {@link #peekLast peekLast} only in that it
55.322 + * throws an exception if this deque is empty.
55.323 + *
55.324 + * @return the tail of this deque
55.325 + * @throws NoSuchElementException if this deque is empty
55.326 + */
55.327 + E getLast();
55.328 +
55.329 + /**
55.330 + * Retrieves, but does not remove, the first element of this deque,
55.331 + * or returns <tt>null</tt> if this deque is empty.
55.332 + *
55.333 + * @return the head of this deque, or <tt>null</tt> if this deque is empty
55.334 + */
55.335 + E peekFirst();
55.336 +
55.337 + /**
55.338 + * Retrieves, but does not remove, the last element of this deque,
55.339 + * or returns <tt>null</tt> if this deque is empty.
55.340 + *
55.341 + * @return the tail of this deque, or <tt>null</tt> if this deque is empty
55.342 + */
55.343 + E peekLast();
55.344 +
55.345 + /**
55.346 + * Removes the first occurrence of the specified element from this deque.
55.347 + * If the deque does not contain the element, it is unchanged.
55.348 + * More formally, removes the first element <tt>e</tt> such that
55.349 + * <tt>(o==null ? e==null : o.equals(e))</tt>
55.350 + * (if such an element exists).
55.351 + * Returns <tt>true</tt> if this deque contained the specified element
55.352 + * (or equivalently, if this deque changed as a result of the call).
55.353 + *
55.354 + * @param o element to be removed from this deque, if present
55.355 + * @return <tt>true</tt> if an element was removed as a result of this call
55.356 + * @throws ClassCastException if the class of the specified element
55.357 + * is incompatible with this deque
55.358 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.359 + * @throws NullPointerException if the specified element is null and this
55.360 + * deque does not permit null elements
55.361 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.362 + */
55.363 + boolean removeFirstOccurrence(Object o);
55.364 +
55.365 + /**
55.366 + * Removes the last occurrence of the specified element from this deque.
55.367 + * If the deque does not contain the element, it is unchanged.
55.368 + * More formally, removes the last element <tt>e</tt> such that
55.369 + * <tt>(o==null ? e==null : o.equals(e))</tt>
55.370 + * (if such an element exists).
55.371 + * Returns <tt>true</tt> if this deque contained the specified element
55.372 + * (or equivalently, if this deque changed as a result of the call).
55.373 + *
55.374 + * @param o element to be removed from this deque, if present
55.375 + * @return <tt>true</tt> if an element was removed as a result of this call
55.376 + * @throws ClassCastException if the class of the specified element
55.377 + * is incompatible with this deque
55.378 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.379 + * @throws NullPointerException if the specified element is null and this
55.380 + * deque does not permit null elements
55.381 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.382 + */
55.383 + boolean removeLastOccurrence(Object o);
55.384 +
55.385 + // *** Queue methods ***
55.386 +
55.387 + /**
55.388 + * Inserts the specified element into the queue represented by this deque
55.389 + * (in other words, at the tail of this deque) if it is possible to do so
55.390 + * immediately without violating capacity restrictions, returning
55.391 + * <tt>true</tt> upon success and throwing an
55.392 + * <tt>IllegalStateException</tt> if no space is currently available.
55.393 + * When using a capacity-restricted deque, it is generally preferable to
55.394 + * use {@link #offer(Object) offer}.
55.395 + *
55.396 + * <p>This method is equivalent to {@link #addLast}.
55.397 + *
55.398 + * @param e the element to add
55.399 + * @return <tt>true</tt> (as specified by {@link Collection#add})
55.400 + * @throws IllegalStateException if the element cannot be added at this
55.401 + * time due to capacity restrictions
55.402 + * @throws ClassCastException if the class of the specified element
55.403 + * prevents it from being added to this deque
55.404 + * @throws NullPointerException if the specified element is null and this
55.405 + * deque does not permit null elements
55.406 + * @throws IllegalArgumentException if some property of the specified
55.407 + * element prevents it from being added to this deque
55.408 + */
55.409 + boolean add(E e);
55.410 +
55.411 + /**
55.412 + * Inserts the specified element into the queue represented by this deque
55.413 + * (in other words, at the tail of this deque) if it is possible to do so
55.414 + * immediately without violating capacity restrictions, returning
55.415 + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
55.416 + * available. When using a capacity-restricted deque, this method is
55.417 + * generally preferable to the {@link #add} method, which can fail to
55.418 + * insert an element only by throwing an exception.
55.419 + *
55.420 + * <p>This method is equivalent to {@link #offerLast}.
55.421 + *
55.422 + * @param e the element to add
55.423 + * @return <tt>true</tt> if the element was added to this deque, else
55.424 + * <tt>false</tt>
55.425 + * @throws ClassCastException if the class of the specified element
55.426 + * prevents it from being added to this deque
55.427 + * @throws NullPointerException if the specified element is null and this
55.428 + * deque does not permit null elements
55.429 + * @throws IllegalArgumentException if some property of the specified
55.430 + * element prevents it from being added to this deque
55.431 + */
55.432 + boolean offer(E e);
55.433 +
55.434 + /**
55.435 + * Retrieves and removes the head of the queue represented by this deque
55.436 + * (in other words, the first element of this deque).
55.437 + * This method differs from {@link #poll poll} only in that it throws an
55.438 + * exception if this deque is empty.
55.439 + *
55.440 + * <p>This method is equivalent to {@link #removeFirst()}.
55.441 + *
55.442 + * @return the head of the queue represented by this deque
55.443 + * @throws NoSuchElementException if this deque is empty
55.444 + */
55.445 + E remove();
55.446 +
55.447 + /**
55.448 + * Retrieves and removes the head of the queue represented by this deque
55.449 + * (in other words, the first element of this deque), or returns
55.450 + * <tt>null</tt> if this deque is empty.
55.451 + *
55.452 + * <p>This method is equivalent to {@link #pollFirst()}.
55.453 + *
55.454 + * @return the first element of this deque, or <tt>null</tt> if
55.455 + * this deque is empty
55.456 + */
55.457 + E poll();
55.458 +
55.459 + /**
55.460 + * Retrieves, but does not remove, the head of the queue represented by
55.461 + * this deque (in other words, the first element of this deque).
55.462 + * This method differs from {@link #peek peek} only in that it throws an
55.463 + * exception if this deque is empty.
55.464 + *
55.465 + * <p>This method is equivalent to {@link #getFirst()}.
55.466 + *
55.467 + * @return the head of the queue represented by this deque
55.468 + * @throws NoSuchElementException if this deque is empty
55.469 + */
55.470 + E element();
55.471 +
55.472 + /**
55.473 + * Retrieves, but does not remove, the head of the queue represented by
55.474 + * this deque (in other words, the first element of this deque), or
55.475 + * returns <tt>null</tt> if this deque is empty.
55.476 + *
55.477 + * <p>This method is equivalent to {@link #peekFirst()}.
55.478 + *
55.479 + * @return the head of the queue represented by this deque, or
55.480 + * <tt>null</tt> if this deque is empty
55.481 + */
55.482 + E peek();
55.483 +
55.484 +
55.485 + // *** Stack methods ***
55.486 +
55.487 + /**
55.488 + * Pushes an element onto the stack represented by this deque (in other
55.489 + * words, at the head of this deque) if it is possible to do so
55.490 + * immediately without violating capacity restrictions, returning
55.491 + * <tt>true</tt> upon success and throwing an
55.492 + * <tt>IllegalStateException</tt> if no space is currently available.
55.493 + *
55.494 + * <p>This method is equivalent to {@link #addFirst}.
55.495 + *
55.496 + * @param e the element to push
55.497 + * @throws IllegalStateException if the element cannot be added at this
55.498 + * time due to capacity restrictions
55.499 + * @throws ClassCastException if the class of the specified element
55.500 + * prevents it from being added to this deque
55.501 + * @throws NullPointerException if the specified element is null and this
55.502 + * deque does not permit null elements
55.503 + * @throws IllegalArgumentException if some property of the specified
55.504 + * element prevents it from being added to this deque
55.505 + */
55.506 + void push(E e);
55.507 +
55.508 + /**
55.509 + * Pops an element from the stack represented by this deque. In other
55.510 + * words, removes and returns the first element of this deque.
55.511 + *
55.512 + * <p>This method is equivalent to {@link #removeFirst()}.
55.513 + *
55.514 + * @return the element at the front of this deque (which is the top
55.515 + * of the stack represented by this deque)
55.516 + * @throws NoSuchElementException if this deque is empty
55.517 + */
55.518 + E pop();
55.519 +
55.520 +
55.521 + // *** Collection methods ***
55.522 +
55.523 + /**
55.524 + * Removes the first occurrence of the specified element from this deque.
55.525 + * If the deque does not contain the element, it is unchanged.
55.526 + * More formally, removes the first element <tt>e</tt> such that
55.527 + * <tt>(o==null ? e==null : o.equals(e))</tt>
55.528 + * (if such an element exists).
55.529 + * Returns <tt>true</tt> if this deque contained the specified element
55.530 + * (or equivalently, if this deque changed as a result of the call).
55.531 + *
55.532 + * <p>This method is equivalent to {@link #removeFirstOccurrence}.
55.533 + *
55.534 + * @param o element to be removed from this deque, if present
55.535 + * @return <tt>true</tt> if an element was removed as a result of this call
55.536 + * @throws ClassCastException if the class of the specified element
55.537 + * is incompatible with this deque
55.538 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.539 + * @throws NullPointerException if the specified element is null and this
55.540 + * deque does not permit null elements
55.541 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.542 + */
55.543 + boolean remove(Object o);
55.544 +
55.545 + /**
55.546 + * Returns <tt>true</tt> if this deque contains the specified element.
55.547 + * More formally, returns <tt>true</tt> if and only if this deque contains
55.548 + * at least one element <tt>e</tt> such that
55.549 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
55.550 + *
55.551 + * @param o element whose presence in this deque is to be tested
55.552 + * @return <tt>true</tt> if this deque contains the specified element
55.553 + * @throws ClassCastException if the type of the specified element
55.554 + * is incompatible with this deque
55.555 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.556 + * @throws NullPointerException if the specified element is null and this
55.557 + * deque does not permit null elements
55.558 + * (<a href="Collection.html#optional-restrictions">optional</a>)
55.559 + */
55.560 + boolean contains(Object o);
55.561 +
55.562 + /**
55.563 + * Returns the number of elements in this deque.
55.564 + *
55.565 + * @return the number of elements in this deque
55.566 + */
55.567 + public int size();
55.568 +
55.569 + /**
55.570 + * Returns an iterator over the elements in this deque in proper sequence.
55.571 + * The elements will be returned in order from first (head) to last (tail).
55.572 + *
55.573 + * @return an iterator over the elements in this deque in proper sequence
55.574 + */
55.575 + Iterator<E> iterator();
55.576 +
55.577 + /**
55.578 + * Returns an iterator over the elements in this deque in reverse
55.579 + * sequential order. The elements will be returned in order from
55.580 + * last (tail) to first (head).
55.581 + *
55.582 + * @return an iterator over the elements in this deque in reverse
55.583 + * sequence
55.584 + */
55.585 + Iterator<E> descendingIterator();
55.586 +
55.587 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/emul/compact/src/main/java/java/util/Dictionary.java Tue Feb 05 17:04:22 2013 +0100
56.3 @@ -0,0 +1,155 @@
56.4 +/*
56.5 + * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
56.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
56.7 + *
56.8 + * This code is free software; you can redistribute it and/or modify it
56.9 + * under the terms of the GNU General Public License version 2 only, as
56.10 + * published by the Free Software Foundation. Oracle designates this
56.11 + * particular file as subject to the "Classpath" exception as provided
56.12 + * by Oracle in the LICENSE file that accompanied this code.
56.13 + *
56.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
56.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
56.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56.17 + * version 2 for more details (a copy is included in the LICENSE file that
56.18 + * accompanied this code).
56.19 + *
56.20 + * You should have received a copy of the GNU General Public License version
56.21 + * 2 along with this work; if not, write to the Free Software Foundation,
56.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
56.23 + *
56.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
56.25 + * or visit www.oracle.com if you need additional information or have any
56.26 + * questions.
56.27 + */
56.28 +
56.29 +package java.util;
56.30 +
56.31 +/**
56.32 + * The <code>Dictionary</code> class is the abstract parent of any
56.33 + * class, such as <code>Hashtable</code>, which maps keys to values.
56.34 + * Every key and every value is an object. In any one <tt>Dictionary</tt>
56.35 + * object, every key is associated with at most one value. Given a
56.36 + * <tt>Dictionary</tt> and a key, the associated element can be looked up.
56.37 + * Any non-<code>null</code> object can be used as a key and as a value.
56.38 + * <p>
56.39 + * As a rule, the <code>equals</code> method should be used by
56.40 + * implementations of this class to decide if two keys are the same.
56.41 + * <p>
56.42 + * <strong>NOTE: This class is obsolete. New implementations should
56.43 + * implement the Map interface, rather than extending this class.</strong>
56.44 + *
56.45 + * @author unascribed
56.46 + * @see java.util.Map
56.47 + * @see java.lang.Object#equals(java.lang.Object)
56.48 + * @see java.lang.Object#hashCode()
56.49 + * @see java.util.Hashtable
56.50 + * @since JDK1.0
56.51 + */
56.52 +public abstract
56.53 +class Dictionary<K,V> {
56.54 + /**
56.55 + * Sole constructor. (For invocation by subclass constructors, typically
56.56 + * implicit.)
56.57 + */
56.58 + public Dictionary() {
56.59 + }
56.60 +
56.61 + /**
56.62 + * Returns the number of entries (distinct keys) in this dictionary.
56.63 + *
56.64 + * @return the number of keys in this dictionary.
56.65 + */
56.66 + abstract public int size();
56.67 +
56.68 + /**
56.69 + * Tests if this dictionary maps no keys to value. The general contract
56.70 + * for the <tt>isEmpty</tt> method is that the result is true if and only
56.71 + * if this dictionary contains no entries.
56.72 + *
56.73 + * @return <code>true</code> if this dictionary maps no keys to values;
56.74 + * <code>false</code> otherwise.
56.75 + */
56.76 + abstract public boolean isEmpty();
56.77 +
56.78 + /**
56.79 + * Returns an enumeration of the keys in this dictionary. The general
56.80 + * contract for the keys method is that an <tt>Enumeration</tt> object
56.81 + * is returned that will generate all the keys for which this dictionary
56.82 + * contains entries.
56.83 + *
56.84 + * @return an enumeration of the keys in this dictionary.
56.85 + * @see java.util.Dictionary#elements()
56.86 + * @see java.util.Enumeration
56.87 + */
56.88 + abstract public Enumeration<K> keys();
56.89 +
56.90 + /**
56.91 + * Returns an enumeration of the values in this dictionary. The general
56.92 + * contract for the <tt>elements</tt> method is that an
56.93 + * <tt>Enumeration</tt> is returned that will generate all the elements
56.94 + * contained in entries in this dictionary.
56.95 + *
56.96 + * @return an enumeration of the values in this dictionary.
56.97 + * @see java.util.Dictionary#keys()
56.98 + * @see java.util.Enumeration
56.99 + */
56.100 + abstract public Enumeration<V> elements();
56.101 +
56.102 + /**
56.103 + * Returns the value to which the key is mapped in this dictionary.
56.104 + * The general contract for the <tt>isEmpty</tt> method is that if this
56.105 + * dictionary contains an entry for the specified key, the associated
56.106 + * value is returned; otherwise, <tt>null</tt> is returned.
56.107 + *
56.108 + * @return the value to which the key is mapped in this dictionary;
56.109 + * @param key a key in this dictionary.
56.110 + * <code>null</code> if the key is not mapped to any value in
56.111 + * this dictionary.
56.112 + * @exception NullPointerException if the <tt>key</tt> is <tt>null</tt>.
56.113 + * @see java.util.Dictionary#put(java.lang.Object, java.lang.Object)
56.114 + */
56.115 + abstract public V get(Object key);
56.116 +
56.117 + /**
56.118 + * Maps the specified <code>key</code> to the specified
56.119 + * <code>value</code> in this dictionary. Neither the key nor the
56.120 + * value can be <code>null</code>.
56.121 + * <p>
56.122 + * If this dictionary already contains an entry for the specified
56.123 + * <tt>key</tt>, the value already in this dictionary for that
56.124 + * <tt>key</tt> is returned, after modifying the entry to contain the
56.125 + * new element. <p>If this dictionary does not already have an entry
56.126 + * for the specified <tt>key</tt>, an entry is created for the
56.127 + * specified <tt>key</tt> and <tt>value</tt>, and <tt>null</tt> is
56.128 + * returned.
56.129 + * <p>
56.130 + * The <code>value</code> can be retrieved by calling the
56.131 + * <code>get</code> method with a <code>key</code> that is equal to
56.132 + * the original <code>key</code>.
56.133 + *
56.134 + * @param key the hashtable key.
56.135 + * @param value the value.
56.136 + * @return the previous value to which the <code>key</code> was mapped
56.137 + * in this dictionary, or <code>null</code> if the key did not
56.138 + * have a previous mapping.
56.139 + * @exception NullPointerException if the <code>key</code> or
56.140 + * <code>value</code> is <code>null</code>.
56.141 + * @see java.lang.Object#equals(java.lang.Object)
56.142 + * @see java.util.Dictionary#get(java.lang.Object)
56.143 + */
56.144 + abstract public V put(K key, V value);
56.145 +
56.146 + /**
56.147 + * Removes the <code>key</code> (and its corresponding
56.148 + * <code>value</code>) from this dictionary. This method does nothing
56.149 + * if the <code>key</code> is not in this dictionary.
56.150 + *
56.151 + * @param key the key that needs to be removed.
56.152 + * @return the value to which the <code>key</code> had been mapped in this
56.153 + * dictionary, or <code>null</code> if the key did not have a
56.154 + * mapping.
56.155 + * @exception NullPointerException if <tt>key</tt> is <tt>null</tt>.
56.156 + */
56.157 + abstract public V remove(Object key);
56.158 +}
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/emul/compact/src/main/java/java/util/EmptyStackException.java Tue Feb 05 17:04:22 2013 +0100
57.3 @@ -0,0 +1,46 @@
57.4 +/*
57.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
57.7 + *
57.8 + * This code is free software; you can redistribute it and/or modify it
57.9 + * under the terms of the GNU General Public License version 2 only, as
57.10 + * published by the Free Software Foundation. Oracle designates this
57.11 + * particular file as subject to the "Classpath" exception as provided
57.12 + * by Oracle in the LICENSE file that accompanied this code.
57.13 + *
57.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
57.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
57.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57.17 + * version 2 for more details (a copy is included in the LICENSE file that
57.18 + * accompanied this code).
57.19 + *
57.20 + * You should have received a copy of the GNU General Public License version
57.21 + * 2 along with this work; if not, write to the Free Software Foundation,
57.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
57.23 + *
57.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
57.25 + * or visit www.oracle.com if you need additional information or have any
57.26 + * questions.
57.27 + */
57.28 +
57.29 +package java.util;
57.30 +
57.31 +/**
57.32 + * Thrown by methods in the <code>Stack</code> class to indicate
57.33 + * that the stack is empty.
57.34 + *
57.35 + * @author Jonathan Payne
57.36 + * @see java.util.Stack
57.37 + * @since JDK1.0
57.38 + */
57.39 +public
57.40 +class EmptyStackException extends RuntimeException {
57.41 + private static final long serialVersionUID = 5084686378493302095L;
57.42 +
57.43 + /**
57.44 + * Constructs a new <code>EmptyStackException</code> with <tt>null</tt>
57.45 + * as its error message string.
57.46 + */
57.47 + public EmptyStackException() {
57.48 + }
57.49 +}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/emul/compact/src/main/java/java/util/EventListener.java Tue Feb 05 17:04:22 2013 +0100
58.3 @@ -0,0 +1,33 @@
58.4 +/*
58.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
58.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
58.7 + *
58.8 + * This code is free software; you can redistribute it and/or modify it
58.9 + * under the terms of the GNU General Public License version 2 only, as
58.10 + * published by the Free Software Foundation. Oracle designates this
58.11 + * particular file as subject to the "Classpath" exception as provided
58.12 + * by Oracle in the LICENSE file that accompanied this code.
58.13 + *
58.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
58.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
58.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
58.17 + * version 2 for more details (a copy is included in the LICENSE file that
58.18 + * accompanied this code).
58.19 + *
58.20 + * You should have received a copy of the GNU General Public License version
58.21 + * 2 along with this work; if not, write to the Free Software Foundation,
58.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
58.23 + *
58.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
58.25 + * or visit www.oracle.com if you need additional information or have any
58.26 + * questions.
58.27 + */
58.28 +
58.29 +package java.util;
58.30 +
58.31 +/**
58.32 + * A tagging interface that all event listener interfaces must extend.
58.33 + * @since JDK1.1
58.34 + */
58.35 +public interface EventListener {
58.36 +}
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/emul/compact/src/main/java/java/util/EventListenerProxy.java Tue Feb 05 17:04:22 2013 +0100
59.3 @@ -0,0 +1,75 @@
59.4 +/*
59.5 + * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
59.7 + *
59.8 + * This code is free software; you can redistribute it and/or modify it
59.9 + * under the terms of the GNU General Public License version 2 only, as
59.10 + * published by the Free Software Foundation. Oracle designates this
59.11 + * particular file as subject to the "Classpath" exception as provided
59.12 + * by Oracle in the LICENSE file that accompanied this code.
59.13 + *
59.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
59.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
59.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
59.17 + * version 2 for more details (a copy is included in the LICENSE file that
59.18 + * accompanied this code).
59.19 + *
59.20 + * You should have received a copy of the GNU General Public License version
59.21 + * 2 along with this work; if not, write to the Free Software Foundation,
59.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
59.23 + *
59.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
59.25 + * or visit www.oracle.com if you need additional information or have any
59.26 + * questions.
59.27 + */
59.28 +
59.29 +package java.util;
59.30 +
59.31 +/**
59.32 + * An abstract wrapper class for an {@code EventListener} class
59.33 + * which associates a set of additional parameters with the listener.
59.34 + * Subclasses must provide the storage and accessor methods
59.35 + * for the additional arguments or parameters.
59.36 + * <p>
59.37 + * For example, a bean which supports named properties
59.38 + * would have a two argument method signature for adding
59.39 + * a {@code PropertyChangeListener} for a property:
59.40 + * <pre>
59.41 + * public void addPropertyChangeListener(String propertyName,
59.42 + * PropertyChangeListener listener)
59.43 + * </pre>
59.44 + * If the bean also implemented the zero argument get listener method:
59.45 + * <pre>
59.46 + * public PropertyChangeListener[] getPropertyChangeListeners()
59.47 + * </pre>
59.48 + * then the array may contain inner {@code PropertyChangeListeners}
59.49 + * which are also {@code PropertyChangeListenerProxy} objects.
59.50 + * <p>
59.51 + * If the calling method is interested in retrieving the named property
59.52 + * then it would have to test the element to see if it is a proxy class.
59.53 + *
59.54 + * @since 1.4
59.55 + */
59.56 +public abstract class EventListenerProxy<T extends EventListener>
59.57 + implements EventListener {
59.58 +
59.59 + private final T listener;
59.60 +
59.61 + /**
59.62 + * Creates a proxy for the specified listener.
59.63 + *
59.64 + * @param listener the listener object
59.65 + */
59.66 + public EventListenerProxy(T listener) {
59.67 + this.listener = listener;
59.68 + }
59.69 +
59.70 + /**
59.71 + * Returns the listener associated with the proxy.
59.72 + *
59.73 + * @return the listener associated with the proxy
59.74 + */
59.75 + public T getListener() {
59.76 + return this.listener;
59.77 + }
59.78 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/emul/compact/src/main/java/java/util/EventObject.java Tue Feb 05 17:04:22 2013 +0100
60.3 @@ -0,0 +1,78 @@
60.4 +/*
60.5 + * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
60.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
60.7 + *
60.8 + * This code is free software; you can redistribute it and/or modify it
60.9 + * under the terms of the GNU General Public License version 2 only, as
60.10 + * published by the Free Software Foundation. Oracle designates this
60.11 + * particular file as subject to the "Classpath" exception as provided
60.12 + * by Oracle in the LICENSE file that accompanied this code.
60.13 + *
60.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
60.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
60.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
60.17 + * version 2 for more details (a copy is included in the LICENSE file that
60.18 + * accompanied this code).
60.19 + *
60.20 + * You should have received a copy of the GNU General Public License version
60.21 + * 2 along with this work; if not, write to the Free Software Foundation,
60.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
60.23 + *
60.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
60.25 + * or visit www.oracle.com if you need additional information or have any
60.26 + * questions.
60.27 + */
60.28 +
60.29 +package java.util;
60.30 +
60.31 +/**
60.32 + * <p>
60.33 + * The root class from which all event state objects shall be derived.
60.34 + * <p>
60.35 + * All Events are constructed with a reference to the object, the "source",
60.36 + * that is logically deemed to be the object upon which the Event in question
60.37 + * initially occurred upon.
60.38 + *
60.39 + * @since JDK1.1
60.40 + */
60.41 +
60.42 +public class EventObject implements java.io.Serializable {
60.43 +
60.44 + private static final long serialVersionUID = 5516075349620653480L;
60.45 +
60.46 + /**
60.47 + * The object on which the Event initially occurred.
60.48 + */
60.49 + protected transient Object source;
60.50 +
60.51 + /**
60.52 + * Constructs a prototypical Event.
60.53 + *
60.54 + * @param source The object on which the Event initially occurred.
60.55 + * @exception IllegalArgumentException if source is null.
60.56 + */
60.57 + public EventObject(Object source) {
60.58 + if (source == null)
60.59 + throw new IllegalArgumentException("null source");
60.60 +
60.61 + this.source = source;
60.62 + }
60.63 +
60.64 + /**
60.65 + * The object on which the Event initially occurred.
60.66 + *
60.67 + * @return The object on which the Event initially occurred.
60.68 + */
60.69 + public Object getSource() {
60.70 + return source;
60.71 + }
60.72 +
60.73 + /**
60.74 + * Returns a String representation of this EventObject.
60.75 + *
60.76 + * @return A a String representation of this EventObject.
60.77 + */
60.78 + public String toString() {
60.79 + return getClass().getName() + "[source=" + source + "]";
60.80 + }
60.81 +}
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/emul/compact/src/main/java/java/util/Hashtable.java Tue Feb 05 17:04:22 2013 +0100
61.3 @@ -0,0 +1,1005 @@
61.4 +/*
61.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
61.7 + *
61.8 + * This code is free software; you can redistribute it and/or modify it
61.9 + * under the terms of the GNU General Public License version 2 only, as
61.10 + * published by the Free Software Foundation. Oracle designates this
61.11 + * particular file as subject to the "Classpath" exception as provided
61.12 + * by Oracle in the LICENSE file that accompanied this code.
61.13 + *
61.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
61.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
61.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
61.17 + * version 2 for more details (a copy is included in the LICENSE file that
61.18 + * accompanied this code).
61.19 + *
61.20 + * You should have received a copy of the GNU General Public License version
61.21 + * 2 along with this work; if not, write to the Free Software Foundation,
61.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
61.23 + *
61.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
61.25 + * or visit www.oracle.com if you need additional information or have any
61.26 + * questions.
61.27 + */
61.28 +
61.29 +package java.util;
61.30 +import java.io.*;
61.31 +
61.32 +/**
61.33 + * This class implements a hash table, which maps keys to values. Any
61.34 + * non-<code>null</code> object can be used as a key or as a value. <p>
61.35 + *
61.36 + * To successfully store and retrieve objects from a hashtable, the
61.37 + * objects used as keys must implement the <code>hashCode</code>
61.38 + * method and the <code>equals</code> method. <p>
61.39 + *
61.40 + * An instance of <code>Hashtable</code> has two parameters that affect its
61.41 + * performance: <i>initial capacity</i> and <i>load factor</i>. The
61.42 + * <i>capacity</i> is the number of <i>buckets</i> in the hash table, and the
61.43 + * <i>initial capacity</i> is simply the capacity at the time the hash table
61.44 + * is created. Note that the hash table is <i>open</i>: in the case of a "hash
61.45 + * collision", a single bucket stores multiple entries, which must be searched
61.46 + * sequentially. The <i>load factor</i> is a measure of how full the hash
61.47 + * table is allowed to get before its capacity is automatically increased.
61.48 + * The initial capacity and load factor parameters are merely hints to
61.49 + * the implementation. The exact details as to when and whether the rehash
61.50 + * method is invoked are implementation-dependent.<p>
61.51 + *
61.52 + * Generally, the default load factor (.75) offers a good tradeoff between
61.53 + * time and space costs. Higher values decrease the space overhead but
61.54 + * increase the time cost to look up an entry (which is reflected in most
61.55 + * <tt>Hashtable</tt> operations, including <tt>get</tt> and <tt>put</tt>).<p>
61.56 + *
61.57 + * The initial capacity controls a tradeoff between wasted space and the
61.58 + * need for <code>rehash</code> operations, which are time-consuming.
61.59 + * No <code>rehash</code> operations will <i>ever</i> occur if the initial
61.60 + * capacity is greater than the maximum number of entries the
61.61 + * <tt>Hashtable</tt> will contain divided by its load factor. However,
61.62 + * setting the initial capacity too high can waste space.<p>
61.63 + *
61.64 + * If many entries are to be made into a <code>Hashtable</code>,
61.65 + * creating it with a sufficiently large capacity may allow the
61.66 + * entries to be inserted more efficiently than letting it perform
61.67 + * automatic rehashing as needed to grow the table. <p>
61.68 + *
61.69 + * This example creates a hashtable of numbers. It uses the names of
61.70 + * the numbers as keys:
61.71 + * <pre> {@code
61.72 + * Hashtable<String, Integer> numbers
61.73 + * = new Hashtable<String, Integer>();
61.74 + * numbers.put("one", 1);
61.75 + * numbers.put("two", 2);
61.76 + * numbers.put("three", 3);}</pre>
61.77 + *
61.78 + * <p>To retrieve a number, use the following code:
61.79 + * <pre> {@code
61.80 + * Integer n = numbers.get("two");
61.81 + * if (n != null) {
61.82 + * System.out.println("two = " + n);
61.83 + * }}</pre>
61.84 + *
61.85 + * <p>The iterators returned by the <tt>iterator</tt> method of the collections
61.86 + * returned by all of this class's "collection view methods" are
61.87 + * <em>fail-fast</em>: if the Hashtable is structurally modified at any time
61.88 + * after the iterator is created, in any way except through the iterator's own
61.89 + * <tt>remove</tt> method, the iterator will throw a {@link
61.90 + * ConcurrentModificationException}. Thus, in the face of concurrent
61.91 + * modification, the iterator fails quickly and cleanly, rather than risking
61.92 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
61.93 + * The Enumerations returned by Hashtable's keys and elements methods are
61.94 + * <em>not</em> fail-fast.
61.95 + *
61.96 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
61.97 + * as it is, generally speaking, impossible to make any hard guarantees in the
61.98 + * presence of unsynchronized concurrent modification. Fail-fast iterators
61.99 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
61.100 + * Therefore, it would be wrong to write a program that depended on this
61.101 + * exception for its correctness: <i>the fail-fast behavior of iterators
61.102 + * should be used only to detect bugs.</i>
61.103 + *
61.104 + * <p>As of the Java 2 platform v1.2, this class was retrofitted to
61.105 + * implement the {@link Map} interface, making it a member of the
61.106 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
61.107 + *
61.108 + * Java Collections Framework</a>. Unlike the new collection
61.109 + * implementations, {@code Hashtable} is synchronized. If a
61.110 + * thread-safe implementation is not needed, it is recommended to use
61.111 + * {@link HashMap} in place of {@code Hashtable}. If a thread-safe
61.112 + * highly-concurrent implementation is desired, then it is recommended
61.113 + * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
61.114 + * {@code Hashtable}.
61.115 + *
61.116 + * @author Arthur van Hoff
61.117 + * @author Josh Bloch
61.118 + * @author Neal Gafter
61.119 + * @see Object#equals(java.lang.Object)
61.120 + * @see Object#hashCode()
61.121 + * @see Hashtable#rehash()
61.122 + * @see Collection
61.123 + * @see Map
61.124 + * @see HashMap
61.125 + * @see TreeMap
61.126 + * @since JDK1.0
61.127 + */
61.128 +public class Hashtable<K,V>
61.129 + extends Dictionary<K,V>
61.130 + implements Map<K,V>, Cloneable, java.io.Serializable {
61.131 +
61.132 + /**
61.133 + * The hash table data.
61.134 + */
61.135 + private transient Entry[] table;
61.136 +
61.137 + /**
61.138 + * The total number of entries in the hash table.
61.139 + */
61.140 + private transient int count;
61.141 +
61.142 + /**
61.143 + * The table is rehashed when its size exceeds this threshold. (The
61.144 + * value of this field is (int)(capacity * loadFactor).)
61.145 + *
61.146 + * @serial
61.147 + */
61.148 + private int threshold;
61.149 +
61.150 + /**
61.151 + * The load factor for the hashtable.
61.152 + *
61.153 + * @serial
61.154 + */
61.155 + private float loadFactor;
61.156 +
61.157 + /**
61.158 + * The number of times this Hashtable has been structurally modified
61.159 + * Structural modifications are those that change the number of entries in
61.160 + * the Hashtable or otherwise modify its internal structure (e.g.,
61.161 + * rehash). This field is used to make iterators on Collection-views of
61.162 + * the Hashtable fail-fast. (See ConcurrentModificationException).
61.163 + */
61.164 + private transient int modCount = 0;
61.165 +
61.166 + /** use serialVersionUID from JDK 1.0.2 for interoperability */
61.167 + private static final long serialVersionUID = 1421746759512286392L;
61.168 +
61.169 + /**
61.170 + * Constructs a new, empty hashtable with the specified initial
61.171 + * capacity and the specified load factor.
61.172 + *
61.173 + * @param initialCapacity the initial capacity of the hashtable.
61.174 + * @param loadFactor the load factor of the hashtable.
61.175 + * @exception IllegalArgumentException if the initial capacity is less
61.176 + * than zero, or if the load factor is nonpositive.
61.177 + */
61.178 + public Hashtable(int initialCapacity, float loadFactor) {
61.179 + if (initialCapacity < 0)
61.180 + throw new IllegalArgumentException("Illegal Capacity: "+
61.181 + initialCapacity);
61.182 + if (loadFactor <= 0 || Float.isNaN(loadFactor))
61.183 + throw new IllegalArgumentException("Illegal Load: "+loadFactor);
61.184 +
61.185 + if (initialCapacity==0)
61.186 + initialCapacity = 1;
61.187 + this.loadFactor = loadFactor;
61.188 + table = new Entry[initialCapacity];
61.189 + threshold = (int)(initialCapacity * loadFactor);
61.190 + }
61.191 +
61.192 + /**
61.193 + * Constructs a new, empty hashtable with the specified initial capacity
61.194 + * and default load factor (0.75).
61.195 + *
61.196 + * @param initialCapacity the initial capacity of the hashtable.
61.197 + * @exception IllegalArgumentException if the initial capacity is less
61.198 + * than zero.
61.199 + */
61.200 + public Hashtable(int initialCapacity) {
61.201 + this(initialCapacity, 0.75f);
61.202 + }
61.203 +
61.204 + /**
61.205 + * Constructs a new, empty hashtable with a default initial capacity (11)
61.206 + * and load factor (0.75).
61.207 + */
61.208 + public Hashtable() {
61.209 + this(11, 0.75f);
61.210 + }
61.211 +
61.212 + /**
61.213 + * Constructs a new hashtable with the same mappings as the given
61.214 + * Map. The hashtable is created with an initial capacity sufficient to
61.215 + * hold the mappings in the given Map and a default load factor (0.75).
61.216 + *
61.217 + * @param t the map whose mappings are to be placed in this map.
61.218 + * @throws NullPointerException if the specified map is null.
61.219 + * @since 1.2
61.220 + */
61.221 + public Hashtable(Map<? extends K, ? extends V> t) {
61.222 + this(Math.max(2*t.size(), 11), 0.75f);
61.223 + putAll(t);
61.224 + }
61.225 +
61.226 + /**
61.227 + * Returns the number of keys in this hashtable.
61.228 + *
61.229 + * @return the number of keys in this hashtable.
61.230 + */
61.231 + public synchronized int size() {
61.232 + return count;
61.233 + }
61.234 +
61.235 + /**
61.236 + * Tests if this hashtable maps no keys to values.
61.237 + *
61.238 + * @return <code>true</code> if this hashtable maps no keys to values;
61.239 + * <code>false</code> otherwise.
61.240 + */
61.241 + public synchronized boolean isEmpty() {
61.242 + return count == 0;
61.243 + }
61.244 +
61.245 + /**
61.246 + * Returns an enumeration of the keys in this hashtable.
61.247 + *
61.248 + * @return an enumeration of the keys in this hashtable.
61.249 + * @see Enumeration
61.250 + * @see #elements()
61.251 + * @see #keySet()
61.252 + * @see Map
61.253 + */
61.254 + public synchronized Enumeration<K> keys() {
61.255 + return this.<K>getEnumeration(KEYS);
61.256 + }
61.257 +
61.258 + /**
61.259 + * Returns an enumeration of the values in this hashtable.
61.260 + * Use the Enumeration methods on the returned object to fetch the elements
61.261 + * sequentially.
61.262 + *
61.263 + * @return an enumeration of the values in this hashtable.
61.264 + * @see java.util.Enumeration
61.265 + * @see #keys()
61.266 + * @see #values()
61.267 + * @see Map
61.268 + */
61.269 + public synchronized Enumeration<V> elements() {
61.270 + return this.<V>getEnumeration(VALUES);
61.271 + }
61.272 +
61.273 + /**
61.274 + * Tests if some key maps into the specified value in this hashtable.
61.275 + * This operation is more expensive than the {@link #containsKey
61.276 + * containsKey} method.
61.277 + *
61.278 + * <p>Note that this method is identical in functionality to
61.279 + * {@link #containsValue containsValue}, (which is part of the
61.280 + * {@link Map} interface in the collections framework).
61.281 + *
61.282 + * @param value a value to search for
61.283 + * @return <code>true</code> if and only if some key maps to the
61.284 + * <code>value</code> argument in this hashtable as
61.285 + * determined by the <tt>equals</tt> method;
61.286 + * <code>false</code> otherwise.
61.287 + * @exception NullPointerException if the value is <code>null</code>
61.288 + */
61.289 + public synchronized boolean contains(Object value) {
61.290 + if (value == null) {
61.291 + throw new NullPointerException();
61.292 + }
61.293 +
61.294 + Entry tab[] = table;
61.295 + for (int i = tab.length ; i-- > 0 ;) {
61.296 + for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
61.297 + if (e.value.equals(value)) {
61.298 + return true;
61.299 + }
61.300 + }
61.301 + }
61.302 + return false;
61.303 + }
61.304 +
61.305 + /**
61.306 + * Returns true if this hashtable maps one or more keys to this value.
61.307 + *
61.308 + * <p>Note that this method is identical in functionality to {@link
61.309 + * #contains contains} (which predates the {@link Map} interface).
61.310 + *
61.311 + * @param value value whose presence in this hashtable is to be tested
61.312 + * @return <tt>true</tt> if this map maps one or more keys to the
61.313 + * specified value
61.314 + * @throws NullPointerException if the value is <code>null</code>
61.315 + * @since 1.2
61.316 + */
61.317 + public boolean containsValue(Object value) {
61.318 + return contains(value);
61.319 + }
61.320 +
61.321 + /**
61.322 + * Tests if the specified object is a key in this hashtable.
61.323 + *
61.324 + * @param key possible key
61.325 + * @return <code>true</code> if and only if the specified object
61.326 + * is a key in this hashtable, as determined by the
61.327 + * <tt>equals</tt> method; <code>false</code> otherwise.
61.328 + * @throws NullPointerException if the key is <code>null</code>
61.329 + * @see #contains(Object)
61.330 + */
61.331 + public synchronized boolean containsKey(Object key) {
61.332 + Entry tab[] = table;
61.333 + int hash = key.hashCode();
61.334 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.335 + for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
61.336 + if ((e.hash == hash) && e.key.equals(key)) {
61.337 + return true;
61.338 + }
61.339 + }
61.340 + return false;
61.341 + }
61.342 +
61.343 + /**
61.344 + * Returns the value to which the specified key is mapped,
61.345 + * or {@code null} if this map contains no mapping for the key.
61.346 + *
61.347 + * <p>More formally, if this map contains a mapping from a key
61.348 + * {@code k} to a value {@code v} such that {@code (key.equals(k))},
61.349 + * then this method returns {@code v}; otherwise it returns
61.350 + * {@code null}. (There can be at most one such mapping.)
61.351 + *
61.352 + * @param key the key whose associated value is to be returned
61.353 + * @return the value to which the specified key is mapped, or
61.354 + * {@code null} if this map contains no mapping for the key
61.355 + * @throws NullPointerException if the specified key is null
61.356 + * @see #put(Object, Object)
61.357 + */
61.358 + public synchronized V get(Object key) {
61.359 + Entry tab[] = table;
61.360 + int hash = key.hashCode();
61.361 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.362 + for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
61.363 + if ((e.hash == hash) && e.key.equals(key)) {
61.364 + return e.value;
61.365 + }
61.366 + }
61.367 + return null;
61.368 + }
61.369 +
61.370 + /**
61.371 + * The maximum size of array to allocate.
61.372 + * Some VMs reserve some header words in an array.
61.373 + * Attempts to allocate larger arrays may result in
61.374 + * OutOfMemoryError: Requested array size exceeds VM limit
61.375 + */
61.376 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
61.377 +
61.378 + /**
61.379 + * Increases the capacity of and internally reorganizes this
61.380 + * hashtable, in order to accommodate and access its entries more
61.381 + * efficiently. This method is called automatically when the
61.382 + * number of keys in the hashtable exceeds this hashtable's capacity
61.383 + * and load factor.
61.384 + */
61.385 + protected void rehash() {
61.386 + int oldCapacity = table.length;
61.387 + Entry[] oldMap = table;
61.388 +
61.389 + // overflow-conscious code
61.390 + int newCapacity = (oldCapacity << 1) + 1;
61.391 + if (newCapacity - MAX_ARRAY_SIZE > 0) {
61.392 + if (oldCapacity == MAX_ARRAY_SIZE)
61.393 + // Keep running with MAX_ARRAY_SIZE buckets
61.394 + return;
61.395 + newCapacity = MAX_ARRAY_SIZE;
61.396 + }
61.397 + Entry[] newMap = new Entry[newCapacity];
61.398 +
61.399 + modCount++;
61.400 + threshold = (int)(newCapacity * loadFactor);
61.401 + table = newMap;
61.402 +
61.403 + for (int i = oldCapacity ; i-- > 0 ;) {
61.404 + for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
61.405 + Entry<K,V> e = old;
61.406 + old = old.next;
61.407 +
61.408 + int index = (e.hash & 0x7FFFFFFF) % newCapacity;
61.409 + e.next = newMap[index];
61.410 + newMap[index] = e;
61.411 + }
61.412 + }
61.413 + }
61.414 +
61.415 + /**
61.416 + * Maps the specified <code>key</code> to the specified
61.417 + * <code>value</code> in this hashtable. Neither the key nor the
61.418 + * value can be <code>null</code>. <p>
61.419 + *
61.420 + * The value can be retrieved by calling the <code>get</code> method
61.421 + * with a key that is equal to the original key.
61.422 + *
61.423 + * @param key the hashtable key
61.424 + * @param value the value
61.425 + * @return the previous value of the specified key in this hashtable,
61.426 + * or <code>null</code> if it did not have one
61.427 + * @exception NullPointerException if the key or value is
61.428 + * <code>null</code>
61.429 + * @see Object#equals(Object)
61.430 + * @see #get(Object)
61.431 + */
61.432 + public synchronized V put(K key, V value) {
61.433 + // Make sure the value is not null
61.434 + if (value == null) {
61.435 + throw new NullPointerException();
61.436 + }
61.437 +
61.438 + // Makes sure the key is not already in the hashtable.
61.439 + Entry tab[] = table;
61.440 + int hash = key.hashCode();
61.441 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.442 + for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
61.443 + if ((e.hash == hash) && e.key.equals(key)) {
61.444 + V old = e.value;
61.445 + e.value = value;
61.446 + return old;
61.447 + }
61.448 + }
61.449 +
61.450 + modCount++;
61.451 + if (count >= threshold) {
61.452 + // Rehash the table if the threshold is exceeded
61.453 + rehash();
61.454 +
61.455 + tab = table;
61.456 + index = (hash & 0x7FFFFFFF) % tab.length;
61.457 + }
61.458 +
61.459 + // Creates the new entry.
61.460 + Entry<K,V> e = tab[index];
61.461 + tab[index] = new Entry<>(hash, key, value, e);
61.462 + count++;
61.463 + return null;
61.464 + }
61.465 +
61.466 + /**
61.467 + * Removes the key (and its corresponding value) from this
61.468 + * hashtable. This method does nothing if the key is not in the hashtable.
61.469 + *
61.470 + * @param key the key that needs to be removed
61.471 + * @return the value to which the key had been mapped in this hashtable,
61.472 + * or <code>null</code> if the key did not have a mapping
61.473 + * @throws NullPointerException if the key is <code>null</code>
61.474 + */
61.475 + public synchronized V remove(Object key) {
61.476 + Entry tab[] = table;
61.477 + int hash = key.hashCode();
61.478 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.479 + for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
61.480 + if ((e.hash == hash) && e.key.equals(key)) {
61.481 + modCount++;
61.482 + if (prev != null) {
61.483 + prev.next = e.next;
61.484 + } else {
61.485 + tab[index] = e.next;
61.486 + }
61.487 + count--;
61.488 + V oldValue = e.value;
61.489 + e.value = null;
61.490 + return oldValue;
61.491 + }
61.492 + }
61.493 + return null;
61.494 + }
61.495 +
61.496 + /**
61.497 + * Copies all of the mappings from the specified map to this hashtable.
61.498 + * These mappings will replace any mappings that this hashtable had for any
61.499 + * of the keys currently in the specified map.
61.500 + *
61.501 + * @param t mappings to be stored in this map
61.502 + * @throws NullPointerException if the specified map is null
61.503 + * @since 1.2
61.504 + */
61.505 + public synchronized void putAll(Map<? extends K, ? extends V> t) {
61.506 + for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
61.507 + put(e.getKey(), e.getValue());
61.508 + }
61.509 +
61.510 + /**
61.511 + * Clears this hashtable so that it contains no keys.
61.512 + */
61.513 + public synchronized void clear() {
61.514 + Entry tab[] = table;
61.515 + modCount++;
61.516 + for (int index = tab.length; --index >= 0; )
61.517 + tab[index] = null;
61.518 + count = 0;
61.519 + }
61.520 +
61.521 + /**
61.522 + * Creates a shallow copy of this hashtable. All the structure of the
61.523 + * hashtable itself is copied, but the keys and values are not cloned.
61.524 + * This is a relatively expensive operation.
61.525 + *
61.526 + * @return a clone of the hashtable
61.527 + */
61.528 + public synchronized Object clone() {
61.529 + try {
61.530 + Hashtable<K,V> t = (Hashtable<K,V>) super.clone();
61.531 + t.table = new Entry[table.length];
61.532 + for (int i = table.length ; i-- > 0 ; ) {
61.533 + t.table[i] = (table[i] != null)
61.534 + ? (Entry<K,V>) table[i].clone() : null;
61.535 + }
61.536 + t.keySet = null;
61.537 + t.entrySet = null;
61.538 + t.values = null;
61.539 + t.modCount = 0;
61.540 + return t;
61.541 + } catch (CloneNotSupportedException e) {
61.542 + // this shouldn't happen, since we are Cloneable
61.543 + throw new InternalError();
61.544 + }
61.545 + }
61.546 +
61.547 + /**
61.548 + * Returns a string representation of this <tt>Hashtable</tt> object
61.549 + * in the form of a set of entries, enclosed in braces and separated
61.550 + * by the ASCII characters "<tt>, </tt>" (comma and space). Each
61.551 + * entry is rendered as the key, an equals sign <tt>=</tt>, and the
61.552 + * associated element, where the <tt>toString</tt> method is used to
61.553 + * convert the key and element to strings.
61.554 + *
61.555 + * @return a string representation of this hashtable
61.556 + */
61.557 + public synchronized String toString() {
61.558 + int max = size() - 1;
61.559 + if (max == -1)
61.560 + return "{}";
61.561 +
61.562 + StringBuilder sb = new StringBuilder();
61.563 + Iterator<Map.Entry<K,V>> it = entrySet().iterator();
61.564 +
61.565 + sb.append('{');
61.566 + for (int i = 0; ; i++) {
61.567 + Map.Entry<K,V> e = it.next();
61.568 + K key = e.getKey();
61.569 + V value = e.getValue();
61.570 + sb.append(key == this ? "(this Map)" : key.toString());
61.571 + sb.append('=');
61.572 + sb.append(value == this ? "(this Map)" : value.toString());
61.573 +
61.574 + if (i == max)
61.575 + return sb.append('}').toString();
61.576 + sb.append(", ");
61.577 + }
61.578 + }
61.579 +
61.580 +
61.581 + private <T> Enumeration<T> getEnumeration(int type) {
61.582 + if (count == 0) {
61.583 + return Collections.emptyEnumeration();
61.584 + } else {
61.585 + return new Enumerator<>(type, false);
61.586 + }
61.587 + }
61.588 +
61.589 + private <T> Iterator<T> getIterator(int type) {
61.590 + if (count == 0) {
61.591 + return Collections.emptyIterator();
61.592 + } else {
61.593 + return new Enumerator<>(type, true);
61.594 + }
61.595 + }
61.596 +
61.597 + // Views
61.598 +
61.599 + /**
61.600 + * Each of these fields are initialized to contain an instance of the
61.601 + * appropriate view the first time this view is requested. The views are
61.602 + * stateless, so there's no reason to create more than one of each.
61.603 + */
61.604 + private transient volatile Set<K> keySet = null;
61.605 + private transient volatile Set<Map.Entry<K,V>> entrySet = null;
61.606 + private transient volatile Collection<V> values = null;
61.607 +
61.608 + /**
61.609 + * Returns a {@link Set} view of the keys contained in this map.
61.610 + * The set is backed by the map, so changes to the map are
61.611 + * reflected in the set, and vice-versa. If the map is modified
61.612 + * while an iteration over the set is in progress (except through
61.613 + * the iterator's own <tt>remove</tt> operation), the results of
61.614 + * the iteration are undefined. The set supports element removal,
61.615 + * which removes the corresponding mapping from the map, via the
61.616 + * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
61.617 + * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
61.618 + * operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
61.619 + * operations.
61.620 + *
61.621 + * @since 1.2
61.622 + */
61.623 + public Set<K> keySet() {
61.624 + if (keySet == null)
61.625 + keySet = Collections.synchronizedSet(new KeySet(), this);
61.626 + return keySet;
61.627 + }
61.628 +
61.629 + private class KeySet extends AbstractSet<K> {
61.630 + public Iterator<K> iterator() {
61.631 + return getIterator(KEYS);
61.632 + }
61.633 + public int size() {
61.634 + return count;
61.635 + }
61.636 + public boolean contains(Object o) {
61.637 + return containsKey(o);
61.638 + }
61.639 + public boolean remove(Object o) {
61.640 + return Hashtable.this.remove(o) != null;
61.641 + }
61.642 + public void clear() {
61.643 + Hashtable.this.clear();
61.644 + }
61.645 + }
61.646 +
61.647 + /**
61.648 + * Returns a {@link Set} view of the mappings contained in this map.
61.649 + * The set is backed by the map, so changes to the map are
61.650 + * reflected in the set, and vice-versa. If the map is modified
61.651 + * while an iteration over the set is in progress (except through
61.652 + * the iterator's own <tt>remove</tt> operation, or through the
61.653 + * <tt>setValue</tt> operation on a map entry returned by the
61.654 + * iterator) the results of the iteration are undefined. The set
61.655 + * supports element removal, which removes the corresponding
61.656 + * mapping from the map, via the <tt>Iterator.remove</tt>,
61.657 + * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
61.658 + * <tt>clear</tt> operations. It does not support the
61.659 + * <tt>add</tt> or <tt>addAll</tt> operations.
61.660 + *
61.661 + * @since 1.2
61.662 + */
61.663 + public Set<Map.Entry<K,V>> entrySet() {
61.664 + if (entrySet==null)
61.665 + entrySet = Collections.synchronizedSet(new EntrySet(), this);
61.666 + return entrySet;
61.667 + }
61.668 +
61.669 + private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
61.670 + public Iterator<Map.Entry<K,V>> iterator() {
61.671 + return getIterator(ENTRIES);
61.672 + }
61.673 +
61.674 + public boolean add(Map.Entry<K,V> o) {
61.675 + return super.add(o);
61.676 + }
61.677 +
61.678 + public boolean contains(Object o) {
61.679 + if (!(o instanceof Map.Entry))
61.680 + return false;
61.681 + Map.Entry entry = (Map.Entry)o;
61.682 + Object key = entry.getKey();
61.683 + Entry[] tab = table;
61.684 + int hash = key.hashCode();
61.685 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.686 +
61.687 + for (Entry e = tab[index]; e != null; e = e.next)
61.688 + if (e.hash==hash && e.equals(entry))
61.689 + return true;
61.690 + return false;
61.691 + }
61.692 +
61.693 + public boolean remove(Object o) {
61.694 + if (!(o instanceof Map.Entry))
61.695 + return false;
61.696 + Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
61.697 + K key = entry.getKey();
61.698 + Entry[] tab = table;
61.699 + int hash = key.hashCode();
61.700 + int index = (hash & 0x7FFFFFFF) % tab.length;
61.701 +
61.702 + for (Entry<K,V> e = tab[index], prev = null; e != null;
61.703 + prev = e, e = e.next) {
61.704 + if (e.hash==hash && e.equals(entry)) {
61.705 + modCount++;
61.706 + if (prev != null)
61.707 + prev.next = e.next;
61.708 + else
61.709 + tab[index] = e.next;
61.710 +
61.711 + count--;
61.712 + e.value = null;
61.713 + return true;
61.714 + }
61.715 + }
61.716 + return false;
61.717 + }
61.718 +
61.719 + public int size() {
61.720 + return count;
61.721 + }
61.722 +
61.723 + public void clear() {
61.724 + Hashtable.this.clear();
61.725 + }
61.726 + }
61.727 +
61.728 + /**
61.729 + * Returns a {@link Collection} view of the values contained in this map.
61.730 + * The collection is backed by the map, so changes to the map are
61.731 + * reflected in the collection, and vice-versa. If the map is
61.732 + * modified while an iteration over the collection is in progress
61.733 + * (except through the iterator's own <tt>remove</tt> operation),
61.734 + * the results of the iteration are undefined. The collection
61.735 + * supports element removal, which removes the corresponding
61.736 + * mapping from the map, via the <tt>Iterator.remove</tt>,
61.737 + * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
61.738 + * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
61.739 + * support the <tt>add</tt> or <tt>addAll</tt> operations.
61.740 + *
61.741 + * @since 1.2
61.742 + */
61.743 + public Collection<V> values() {
61.744 + if (values==null)
61.745 + values = Collections.synchronizedCollection(new ValueCollection(),
61.746 + this);
61.747 + return values;
61.748 + }
61.749 +
61.750 + private class ValueCollection extends AbstractCollection<V> {
61.751 + public Iterator<V> iterator() {
61.752 + return getIterator(VALUES);
61.753 + }
61.754 + public int size() {
61.755 + return count;
61.756 + }
61.757 + public boolean contains(Object o) {
61.758 + return containsValue(o);
61.759 + }
61.760 + public void clear() {
61.761 + Hashtable.this.clear();
61.762 + }
61.763 + }
61.764 +
61.765 + // Comparison and hashing
61.766 +
61.767 + /**
61.768 + * Compares the specified Object with this Map for equality,
61.769 + * as per the definition in the Map interface.
61.770 + *
61.771 + * @param o object to be compared for equality with this hashtable
61.772 + * @return true if the specified Object is equal to this Map
61.773 + * @see Map#equals(Object)
61.774 + * @since 1.2
61.775 + */
61.776 + public synchronized boolean equals(Object o) {
61.777 + if (o == this)
61.778 + return true;
61.779 +
61.780 + if (!(o instanceof Map))
61.781 + return false;
61.782 + Map<K,V> t = (Map<K,V>) o;
61.783 + if (t.size() != size())
61.784 + return false;
61.785 +
61.786 + try {
61.787 + Iterator<Map.Entry<K,V>> i = entrySet().iterator();
61.788 + while (i.hasNext()) {
61.789 + Map.Entry<K,V> e = i.next();
61.790 + K key = e.getKey();
61.791 + V value = e.getValue();
61.792 + if (value == null) {
61.793 + if (!(t.get(key)==null && t.containsKey(key)))
61.794 + return false;
61.795 + } else {
61.796 + if (!value.equals(t.get(key)))
61.797 + return false;
61.798 + }
61.799 + }
61.800 + } catch (ClassCastException unused) {
61.801 + return false;
61.802 + } catch (NullPointerException unused) {
61.803 + return false;
61.804 + }
61.805 +
61.806 + return true;
61.807 + }
61.808 +
61.809 + /**
61.810 + * Returns the hash code value for this Map as per the definition in the
61.811 + * Map interface.
61.812 + *
61.813 + * @see Map#hashCode()
61.814 + * @since 1.2
61.815 + */
61.816 + public synchronized int hashCode() {
61.817 + /*
61.818 + * This code detects the recursion caused by computing the hash code
61.819 + * of a self-referential hash table and prevents the stack overflow
61.820 + * that would otherwise result. This allows certain 1.1-era
61.821 + * applets with self-referential hash tables to work. This code
61.822 + * abuses the loadFactor field to do double-duty as a hashCode
61.823 + * in progress flag, so as not to worsen the space performance.
61.824 + * A negative load factor indicates that hash code computation is
61.825 + * in progress.
61.826 + */
61.827 + int h = 0;
61.828 + if (count == 0 || loadFactor < 0)
61.829 + return h; // Returns zero
61.830 +
61.831 + loadFactor = -loadFactor; // Mark hashCode computation in progress
61.832 + Entry[] tab = table;
61.833 + for (int i = 0; i < tab.length; i++)
61.834 + for (Entry e = tab[i]; e != null; e = e.next)
61.835 + h += e.key.hashCode() ^ e.value.hashCode();
61.836 + loadFactor = -loadFactor; // Mark hashCode computation complete
61.837 +
61.838 + return h;
61.839 + }
61.840 +
61.841 + /**
61.842 + * Hashtable collision list.
61.843 + */
61.844 + private static class Entry<K,V> implements Map.Entry<K,V> {
61.845 + int hash;
61.846 + K key;
61.847 + V value;
61.848 + Entry<K,V> next;
61.849 +
61.850 + protected Entry(int hash, K key, V value, Entry<K,V> next) {
61.851 + this.hash = hash;
61.852 + this.key = key;
61.853 + this.value = value;
61.854 + this.next = next;
61.855 + }
61.856 +
61.857 + protected Object clone() {
61.858 + return new Entry<>(hash, key, value,
61.859 + (next==null ? null : (Entry<K,V>) next.clone()));
61.860 + }
61.861 +
61.862 + // Map.Entry Ops
61.863 +
61.864 + public K getKey() {
61.865 + return key;
61.866 + }
61.867 +
61.868 + public V getValue() {
61.869 + return value;
61.870 + }
61.871 +
61.872 + public V setValue(V value) {
61.873 + if (value == null)
61.874 + throw new NullPointerException();
61.875 +
61.876 + V oldValue = this.value;
61.877 + this.value = value;
61.878 + return oldValue;
61.879 + }
61.880 +
61.881 + public boolean equals(Object o) {
61.882 + if (!(o instanceof Map.Entry))
61.883 + return false;
61.884 + Map.Entry e = (Map.Entry)o;
61.885 +
61.886 + return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
61.887 + (value==null ? e.getValue()==null : value.equals(e.getValue()));
61.888 + }
61.889 +
61.890 + public int hashCode() {
61.891 + return hash ^ (value==null ? 0 : value.hashCode());
61.892 + }
61.893 +
61.894 + public String toString() {
61.895 + return key.toString()+"="+value.toString();
61.896 + }
61.897 + }
61.898 +
61.899 + // Types of Enumerations/Iterations
61.900 + private static final int KEYS = 0;
61.901 + private static final int VALUES = 1;
61.902 + private static final int ENTRIES = 2;
61.903 +
61.904 + /**
61.905 + * A hashtable enumerator class. This class implements both the
61.906 + * Enumeration and Iterator interfaces, but individual instances
61.907 + * can be created with the Iterator methods disabled. This is necessary
61.908 + * to avoid unintentionally increasing the capabilities granted a user
61.909 + * by passing an Enumeration.
61.910 + */
61.911 + private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
61.912 + Entry[] table = Hashtable.this.table;
61.913 + int index = table.length;
61.914 + Entry<K,V> entry = null;
61.915 + Entry<K,V> lastReturned = null;
61.916 + int type;
61.917 +
61.918 + /**
61.919 + * Indicates whether this Enumerator is serving as an Iterator
61.920 + * or an Enumeration. (true -> Iterator).
61.921 + */
61.922 + boolean iterator;
61.923 +
61.924 + /**
61.925 + * The modCount value that the iterator believes that the backing
61.926 + * Hashtable should have. If this expectation is violated, the iterator
61.927 + * has detected concurrent modification.
61.928 + */
61.929 + protected int expectedModCount = modCount;
61.930 +
61.931 + Enumerator(int type, boolean iterator) {
61.932 + this.type = type;
61.933 + this.iterator = iterator;
61.934 + }
61.935 +
61.936 + public boolean hasMoreElements() {
61.937 + Entry<K,V> e = entry;
61.938 + int i = index;
61.939 + Entry[] t = table;
61.940 + /* Use locals for faster loop iteration */
61.941 + while (e == null && i > 0) {
61.942 + e = t[--i];
61.943 + }
61.944 + entry = e;
61.945 + index = i;
61.946 + return e != null;
61.947 + }
61.948 +
61.949 + public T nextElement() {
61.950 + Entry<K,V> et = entry;
61.951 + int i = index;
61.952 + Entry[] t = table;
61.953 + /* Use locals for faster loop iteration */
61.954 + while (et == null && i > 0) {
61.955 + et = t[--i];
61.956 + }
61.957 + entry = et;
61.958 + index = i;
61.959 + if (et != null) {
61.960 + Entry<K,V> e = lastReturned = entry;
61.961 + entry = e.next;
61.962 + return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
61.963 + }
61.964 + throw new NoSuchElementException("Hashtable Enumerator");
61.965 + }
61.966 +
61.967 + // Iterator methods
61.968 + public boolean hasNext() {
61.969 + return hasMoreElements();
61.970 + }
61.971 +
61.972 + public T next() {
61.973 + if (modCount != expectedModCount)
61.974 + throw new ConcurrentModificationException();
61.975 + return nextElement();
61.976 + }
61.977 +
61.978 + public void remove() {
61.979 + if (!iterator)
61.980 + throw new UnsupportedOperationException();
61.981 + if (lastReturned == null)
61.982 + throw new IllegalStateException("Hashtable Enumerator");
61.983 + if (modCount != expectedModCount)
61.984 + throw new ConcurrentModificationException();
61.985 +
61.986 + synchronized(Hashtable.this) {
61.987 + Entry[] tab = Hashtable.this.table;
61.988 + int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
61.989 +
61.990 + for (Entry<K,V> e = tab[index], prev = null; e != null;
61.991 + prev = e, e = e.next) {
61.992 + if (e == lastReturned) {
61.993 + modCount++;
61.994 + expectedModCount++;
61.995 + if (prev == null)
61.996 + tab[index] = e.next;
61.997 + else
61.998 + prev.next = e.next;
61.999 + count--;
61.1000 + lastReturned = null;
61.1001 + return;
61.1002 + }
61.1003 + }
61.1004 + throw new ConcurrentModificationException();
61.1005 + }
61.1006 + }
61.1007 + }
61.1008 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/emul/compact/src/main/java/java/util/LinkedList.java Tue Feb 05 17:04:22 2013 +0100
62.3 @@ -0,0 +1,1100 @@
62.4 +/*
62.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
62.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
62.7 + *
62.8 + * This code is free software; you can redistribute it and/or modify it
62.9 + * under the terms of the GNU General Public License version 2 only, as
62.10 + * published by the Free Software Foundation. Oracle designates this
62.11 + * particular file as subject to the "Classpath" exception as provided
62.12 + * by Oracle in the LICENSE file that accompanied this code.
62.13 + *
62.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
62.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
62.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
62.17 + * version 2 for more details (a copy is included in the LICENSE file that
62.18 + * accompanied this code).
62.19 + *
62.20 + * You should have received a copy of the GNU General Public License version
62.21 + * 2 along with this work; if not, write to the Free Software Foundation,
62.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
62.23 + *
62.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
62.25 + * or visit www.oracle.com if you need additional information or have any
62.26 + * questions.
62.27 + */
62.28 +
62.29 +package java.util;
62.30 +
62.31 +/**
62.32 + * Doubly-linked list implementation of the {@code List} and {@code Deque}
62.33 + * interfaces. Implements all optional list operations, and permits all
62.34 + * elements (including {@code null}).
62.35 + *
62.36 + * <p>All of the operations perform as could be expected for a doubly-linked
62.37 + * list. Operations that index into the list will traverse the list from
62.38 + * the beginning or the end, whichever is closer to the specified index.
62.39 + *
62.40 + * <p><strong>Note that this implementation is not synchronized.</strong>
62.41 + * If multiple threads access a linked list concurrently, and at least
62.42 + * one of the threads modifies the list structurally, it <i>must</i> be
62.43 + * synchronized externally. (A structural modification is any operation
62.44 + * that adds or deletes one or more elements; merely setting the value of
62.45 + * an element is not a structural modification.) This is typically
62.46 + * accomplished by synchronizing on some object that naturally
62.47 + * encapsulates the list.
62.48 + *
62.49 + * If no such object exists, the list should be "wrapped" using the
62.50 + * {@link Collections#synchronizedList Collections.synchronizedList}
62.51 + * method. This is best done at creation time, to prevent accidental
62.52 + * unsynchronized access to the list:<pre>
62.53 + * List list = Collections.synchronizedList(new LinkedList(...));</pre>
62.54 + *
62.55 + * <p>The iterators returned by this class's {@code iterator} and
62.56 + * {@code listIterator} methods are <i>fail-fast</i>: if the list is
62.57 + * structurally modified at any time after the iterator is created, in
62.58 + * any way except through the Iterator's own {@code remove} or
62.59 + * {@code add} methods, the iterator will throw a {@link
62.60 + * ConcurrentModificationException}. Thus, in the face of concurrent
62.61 + * modification, the iterator fails quickly and cleanly, rather than
62.62 + * risking arbitrary, non-deterministic behavior at an undetermined
62.63 + * time in the future.
62.64 + *
62.65 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
62.66 + * as it is, generally speaking, impossible to make any hard guarantees in the
62.67 + * presence of unsynchronized concurrent modification. Fail-fast iterators
62.68 + * throw {@code ConcurrentModificationException} on a best-effort basis.
62.69 + * Therefore, it would be wrong to write a program that depended on this
62.70 + * exception for its correctness: <i>the fail-fast behavior of iterators
62.71 + * should be used only to detect bugs.</i>
62.72 + *
62.73 + * <p>This class is a member of the
62.74 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
62.75 + * Java Collections Framework</a>.
62.76 + *
62.77 + * @author Josh Bloch
62.78 + * @see List
62.79 + * @see ArrayList
62.80 + * @since 1.2
62.81 + * @param <E> the type of elements held in this collection
62.82 + */
62.83 +
62.84 +public class LinkedList<E>
62.85 + extends AbstractSequentialList<E>
62.86 + implements List<E>, Deque<E>, Cloneable, java.io.Serializable
62.87 +{
62.88 + transient int size = 0;
62.89 +
62.90 + /**
62.91 + * Pointer to first node.
62.92 + * Invariant: (first == null && last == null) ||
62.93 + * (first.prev == null && first.item != null)
62.94 + */
62.95 + transient Node<E> first;
62.96 +
62.97 + /**
62.98 + * Pointer to last node.
62.99 + * Invariant: (first == null && last == null) ||
62.100 + * (last.next == null && last.item != null)
62.101 + */
62.102 + transient Node<E> last;
62.103 +
62.104 + /**
62.105 + * Constructs an empty list.
62.106 + */
62.107 + public LinkedList() {
62.108 + }
62.109 +
62.110 + /**
62.111 + * Constructs a list containing the elements of the specified
62.112 + * collection, in the order they are returned by the collection's
62.113 + * iterator.
62.114 + *
62.115 + * @param c the collection whose elements are to be placed into this list
62.116 + * @throws NullPointerException if the specified collection is null
62.117 + */
62.118 + public LinkedList(Collection<? extends E> c) {
62.119 + this();
62.120 + addAll(c);
62.121 + }
62.122 +
62.123 + /**
62.124 + * Links e as first element.
62.125 + */
62.126 + private void linkFirst(E e) {
62.127 + final Node<E> f = first;
62.128 + final Node<E> newNode = new Node<>(null, e, f);
62.129 + first = newNode;
62.130 + if (f == null)
62.131 + last = newNode;
62.132 + else
62.133 + f.prev = newNode;
62.134 + size++;
62.135 + modCount++;
62.136 + }
62.137 +
62.138 + /**
62.139 + * Links e as last element.
62.140 + */
62.141 + void linkLast(E e) {
62.142 + final Node<E> l = last;
62.143 + final Node<E> newNode = new Node<>(l, e, null);
62.144 + last = newNode;
62.145 + if (l == null)
62.146 + first = newNode;
62.147 + else
62.148 + l.next = newNode;
62.149 + size++;
62.150 + modCount++;
62.151 + }
62.152 +
62.153 + /**
62.154 + * Inserts element e before non-null Node succ.
62.155 + */
62.156 + void linkBefore(E e, Node<E> succ) {
62.157 + // assert succ != null;
62.158 + final Node<E> pred = succ.prev;
62.159 + final Node<E> newNode = new Node<>(pred, e, succ);
62.160 + succ.prev = newNode;
62.161 + if (pred == null)
62.162 + first = newNode;
62.163 + else
62.164 + pred.next = newNode;
62.165 + size++;
62.166 + modCount++;
62.167 + }
62.168 +
62.169 + /**
62.170 + * Unlinks non-null first node f.
62.171 + */
62.172 + private E unlinkFirst(Node<E> f) {
62.173 + // assert f == first && f != null;
62.174 + final E element = f.item;
62.175 + final Node<E> next = f.next;
62.176 + f.item = null;
62.177 + f.next = null; // help GC
62.178 + first = next;
62.179 + if (next == null)
62.180 + last = null;
62.181 + else
62.182 + next.prev = null;
62.183 + size--;
62.184 + modCount++;
62.185 + return element;
62.186 + }
62.187 +
62.188 + /**
62.189 + * Unlinks non-null last node l.
62.190 + */
62.191 + private E unlinkLast(Node<E> l) {
62.192 + // assert l == last && l != null;
62.193 + final E element = l.item;
62.194 + final Node<E> prev = l.prev;
62.195 + l.item = null;
62.196 + l.prev = null; // help GC
62.197 + last = prev;
62.198 + if (prev == null)
62.199 + first = null;
62.200 + else
62.201 + prev.next = null;
62.202 + size--;
62.203 + modCount++;
62.204 + return element;
62.205 + }
62.206 +
62.207 + /**
62.208 + * Unlinks non-null node x.
62.209 + */
62.210 + E unlink(Node<E> x) {
62.211 + // assert x != null;
62.212 + final E element = x.item;
62.213 + final Node<E> next = x.next;
62.214 + final Node<E> prev = x.prev;
62.215 +
62.216 + if (prev == null) {
62.217 + first = next;
62.218 + } else {
62.219 + prev.next = next;
62.220 + x.prev = null;
62.221 + }
62.222 +
62.223 + if (next == null) {
62.224 + last = prev;
62.225 + } else {
62.226 + next.prev = prev;
62.227 + x.next = null;
62.228 + }
62.229 +
62.230 + x.item = null;
62.231 + size--;
62.232 + modCount++;
62.233 + return element;
62.234 + }
62.235 +
62.236 + /**
62.237 + * Returns the first element in this list.
62.238 + *
62.239 + * @return the first element in this list
62.240 + * @throws NoSuchElementException if this list is empty
62.241 + */
62.242 + public E getFirst() {
62.243 + final Node<E> f = first;
62.244 + if (f == null)
62.245 + throw new NoSuchElementException();
62.246 + return f.item;
62.247 + }
62.248 +
62.249 + /**
62.250 + * Returns the last element in this list.
62.251 + *
62.252 + * @return the last element in this list
62.253 + * @throws NoSuchElementException if this list is empty
62.254 + */
62.255 + public E getLast() {
62.256 + final Node<E> l = last;
62.257 + if (l == null)
62.258 + throw new NoSuchElementException();
62.259 + return l.item;
62.260 + }
62.261 +
62.262 + /**
62.263 + * Removes and returns the first element from this list.
62.264 + *
62.265 + * @return the first element from this list
62.266 + * @throws NoSuchElementException if this list is empty
62.267 + */
62.268 + public E removeFirst() {
62.269 + final Node<E> f = first;
62.270 + if (f == null)
62.271 + throw new NoSuchElementException();
62.272 + return unlinkFirst(f);
62.273 + }
62.274 +
62.275 + /**
62.276 + * Removes and returns the last element from this list.
62.277 + *
62.278 + * @return the last element from this list
62.279 + * @throws NoSuchElementException if this list is empty
62.280 + */
62.281 + public E removeLast() {
62.282 + final Node<E> l = last;
62.283 + if (l == null)
62.284 + throw new NoSuchElementException();
62.285 + return unlinkLast(l);
62.286 + }
62.287 +
62.288 + /**
62.289 + * Inserts the specified element at the beginning of this list.
62.290 + *
62.291 + * @param e the element to add
62.292 + */
62.293 + public void addFirst(E e) {
62.294 + linkFirst(e);
62.295 + }
62.296 +
62.297 + /**
62.298 + * Appends the specified element to the end of this list.
62.299 + *
62.300 + * <p>This method is equivalent to {@link #add}.
62.301 + *
62.302 + * @param e the element to add
62.303 + */
62.304 + public void addLast(E e) {
62.305 + linkLast(e);
62.306 + }
62.307 +
62.308 + /**
62.309 + * Returns {@code true} if this list contains the specified element.
62.310 + * More formally, returns {@code true} if and only if this list contains
62.311 + * at least one element {@code e} such that
62.312 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
62.313 + *
62.314 + * @param o element whose presence in this list is to be tested
62.315 + * @return {@code true} if this list contains the specified element
62.316 + */
62.317 + public boolean contains(Object o) {
62.318 + return indexOf(o) != -1;
62.319 + }
62.320 +
62.321 + /**
62.322 + * Returns the number of elements in this list.
62.323 + *
62.324 + * @return the number of elements in this list
62.325 + */
62.326 + public int size() {
62.327 + return size;
62.328 + }
62.329 +
62.330 + /**
62.331 + * Appends the specified element to the end of this list.
62.332 + *
62.333 + * <p>This method is equivalent to {@link #addLast}.
62.334 + *
62.335 + * @param e element to be appended to this list
62.336 + * @return {@code true} (as specified by {@link Collection#add})
62.337 + */
62.338 + public boolean add(E e) {
62.339 + linkLast(e);
62.340 + return true;
62.341 + }
62.342 +
62.343 + /**
62.344 + * Removes the first occurrence of the specified element from this list,
62.345 + * if it is present. If this list does not contain the element, it is
62.346 + * unchanged. More formally, removes the element with the lowest index
62.347 + * {@code i} such that
62.348 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
62.349 + * (if such an element exists). Returns {@code true} if this list
62.350 + * contained the specified element (or equivalently, if this list
62.351 + * changed as a result of the call).
62.352 + *
62.353 + * @param o element to be removed from this list, if present
62.354 + * @return {@code true} if this list contained the specified element
62.355 + */
62.356 + public boolean remove(Object o) {
62.357 + if (o == null) {
62.358 + for (Node<E> x = first; x != null; x = x.next) {
62.359 + if (x.item == null) {
62.360 + unlink(x);
62.361 + return true;
62.362 + }
62.363 + }
62.364 + } else {
62.365 + for (Node<E> x = first; x != null; x = x.next) {
62.366 + if (o.equals(x.item)) {
62.367 + unlink(x);
62.368 + return true;
62.369 + }
62.370 + }
62.371 + }
62.372 + return false;
62.373 + }
62.374 +
62.375 + /**
62.376 + * Appends all of the elements in the specified collection to the end of
62.377 + * this list, in the order that they are returned by the specified
62.378 + * collection's iterator. The behavior of this operation is undefined if
62.379 + * the specified collection is modified while the operation is in
62.380 + * progress. (Note that this will occur if the specified collection is
62.381 + * this list, and it's nonempty.)
62.382 + *
62.383 + * @param c collection containing elements to be added to this list
62.384 + * @return {@code true} if this list changed as a result of the call
62.385 + * @throws NullPointerException if the specified collection is null
62.386 + */
62.387 + public boolean addAll(Collection<? extends E> c) {
62.388 + return addAll(size, c);
62.389 + }
62.390 +
62.391 + /**
62.392 + * Inserts all of the elements in the specified collection into this
62.393 + * list, starting at the specified position. Shifts the element
62.394 + * currently at that position (if any) and any subsequent elements to
62.395 + * the right (increases their indices). The new elements will appear
62.396 + * in the list in the order that they are returned by the
62.397 + * specified collection's iterator.
62.398 + *
62.399 + * @param index index at which to insert the first element
62.400 + * from the specified collection
62.401 + * @param c collection containing elements to be added to this list
62.402 + * @return {@code true} if this list changed as a result of the call
62.403 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.404 + * @throws NullPointerException if the specified collection is null
62.405 + */
62.406 + public boolean addAll(int index, Collection<? extends E> c) {
62.407 + checkPositionIndex(index);
62.408 +
62.409 + Object[] a = c.toArray();
62.410 + int numNew = a.length;
62.411 + if (numNew == 0)
62.412 + return false;
62.413 +
62.414 + Node<E> pred, succ;
62.415 + if (index == size) {
62.416 + succ = null;
62.417 + pred = last;
62.418 + } else {
62.419 + succ = node(index);
62.420 + pred = succ.prev;
62.421 + }
62.422 +
62.423 + for (Object o : a) {
62.424 + @SuppressWarnings("unchecked") E e = (E) o;
62.425 + Node<E> newNode = new Node<>(pred, e, null);
62.426 + if (pred == null)
62.427 + first = newNode;
62.428 + else
62.429 + pred.next = newNode;
62.430 + pred = newNode;
62.431 + }
62.432 +
62.433 + if (succ == null) {
62.434 + last = pred;
62.435 + } else {
62.436 + pred.next = succ;
62.437 + succ.prev = pred;
62.438 + }
62.439 +
62.440 + size += numNew;
62.441 + modCount++;
62.442 + return true;
62.443 + }
62.444 +
62.445 + /**
62.446 + * Removes all of the elements from this list.
62.447 + * The list will be empty after this call returns.
62.448 + */
62.449 + public void clear() {
62.450 + // Clearing all of the links between nodes is "unnecessary", but:
62.451 + // - helps a generational GC if the discarded nodes inhabit
62.452 + // more than one generation
62.453 + // - is sure to free memory even if there is a reachable Iterator
62.454 + for (Node<E> x = first; x != null; ) {
62.455 + Node<E> next = x.next;
62.456 + x.item = null;
62.457 + x.next = null;
62.458 + x.prev = null;
62.459 + x = next;
62.460 + }
62.461 + first = last = null;
62.462 + size = 0;
62.463 + modCount++;
62.464 + }
62.465 +
62.466 +
62.467 + // Positional Access Operations
62.468 +
62.469 + /**
62.470 + * Returns the element at the specified position in this list.
62.471 + *
62.472 + * @param index index of the element to return
62.473 + * @return the element at the specified position in this list
62.474 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.475 + */
62.476 + public E get(int index) {
62.477 + checkElementIndex(index);
62.478 + return node(index).item;
62.479 + }
62.480 +
62.481 + /**
62.482 + * Replaces the element at the specified position in this list with the
62.483 + * specified element.
62.484 + *
62.485 + * @param index index of the element to replace
62.486 + * @param element element to be stored at the specified position
62.487 + * @return the element previously at the specified position
62.488 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.489 + */
62.490 + public E set(int index, E element) {
62.491 + checkElementIndex(index);
62.492 + Node<E> x = node(index);
62.493 + E oldVal = x.item;
62.494 + x.item = element;
62.495 + return oldVal;
62.496 + }
62.497 +
62.498 + /**
62.499 + * Inserts the specified element at the specified position in this list.
62.500 + * Shifts the element currently at that position (if any) and any
62.501 + * subsequent elements to the right (adds one to their indices).
62.502 + *
62.503 + * @param index index at which the specified element is to be inserted
62.504 + * @param element element to be inserted
62.505 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.506 + */
62.507 + public void add(int index, E element) {
62.508 + checkPositionIndex(index);
62.509 +
62.510 + if (index == size)
62.511 + linkLast(element);
62.512 + else
62.513 + linkBefore(element, node(index));
62.514 + }
62.515 +
62.516 + /**
62.517 + * Removes the element at the specified position in this list. Shifts any
62.518 + * subsequent elements to the left (subtracts one from their indices).
62.519 + * Returns the element that was removed from the list.
62.520 + *
62.521 + * @param index the index of the element to be removed
62.522 + * @return the element previously at the specified position
62.523 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.524 + */
62.525 + public E remove(int index) {
62.526 + checkElementIndex(index);
62.527 + return unlink(node(index));
62.528 + }
62.529 +
62.530 + /**
62.531 + * Tells if the argument is the index of an existing element.
62.532 + */
62.533 + private boolean isElementIndex(int index) {
62.534 + return index >= 0 && index < size;
62.535 + }
62.536 +
62.537 + /**
62.538 + * Tells if the argument is the index of a valid position for an
62.539 + * iterator or an add operation.
62.540 + */
62.541 + private boolean isPositionIndex(int index) {
62.542 + return index >= 0 && index <= size;
62.543 + }
62.544 +
62.545 + /**
62.546 + * Constructs an IndexOutOfBoundsException detail message.
62.547 + * Of the many possible refactorings of the error handling code,
62.548 + * this "outlining" performs best with both server and client VMs.
62.549 + */
62.550 + private String outOfBoundsMsg(int index) {
62.551 + return "Index: "+index+", Size: "+size;
62.552 + }
62.553 +
62.554 + private void checkElementIndex(int index) {
62.555 + if (!isElementIndex(index))
62.556 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
62.557 + }
62.558 +
62.559 + private void checkPositionIndex(int index) {
62.560 + if (!isPositionIndex(index))
62.561 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
62.562 + }
62.563 +
62.564 + /**
62.565 + * Returns the (non-null) Node at the specified element index.
62.566 + */
62.567 + Node<E> node(int index) {
62.568 + // assert isElementIndex(index);
62.569 +
62.570 + if (index < (size >> 1)) {
62.571 + Node<E> x = first;
62.572 + for (int i = 0; i < index; i++)
62.573 + x = x.next;
62.574 + return x;
62.575 + } else {
62.576 + Node<E> x = last;
62.577 + for (int i = size - 1; i > index; i--)
62.578 + x = x.prev;
62.579 + return x;
62.580 + }
62.581 + }
62.582 +
62.583 + // Search Operations
62.584 +
62.585 + /**
62.586 + * Returns the index of the first occurrence of the specified element
62.587 + * in this list, or -1 if this list does not contain the element.
62.588 + * More formally, returns the lowest index {@code i} such that
62.589 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
62.590 + * or -1 if there is no such index.
62.591 + *
62.592 + * @param o element to search for
62.593 + * @return the index of the first occurrence of the specified element in
62.594 + * this list, or -1 if this list does not contain the element
62.595 + */
62.596 + public int indexOf(Object o) {
62.597 + int index = 0;
62.598 + if (o == null) {
62.599 + for (Node<E> x = first; x != null; x = x.next) {
62.600 + if (x.item == null)
62.601 + return index;
62.602 + index++;
62.603 + }
62.604 + } else {
62.605 + for (Node<E> x = first; x != null; x = x.next) {
62.606 + if (o.equals(x.item))
62.607 + return index;
62.608 + index++;
62.609 + }
62.610 + }
62.611 + return -1;
62.612 + }
62.613 +
62.614 + /**
62.615 + * Returns the index of the last occurrence of the specified element
62.616 + * in this list, or -1 if this list does not contain the element.
62.617 + * More formally, returns the highest index {@code i} such that
62.618 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
62.619 + * or -1 if there is no such index.
62.620 + *
62.621 + * @param o element to search for
62.622 + * @return the index of the last occurrence of the specified element in
62.623 + * this list, or -1 if this list does not contain the element
62.624 + */
62.625 + public int lastIndexOf(Object o) {
62.626 + int index = size;
62.627 + if (o == null) {
62.628 + for (Node<E> x = last; x != null; x = x.prev) {
62.629 + index--;
62.630 + if (x.item == null)
62.631 + return index;
62.632 + }
62.633 + } else {
62.634 + for (Node<E> x = last; x != null; x = x.prev) {
62.635 + index--;
62.636 + if (o.equals(x.item))
62.637 + return index;
62.638 + }
62.639 + }
62.640 + return -1;
62.641 + }
62.642 +
62.643 + // Queue operations.
62.644 +
62.645 + /**
62.646 + * Retrieves, but does not remove, the head (first element) of this list.
62.647 + *
62.648 + * @return the head of this list, or {@code null} if this list is empty
62.649 + * @since 1.5
62.650 + */
62.651 + public E peek() {
62.652 + final Node<E> f = first;
62.653 + return (f == null) ? null : f.item;
62.654 + }
62.655 +
62.656 + /**
62.657 + * Retrieves, but does not remove, the head (first element) of this list.
62.658 + *
62.659 + * @return the head of this list
62.660 + * @throws NoSuchElementException if this list is empty
62.661 + * @since 1.5
62.662 + */
62.663 + public E element() {
62.664 + return getFirst();
62.665 + }
62.666 +
62.667 + /**
62.668 + * Retrieves and removes the head (first element) of this list.
62.669 + *
62.670 + * @return the head of this list, or {@code null} if this list is empty
62.671 + * @since 1.5
62.672 + */
62.673 + public E poll() {
62.674 + final Node<E> f = first;
62.675 + return (f == null) ? null : unlinkFirst(f);
62.676 + }
62.677 +
62.678 + /**
62.679 + * Retrieves and removes the head (first element) of this list.
62.680 + *
62.681 + * @return the head of this list
62.682 + * @throws NoSuchElementException if this list is empty
62.683 + * @since 1.5
62.684 + */
62.685 + public E remove() {
62.686 + return removeFirst();
62.687 + }
62.688 +
62.689 + /**
62.690 + * Adds the specified element as the tail (last element) of this list.
62.691 + *
62.692 + * @param e the element to add
62.693 + * @return {@code true} (as specified by {@link Queue#offer})
62.694 + * @since 1.5
62.695 + */
62.696 + public boolean offer(E e) {
62.697 + return add(e);
62.698 + }
62.699 +
62.700 + // Deque operations
62.701 + /**
62.702 + * Inserts the specified element at the front of this list.
62.703 + *
62.704 + * @param e the element to insert
62.705 + * @return {@code true} (as specified by {@link Deque#offerFirst})
62.706 + * @since 1.6
62.707 + */
62.708 + public boolean offerFirst(E e) {
62.709 + addFirst(e);
62.710 + return true;
62.711 + }
62.712 +
62.713 + /**
62.714 + * Inserts the specified element at the end of this list.
62.715 + *
62.716 + * @param e the element to insert
62.717 + * @return {@code true} (as specified by {@link Deque#offerLast})
62.718 + * @since 1.6
62.719 + */
62.720 + public boolean offerLast(E e) {
62.721 + addLast(e);
62.722 + return true;
62.723 + }
62.724 +
62.725 + /**
62.726 + * Retrieves, but does not remove, the first element of this list,
62.727 + * or returns {@code null} if this list is empty.
62.728 + *
62.729 + * @return the first element of this list, or {@code null}
62.730 + * if this list is empty
62.731 + * @since 1.6
62.732 + */
62.733 + public E peekFirst() {
62.734 + final Node<E> f = first;
62.735 + return (f == null) ? null : f.item;
62.736 + }
62.737 +
62.738 + /**
62.739 + * Retrieves, but does not remove, the last element of this list,
62.740 + * or returns {@code null} if this list is empty.
62.741 + *
62.742 + * @return the last element of this list, or {@code null}
62.743 + * if this list is empty
62.744 + * @since 1.6
62.745 + */
62.746 + public E peekLast() {
62.747 + final Node<E> l = last;
62.748 + return (l == null) ? null : l.item;
62.749 + }
62.750 +
62.751 + /**
62.752 + * Retrieves and removes the first element of this list,
62.753 + * or returns {@code null} if this list is empty.
62.754 + *
62.755 + * @return the first element of this list, or {@code null} if
62.756 + * this list is empty
62.757 + * @since 1.6
62.758 + */
62.759 + public E pollFirst() {
62.760 + final Node<E> f = first;
62.761 + return (f == null) ? null : unlinkFirst(f);
62.762 + }
62.763 +
62.764 + /**
62.765 + * Retrieves and removes the last element of this list,
62.766 + * or returns {@code null} if this list is empty.
62.767 + *
62.768 + * @return the last element of this list, or {@code null} if
62.769 + * this list is empty
62.770 + * @since 1.6
62.771 + */
62.772 + public E pollLast() {
62.773 + final Node<E> l = last;
62.774 + return (l == null) ? null : unlinkLast(l);
62.775 + }
62.776 +
62.777 + /**
62.778 + * Pushes an element onto the stack represented by this list. In other
62.779 + * words, inserts the element at the front of this list.
62.780 + *
62.781 + * <p>This method is equivalent to {@link #addFirst}.
62.782 + *
62.783 + * @param e the element to push
62.784 + * @since 1.6
62.785 + */
62.786 + public void push(E e) {
62.787 + addFirst(e);
62.788 + }
62.789 +
62.790 + /**
62.791 + * Pops an element from the stack represented by this list. In other
62.792 + * words, removes and returns the first element of this list.
62.793 + *
62.794 + * <p>This method is equivalent to {@link #removeFirst()}.
62.795 + *
62.796 + * @return the element at the front of this list (which is the top
62.797 + * of the stack represented by this list)
62.798 + * @throws NoSuchElementException if this list is empty
62.799 + * @since 1.6
62.800 + */
62.801 + public E pop() {
62.802 + return removeFirst();
62.803 + }
62.804 +
62.805 + /**
62.806 + * Removes the first occurrence of the specified element in this
62.807 + * list (when traversing the list from head to tail). If the list
62.808 + * does not contain the element, it is unchanged.
62.809 + *
62.810 + * @param o element to be removed from this list, if present
62.811 + * @return {@code true} if the list contained the specified element
62.812 + * @since 1.6
62.813 + */
62.814 + public boolean removeFirstOccurrence(Object o) {
62.815 + return remove(o);
62.816 + }
62.817 +
62.818 + /**
62.819 + * Removes the last occurrence of the specified element in this
62.820 + * list (when traversing the list from head to tail). If the list
62.821 + * does not contain the element, it is unchanged.
62.822 + *
62.823 + * @param o element to be removed from this list, if present
62.824 + * @return {@code true} if the list contained the specified element
62.825 + * @since 1.6
62.826 + */
62.827 + public boolean removeLastOccurrence(Object o) {
62.828 + if (o == null) {
62.829 + for (Node<E> x = last; x != null; x = x.prev) {
62.830 + if (x.item == null) {
62.831 + unlink(x);
62.832 + return true;
62.833 + }
62.834 + }
62.835 + } else {
62.836 + for (Node<E> x = last; x != null; x = x.prev) {
62.837 + if (o.equals(x.item)) {
62.838 + unlink(x);
62.839 + return true;
62.840 + }
62.841 + }
62.842 + }
62.843 + return false;
62.844 + }
62.845 +
62.846 + /**
62.847 + * Returns a list-iterator of the elements in this list (in proper
62.848 + * sequence), starting at the specified position in the list.
62.849 + * Obeys the general contract of {@code List.listIterator(int)}.<p>
62.850 + *
62.851 + * The list-iterator is <i>fail-fast</i>: if the list is structurally
62.852 + * modified at any time after the Iterator is created, in any way except
62.853 + * through the list-iterator's own {@code remove} or {@code add}
62.854 + * methods, the list-iterator will throw a
62.855 + * {@code ConcurrentModificationException}. Thus, in the face of
62.856 + * concurrent modification, the iterator fails quickly and cleanly, rather
62.857 + * than risking arbitrary, non-deterministic behavior at an undetermined
62.858 + * time in the future.
62.859 + *
62.860 + * @param index index of the first element to be returned from the
62.861 + * list-iterator (by a call to {@code next})
62.862 + * @return a ListIterator of the elements in this list (in proper
62.863 + * sequence), starting at the specified position in the list
62.864 + * @throws IndexOutOfBoundsException {@inheritDoc}
62.865 + * @see List#listIterator(int)
62.866 + */
62.867 + public ListIterator<E> listIterator(int index) {
62.868 + checkPositionIndex(index);
62.869 + return new ListItr(index);
62.870 + }
62.871 +
62.872 + private class ListItr implements ListIterator<E> {
62.873 + private Node<E> lastReturned = null;
62.874 + private Node<E> next;
62.875 + private int nextIndex;
62.876 + private int expectedModCount = modCount;
62.877 +
62.878 + ListItr(int index) {
62.879 + // assert isPositionIndex(index);
62.880 + next = (index == size) ? null : node(index);
62.881 + nextIndex = index;
62.882 + }
62.883 +
62.884 + public boolean hasNext() {
62.885 + return nextIndex < size;
62.886 + }
62.887 +
62.888 + public E next() {
62.889 + checkForComodification();
62.890 + if (!hasNext())
62.891 + throw new NoSuchElementException();
62.892 +
62.893 + lastReturned = next;
62.894 + next = next.next;
62.895 + nextIndex++;
62.896 + return lastReturned.item;
62.897 + }
62.898 +
62.899 + public boolean hasPrevious() {
62.900 + return nextIndex > 0;
62.901 + }
62.902 +
62.903 + public E previous() {
62.904 + checkForComodification();
62.905 + if (!hasPrevious())
62.906 + throw new NoSuchElementException();
62.907 +
62.908 + lastReturned = next = (next == null) ? last : next.prev;
62.909 + nextIndex--;
62.910 + return lastReturned.item;
62.911 + }
62.912 +
62.913 + public int nextIndex() {
62.914 + return nextIndex;
62.915 + }
62.916 +
62.917 + public int previousIndex() {
62.918 + return nextIndex - 1;
62.919 + }
62.920 +
62.921 + public void remove() {
62.922 + checkForComodification();
62.923 + if (lastReturned == null)
62.924 + throw new IllegalStateException();
62.925 +
62.926 + Node<E> lastNext = lastReturned.next;
62.927 + unlink(lastReturned);
62.928 + if (next == lastReturned)
62.929 + next = lastNext;
62.930 + else
62.931 + nextIndex--;
62.932 + lastReturned = null;
62.933 + expectedModCount++;
62.934 + }
62.935 +
62.936 + public void set(E e) {
62.937 + if (lastReturned == null)
62.938 + throw new IllegalStateException();
62.939 + checkForComodification();
62.940 + lastReturned.item = e;
62.941 + }
62.942 +
62.943 + public void add(E e) {
62.944 + checkForComodification();
62.945 + lastReturned = null;
62.946 + if (next == null)
62.947 + linkLast(e);
62.948 + else
62.949 + linkBefore(e, next);
62.950 + nextIndex++;
62.951 + expectedModCount++;
62.952 + }
62.953 +
62.954 + final void checkForComodification() {
62.955 + if (modCount != expectedModCount)
62.956 + throw new ConcurrentModificationException();
62.957 + }
62.958 + }
62.959 +
62.960 + private static class Node<E> {
62.961 + E item;
62.962 + Node<E> next;
62.963 + Node<E> prev;
62.964 +
62.965 + Node(Node<E> prev, E element, Node<E> next) {
62.966 + this.item = element;
62.967 + this.next = next;
62.968 + this.prev = prev;
62.969 + }
62.970 + }
62.971 +
62.972 + /**
62.973 + * @since 1.6
62.974 + */
62.975 + public Iterator<E> descendingIterator() {
62.976 + return new DescendingIterator();
62.977 + }
62.978 +
62.979 + /**
62.980 + * Adapter to provide descending iterators via ListItr.previous
62.981 + */
62.982 + private class DescendingIterator implements Iterator<E> {
62.983 + private final ListItr itr = new ListItr(size());
62.984 + public boolean hasNext() {
62.985 + return itr.hasPrevious();
62.986 + }
62.987 + public E next() {
62.988 + return itr.previous();
62.989 + }
62.990 + public void remove() {
62.991 + itr.remove();
62.992 + }
62.993 + }
62.994 +
62.995 + @SuppressWarnings("unchecked")
62.996 + private LinkedList<E> superClone() {
62.997 + try {
62.998 + return (LinkedList<E>) super.clone();
62.999 + } catch (CloneNotSupportedException e) {
62.1000 + throw new InternalError();
62.1001 + }
62.1002 + }
62.1003 +
62.1004 + /**
62.1005 + * Returns a shallow copy of this {@code LinkedList}. (The elements
62.1006 + * themselves are not cloned.)
62.1007 + *
62.1008 + * @return a shallow copy of this {@code LinkedList} instance
62.1009 + */
62.1010 + public Object clone() {
62.1011 + LinkedList<E> clone = superClone();
62.1012 +
62.1013 + // Put clone into "virgin" state
62.1014 + clone.first = clone.last = null;
62.1015 + clone.size = 0;
62.1016 + clone.modCount = 0;
62.1017 +
62.1018 + // Initialize clone with our elements
62.1019 + for (Node<E> x = first; x != null; x = x.next)
62.1020 + clone.add(x.item);
62.1021 +
62.1022 + return clone;
62.1023 + }
62.1024 +
62.1025 + /**
62.1026 + * Returns an array containing all of the elements in this list
62.1027 + * in proper sequence (from first to last element).
62.1028 + *
62.1029 + * <p>The returned array will be "safe" in that no references to it are
62.1030 + * maintained by this list. (In other words, this method must allocate
62.1031 + * a new array). The caller is thus free to modify the returned array.
62.1032 + *
62.1033 + * <p>This method acts as bridge between array-based and collection-based
62.1034 + * APIs.
62.1035 + *
62.1036 + * @return an array containing all of the elements in this list
62.1037 + * in proper sequence
62.1038 + */
62.1039 + public Object[] toArray() {
62.1040 + Object[] result = new Object[size];
62.1041 + int i = 0;
62.1042 + for (Node<E> x = first; x != null; x = x.next)
62.1043 + result[i++] = x.item;
62.1044 + return result;
62.1045 + }
62.1046 +
62.1047 + /**
62.1048 + * Returns an array containing all of the elements in this list in
62.1049 + * proper sequence (from first to last element); the runtime type of
62.1050 + * the returned array is that of the specified array. If the list fits
62.1051 + * in the specified array, it is returned therein. Otherwise, a new
62.1052 + * array is allocated with the runtime type of the specified array and
62.1053 + * the size of this list.
62.1054 + *
62.1055 + * <p>If the list fits in the specified array with room to spare (i.e.,
62.1056 + * the array has more elements than the list), the element in the array
62.1057 + * immediately following the end of the list is set to {@code null}.
62.1058 + * (This is useful in determining the length of the list <i>only</i> if
62.1059 + * the caller knows that the list does not contain any null elements.)
62.1060 + *
62.1061 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
62.1062 + * array-based and collection-based APIs. Further, this method allows
62.1063 + * precise control over the runtime type of the output array, and may,
62.1064 + * under certain circumstances, be used to save allocation costs.
62.1065 + *
62.1066 + * <p>Suppose {@code x} is a list known to contain only strings.
62.1067 + * The following code can be used to dump the list into a newly
62.1068 + * allocated array of {@code String}:
62.1069 + *
62.1070 + * <pre>
62.1071 + * String[] y = x.toArray(new String[0]);</pre>
62.1072 + *
62.1073 + * Note that {@code toArray(new Object[0])} is identical in function to
62.1074 + * {@code toArray()}.
62.1075 + *
62.1076 + * @param a the array into which the elements of the list are to
62.1077 + * be stored, if it is big enough; otherwise, a new array of the
62.1078 + * same runtime type is allocated for this purpose.
62.1079 + * @return an array containing the elements of the list
62.1080 + * @throws ArrayStoreException if the runtime type of the specified array
62.1081 + * is not a supertype of the runtime type of every element in
62.1082 + * this list
62.1083 + * @throws NullPointerException if the specified array is null
62.1084 + */
62.1085 + @SuppressWarnings("unchecked")
62.1086 + public <T> T[] toArray(T[] a) {
62.1087 + if (a.length < size)
62.1088 + a = (T[])java.lang.reflect.Array.newInstance(
62.1089 + a.getClass().getComponentType(), size);
62.1090 + int i = 0;
62.1091 + Object[] result = a;
62.1092 + for (Node<E> x = first; x != null; x = x.next)
62.1093 + result[i++] = x.item;
62.1094 +
62.1095 + if (a.length > size)
62.1096 + a[size] = null;
62.1097 +
62.1098 + return a;
62.1099 + }
62.1100 +
62.1101 + private static final long serialVersionUID = 876323262645176354L;
62.1102 +
62.1103 +}
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/emul/compact/src/main/java/java/util/PriorityQueue.java Tue Feb 05 17:04:22 2013 +0100
63.3 @@ -0,0 +1,731 @@
63.4 +/*
63.5 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
63.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
63.7 + *
63.8 + * This code is free software; you can redistribute it and/or modify it
63.9 + * under the terms of the GNU General Public License version 2 only, as
63.10 + * published by the Free Software Foundation. Oracle designates this
63.11 + * particular file as subject to the "Classpath" exception as provided
63.12 + * by Oracle in the LICENSE file that accompanied this code.
63.13 + *
63.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
63.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
63.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
63.17 + * version 2 for more details (a copy is included in the LICENSE file that
63.18 + * accompanied this code).
63.19 + *
63.20 + * You should have received a copy of the GNU General Public License version
63.21 + * 2 along with this work; if not, write to the Free Software Foundation,
63.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
63.23 + *
63.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
63.25 + * or visit www.oracle.com if you need additional information or have any
63.26 + * questions.
63.27 + */
63.28 +
63.29 +package java.util;
63.30 +
63.31 +
63.32 +/**
63.33 + * An unbounded priority {@linkplain Queue queue} based on a priority heap.
63.34 + * The elements of the priority queue are ordered according to their
63.35 + * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
63.36 + * provided at queue construction time, depending on which constructor is
63.37 + * used. A priority queue does not permit {@code null} elements.
63.38 + * A priority queue relying on natural ordering also does not permit
63.39 + * insertion of non-comparable objects (doing so may result in
63.40 + * {@code ClassCastException}).
63.41 + *
63.42 + * <p>The <em>head</em> of this queue is the <em>least</em> element
63.43 + * with respect to the specified ordering. If multiple elements are
63.44 + * tied for least value, the head is one of those elements -- ties are
63.45 + * broken arbitrarily. The queue retrieval operations {@code poll},
63.46 + * {@code remove}, {@code peek}, and {@code element} access the
63.47 + * element at the head of the queue.
63.48 + *
63.49 + * <p>A priority queue is unbounded, but has an internal
63.50 + * <i>capacity</i> governing the size of an array used to store the
63.51 + * elements on the queue. It is always at least as large as the queue
63.52 + * size. As elements are added to a priority queue, its capacity
63.53 + * grows automatically. The details of the growth policy are not
63.54 + * specified.
63.55 + *
63.56 + * <p>This class and its iterator implement all of the
63.57 + * <em>optional</em> methods of the {@link Collection} and {@link
63.58 + * Iterator} interfaces. The Iterator provided in method {@link
63.59 + * #iterator()} is <em>not</em> guaranteed to traverse the elements of
63.60 + * the priority queue in any particular order. If you need ordered
63.61 + * traversal, consider using {@code Arrays.sort(pq.toArray())}.
63.62 + *
63.63 + * <p> <strong>Note that this implementation is not synchronized.</strong>
63.64 + * Multiple threads should not access a {@code PriorityQueue}
63.65 + * instance concurrently if any of the threads modifies the queue.
63.66 + * Instead, use the thread-safe {@link
63.67 + * java.util.concurrent.PriorityBlockingQueue} class.
63.68 + *
63.69 + * <p>Implementation note: this implementation provides
63.70 + * O(log(n)) time for the enqueing and dequeing methods
63.71 + * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
63.72 + * linear time for the {@code remove(Object)} and {@code contains(Object)}
63.73 + * methods; and constant time for the retrieval methods
63.74 + * ({@code peek}, {@code element}, and {@code size}).
63.75 + *
63.76 + * <p>This class is a member of the
63.77 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
63.78 + * Java Collections Framework</a>.
63.79 + *
63.80 + * @since 1.5
63.81 + * @author Josh Bloch, Doug Lea
63.82 + * @param <E> the type of elements held in this collection
63.83 + */
63.84 +public class PriorityQueue<E> extends AbstractQueue<E>
63.85 + implements java.io.Serializable {
63.86 +
63.87 + private static final long serialVersionUID = -7720805057305804111L;
63.88 +
63.89 + private static final int DEFAULT_INITIAL_CAPACITY = 11;
63.90 +
63.91 + /**
63.92 + * Priority queue represented as a balanced binary heap: the two
63.93 + * children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
63.94 + * priority queue is ordered by comparator, or by the elements'
63.95 + * natural ordering, if comparator is null: For each node n in the
63.96 + * heap and each descendant d of n, n <= d. The element with the
63.97 + * lowest value is in queue[0], assuming the queue is nonempty.
63.98 + */
63.99 + private transient Object[] queue;
63.100 +
63.101 + /**
63.102 + * The number of elements in the priority queue.
63.103 + */
63.104 + private int size = 0;
63.105 +
63.106 + /**
63.107 + * The comparator, or null if priority queue uses elements'
63.108 + * natural ordering.
63.109 + */
63.110 + private final Comparator<? super E> comparator;
63.111 +
63.112 + /**
63.113 + * The number of times this priority queue has been
63.114 + * <i>structurally modified</i>. See AbstractList for gory details.
63.115 + */
63.116 + private transient int modCount = 0;
63.117 +
63.118 + /**
63.119 + * Creates a {@code PriorityQueue} with the default initial
63.120 + * capacity (11) that orders its elements according to their
63.121 + * {@linkplain Comparable natural ordering}.
63.122 + */
63.123 + public PriorityQueue() {
63.124 + this(DEFAULT_INITIAL_CAPACITY, null);
63.125 + }
63.126 +
63.127 + /**
63.128 + * Creates a {@code PriorityQueue} with the specified initial
63.129 + * capacity that orders its elements according to their
63.130 + * {@linkplain Comparable natural ordering}.
63.131 + *
63.132 + * @param initialCapacity the initial capacity for this priority queue
63.133 + * @throws IllegalArgumentException if {@code initialCapacity} is less
63.134 + * than 1
63.135 + */
63.136 + public PriorityQueue(int initialCapacity) {
63.137 + this(initialCapacity, null);
63.138 + }
63.139 +
63.140 + /**
63.141 + * Creates a {@code PriorityQueue} with the specified initial capacity
63.142 + * that orders its elements according to the specified comparator.
63.143 + *
63.144 + * @param initialCapacity the initial capacity for this priority queue
63.145 + * @param comparator the comparator that will be used to order this
63.146 + * priority queue. If {@code null}, the {@linkplain Comparable
63.147 + * natural ordering} of the elements will be used.
63.148 + * @throws IllegalArgumentException if {@code initialCapacity} is
63.149 + * less than 1
63.150 + */
63.151 + public PriorityQueue(int initialCapacity,
63.152 + Comparator<? super E> comparator) {
63.153 + // Note: This restriction of at least one is not actually needed,
63.154 + // but continues for 1.5 compatibility
63.155 + if (initialCapacity < 1)
63.156 + throw new IllegalArgumentException();
63.157 + this.queue = new Object[initialCapacity];
63.158 + this.comparator = comparator;
63.159 + }
63.160 +
63.161 + /**
63.162 + * Creates a {@code PriorityQueue} containing the elements in the
63.163 + * specified collection. If the specified collection is an instance of
63.164 + * a {@link SortedSet} or is another {@code PriorityQueue}, this
63.165 + * priority queue will be ordered according to the same ordering.
63.166 + * Otherwise, this priority queue will be ordered according to the
63.167 + * {@linkplain Comparable natural ordering} of its elements.
63.168 + *
63.169 + * @param c the collection whose elements are to be placed
63.170 + * into this priority queue
63.171 + * @throws ClassCastException if elements of the specified collection
63.172 + * cannot be compared to one another according to the priority
63.173 + * queue's ordering
63.174 + * @throws NullPointerException if the specified collection or any
63.175 + * of its elements are null
63.176 + */
63.177 + @SuppressWarnings("unchecked")
63.178 + public PriorityQueue(Collection<? extends E> c) {
63.179 + if (c instanceof SortedSet<?>) {
63.180 + SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
63.181 + this.comparator = (Comparator<? super E>) ss.comparator();
63.182 + initElementsFromCollection(ss);
63.183 + }
63.184 + else if (c instanceof PriorityQueue<?>) {
63.185 + PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
63.186 + this.comparator = (Comparator<? super E>) pq.comparator();
63.187 + initFromPriorityQueue(pq);
63.188 + }
63.189 + else {
63.190 + this.comparator = null;
63.191 + initFromCollection(c);
63.192 + }
63.193 + }
63.194 +
63.195 + /**
63.196 + * Creates a {@code PriorityQueue} containing the elements in the
63.197 + * specified priority queue. This priority queue will be
63.198 + * ordered according to the same ordering as the given priority
63.199 + * queue.
63.200 + *
63.201 + * @param c the priority queue whose elements are to be placed
63.202 + * into this priority queue
63.203 + * @throws ClassCastException if elements of {@code c} cannot be
63.204 + * compared to one another according to {@code c}'s
63.205 + * ordering
63.206 + * @throws NullPointerException if the specified priority queue or any
63.207 + * of its elements are null
63.208 + */
63.209 + @SuppressWarnings("unchecked")
63.210 + public PriorityQueue(PriorityQueue<? extends E> c) {
63.211 + this.comparator = (Comparator<? super E>) c.comparator();
63.212 + initFromPriorityQueue(c);
63.213 + }
63.214 +
63.215 + /**
63.216 + * Creates a {@code PriorityQueue} containing the elements in the
63.217 + * specified sorted set. This priority queue will be ordered
63.218 + * according to the same ordering as the given sorted set.
63.219 + *
63.220 + * @param c the sorted set whose elements are to be placed
63.221 + * into this priority queue
63.222 + * @throws ClassCastException if elements of the specified sorted
63.223 + * set cannot be compared to one another according to the
63.224 + * sorted set's ordering
63.225 + * @throws NullPointerException if the specified sorted set or any
63.226 + * of its elements are null
63.227 + */
63.228 + @SuppressWarnings("unchecked")
63.229 + public PriorityQueue(SortedSet<? extends E> c) {
63.230 + this.comparator = (Comparator<? super E>) c.comparator();
63.231 + initElementsFromCollection(c);
63.232 + }
63.233 +
63.234 + private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
63.235 + if (c.getClass() == PriorityQueue.class) {
63.236 + this.queue = c.toArray();
63.237 + this.size = c.size();
63.238 + } else {
63.239 + initFromCollection(c);
63.240 + }
63.241 + }
63.242 +
63.243 + private void initElementsFromCollection(Collection<? extends E> c) {
63.244 + Object[] a = c.toArray();
63.245 + // If c.toArray incorrectly doesn't return Object[], copy it.
63.246 + if (a.getClass() != Object[].class)
63.247 + a = Arrays.copyOf(a, a.length, Object[].class);
63.248 + int len = a.length;
63.249 + if (len == 1 || this.comparator != null)
63.250 + for (int i = 0; i < len; i++)
63.251 + if (a[i] == null)
63.252 + throw new NullPointerException();
63.253 + this.queue = a;
63.254 + this.size = a.length;
63.255 + }
63.256 +
63.257 + /**
63.258 + * Initializes queue array with elements from the given Collection.
63.259 + *
63.260 + * @param c the collection
63.261 + */
63.262 + private void initFromCollection(Collection<? extends E> c) {
63.263 + initElementsFromCollection(c);
63.264 + heapify();
63.265 + }
63.266 +
63.267 + /**
63.268 + * The maximum size of array to allocate.
63.269 + * Some VMs reserve some header words in an array.
63.270 + * Attempts to allocate larger arrays may result in
63.271 + * OutOfMemoryError: Requested array size exceeds VM limit
63.272 + */
63.273 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
63.274 +
63.275 + /**
63.276 + * Increases the capacity of the array.
63.277 + *
63.278 + * @param minCapacity the desired minimum capacity
63.279 + */
63.280 + private void grow(int minCapacity) {
63.281 + int oldCapacity = queue.length;
63.282 + // Double size if small; else grow by 50%
63.283 + int newCapacity = oldCapacity + ((oldCapacity < 64) ?
63.284 + (oldCapacity + 2) :
63.285 + (oldCapacity >> 1));
63.286 + // overflow-conscious code
63.287 + if (newCapacity - MAX_ARRAY_SIZE > 0)
63.288 + newCapacity = hugeCapacity(minCapacity);
63.289 + queue = Arrays.copyOf(queue, newCapacity);
63.290 + }
63.291 +
63.292 + private static int hugeCapacity(int minCapacity) {
63.293 + if (minCapacity < 0) // overflow
63.294 + throw new OutOfMemoryError();
63.295 + return (minCapacity > MAX_ARRAY_SIZE) ?
63.296 + Integer.MAX_VALUE :
63.297 + MAX_ARRAY_SIZE;
63.298 + }
63.299 +
63.300 + /**
63.301 + * Inserts the specified element into this priority queue.
63.302 + *
63.303 + * @return {@code true} (as specified by {@link Collection#add})
63.304 + * @throws ClassCastException if the specified element cannot be
63.305 + * compared with elements currently in this priority queue
63.306 + * according to the priority queue's ordering
63.307 + * @throws NullPointerException if the specified element is null
63.308 + */
63.309 + public boolean add(E e) {
63.310 + return offer(e);
63.311 + }
63.312 +
63.313 + /**
63.314 + * Inserts the specified element into this priority queue.
63.315 + *
63.316 + * @return {@code true} (as specified by {@link Queue#offer})
63.317 + * @throws ClassCastException if the specified element cannot be
63.318 + * compared with elements currently in this priority queue
63.319 + * according to the priority queue's ordering
63.320 + * @throws NullPointerException if the specified element is null
63.321 + */
63.322 + public boolean offer(E e) {
63.323 + if (e == null)
63.324 + throw new NullPointerException();
63.325 + modCount++;
63.326 + int i = size;
63.327 + if (i >= queue.length)
63.328 + grow(i + 1);
63.329 + size = i + 1;
63.330 + if (i == 0)
63.331 + queue[0] = e;
63.332 + else
63.333 + siftUp(i, e);
63.334 + return true;
63.335 + }
63.336 +
63.337 + public E peek() {
63.338 + if (size == 0)
63.339 + return null;
63.340 + return (E) queue[0];
63.341 + }
63.342 +
63.343 + private int indexOf(Object o) {
63.344 + if (o != null) {
63.345 + for (int i = 0; i < size; i++)
63.346 + if (o.equals(queue[i]))
63.347 + return i;
63.348 + }
63.349 + return -1;
63.350 + }
63.351 +
63.352 + /**
63.353 + * Removes a single instance of the specified element from this queue,
63.354 + * if it is present. More formally, removes an element {@code e} such
63.355 + * that {@code o.equals(e)}, if this queue contains one or more such
63.356 + * elements. Returns {@code true} if and only if this queue contained
63.357 + * the specified element (or equivalently, if this queue changed as a
63.358 + * result of the call).
63.359 + *
63.360 + * @param o element to be removed from this queue, if present
63.361 + * @return {@code true} if this queue changed as a result of the call
63.362 + */
63.363 + public boolean remove(Object o) {
63.364 + int i = indexOf(o);
63.365 + if (i == -1)
63.366 + return false;
63.367 + else {
63.368 + removeAt(i);
63.369 + return true;
63.370 + }
63.371 + }
63.372 +
63.373 + /**
63.374 + * Version of remove using reference equality, not equals.
63.375 + * Needed by iterator.remove.
63.376 + *
63.377 + * @param o element to be removed from this queue, if present
63.378 + * @return {@code true} if removed
63.379 + */
63.380 + boolean removeEq(Object o) {
63.381 + for (int i = 0; i < size; i++) {
63.382 + if (o == queue[i]) {
63.383 + removeAt(i);
63.384 + return true;
63.385 + }
63.386 + }
63.387 + return false;
63.388 + }
63.389 +
63.390 + /**
63.391 + * Returns {@code true} if this queue contains the specified element.
63.392 + * More formally, returns {@code true} if and only if this queue contains
63.393 + * at least one element {@code e} such that {@code o.equals(e)}.
63.394 + *
63.395 + * @param o object to be checked for containment in this queue
63.396 + * @return {@code true} if this queue contains the specified element
63.397 + */
63.398 + public boolean contains(Object o) {
63.399 + return indexOf(o) != -1;
63.400 + }
63.401 +
63.402 + /**
63.403 + * Returns an array containing all of the elements in this queue.
63.404 + * The elements are in no particular order.
63.405 + *
63.406 + * <p>The returned array will be "safe" in that no references to it are
63.407 + * maintained by this queue. (In other words, this method must allocate
63.408 + * a new array). The caller is thus free to modify the returned array.
63.409 + *
63.410 + * <p>This method acts as bridge between array-based and collection-based
63.411 + * APIs.
63.412 + *
63.413 + * @return an array containing all of the elements in this queue
63.414 + */
63.415 + public Object[] toArray() {
63.416 + return Arrays.copyOf(queue, size);
63.417 + }
63.418 +
63.419 + /**
63.420 + * Returns an array containing all of the elements in this queue; the
63.421 + * runtime type of the returned array is that of the specified array.
63.422 + * The returned array elements are in no particular order.
63.423 + * If the queue fits in the specified array, it is returned therein.
63.424 + * Otherwise, a new array is allocated with the runtime type of the
63.425 + * specified array and the size of this queue.
63.426 + *
63.427 + * <p>If the queue fits in the specified array with room to spare
63.428 + * (i.e., the array has more elements than the queue), the element in
63.429 + * the array immediately following the end of the collection is set to
63.430 + * {@code null}.
63.431 + *
63.432 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
63.433 + * array-based and collection-based APIs. Further, this method allows
63.434 + * precise control over the runtime type of the output array, and may,
63.435 + * under certain circumstances, be used to save allocation costs.
63.436 + *
63.437 + * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
63.438 + * The following code can be used to dump the queue into a newly
63.439 + * allocated array of <tt>String</tt>:
63.440 + *
63.441 + * <pre>
63.442 + * String[] y = x.toArray(new String[0]);</pre>
63.443 + *
63.444 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
63.445 + * <tt>toArray()</tt>.
63.446 + *
63.447 + * @param a the array into which the elements of the queue are to
63.448 + * be stored, if it is big enough; otherwise, a new array of the
63.449 + * same runtime type is allocated for this purpose.
63.450 + * @return an array containing all of the elements in this queue
63.451 + * @throws ArrayStoreException if the runtime type of the specified array
63.452 + * is not a supertype of the runtime type of every element in
63.453 + * this queue
63.454 + * @throws NullPointerException if the specified array is null
63.455 + */
63.456 + public <T> T[] toArray(T[] a) {
63.457 + if (a.length < size)
63.458 + // Make a new array of a's runtime type, but my contents:
63.459 + return (T[]) Arrays.copyOf(queue, size, a.getClass());
63.460 + System.arraycopy(queue, 0, a, 0, size);
63.461 + if (a.length > size)
63.462 + a[size] = null;
63.463 + return a;
63.464 + }
63.465 +
63.466 + /**
63.467 + * Returns an iterator over the elements in this queue. The iterator
63.468 + * does not return the elements in any particular order.
63.469 + *
63.470 + * @return an iterator over the elements in this queue
63.471 + */
63.472 + public Iterator<E> iterator() {
63.473 + return new Itr();
63.474 + }
63.475 +
63.476 + private final class Itr implements Iterator<E> {
63.477 + /**
63.478 + * Index (into queue array) of element to be returned by
63.479 + * subsequent call to next.
63.480 + */
63.481 + private int cursor = 0;
63.482 +
63.483 + /**
63.484 + * Index of element returned by most recent call to next,
63.485 + * unless that element came from the forgetMeNot list.
63.486 + * Set to -1 if element is deleted by a call to remove.
63.487 + */
63.488 + private int lastRet = -1;
63.489 +
63.490 + /**
63.491 + * A queue of elements that were moved from the unvisited portion of
63.492 + * the heap into the visited portion as a result of "unlucky" element
63.493 + * removals during the iteration. (Unlucky element removals are those
63.494 + * that require a siftup instead of a siftdown.) We must visit all of
63.495 + * the elements in this list to complete the iteration. We do this
63.496 + * after we've completed the "normal" iteration.
63.497 + *
63.498 + * We expect that most iterations, even those involving removals,
63.499 + * will not need to store elements in this field.
63.500 + */
63.501 + private ArrayDeque<E> forgetMeNot = null;
63.502 +
63.503 + /**
63.504 + * Element returned by the most recent call to next iff that
63.505 + * element was drawn from the forgetMeNot list.
63.506 + */
63.507 + private E lastRetElt = null;
63.508 +
63.509 + /**
63.510 + * The modCount value that the iterator believes that the backing
63.511 + * Queue should have. If this expectation is violated, the iterator
63.512 + * has detected concurrent modification.
63.513 + */
63.514 + private int expectedModCount = modCount;
63.515 +
63.516 + public boolean hasNext() {
63.517 + return cursor < size ||
63.518 + (forgetMeNot != null && !forgetMeNot.isEmpty());
63.519 + }
63.520 +
63.521 + public E next() {
63.522 + if (expectedModCount != modCount)
63.523 + throw new ConcurrentModificationException();
63.524 + if (cursor < size)
63.525 + return (E) queue[lastRet = cursor++];
63.526 + if (forgetMeNot != null) {
63.527 + lastRet = -1;
63.528 + lastRetElt = forgetMeNot.poll();
63.529 + if (lastRetElt != null)
63.530 + return lastRetElt;
63.531 + }
63.532 + throw new NoSuchElementException();
63.533 + }
63.534 +
63.535 + public void remove() {
63.536 + if (expectedModCount != modCount)
63.537 + throw new ConcurrentModificationException();
63.538 + if (lastRet != -1) {
63.539 + E moved = PriorityQueue.this.removeAt(lastRet);
63.540 + lastRet = -1;
63.541 + if (moved == null)
63.542 + cursor--;
63.543 + else {
63.544 + if (forgetMeNot == null)
63.545 + forgetMeNot = new ArrayDeque<>();
63.546 + forgetMeNot.add(moved);
63.547 + }
63.548 + } else if (lastRetElt != null) {
63.549 + PriorityQueue.this.removeEq(lastRetElt);
63.550 + lastRetElt = null;
63.551 + } else {
63.552 + throw new IllegalStateException();
63.553 + }
63.554 + expectedModCount = modCount;
63.555 + }
63.556 + }
63.557 +
63.558 + public int size() {
63.559 + return size;
63.560 + }
63.561 +
63.562 + /**
63.563 + * Removes all of the elements from this priority queue.
63.564 + * The queue will be empty after this call returns.
63.565 + */
63.566 + public void clear() {
63.567 + modCount++;
63.568 + for (int i = 0; i < size; i++)
63.569 + queue[i] = null;
63.570 + size = 0;
63.571 + }
63.572 +
63.573 + public E poll() {
63.574 + if (size == 0)
63.575 + return null;
63.576 + int s = --size;
63.577 + modCount++;
63.578 + E result = (E) queue[0];
63.579 + E x = (E) queue[s];
63.580 + queue[s] = null;
63.581 + if (s != 0)
63.582 + siftDown(0, x);
63.583 + return result;
63.584 + }
63.585 +
63.586 + /**
63.587 + * Removes the ith element from queue.
63.588 + *
63.589 + * Normally this method leaves the elements at up to i-1,
63.590 + * inclusive, untouched. Under these circumstances, it returns
63.591 + * null. Occasionally, in order to maintain the heap invariant,
63.592 + * it must swap a later element of the list with one earlier than
63.593 + * i. Under these circumstances, this method returns the element
63.594 + * that was previously at the end of the list and is now at some
63.595 + * position before i. This fact is used by iterator.remove so as to
63.596 + * avoid missing traversing elements.
63.597 + */
63.598 + private E removeAt(int i) {
63.599 + assert i >= 0 && i < size;
63.600 + modCount++;
63.601 + int s = --size;
63.602 + if (s == i) // removed last element
63.603 + queue[i] = null;
63.604 + else {
63.605 + E moved = (E) queue[s];
63.606 + queue[s] = null;
63.607 + siftDown(i, moved);
63.608 + if (queue[i] == moved) {
63.609 + siftUp(i, moved);
63.610 + if (queue[i] != moved)
63.611 + return moved;
63.612 + }
63.613 + }
63.614 + return null;
63.615 + }
63.616 +
63.617 + /**
63.618 + * Inserts item x at position k, maintaining heap invariant by
63.619 + * promoting x up the tree until it is greater than or equal to
63.620 + * its parent, or is the root.
63.621 + *
63.622 + * To simplify and speed up coercions and comparisons. the
63.623 + * Comparable and Comparator versions are separated into different
63.624 + * methods that are otherwise identical. (Similarly for siftDown.)
63.625 + *
63.626 + * @param k the position to fill
63.627 + * @param x the item to insert
63.628 + */
63.629 + private void siftUp(int k, E x) {
63.630 + if (comparator != null)
63.631 + siftUpUsingComparator(k, x);
63.632 + else
63.633 + siftUpComparable(k, x);
63.634 + }
63.635 +
63.636 + private void siftUpComparable(int k, E x) {
63.637 + Comparable<? super E> key = (Comparable<? super E>) x;
63.638 + while (k > 0) {
63.639 + int parent = (k - 1) >>> 1;
63.640 + Object e = queue[parent];
63.641 + if (key.compareTo((E) e) >= 0)
63.642 + break;
63.643 + queue[k] = e;
63.644 + k = parent;
63.645 + }
63.646 + queue[k] = key;
63.647 + }
63.648 +
63.649 + private void siftUpUsingComparator(int k, E x) {
63.650 + while (k > 0) {
63.651 + int parent = (k - 1) >>> 1;
63.652 + Object e = queue[parent];
63.653 + if (comparator.compare(x, (E) e) >= 0)
63.654 + break;
63.655 + queue[k] = e;
63.656 + k = parent;
63.657 + }
63.658 + queue[k] = x;
63.659 + }
63.660 +
63.661 + /**
63.662 + * Inserts item x at position k, maintaining heap invariant by
63.663 + * demoting x down the tree repeatedly until it is less than or
63.664 + * equal to its children or is a leaf.
63.665 + *
63.666 + * @param k the position to fill
63.667 + * @param x the item to insert
63.668 + */
63.669 + private void siftDown(int k, E x) {
63.670 + if (comparator != null)
63.671 + siftDownUsingComparator(k, x);
63.672 + else
63.673 + siftDownComparable(k, x);
63.674 + }
63.675 +
63.676 + private void siftDownComparable(int k, E x) {
63.677 + Comparable<? super E> key = (Comparable<? super E>)x;
63.678 + int half = size >>> 1; // loop while a non-leaf
63.679 + while (k < half) {
63.680 + int child = (k << 1) + 1; // assume left child is least
63.681 + Object c = queue[child];
63.682 + int right = child + 1;
63.683 + if (right < size &&
63.684 + ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
63.685 + c = queue[child = right];
63.686 + if (key.compareTo((E) c) <= 0)
63.687 + break;
63.688 + queue[k] = c;
63.689 + k = child;
63.690 + }
63.691 + queue[k] = key;
63.692 + }
63.693 +
63.694 + private void siftDownUsingComparator(int k, E x) {
63.695 + int half = size >>> 1;
63.696 + while (k < half) {
63.697 + int child = (k << 1) + 1;
63.698 + Object c = queue[child];
63.699 + int right = child + 1;
63.700 + if (right < size &&
63.701 + comparator.compare((E) c, (E) queue[right]) > 0)
63.702 + c = queue[child = right];
63.703 + if (comparator.compare(x, (E) c) <= 0)
63.704 + break;
63.705 + queue[k] = c;
63.706 + k = child;
63.707 + }
63.708 + queue[k] = x;
63.709 + }
63.710 +
63.711 + /**
63.712 + * Establishes the heap invariant (described above) in the entire tree,
63.713 + * assuming nothing about the order of the elements prior to the call.
63.714 + */
63.715 + private void heapify() {
63.716 + for (int i = (size >>> 1) - 1; i >= 0; i--)
63.717 + siftDown(i, (E) queue[i]);
63.718 + }
63.719 +
63.720 + /**
63.721 + * Returns the comparator used to order the elements in this
63.722 + * queue, or {@code null} if this queue is sorted according to
63.723 + * the {@linkplain Comparable natural ordering} of its elements.
63.724 + *
63.725 + * @return the comparator used to order this queue, or
63.726 + * {@code null} if this queue is sorted according to the
63.727 + * natural ordering of its elements
63.728 + */
63.729 + public Comparator<? super E> comparator() {
63.730 + return comparator;
63.731 + }
63.732 +
63.733 +
63.734 +}
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/emul/compact/src/main/java/java/util/Queue.java Tue Feb 05 17:04:22 2013 +0100
64.3 @@ -0,0 +1,218 @@
64.4 +/*
64.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
64.6 + *
64.7 + * This code is free software; you can redistribute it and/or modify it
64.8 + * under the terms of the GNU General Public License version 2 only, as
64.9 + * published by the Free Software Foundation. Oracle designates this
64.10 + * particular file as subject to the "Classpath" exception as provided
64.11 + * by Oracle in the LICENSE file that accompanied this code.
64.12 + *
64.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
64.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
64.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
64.16 + * version 2 for more details (a copy is included in the LICENSE file that
64.17 + * accompanied this code).
64.18 + *
64.19 + * You should have received a copy of the GNU General Public License version
64.20 + * 2 along with this work; if not, write to the Free Software Foundation,
64.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
64.22 + *
64.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
64.24 + * or visit www.oracle.com if you need additional information or have any
64.25 + * questions.
64.26 + */
64.27 +
64.28 +/*
64.29 + * This file is available under and governed by the GNU General Public
64.30 + * License version 2 only, as published by the Free Software Foundation.
64.31 + * However, the following notice accompanied the original version of this
64.32 + * file:
64.33 + *
64.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
64.35 + * Expert Group and released to the public domain, as explained at
64.36 + * http://creativecommons.org/publicdomain/zero/1.0/
64.37 + */
64.38 +
64.39 +package java.util;
64.40 +
64.41 +/**
64.42 + * A collection designed for holding elements prior to processing.
64.43 + * Besides basic {@link java.util.Collection Collection} operations,
64.44 + * queues provide additional insertion, extraction, and inspection
64.45 + * operations. Each of these methods exists in two forms: one throws
64.46 + * an exception if the operation fails, the other returns a special
64.47 + * value (either <tt>null</tt> or <tt>false</tt>, depending on the
64.48 + * operation). The latter form of the insert operation is designed
64.49 + * specifically for use with capacity-restricted <tt>Queue</tt>
64.50 + * implementations; in most implementations, insert operations cannot
64.51 + * fail.
64.52 + *
64.53 + * <p>
64.54 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
64.55 + * <tr>
64.56 + * <td></td>
64.57 + * <td ALIGN=CENTER><em>Throws exception</em></td>
64.58 + * <td ALIGN=CENTER><em>Returns special value</em></td>
64.59 + * </tr>
64.60 + * <tr>
64.61 + * <td><b>Insert</b></td>
64.62 + * <td>{@link #add add(e)}</td>
64.63 + * <td>{@link #offer offer(e)}</td>
64.64 + * </tr>
64.65 + * <tr>
64.66 + * <td><b>Remove</b></td>
64.67 + * <td>{@link #remove remove()}</td>
64.68 + * <td>{@link #poll poll()}</td>
64.69 + * </tr>
64.70 + * <tr>
64.71 + * <td><b>Examine</b></td>
64.72 + * <td>{@link #element element()}</td>
64.73 + * <td>{@link #peek peek()}</td>
64.74 + * </tr>
64.75 + * </table>
64.76 + *
64.77 + * <p>Queues typically, but do not necessarily, order elements in a
64.78 + * FIFO (first-in-first-out) manner. Among the exceptions are
64.79 + * priority queues, which order elements according to a supplied
64.80 + * comparator, or the elements' natural ordering, and LIFO queues (or
64.81 + * stacks) which order the elements LIFO (last-in-first-out).
64.82 + * Whatever the ordering used, the <em>head</em> of the queue is that
64.83 + * element which would be removed by a call to {@link #remove() } or
64.84 + * {@link #poll()}. In a FIFO queue, all new elements are inserted at
64.85 + * the <em> tail</em> of the queue. Other kinds of queues may use
64.86 + * different placement rules. Every <tt>Queue</tt> implementation
64.87 + * must specify its ordering properties.
64.88 + *
64.89 + * <p>The {@link #offer offer} method inserts an element if possible,
64.90 + * otherwise returning <tt>false</tt>. This differs from the {@link
64.91 + * java.util.Collection#add Collection.add} method, which can fail to
64.92 + * add an element only by throwing an unchecked exception. The
64.93 + * <tt>offer</tt> method is designed for use when failure is a normal,
64.94 + * rather than exceptional occurrence, for example, in fixed-capacity
64.95 + * (or "bounded") queues.
64.96 + *
64.97 + * <p>The {@link #remove()} and {@link #poll()} methods remove and
64.98 + * return the head of the queue.
64.99 + * Exactly which element is removed from the queue is a
64.100 + * function of the queue's ordering policy, which differs from
64.101 + * implementation to implementation. The <tt>remove()</tt> and
64.102 + * <tt>poll()</tt> methods differ only in their behavior when the
64.103 + * queue is empty: the <tt>remove()</tt> method throws an exception,
64.104 + * while the <tt>poll()</tt> method returns <tt>null</tt>.
64.105 + *
64.106 + * <p>The {@link #element()} and {@link #peek()} methods return, but do
64.107 + * not remove, the head of the queue.
64.108 + *
64.109 + * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue
64.110 + * methods</i>, which are common in concurrent programming. These methods,
64.111 + * which wait for elements to appear or for space to become available, are
64.112 + * defined in the {@link java.util.concurrent.BlockingQueue} interface, which
64.113 + * extends this interface.
64.114 + *
64.115 + * <p><tt>Queue</tt> implementations generally do not allow insertion
64.116 + * of <tt>null</tt> elements, although some implementations, such as
64.117 + * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>.
64.118 + * Even in the implementations that permit it, <tt>null</tt> should
64.119 + * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also
64.120 + * used as a special return value by the <tt>poll</tt> method to
64.121 + * indicate that the queue contains no elements.
64.122 + *
64.123 + * <p><tt>Queue</tt> implementations generally do not define
64.124 + * element-based versions of methods <tt>equals</tt> and
64.125 + * <tt>hashCode</tt> but instead inherit the identity based versions
64.126 + * from class <tt>Object</tt>, because element-based equality is not
64.127 + * always well-defined for queues with the same elements but different
64.128 + * ordering properties.
64.129 + *
64.130 + *
64.131 + * <p>This interface is a member of the
64.132 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
64.133 + * Java Collections Framework</a>.
64.134 + *
64.135 + * @see java.util.Collection
64.136 + * @see LinkedList
64.137 + * @see PriorityQueue
64.138 + * @see java.util.concurrent.LinkedBlockingQueue
64.139 + * @see java.util.concurrent.BlockingQueue
64.140 + * @see java.util.concurrent.ArrayBlockingQueue
64.141 + * @see java.util.concurrent.LinkedBlockingQueue
64.142 + * @see java.util.concurrent.PriorityBlockingQueue
64.143 + * @since 1.5
64.144 + * @author Doug Lea
64.145 + * @param <E> the type of elements held in this collection
64.146 + */
64.147 +public interface Queue<E> extends Collection<E> {
64.148 + /**
64.149 + * Inserts the specified element into this queue if it is possible to do so
64.150 + * immediately without violating capacity restrictions, returning
64.151 + * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
64.152 + * if no space is currently available.
64.153 + *
64.154 + * @param e the element to add
64.155 + * @return <tt>true</tt> (as specified by {@link Collection#add})
64.156 + * @throws IllegalStateException if the element cannot be added at this
64.157 + * time due to capacity restrictions
64.158 + * @throws ClassCastException if the class of the specified element
64.159 + * prevents it from being added to this queue
64.160 + * @throws NullPointerException if the specified element is null and
64.161 + * this queue does not permit null elements
64.162 + * @throws IllegalArgumentException if some property of this element
64.163 + * prevents it from being added to this queue
64.164 + */
64.165 + boolean add(E e);
64.166 +
64.167 + /**
64.168 + * Inserts the specified element into this queue if it is possible to do
64.169 + * so immediately without violating capacity restrictions.
64.170 + * When using a capacity-restricted queue, this method is generally
64.171 + * preferable to {@link #add}, which can fail to insert an element only
64.172 + * by throwing an exception.
64.173 + *
64.174 + * @param e the element to add
64.175 + * @return <tt>true</tt> if the element was added to this queue, else
64.176 + * <tt>false</tt>
64.177 + * @throws ClassCastException if the class of the specified element
64.178 + * prevents it from being added to this queue
64.179 + * @throws NullPointerException if the specified element is null and
64.180 + * this queue does not permit null elements
64.181 + * @throws IllegalArgumentException if some property of this element
64.182 + * prevents it from being added to this queue
64.183 + */
64.184 + boolean offer(E e);
64.185 +
64.186 + /**
64.187 + * Retrieves and removes the head of this queue. This method differs
64.188 + * from {@link #poll poll} only in that it throws an exception if this
64.189 + * queue is empty.
64.190 + *
64.191 + * @return the head of this queue
64.192 + * @throws NoSuchElementException if this queue is empty
64.193 + */
64.194 + E remove();
64.195 +
64.196 + /**
64.197 + * Retrieves and removes the head of this queue,
64.198 + * or returns <tt>null</tt> if this queue is empty.
64.199 + *
64.200 + * @return the head of this queue, or <tt>null</tt> if this queue is empty
64.201 + */
64.202 + E poll();
64.203 +
64.204 + /**
64.205 + * Retrieves, but does not remove, the head of this queue. This method
64.206 + * differs from {@link #peek peek} only in that it throws an exception
64.207 + * if this queue is empty.
64.208 + *
64.209 + * @return the head of this queue
64.210 + * @throws NoSuchElementException if this queue is empty
64.211 + */
64.212 + E element();
64.213 +
64.214 + /**
64.215 + * Retrieves, but does not remove, the head of this queue,
64.216 + * or returns <tt>null</tt> if this queue is empty.
64.217 + *
64.218 + * @return the head of this queue, or <tt>null</tt> if this queue is empty
64.219 + */
64.220 + E peek();
64.221 +}
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/emul/compact/src/main/java/java/util/Random.java Tue Feb 05 17:04:22 2013 +0100
65.3 @@ -0,0 +1,503 @@
65.4 +/*
65.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
65.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
65.7 + *
65.8 + * This code is free software; you can redistribute it and/or modify it
65.9 + * under the terms of the GNU General Public License version 2 only, as
65.10 + * published by the Free Software Foundation. Oracle designates this
65.11 + * particular file as subject to the "Classpath" exception as provided
65.12 + * by Oracle in the LICENSE file that accompanied this code.
65.13 + *
65.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
65.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
65.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
65.17 + * version 2 for more details (a copy is included in the LICENSE file that
65.18 + * accompanied this code).
65.19 + *
65.20 + * You should have received a copy of the GNU General Public License version
65.21 + * 2 along with this work; if not, write to the Free Software Foundation,
65.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
65.23 + *
65.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
65.25 + * or visit www.oracle.com if you need additional information or have any
65.26 + * questions.
65.27 + */
65.28 +
65.29 +package java.util;
65.30 +
65.31 +import org.apidesign.bck2brwsr.emul.lang.System;
65.32 +
65.33 +/**
65.34 + * An instance of this class is used to generate a stream of
65.35 + * pseudorandom numbers. The class uses a 48-bit seed, which is
65.36 + * modified using a linear congruential formula. (See Donald Knuth,
65.37 + * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.)
65.38 + * <p>
65.39 + * If two instances of {@code Random} are created with the same
65.40 + * seed, and the same sequence of method calls is made for each, they
65.41 + * will generate and return identical sequences of numbers. In order to
65.42 + * guarantee this property, particular algorithms are specified for the
65.43 + * class {@code Random}. Java implementations must use all the algorithms
65.44 + * shown here for the class {@code Random}, for the sake of absolute
65.45 + * portability of Java code. However, subclasses of class {@code Random}
65.46 + * are permitted to use other algorithms, so long as they adhere to the
65.47 + * general contracts for all the methods.
65.48 + * <p>
65.49 + * The algorithms implemented by class {@code Random} use a
65.50 + * {@code protected} utility method that on each invocation can supply
65.51 + * up to 32 pseudorandomly generated bits.
65.52 + * <p>
65.53 + * Many applications will find the method {@link Math#random} simpler to use.
65.54 + *
65.55 + * <p>Instances of {@code java.util.Random} are threadsafe.
65.56 + * However, the concurrent use of the same {@code java.util.Random}
65.57 + * instance across threads may encounter contention and consequent
65.58 + * poor performance. Consider instead using
65.59 + * {@link java.util.concurrent.ThreadLocalRandom} in multithreaded
65.60 + * designs.
65.61 + *
65.62 + * <p>Instances of {@code java.util.Random} are not cryptographically
65.63 + * secure. Consider instead using {@link java.security.SecureRandom} to
65.64 + * get a cryptographically secure pseudo-random number generator for use
65.65 + * by security-sensitive applications.
65.66 + *
65.67 + * @author Frank Yellin
65.68 + * @since 1.0
65.69 + */
65.70 +public
65.71 +class Random implements java.io.Serializable {
65.72 + /** use serialVersionUID from JDK 1.1 for interoperability */
65.73 + static final long serialVersionUID = 3905348978240129619L;
65.74 +
65.75 + /**
65.76 + * The internal state associated with this pseudorandom number generator.
65.77 + * (The specs for the methods in this class describe the ongoing
65.78 + * computation of this value.)
65.79 + */
65.80 + private long seed;
65.81 +
65.82 + private static final long multiplier = 0x5DEECE66DL;
65.83 + private static final long addend = 0xBL;
65.84 + private static final long mask = (1L << 48) - 1;
65.85 +
65.86 + /**
65.87 + * Creates a new random number generator. This constructor sets
65.88 + * the seed of the random number generator to a value very likely
65.89 + * to be distinct from any other invocation of this constructor.
65.90 + */
65.91 + public Random() {
65.92 + this(seedUniquifier() ^ System.nanoTime());
65.93 + }
65.94 +
65.95 + private static synchronized long seedUniquifier() {
65.96 + // L'Ecuyer, "Tables of Linear Congruential Generators of
65.97 + // Different Sizes and Good Lattice Structure", 1999
65.98 + long current = seedUniquifier;
65.99 + long next = current * 181783497276652981L;
65.100 + seedUniquifier = next;
65.101 + return next;
65.102 + }
65.103 +
65.104 + private static long seedUniquifier = 8682522807148012L;
65.105 +
65.106 + /**
65.107 + * Creates a new random number generator using a single {@code long} seed.
65.108 + * The seed is the initial value of the internal state of the pseudorandom
65.109 + * number generator which is maintained by method {@link #next}.
65.110 + *
65.111 + * <p>The invocation {@code new Random(seed)} is equivalent to:
65.112 + * <pre> {@code
65.113 + * Random rnd = new Random();
65.114 + * rnd.setSeed(seed);}</pre>
65.115 + *
65.116 + * @param seed the initial seed
65.117 + * @see #setSeed(long)
65.118 + */
65.119 + public Random(long seed) {
65.120 + this.seed = initialScramble(seed);
65.121 + }
65.122 +
65.123 + private static long initialScramble(long seed) {
65.124 + return (seed ^ multiplier) & mask;
65.125 + }
65.126 +
65.127 + /**
65.128 + * Sets the seed of this random number generator using a single
65.129 + * {@code long} seed. The general contract of {@code setSeed} is
65.130 + * that it alters the state of this random number generator object
65.131 + * so as to be in exactly the same state as if it had just been
65.132 + * created with the argument {@code seed} as a seed. The method
65.133 + * {@code setSeed} is implemented by class {@code Random} by
65.134 + * atomically updating the seed to
65.135 + * <pre>{@code (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)}</pre>
65.136 + * and clearing the {@code haveNextNextGaussian} flag used by {@link
65.137 + * #nextGaussian}.
65.138 + *
65.139 + * <p>The implementation of {@code setSeed} by class {@code Random}
65.140 + * happens to use only 48 bits of the given seed. In general, however,
65.141 + * an overriding method may use all 64 bits of the {@code long}
65.142 + * argument as a seed value.
65.143 + *
65.144 + * @param seed the initial seed
65.145 + */
65.146 + synchronized public void setSeed(long seed) {
65.147 + this.seed = initialScramble(seed);
65.148 + haveNextNextGaussian = false;
65.149 + }
65.150 +
65.151 + /**
65.152 + * Generates the next pseudorandom number. Subclasses should
65.153 + * override this, as this is used by all other methods.
65.154 + *
65.155 + * <p>The general contract of {@code next} is that it returns an
65.156 + * {@code int} value and if the argument {@code bits} is between
65.157 + * {@code 1} and {@code 32} (inclusive), then that many low-order
65.158 + * bits of the returned value will be (approximately) independently
65.159 + * chosen bit values, each of which is (approximately) equally
65.160 + * likely to be {@code 0} or {@code 1}. The method {@code next} is
65.161 + * implemented by class {@code Random} by atomically updating the seed to
65.162 + * <pre>{@code (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)}</pre>
65.163 + * and returning
65.164 + * <pre>{@code (int)(seed >>> (48 - bits))}.</pre>
65.165 + *
65.166 + * This is a linear congruential pseudorandom number generator, as
65.167 + * defined by D. H. Lehmer and described by Donald E. Knuth in
65.168 + * <i>The Art of Computer Programming,</i> Volume 3:
65.169 + * <i>Seminumerical Algorithms</i>, section 3.2.1.
65.170 + *
65.171 + * @param bits random bits
65.172 + * @return the next pseudorandom value from this random number
65.173 + * generator's sequence
65.174 + * @since 1.1
65.175 + */
65.176 + protected synchronized int next(int bits) {
65.177 + long oldseed, nextseed;
65.178 + long seed = this.seed;
65.179 + oldseed = seed;
65.180 + nextseed = (oldseed * multiplier + addend) & mask;
65.181 + this.seed = nextseed;
65.182 + return (int)(nextseed >>> (48 - bits));
65.183 + }
65.184 +
65.185 + /**
65.186 + * Generates random bytes and places them into a user-supplied
65.187 + * byte array. The number of random bytes produced is equal to
65.188 + * the length of the byte array.
65.189 + *
65.190 + * <p>The method {@code nextBytes} is implemented by class {@code Random}
65.191 + * as if by:
65.192 + * <pre> {@code
65.193 + * public void nextBytes(byte[] bytes) {
65.194 + * for (int i = 0; i < bytes.length; )
65.195 + * for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4);
65.196 + * n-- > 0; rnd >>= 8)
65.197 + * bytes[i++] = (byte)rnd;
65.198 + * }}</pre>
65.199 + *
65.200 + * @param bytes the byte array to fill with random bytes
65.201 + * @throws NullPointerException if the byte array is null
65.202 + * @since 1.1
65.203 + */
65.204 + public void nextBytes(byte[] bytes) {
65.205 + for (int i = 0, len = bytes.length; i < len; )
65.206 + for (int rnd = nextInt(),
65.207 + n = Math.min(len - i, Integer.SIZE/Byte.SIZE);
65.208 + n-- > 0; rnd >>= Byte.SIZE)
65.209 + bytes[i++] = (byte)rnd;
65.210 + }
65.211 +
65.212 + /**
65.213 + * Returns the next pseudorandom, uniformly distributed {@code int}
65.214 + * value from this random number generator's sequence. The general
65.215 + * contract of {@code nextInt} is that one {@code int} value is
65.216 + * pseudorandomly generated and returned. All 2<font size="-1"><sup>32
65.217 + * </sup></font> possible {@code int} values are produced with
65.218 + * (approximately) equal probability.
65.219 + *
65.220 + * <p>The method {@code nextInt} is implemented by class {@code Random}
65.221 + * as if by:
65.222 + * <pre> {@code
65.223 + * public int nextInt() {
65.224 + * return next(32);
65.225 + * }}</pre>
65.226 + *
65.227 + * @return the next pseudorandom, uniformly distributed {@code int}
65.228 + * value from this random number generator's sequence
65.229 + */
65.230 + public int nextInt() {
65.231 + return next(32);
65.232 + }
65.233 +
65.234 + /**
65.235 + * Returns a pseudorandom, uniformly distributed {@code int} value
65.236 + * between 0 (inclusive) and the specified value (exclusive), drawn from
65.237 + * this random number generator's sequence. The general contract of
65.238 + * {@code nextInt} is that one {@code int} value in the specified range
65.239 + * is pseudorandomly generated and returned. All {@code n} possible
65.240 + * {@code int} values are produced with (approximately) equal
65.241 + * probability. The method {@code nextInt(int n)} is implemented by
65.242 + * class {@code Random} as if by:
65.243 + * <pre> {@code
65.244 + * public int nextInt(int n) {
65.245 + * if (n <= 0)
65.246 + * throw new IllegalArgumentException("n must be positive");
65.247 + *
65.248 + * if ((n & -n) == n) // i.e., n is a power of 2
65.249 + * return (int)((n * (long)next(31)) >> 31);
65.250 + *
65.251 + * int bits, val;
65.252 + * do {
65.253 + * bits = next(31);
65.254 + * val = bits % n;
65.255 + * } while (bits - val + (n-1) < 0);
65.256 + * return val;
65.257 + * }}</pre>
65.258 + *
65.259 + * <p>The hedge "approximately" is used in the foregoing description only
65.260 + * because the next method is only approximately an unbiased source of
65.261 + * independently chosen bits. If it were a perfect source of randomly
65.262 + * chosen bits, then the algorithm shown would choose {@code int}
65.263 + * values from the stated range with perfect uniformity.
65.264 + * <p>
65.265 + * The algorithm is slightly tricky. It rejects values that would result
65.266 + * in an uneven distribution (due to the fact that 2^31 is not divisible
65.267 + * by n). The probability of a value being rejected depends on n. The
65.268 + * worst case is n=2^30+1, for which the probability of a reject is 1/2,
65.269 + * and the expected number of iterations before the loop terminates is 2.
65.270 + * <p>
65.271 + * The algorithm treats the case where n is a power of two specially: it
65.272 + * returns the correct number of high-order bits from the underlying
65.273 + * pseudo-random number generator. In the absence of special treatment,
65.274 + * the correct number of <i>low-order</i> bits would be returned. Linear
65.275 + * congruential pseudo-random number generators such as the one
65.276 + * implemented by this class are known to have short periods in the
65.277 + * sequence of values of their low-order bits. Thus, this special case
65.278 + * greatly increases the length of the sequence of values returned by
65.279 + * successive calls to this method if n is a small power of two.
65.280 + *
65.281 + * @param n the bound on the random number to be returned. Must be
65.282 + * positive.
65.283 + * @return the next pseudorandom, uniformly distributed {@code int}
65.284 + * value between {@code 0} (inclusive) and {@code n} (exclusive)
65.285 + * from this random number generator's sequence
65.286 + * @throws IllegalArgumentException if n is not positive
65.287 + * @since 1.2
65.288 + */
65.289 +
65.290 + public int nextInt(int n) {
65.291 + if (n <= 0)
65.292 + throw new IllegalArgumentException("n must be positive");
65.293 +
65.294 + if ((n & -n) == n) // i.e., n is a power of 2
65.295 + return (int)((n * (long)next(31)) >> 31);
65.296 +
65.297 + int bits, val;
65.298 + do {
65.299 + bits = next(31);
65.300 + val = bits % n;
65.301 + } while (bits - val + (n-1) < 0);
65.302 + return val;
65.303 + }
65.304 +
65.305 + /**
65.306 + * Returns the next pseudorandom, uniformly distributed {@code long}
65.307 + * value from this random number generator's sequence. The general
65.308 + * contract of {@code nextLong} is that one {@code long} value is
65.309 + * pseudorandomly generated and returned.
65.310 + *
65.311 + * <p>The method {@code nextLong} is implemented by class {@code Random}
65.312 + * as if by:
65.313 + * <pre> {@code
65.314 + * public long nextLong() {
65.315 + * return ((long)next(32) << 32) + next(32);
65.316 + * }}</pre>
65.317 + *
65.318 + * Because class {@code Random} uses a seed with only 48 bits,
65.319 + * this algorithm will not return all possible {@code long} values.
65.320 + *
65.321 + * @return the next pseudorandom, uniformly distributed {@code long}
65.322 + * value from this random number generator's sequence
65.323 + */
65.324 + public long nextLong() {
65.325 + // it's okay that the bottom word remains signed.
65.326 + return ((long)(next(32)) << 32) + next(32);
65.327 + }
65.328 +
65.329 + /**
65.330 + * Returns the next pseudorandom, uniformly distributed
65.331 + * {@code boolean} value from this random number generator's
65.332 + * sequence. The general contract of {@code nextBoolean} is that one
65.333 + * {@code boolean} value is pseudorandomly generated and returned. The
65.334 + * values {@code true} and {@code false} are produced with
65.335 + * (approximately) equal probability.
65.336 + *
65.337 + * <p>The method {@code nextBoolean} is implemented by class {@code Random}
65.338 + * as if by:
65.339 + * <pre> {@code
65.340 + * public boolean nextBoolean() {
65.341 + * return next(1) != 0;
65.342 + * }}</pre>
65.343 + *
65.344 + * @return the next pseudorandom, uniformly distributed
65.345 + * {@code boolean} value from this random number generator's
65.346 + * sequence
65.347 + * @since 1.2
65.348 + */
65.349 + public boolean nextBoolean() {
65.350 + return next(1) != 0;
65.351 + }
65.352 +
65.353 + /**
65.354 + * Returns the next pseudorandom, uniformly distributed {@code float}
65.355 + * value between {@code 0.0} and {@code 1.0} from this random
65.356 + * number generator's sequence.
65.357 + *
65.358 + * <p>The general contract of {@code nextFloat} is that one
65.359 + * {@code float} value, chosen (approximately) uniformly from the
65.360 + * range {@code 0.0f} (inclusive) to {@code 1.0f} (exclusive), is
65.361 + * pseudorandomly generated and returned. All 2<font
65.362 + * size="-1"><sup>24</sup></font> possible {@code float} values
65.363 + * of the form <i>m x </i>2<font
65.364 + * size="-1"><sup>-24</sup></font>, where <i>m</i> is a positive
65.365 + * integer less than 2<font size="-1"><sup>24</sup> </font>, are
65.366 + * produced with (approximately) equal probability.
65.367 + *
65.368 + * <p>The method {@code nextFloat} is implemented by class {@code Random}
65.369 + * as if by:
65.370 + * <pre> {@code
65.371 + * public float nextFloat() {
65.372 + * return next(24) / ((float)(1 << 24));
65.373 + * }}</pre>
65.374 + *
65.375 + * <p>The hedge "approximately" is used in the foregoing description only
65.376 + * because the next method is only approximately an unbiased source of
65.377 + * independently chosen bits. If it were a perfect source of randomly
65.378 + * chosen bits, then the algorithm shown would choose {@code float}
65.379 + * values from the stated range with perfect uniformity.<p>
65.380 + * [In early versions of Java, the result was incorrectly calculated as:
65.381 + * <pre> {@code
65.382 + * return next(30) / ((float)(1 << 30));}</pre>
65.383 + * This might seem to be equivalent, if not better, but in fact it
65.384 + * introduced a slight nonuniformity because of the bias in the rounding
65.385 + * of floating-point numbers: it was slightly more likely that the
65.386 + * low-order bit of the significand would be 0 than that it would be 1.]
65.387 + *
65.388 + * @return the next pseudorandom, uniformly distributed {@code float}
65.389 + * value between {@code 0.0} and {@code 1.0} from this
65.390 + * random number generator's sequence
65.391 + */
65.392 + public float nextFloat() {
65.393 + return next(24) / ((float)(1 << 24));
65.394 + }
65.395 +
65.396 + /**
65.397 + * Returns the next pseudorandom, uniformly distributed
65.398 + * {@code double} value between {@code 0.0} and
65.399 + * {@code 1.0} from this random number generator's sequence.
65.400 + *
65.401 + * <p>The general contract of {@code nextDouble} is that one
65.402 + * {@code double} value, chosen (approximately) uniformly from the
65.403 + * range {@code 0.0d} (inclusive) to {@code 1.0d} (exclusive), is
65.404 + * pseudorandomly generated and returned.
65.405 + *
65.406 + * <p>The method {@code nextDouble} is implemented by class {@code Random}
65.407 + * as if by:
65.408 + * <pre> {@code
65.409 + * public double nextDouble() {
65.410 + * return (((long)next(26) << 27) + next(27))
65.411 + * / (double)(1L << 53);
65.412 + * }}</pre>
65.413 + *
65.414 + * <p>The hedge "approximately" is used in the foregoing description only
65.415 + * because the {@code next} method is only approximately an unbiased
65.416 + * source of independently chosen bits. If it were a perfect source of
65.417 + * randomly chosen bits, then the algorithm shown would choose
65.418 + * {@code double} values from the stated range with perfect uniformity.
65.419 + * <p>[In early versions of Java, the result was incorrectly calculated as:
65.420 + * <pre> {@code
65.421 + * return (((long)next(27) << 27) + next(27))
65.422 + * / (double)(1L << 54);}</pre>
65.423 + * This might seem to be equivalent, if not better, but in fact it
65.424 + * introduced a large nonuniformity because of the bias in the rounding
65.425 + * of floating-point numbers: it was three times as likely that the
65.426 + * low-order bit of the significand would be 0 than that it would be 1!
65.427 + * This nonuniformity probably doesn't matter much in practice, but we
65.428 + * strive for perfection.]
65.429 + *
65.430 + * @return the next pseudorandom, uniformly distributed {@code double}
65.431 + * value between {@code 0.0} and {@code 1.0} from this
65.432 + * random number generator's sequence
65.433 + * @see Math#random
65.434 + */
65.435 + public double nextDouble() {
65.436 + return (((long)(next(26)) << 27) + next(27))
65.437 + / (double)(1L << 53);
65.438 + }
65.439 +
65.440 + private double nextNextGaussian;
65.441 + private boolean haveNextNextGaussian = false;
65.442 +
65.443 + /**
65.444 + * Returns the next pseudorandom, Gaussian ("normally") distributed
65.445 + * {@code double} value with mean {@code 0.0} and standard
65.446 + * deviation {@code 1.0} from this random number generator's sequence.
65.447 + * <p>
65.448 + * The general contract of {@code nextGaussian} is that one
65.449 + * {@code double} value, chosen from (approximately) the usual
65.450 + * normal distribution with mean {@code 0.0} and standard deviation
65.451 + * {@code 1.0}, is pseudorandomly generated and returned.
65.452 + *
65.453 + * <p>The method {@code nextGaussian} is implemented by class
65.454 + * {@code Random} as if by a threadsafe version of the following:
65.455 + * <pre> {@code
65.456 + * private double nextNextGaussian;
65.457 + * private boolean haveNextNextGaussian = false;
65.458 + *
65.459 + * public double nextGaussian() {
65.460 + * if (haveNextNextGaussian) {
65.461 + * haveNextNextGaussian = false;
65.462 + * return nextNextGaussian;
65.463 + * } else {
65.464 + * double v1, v2, s;
65.465 + * do {
65.466 + * v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
65.467 + * v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
65.468 + * s = v1 * v1 + v2 * v2;
65.469 + * } while (s >= 1 || s == 0);
65.470 + * double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
65.471 + * nextNextGaussian = v2 * multiplier;
65.472 + * haveNextNextGaussian = true;
65.473 + * return v1 * multiplier;
65.474 + * }
65.475 + * }}</pre>
65.476 + * This uses the <i>polar method</i> of G. E. P. Box, M. E. Muller, and
65.477 + * G. Marsaglia, as described by Donald E. Knuth in <i>The Art of
65.478 + * Computer Programming</i>, Volume 3: <i>Seminumerical Algorithms</i>,
65.479 + * section 3.4.1, subsection C, algorithm P. Note that it generates two
65.480 + * independent values at the cost of only one call to {@code StrictMath.log}
65.481 + * and one call to {@code StrictMath.sqrt}.
65.482 + *
65.483 + * @return the next pseudorandom, Gaussian ("normally") distributed
65.484 + * {@code double} value with mean {@code 0.0} and
65.485 + * standard deviation {@code 1.0} from this random number
65.486 + * generator's sequence
65.487 + */
65.488 + synchronized public double nextGaussian() {
65.489 + // See Knuth, ACP, Section 3.4.1 Algorithm C.
65.490 + if (haveNextNextGaussian) {
65.491 + haveNextNextGaussian = false;
65.492 + return nextNextGaussian;
65.493 + } else {
65.494 + double v1, v2, s;
65.495 + do {
65.496 + v1 = 2 * nextDouble() - 1; // between -1 and 1
65.497 + v2 = 2 * nextDouble() - 1; // between -1 and 1
65.498 + s = v1 * v1 + v2 * v2;
65.499 + } while (s >= 1 || s == 0);
65.500 + double multiplier = Math.sqrt(-2 * Math.log(s)/s);
65.501 + nextNextGaussian = v2 * multiplier;
65.502 + haveNextNextGaussian = true;
65.503 + return v1 * multiplier;
65.504 + }
65.505 + }
65.506 +}
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/emul/compact/src/main/java/java/util/SortedMap.java Tue Feb 05 17:04:22 2013 +0100
66.3 @@ -0,0 +1,284 @@
66.4 +/*
66.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
66.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
66.7 + *
66.8 + * This code is free software; you can redistribute it and/or modify it
66.9 + * under the terms of the GNU General Public License version 2 only, as
66.10 + * published by the Free Software Foundation. Oracle designates this
66.11 + * particular file as subject to the "Classpath" exception as provided
66.12 + * by Oracle in the LICENSE file that accompanied this code.
66.13 + *
66.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
66.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
66.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
66.17 + * version 2 for more details (a copy is included in the LICENSE file that
66.18 + * accompanied this code).
66.19 + *
66.20 + * You should have received a copy of the GNU General Public License version
66.21 + * 2 along with this work; if not, write to the Free Software Foundation,
66.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
66.23 + *
66.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
66.25 + * or visit www.oracle.com if you need additional information or have any
66.26 + * questions.
66.27 + */
66.28 +
66.29 +package java.util;
66.30 +
66.31 +/**
66.32 + * A {@link Map} that further provides a <em>total ordering</em> on its keys.
66.33 + * The map is ordered according to the {@linkplain Comparable natural
66.34 + * ordering} of its keys, or by a {@link Comparator} typically
66.35 + * provided at sorted map creation time. This order is reflected when
66.36 + * iterating over the sorted map's collection views (returned by the
66.37 + * {@code entrySet}, {@code keySet} and {@code values} methods).
66.38 + * Several additional operations are provided to take advantage of the
66.39 + * ordering. (This interface is the map analogue of {@link SortedSet}.)
66.40 + *
66.41 + * <p>All keys inserted into a sorted map must implement the {@code Comparable}
66.42 + * interface (or be accepted by the specified comparator). Furthermore, all
66.43 + * such keys must be <em>mutually comparable</em>: {@code k1.compareTo(k2)} (or
66.44 + * {@code comparator.compare(k1, k2)}) must not throw a
66.45 + * {@code ClassCastException} for any keys {@code k1} and {@code k2} in
66.46 + * the sorted map. Attempts to violate this restriction will cause the
66.47 + * offending method or constructor invocation to throw a
66.48 + * {@code ClassCastException}.
66.49 + *
66.50 + * <p>Note that the ordering maintained by a sorted map (whether or not an
66.51 + * explicit comparator is provided) must be <em>consistent with equals</em> if
66.52 + * the sorted map is to correctly implement the {@code Map} interface. (See
66.53 + * the {@code Comparable} interface or {@code Comparator} interface for a
66.54 + * precise definition of <em>consistent with equals</em>.) This is so because
66.55 + * the {@code Map} interface is defined in terms of the {@code equals}
66.56 + * operation, but a sorted map performs all key comparisons using its
66.57 + * {@code compareTo} (or {@code compare}) method, so two keys that are
66.58 + * deemed equal by this method are, from the standpoint of the sorted map,
66.59 + * equal. The behavior of a tree map <em>is</em> well-defined even if its
66.60 + * ordering is inconsistent with equals; it just fails to obey the general
66.61 + * contract of the {@code Map} interface.
66.62 + *
66.63 + * <p>All general-purpose sorted map implementation classes should provide four
66.64 + * "standard" constructors. It is not possible to enforce this recommendation
66.65 + * though as required constructors cannot be specified by interfaces. The
66.66 + * expected "standard" constructors for all sorted map implementations are:
66.67 + * <ol>
66.68 + * <li>A void (no arguments) constructor, which creates an empty sorted map
66.69 + * sorted according to the natural ordering of its keys.</li>
66.70 + * <li>A constructor with a single argument of type {@code Comparator}, which
66.71 + * creates an empty sorted map sorted according to the specified comparator.</li>
66.72 + * <li>A constructor with a single argument of type {@code Map}, which creates
66.73 + * a new map with the same key-value mappings as its argument, sorted
66.74 + * according to the keys' natural ordering.</li>
66.75 + * <li>A constructor with a single argument of type {@code SortedMap}, which
66.76 + * creates a new sorted map with the same key-value mappings and the same
66.77 + * ordering as the input sorted map.</li>
66.78 + * </ol>
66.79 + *
66.80 + * <p><strong>Note</strong>: several methods return submaps with restricted key
66.81 + * ranges. Such ranges are <em>half-open</em>, that is, they include their low
66.82 + * endpoint but not their high endpoint (where applicable). If you need a
66.83 + * <em>closed range</em> (which includes both endpoints), and the key type
66.84 + * allows for calculation of the successor of a given key, merely request
66.85 + * the subrange from {@code lowEndpoint} to
66.86 + * {@code successor(highEndpoint)}. For example, suppose that {@code m}
66.87 + * is a map whose keys are strings. The following idiom obtains a view
66.88 + * containing all of the key-value mappings in {@code m} whose keys are
66.89 + * between {@code low} and {@code high}, inclusive:<pre>
66.90 + * SortedMap<String, V> sub = m.subMap(low, high+"\0");</pre>
66.91 + *
66.92 + * A similar technique can be used to generate an <em>open range</em>
66.93 + * (which contains neither endpoint). The following idiom obtains a
66.94 + * view containing all of the key-value mappings in {@code m} whose keys
66.95 + * are between {@code low} and {@code high}, exclusive:<pre>
66.96 + * SortedMap<String, V> sub = m.subMap(low+"\0", high);</pre>
66.97 + *
66.98 + * <p>This interface is a member of the
66.99 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
66.100 + * Java Collections Framework</a>.
66.101 + *
66.102 + * @param <K> the type of keys maintained by this map
66.103 + * @param <V> the type of mapped values
66.104 + *
66.105 + * @author Josh Bloch
66.106 + * @see Map
66.107 + * @see TreeMap
66.108 + * @see SortedSet
66.109 + * @see Comparator
66.110 + * @see Comparable
66.111 + * @see Collection
66.112 + * @see ClassCastException
66.113 + * @since 1.2
66.114 + */
66.115 +
66.116 +public interface SortedMap<K,V> extends Map<K,V> {
66.117 + /**
66.118 + * Returns the comparator used to order the keys in this map, or
66.119 + * {@code null} if this map uses the {@linkplain Comparable
66.120 + * natural ordering} of its keys.
66.121 + *
66.122 + * @return the comparator used to order the keys in this map,
66.123 + * or {@code null} if this map uses the natural ordering
66.124 + * of its keys
66.125 + */
66.126 + Comparator<? super K> comparator();
66.127 +
66.128 + /**
66.129 + * Returns a view of the portion of this map whose keys range from
66.130 + * {@code fromKey}, inclusive, to {@code toKey}, exclusive. (If
66.131 + * {@code fromKey} and {@code toKey} are equal, the returned map
66.132 + * is empty.) The returned map is backed by this map, so changes
66.133 + * in the returned map are reflected in this map, and vice-versa.
66.134 + * The returned map supports all optional map operations that this
66.135 + * map supports.
66.136 + *
66.137 + * <p>The returned map will throw an {@code IllegalArgumentException}
66.138 + * on an attempt to insert a key outside its range.
66.139 + *
66.140 + * @param fromKey low endpoint (inclusive) of the keys in the returned map
66.141 + * @param toKey high endpoint (exclusive) of the keys in the returned map
66.142 + * @return a view of the portion of this map whose keys range from
66.143 + * {@code fromKey}, inclusive, to {@code toKey}, exclusive
66.144 + * @throws ClassCastException if {@code fromKey} and {@code toKey}
66.145 + * cannot be compared to one another using this map's comparator
66.146 + * (or, if the map has no comparator, using natural ordering).
66.147 + * Implementations may, but are not required to, throw this
66.148 + * exception if {@code fromKey} or {@code toKey}
66.149 + * cannot be compared to keys currently in the map.
66.150 + * @throws NullPointerException if {@code fromKey} or {@code toKey}
66.151 + * is null and this map does not permit null keys
66.152 + * @throws IllegalArgumentException if {@code fromKey} is greater than
66.153 + * {@code toKey}; or if this map itself has a restricted
66.154 + * range, and {@code fromKey} or {@code toKey} lies
66.155 + * outside the bounds of the range
66.156 + */
66.157 + SortedMap<K,V> subMap(K fromKey, K toKey);
66.158 +
66.159 + /**
66.160 + * Returns a view of the portion of this map whose keys are
66.161 + * strictly less than {@code toKey}. The returned map is backed
66.162 + * by this map, so changes in the returned map are reflected in
66.163 + * this map, and vice-versa. The returned map supports all
66.164 + * optional map operations that this map supports.
66.165 + *
66.166 + * <p>The returned map will throw an {@code IllegalArgumentException}
66.167 + * on an attempt to insert a key outside its range.
66.168 + *
66.169 + * @param toKey high endpoint (exclusive) of the keys in the returned map
66.170 + * @return a view of the portion of this map whose keys are strictly
66.171 + * less than {@code toKey}
66.172 + * @throws ClassCastException if {@code toKey} is not compatible
66.173 + * with this map's comparator (or, if the map has no comparator,
66.174 + * if {@code toKey} does not implement {@link Comparable}).
66.175 + * Implementations may, but are not required to, throw this
66.176 + * exception if {@code toKey} cannot be compared to keys
66.177 + * currently in the map.
66.178 + * @throws NullPointerException if {@code toKey} is null and
66.179 + * this map does not permit null keys
66.180 + * @throws IllegalArgumentException if this map itself has a
66.181 + * restricted range, and {@code toKey} lies outside the
66.182 + * bounds of the range
66.183 + */
66.184 + SortedMap<K,V> headMap(K toKey);
66.185 +
66.186 + /**
66.187 + * Returns a view of the portion of this map whose keys are
66.188 + * greater than or equal to {@code fromKey}. The returned map is
66.189 + * backed by this map, so changes in the returned map are
66.190 + * reflected in this map, and vice-versa. The returned map
66.191 + * supports all optional map operations that this map supports.
66.192 + *
66.193 + * <p>The returned map will throw an {@code IllegalArgumentException}
66.194 + * on an attempt to insert a key outside its range.
66.195 + *
66.196 + * @param fromKey low endpoint (inclusive) of the keys in the returned map
66.197 + * @return a view of the portion of this map whose keys are greater
66.198 + * than or equal to {@code fromKey}
66.199 + * @throws ClassCastException if {@code fromKey} is not compatible
66.200 + * with this map's comparator (or, if the map has no comparator,
66.201 + * if {@code fromKey} does not implement {@link Comparable}).
66.202 + * Implementations may, but are not required to, throw this
66.203 + * exception if {@code fromKey} cannot be compared to keys
66.204 + * currently in the map.
66.205 + * @throws NullPointerException if {@code fromKey} is null and
66.206 + * this map does not permit null keys
66.207 + * @throws IllegalArgumentException if this map itself has a
66.208 + * restricted range, and {@code fromKey} lies outside the
66.209 + * bounds of the range
66.210 + */
66.211 + SortedMap<K,V> tailMap(K fromKey);
66.212 +
66.213 + /**
66.214 + * Returns the first (lowest) key currently in this map.
66.215 + *
66.216 + * @return the first (lowest) key currently in this map
66.217 + * @throws NoSuchElementException if this map is empty
66.218 + */
66.219 + K firstKey();
66.220 +
66.221 + /**
66.222 + * Returns the last (highest) key currently in this map.
66.223 + *
66.224 + * @return the last (highest) key currently in this map
66.225 + * @throws NoSuchElementException if this map is empty
66.226 + */
66.227 + K lastKey();
66.228 +
66.229 + /**
66.230 + * Returns a {@link Set} view of the keys contained in this map.
66.231 + * The set's iterator returns the keys in ascending order.
66.232 + * The set is backed by the map, so changes to the map are
66.233 + * reflected in the set, and vice-versa. If the map is modified
66.234 + * while an iteration over the set is in progress (except through
66.235 + * the iterator's own {@code remove} operation), the results of
66.236 + * the iteration are undefined. The set supports element removal,
66.237 + * which removes the corresponding mapping from the map, via the
66.238 + * {@code Iterator.remove}, {@code Set.remove},
66.239 + * {@code removeAll}, {@code retainAll}, and {@code clear}
66.240 + * operations. It does not support the {@code add} or {@code addAll}
66.241 + * operations.
66.242 + *
66.243 + * @return a set view of the keys contained in this map, sorted in
66.244 + * ascending order
66.245 + */
66.246 + Set<K> keySet();
66.247 +
66.248 + /**
66.249 + * Returns a {@link Collection} view of the values contained in this map.
66.250 + * The collection's iterator returns the values in ascending order
66.251 + * of the corresponding keys.
66.252 + * The collection is backed by the map, so changes to the map are
66.253 + * reflected in the collection, and vice-versa. If the map is
66.254 + * modified while an iteration over the collection is in progress
66.255 + * (except through the iterator's own {@code remove} operation),
66.256 + * the results of the iteration are undefined. The collection
66.257 + * supports element removal, which removes the corresponding
66.258 + * mapping from the map, via the {@code Iterator.remove},
66.259 + * {@code Collection.remove}, {@code removeAll},
66.260 + * {@code retainAll} and {@code clear} operations. It does not
66.261 + * support the {@code add} or {@code addAll} operations.
66.262 + *
66.263 + * @return a collection view of the values contained in this map,
66.264 + * sorted in ascending key order
66.265 + */
66.266 + Collection<V> values();
66.267 +
66.268 + /**
66.269 + * Returns a {@link Set} view of the mappings contained in this map.
66.270 + * The set's iterator returns the entries in ascending key order.
66.271 + * The set is backed by the map, so changes to the map are
66.272 + * reflected in the set, and vice-versa. If the map is modified
66.273 + * while an iteration over the set is in progress (except through
66.274 + * the iterator's own {@code remove} operation, or through the
66.275 + * {@code setValue} operation on a map entry returned by the
66.276 + * iterator) the results of the iteration are undefined. The set
66.277 + * supports element removal, which removes the corresponding
66.278 + * mapping from the map, via the {@code Iterator.remove},
66.279 + * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
66.280 + * {@code clear} operations. It does not support the
66.281 + * {@code add} or {@code addAll} operations.
66.282 + *
66.283 + * @return a set view of the mappings contained in this map,
66.284 + * sorted in ascending key order
66.285 + */
66.286 + Set<Map.Entry<K, V>> entrySet();
66.287 +}
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/emul/compact/src/main/java/java/util/SortedSet.java Tue Feb 05 17:04:22 2013 +0100
67.3 @@ -0,0 +1,222 @@
67.4 +/*
67.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
67.7 + *
67.8 + * This code is free software; you can redistribute it and/or modify it
67.9 + * under the terms of the GNU General Public License version 2 only, as
67.10 + * published by the Free Software Foundation. Oracle designates this
67.11 + * particular file as subject to the "Classpath" exception as provided
67.12 + * by Oracle in the LICENSE file that accompanied this code.
67.13 + *
67.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
67.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
67.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
67.17 + * version 2 for more details (a copy is included in the LICENSE file that
67.18 + * accompanied this code).
67.19 + *
67.20 + * You should have received a copy of the GNU General Public License version
67.21 + * 2 along with this work; if not, write to the Free Software Foundation,
67.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
67.23 + *
67.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
67.25 + * or visit www.oracle.com if you need additional information or have any
67.26 + * questions.
67.27 + */
67.28 +
67.29 +package java.util;
67.30 +
67.31 +/**
67.32 + * A {@link Set} that further provides a <i>total ordering</i> on its elements.
67.33 + * The elements are ordered using their {@linkplain Comparable natural
67.34 + * ordering}, or by a {@link Comparator} typically provided at sorted
67.35 + * set creation time. The set's iterator will traverse the set in
67.36 + * ascending element order. Several additional operations are provided
67.37 + * to take advantage of the ordering. (This interface is the set
67.38 + * analogue of {@link SortedMap}.)
67.39 + *
67.40 + * <p>All elements inserted into a sorted set must implement the <tt>Comparable</tt>
67.41 + * interface (or be accepted by the specified comparator). Furthermore, all
67.42 + * such elements must be <i>mutually comparable</i>: <tt>e1.compareTo(e2)</tt>
67.43 + * (or <tt>comparator.compare(e1, e2)</tt>) must not throw a
67.44 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and <tt>e2</tt> in
67.45 + * the sorted set. Attempts to violate this restriction will cause the
67.46 + * offending method or constructor invocation to throw a
67.47 + * <tt>ClassCastException</tt>.
67.48 + *
67.49 + * <p>Note that the ordering maintained by a sorted set (whether or not an
67.50 + * explicit comparator is provided) must be <i>consistent with equals</i> if
67.51 + * the sorted set is to correctly implement the <tt>Set</tt> interface. (See
67.52 + * the <tt>Comparable</tt> interface or <tt>Comparator</tt> interface for a
67.53 + * precise definition of <i>consistent with equals</i>.) This is so because
67.54 + * the <tt>Set</tt> interface is defined in terms of the <tt>equals</tt>
67.55 + * operation, but a sorted set performs all element comparisons using its
67.56 + * <tt>compareTo</tt> (or <tt>compare</tt>) method, so two elements that are
67.57 + * deemed equal by this method are, from the standpoint of the sorted set,
67.58 + * equal. The behavior of a sorted set <i>is</i> well-defined even if its
67.59 + * ordering is inconsistent with equals; it just fails to obey the general
67.60 + * contract of the <tt>Set</tt> interface.
67.61 + *
67.62 + * <p>All general-purpose sorted set implementation classes should
67.63 + * provide four "standard" constructors: 1) A void (no arguments)
67.64 + * constructor, which creates an empty sorted set sorted according to
67.65 + * the natural ordering of its elements. 2) A constructor with a
67.66 + * single argument of type <tt>Comparator</tt>, which creates an empty
67.67 + * sorted set sorted according to the specified comparator. 3) A
67.68 + * constructor with a single argument of type <tt>Collection</tt>,
67.69 + * which creates a new sorted set with the same elements as its
67.70 + * argument, sorted according to the natural ordering of the elements.
67.71 + * 4) A constructor with a single argument of type <tt>SortedSet</tt>,
67.72 + * which creates a new sorted set with the same elements and the same
67.73 + * ordering as the input sorted set. There is no way to enforce this
67.74 + * recommendation, as interfaces cannot contain constructors.
67.75 + *
67.76 + * <p>Note: several methods return subsets with restricted ranges.
67.77 + * Such ranges are <i>half-open</i>, that is, they include their low
67.78 + * endpoint but not their high endpoint (where applicable).
67.79 + * If you need a <i>closed range</i> (which includes both endpoints), and
67.80 + * the element type allows for calculation of the successor of a given
67.81 + * value, merely request the subrange from <tt>lowEndpoint</tt> to
67.82 + * <tt>successor(highEndpoint)</tt>. For example, suppose that <tt>s</tt>
67.83 + * is a sorted set of strings. The following idiom obtains a view
67.84 + * containing all of the strings in <tt>s</tt> from <tt>low</tt> to
67.85 + * <tt>high</tt>, inclusive:<pre>
67.86 + * SortedSet<String> sub = s.subSet(low, high+"\0");</pre>
67.87 + *
67.88 + * A similar technique can be used to generate an <i>open range</i> (which
67.89 + * contains neither endpoint). The following idiom obtains a view
67.90 + * containing all of the Strings in <tt>s</tt> from <tt>low</tt> to
67.91 + * <tt>high</tt>, exclusive:<pre>
67.92 + * SortedSet<String> sub = s.subSet(low+"\0", high);</pre>
67.93 + *
67.94 + * <p>This interface is a member of the
67.95 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
67.96 + * Java Collections Framework</a>.
67.97 + *
67.98 + * @param <E> the type of elements maintained by this set
67.99 + *
67.100 + * @author Josh Bloch
67.101 + * @see Set
67.102 + * @see TreeSet
67.103 + * @see SortedMap
67.104 + * @see Collection
67.105 + * @see Comparable
67.106 + * @see Comparator
67.107 + * @see ClassCastException
67.108 + * @since 1.2
67.109 + */
67.110 +
67.111 +public interface SortedSet<E> extends Set<E> {
67.112 + /**
67.113 + * Returns the comparator used to order the elements in this set,
67.114 + * or <tt>null</tt> if this set uses the {@linkplain Comparable
67.115 + * natural ordering} of its elements.
67.116 + *
67.117 + * @return the comparator used to order the elements in this set,
67.118 + * or <tt>null</tt> if this set uses the natural ordering
67.119 + * of its elements
67.120 + */
67.121 + Comparator<? super E> comparator();
67.122 +
67.123 + /**
67.124 + * Returns a view of the portion of this set whose elements range
67.125 + * from <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>,
67.126 + * exclusive. (If <tt>fromElement</tt> and <tt>toElement</tt> are
67.127 + * equal, the returned set is empty.) The returned set is backed
67.128 + * by this set, so changes in the returned set are reflected in
67.129 + * this set, and vice-versa. The returned set supports all
67.130 + * optional set operations that this set supports.
67.131 + *
67.132 + * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
67.133 + * on an attempt to insert an element outside its range.
67.134 + *
67.135 + * @param fromElement low endpoint (inclusive) of the returned set
67.136 + * @param toElement high endpoint (exclusive) of the returned set
67.137 + * @return a view of the portion of this set whose elements range from
67.138 + * <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>, exclusive
67.139 + * @throws ClassCastException if <tt>fromElement</tt> and
67.140 + * <tt>toElement</tt> cannot be compared to one another using this
67.141 + * set's comparator (or, if the set has no comparator, using
67.142 + * natural ordering). Implementations may, but are not required
67.143 + * to, throw this exception if <tt>fromElement</tt> or
67.144 + * <tt>toElement</tt> cannot be compared to elements currently in
67.145 + * the set.
67.146 + * @throws NullPointerException if <tt>fromElement</tt> or
67.147 + * <tt>toElement</tt> is null and this set does not permit null
67.148 + * elements
67.149 + * @throws IllegalArgumentException if <tt>fromElement</tt> is
67.150 + * greater than <tt>toElement</tt>; or if this set itself
67.151 + * has a restricted range, and <tt>fromElement</tt> or
67.152 + * <tt>toElement</tt> lies outside the bounds of the range
67.153 + */
67.154 + SortedSet<E> subSet(E fromElement, E toElement);
67.155 +
67.156 + /**
67.157 + * Returns a view of the portion of this set whose elements are
67.158 + * strictly less than <tt>toElement</tt>. The returned set is
67.159 + * backed by this set, so changes in the returned set are
67.160 + * reflected in this set, and vice-versa. The returned set
67.161 + * supports all optional set operations that this set supports.
67.162 + *
67.163 + * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
67.164 + * on an attempt to insert an element outside its range.
67.165 + *
67.166 + * @param toElement high endpoint (exclusive) of the returned set
67.167 + * @return a view of the portion of this set whose elements are strictly
67.168 + * less than <tt>toElement</tt>
67.169 + * @throws ClassCastException if <tt>toElement</tt> is not compatible
67.170 + * with this set's comparator (or, if the set has no comparator,
67.171 + * if <tt>toElement</tt> does not implement {@link Comparable}).
67.172 + * Implementations may, but are not required to, throw this
67.173 + * exception if <tt>toElement</tt> cannot be compared to elements
67.174 + * currently in the set.
67.175 + * @throws NullPointerException if <tt>toElement</tt> is null and
67.176 + * this set does not permit null elements
67.177 + * @throws IllegalArgumentException if this set itself has a
67.178 + * restricted range, and <tt>toElement</tt> lies outside the
67.179 + * bounds of the range
67.180 + */
67.181 + SortedSet<E> headSet(E toElement);
67.182 +
67.183 + /**
67.184 + * Returns a view of the portion of this set whose elements are
67.185 + * greater than or equal to <tt>fromElement</tt>. The returned
67.186 + * set is backed by this set, so changes in the returned set are
67.187 + * reflected in this set, and vice-versa. The returned set
67.188 + * supports all optional set operations that this set supports.
67.189 + *
67.190 + * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
67.191 + * on an attempt to insert an element outside its range.
67.192 + *
67.193 + * @param fromElement low endpoint (inclusive) of the returned set
67.194 + * @return a view of the portion of this set whose elements are greater
67.195 + * than or equal to <tt>fromElement</tt>
67.196 + * @throws ClassCastException if <tt>fromElement</tt> is not compatible
67.197 + * with this set's comparator (or, if the set has no comparator,
67.198 + * if <tt>fromElement</tt> does not implement {@link Comparable}).
67.199 + * Implementations may, but are not required to, throw this
67.200 + * exception if <tt>fromElement</tt> cannot be compared to elements
67.201 + * currently in the set.
67.202 + * @throws NullPointerException if <tt>fromElement</tt> is null
67.203 + * and this set does not permit null elements
67.204 + * @throws IllegalArgumentException if this set itself has a
67.205 + * restricted range, and <tt>fromElement</tt> lies outside the
67.206 + * bounds of the range
67.207 + */
67.208 + SortedSet<E> tailSet(E fromElement);
67.209 +
67.210 + /**
67.211 + * Returns the first (lowest) element currently in this set.
67.212 + *
67.213 + * @return the first (lowest) element currently in this set
67.214 + * @throws NoSuchElementException if this set is empty
67.215 + */
67.216 + E first();
67.217 +
67.218 + /**
67.219 + * Returns the last (highest) element currently in this set.
67.220 + *
67.221 + * @return the last (highest) element currently in this set
67.222 + * @throws NoSuchElementException if this set is empty
67.223 + */
67.224 + E last();
67.225 +}
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/emul/compact/src/main/java/java/util/Stack.java Tue Feb 05 17:04:22 2013 +0100
68.3 @@ -0,0 +1,141 @@
68.4 +/*
68.5 + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
68.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
68.7 + *
68.8 + * This code is free software; you can redistribute it and/or modify it
68.9 + * under the terms of the GNU General Public License version 2 only, as
68.10 + * published by the Free Software Foundation. Oracle designates this
68.11 + * particular file as subject to the "Classpath" exception as provided
68.12 + * by Oracle in the LICENSE file that accompanied this code.
68.13 + *
68.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
68.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
68.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
68.17 + * version 2 for more details (a copy is included in the LICENSE file that
68.18 + * accompanied this code).
68.19 + *
68.20 + * You should have received a copy of the GNU General Public License version
68.21 + * 2 along with this work; if not, write to the Free Software Foundation,
68.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
68.23 + *
68.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
68.25 + * or visit www.oracle.com if you need additional information or have any
68.26 + * questions.
68.27 + */
68.28 +
68.29 +package java.util;
68.30 +
68.31 +/**
68.32 + * The <code>Stack</code> class represents a last-in-first-out
68.33 + * (LIFO) stack of objects. It extends class <tt>Vector</tt> with five
68.34 + * operations that allow a vector to be treated as a stack. The usual
68.35 + * <tt>push</tt> and <tt>pop</tt> operations are provided, as well as a
68.36 + * method to <tt>peek</tt> at the top item on the stack, a method to test
68.37 + * for whether the stack is <tt>empty</tt>, and a method to <tt>search</tt>
68.38 + * the stack for an item and discover how far it is from the top.
68.39 + * <p>
68.40 + * When a stack is first created, it contains no items.
68.41 + *
68.42 + * <p>A more complete and consistent set of LIFO stack operations is
68.43 + * provided by the {@link Deque} interface and its implementations, which
68.44 + * should be used in preference to this class. For example:
68.45 + * <pre> {@code
68.46 + * Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
68.47 + *
68.48 + * @author Jonathan Payne
68.49 + * @since JDK1.0
68.50 + */
68.51 +public
68.52 +class Stack<E> extends Vector<E> {
68.53 + /**
68.54 + * Creates an empty Stack.
68.55 + */
68.56 + public Stack() {
68.57 + }
68.58 +
68.59 + /**
68.60 + * Pushes an item onto the top of this stack. This has exactly
68.61 + * the same effect as:
68.62 + * <blockquote><pre>
68.63 + * addElement(item)</pre></blockquote>
68.64 + *
68.65 + * @param item the item to be pushed onto this stack.
68.66 + * @return the <code>item</code> argument.
68.67 + * @see java.util.Vector#addElement
68.68 + */
68.69 + public E push(E item) {
68.70 + addElement(item);
68.71 +
68.72 + return item;
68.73 + }
68.74 +
68.75 + /**
68.76 + * Removes the object at the top of this stack and returns that
68.77 + * object as the value of this function.
68.78 + *
68.79 + * @return The object at the top of this stack (the last item
68.80 + * of the <tt>Vector</tt> object).
68.81 + * @throws EmptyStackException if this stack is empty.
68.82 + */
68.83 + public synchronized E pop() {
68.84 + E obj;
68.85 + int len = size();
68.86 +
68.87 + obj = peek();
68.88 + removeElementAt(len - 1);
68.89 +
68.90 + return obj;
68.91 + }
68.92 +
68.93 + /**
68.94 + * Looks at the object at the top of this stack without removing it
68.95 + * from the stack.
68.96 + *
68.97 + * @return the object at the top of this stack (the last item
68.98 + * of the <tt>Vector</tt> object).
68.99 + * @throws EmptyStackException if this stack is empty.
68.100 + */
68.101 + public synchronized E peek() {
68.102 + int len = size();
68.103 +
68.104 + if (len == 0)
68.105 + throw new EmptyStackException();
68.106 + return elementAt(len - 1);
68.107 + }
68.108 +
68.109 + /**
68.110 + * Tests if this stack is empty.
68.111 + *
68.112 + * @return <code>true</code> if and only if this stack contains
68.113 + * no items; <code>false</code> otherwise.
68.114 + */
68.115 + public boolean empty() {
68.116 + return size() == 0;
68.117 + }
68.118 +
68.119 + /**
68.120 + * Returns the 1-based position where an object is on this stack.
68.121 + * If the object <tt>o</tt> occurs as an item in this stack, this
68.122 + * method returns the distance from the top of the stack of the
68.123 + * occurrence nearest the top of the stack; the topmost item on the
68.124 + * stack is considered to be at distance <tt>1</tt>. The <tt>equals</tt>
68.125 + * method is used to compare <tt>o</tt> to the
68.126 + * items in this stack.
68.127 + *
68.128 + * @param o the desired object.
68.129 + * @return the 1-based position from the top of the stack where
68.130 + * the object is located; the return value <code>-1</code>
68.131 + * indicates that the object is not on the stack.
68.132 + */
68.133 + public synchronized int search(Object o) {
68.134 + int i = lastIndexOf(o);
68.135 +
68.136 + if (i >= 0) {
68.137 + return size() - i;
68.138 + }
68.139 + return -1;
68.140 + }
68.141 +
68.142 + /** use serialVersionUID from JDK 1.0.2 for interoperability */
68.143 + private static final long serialVersionUID = 1224463164541339165L;
68.144 +}
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/emul/compact/src/main/java/java/util/StringTokenizer.java Tue Feb 05 17:04:22 2013 +0100
69.3 @@ -0,0 +1,431 @@
69.4 +/*
69.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
69.7 + *
69.8 + * This code is free software; you can redistribute it and/or modify it
69.9 + * under the terms of the GNU General Public License version 2 only, as
69.10 + * published by the Free Software Foundation. Oracle designates this
69.11 + * particular file as subject to the "Classpath" exception as provided
69.12 + * by Oracle in the LICENSE file that accompanied this code.
69.13 + *
69.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
69.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
69.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
69.17 + * version 2 for more details (a copy is included in the LICENSE file that
69.18 + * accompanied this code).
69.19 + *
69.20 + * You should have received a copy of the GNU General Public License version
69.21 + * 2 along with this work; if not, write to the Free Software Foundation,
69.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
69.23 + *
69.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
69.25 + * or visit www.oracle.com if you need additional information or have any
69.26 + * questions.
69.27 + */
69.28 +
69.29 +package java.util;
69.30 +
69.31 +import java.lang.*;
69.32 +
69.33 +/**
69.34 + * The string tokenizer class allows an application to break a
69.35 + * string into tokens. The tokenization method is much simpler than
69.36 + * the one used by the <code>StreamTokenizer</code> class. The
69.37 + * <code>StringTokenizer</code> methods do not distinguish among
69.38 + * identifiers, numbers, and quoted strings, nor do they recognize
69.39 + * and skip comments.
69.40 + * <p>
69.41 + * The set of delimiters (the characters that separate tokens) may
69.42 + * be specified either at creation time or on a per-token basis.
69.43 + * <p>
69.44 + * An instance of <code>StringTokenizer</code> behaves in one of two
69.45 + * ways, depending on whether it was created with the
69.46 + * <code>returnDelims</code> flag having the value <code>true</code>
69.47 + * or <code>false</code>:
69.48 + * <ul>
69.49 + * <li>If the flag is <code>false</code>, delimiter characters serve to
69.50 + * separate tokens. A token is a maximal sequence of consecutive
69.51 + * characters that are not delimiters.
69.52 + * <li>If the flag is <code>true</code>, delimiter characters are themselves
69.53 + * considered to be tokens. A token is thus either one delimiter
69.54 + * character, or a maximal sequence of consecutive characters that are
69.55 + * not delimiters.
69.56 + * </ul><p>
69.57 + * A <tt>StringTokenizer</tt> object internally maintains a current
69.58 + * position within the string to be tokenized. Some operations advance this
69.59 + * current position past the characters processed.<p>
69.60 + * A token is returned by taking a substring of the string that was used to
69.61 + * create the <tt>StringTokenizer</tt> object.
69.62 + * <p>
69.63 + * The following is one example of the use of the tokenizer. The code:
69.64 + * <blockquote><pre>
69.65 + * StringTokenizer st = new StringTokenizer("this is a test");
69.66 + * while (st.hasMoreTokens()) {
69.67 + * System.out.println(st.nextToken());
69.68 + * }
69.69 + * </pre></blockquote>
69.70 + * <p>
69.71 + * prints the following output:
69.72 + * <blockquote><pre>
69.73 + * this
69.74 + * is
69.75 + * a
69.76 + * test
69.77 + * </pre></blockquote>
69.78 + *
69.79 + * <p>
69.80 + * <tt>StringTokenizer</tt> is a legacy class that is retained for
69.81 + * compatibility reasons although its use is discouraged in new code. It is
69.82 + * recommended that anyone seeking this functionality use the <tt>split</tt>
69.83 + * method of <tt>String</tt> or the java.util.regex package instead.
69.84 + * <p>
69.85 + * The following example illustrates how the <tt>String.split</tt>
69.86 + * method can be used to break up a string into its basic tokens:
69.87 + * <blockquote><pre>
69.88 + * String[] result = "this is a test".split("\\s");
69.89 + * for (int x=0; x<result.length; x++)
69.90 + * System.out.println(result[x]);
69.91 + * </pre></blockquote>
69.92 + * <p>
69.93 + * prints the following output:
69.94 + * <blockquote><pre>
69.95 + * this
69.96 + * is
69.97 + * a
69.98 + * test
69.99 + * </pre></blockquote>
69.100 + *
69.101 + * @author unascribed
69.102 + * @see java.io.StreamTokenizer
69.103 + * @since JDK1.0
69.104 + */
69.105 +public
69.106 +class StringTokenizer implements Enumeration<Object> {
69.107 + private int currentPosition;
69.108 + private int newPosition;
69.109 + private int maxPosition;
69.110 + private String str;
69.111 + private String delimiters;
69.112 + private boolean retDelims;
69.113 + private boolean delimsChanged;
69.114 +
69.115 + /**
69.116 + * maxDelimCodePoint stores the value of the delimiter character with the
69.117 + * highest value. It is used to optimize the detection of delimiter
69.118 + * characters.
69.119 + *
69.120 + * It is unlikely to provide any optimization benefit in the
69.121 + * hasSurrogates case because most string characters will be
69.122 + * smaller than the limit, but we keep it so that the two code
69.123 + * paths remain similar.
69.124 + */
69.125 + private int maxDelimCodePoint;
69.126 +
69.127 + /**
69.128 + * If delimiters include any surrogates (including surrogate
69.129 + * pairs), hasSurrogates is true and the tokenizer uses the
69.130 + * different code path. This is because String.indexOf(int)
69.131 + * doesn't handle unpaired surrogates as a single character.
69.132 + */
69.133 + private boolean hasSurrogates = false;
69.134 +
69.135 + /**
69.136 + * When hasSurrogates is true, delimiters are converted to code
69.137 + * points and isDelimiter(int) is used to determine if the given
69.138 + * codepoint is a delimiter.
69.139 + */
69.140 + private int[] delimiterCodePoints;
69.141 +
69.142 + /**
69.143 + * Set maxDelimCodePoint to the highest char in the delimiter set.
69.144 + */
69.145 + private void setMaxDelimCodePoint() {
69.146 + if (delimiters == null) {
69.147 + maxDelimCodePoint = 0;
69.148 + return;
69.149 + }
69.150 +
69.151 + int m = 0;
69.152 + int c;
69.153 + int count = 0;
69.154 + for (int i = 0; i < delimiters.length(); i += Character.charCount(c)) {
69.155 + c = delimiters.charAt(i);
69.156 + if (c >= Character.MIN_HIGH_SURROGATE && c <= Character.MAX_LOW_SURROGATE) {
69.157 + c = delimiters.codePointAt(i);
69.158 + hasSurrogates = true;
69.159 + }
69.160 + if (m < c)
69.161 + m = c;
69.162 + count++;
69.163 + }
69.164 + maxDelimCodePoint = m;
69.165 +
69.166 + if (hasSurrogates) {
69.167 + delimiterCodePoints = new int[count];
69.168 + for (int i = 0, j = 0; i < count; i++, j += Character.charCount(c)) {
69.169 + c = delimiters.codePointAt(j);
69.170 + delimiterCodePoints[i] = c;
69.171 + }
69.172 + }
69.173 + }
69.174 +
69.175 + /**
69.176 + * Constructs a string tokenizer for the specified string. All
69.177 + * characters in the <code>delim</code> argument are the delimiters
69.178 + * for separating tokens.
69.179 + * <p>
69.180 + * If the <code>returnDelims</code> flag is <code>true</code>, then
69.181 + * the delimiter characters are also returned as tokens. Each
69.182 + * delimiter is returned as a string of length one. If the flag is
69.183 + * <code>false</code>, the delimiter characters are skipped and only
69.184 + * serve as separators between tokens.
69.185 + * <p>
69.186 + * Note that if <tt>delim</tt> is <tt>null</tt>, this constructor does
69.187 + * not throw an exception. However, trying to invoke other methods on the
69.188 + * resulting <tt>StringTokenizer</tt> may result in a
69.189 + * <tt>NullPointerException</tt>.
69.190 + *
69.191 + * @param str a string to be parsed.
69.192 + * @param delim the delimiters.
69.193 + * @param returnDelims flag indicating whether to return the delimiters
69.194 + * as tokens.
69.195 + * @exception NullPointerException if str is <CODE>null</CODE>
69.196 + */
69.197 + public StringTokenizer(String str, String delim, boolean returnDelims) {
69.198 + currentPosition = 0;
69.199 + newPosition = -1;
69.200 + delimsChanged = false;
69.201 + this.str = str;
69.202 + maxPosition = str.length();
69.203 + delimiters = delim;
69.204 + retDelims = returnDelims;
69.205 + setMaxDelimCodePoint();
69.206 + }
69.207 +
69.208 + /**
69.209 + * Constructs a string tokenizer for the specified string. The
69.210 + * characters in the <code>delim</code> argument are the delimiters
69.211 + * for separating tokens. Delimiter characters themselves will not
69.212 + * be treated as tokens.
69.213 + * <p>
69.214 + * Note that if <tt>delim</tt> is <tt>null</tt>, this constructor does
69.215 + * not throw an exception. However, trying to invoke other methods on the
69.216 + * resulting <tt>StringTokenizer</tt> may result in a
69.217 + * <tt>NullPointerException</tt>.
69.218 + *
69.219 + * @param str a string to be parsed.
69.220 + * @param delim the delimiters.
69.221 + * @exception NullPointerException if str is <CODE>null</CODE>
69.222 + */
69.223 + public StringTokenizer(String str, String delim) {
69.224 + this(str, delim, false);
69.225 + }
69.226 +
69.227 + /**
69.228 + * Constructs a string tokenizer for the specified string. The
69.229 + * tokenizer uses the default delimiter set, which is
69.230 + * <code>" \t\n\r\f"</code>: the space character,
69.231 + * the tab character, the newline character, the carriage-return character,
69.232 + * and the form-feed character. Delimiter characters themselves will
69.233 + * not be treated as tokens.
69.234 + *
69.235 + * @param str a string to be parsed.
69.236 + * @exception NullPointerException if str is <CODE>null</CODE>
69.237 + */
69.238 + public StringTokenizer(String str) {
69.239 + this(str, " \t\n\r\f", false);
69.240 + }
69.241 +
69.242 + /**
69.243 + * Skips delimiters starting from the specified position. If retDelims
69.244 + * is false, returns the index of the first non-delimiter character at or
69.245 + * after startPos. If retDelims is true, startPos is returned.
69.246 + */
69.247 + private int skipDelimiters(int startPos) {
69.248 + if (delimiters == null)
69.249 + throw new NullPointerException();
69.250 +
69.251 + int position = startPos;
69.252 + while (!retDelims && position < maxPosition) {
69.253 + if (!hasSurrogates) {
69.254 + char c = str.charAt(position);
69.255 + if ((c > maxDelimCodePoint) || (delimiters.indexOf(c) < 0))
69.256 + break;
69.257 + position++;
69.258 + } else {
69.259 + int c = str.codePointAt(position);
69.260 + if ((c > maxDelimCodePoint) || !isDelimiter(c)) {
69.261 + break;
69.262 + }
69.263 + position += Character.charCount(c);
69.264 + }
69.265 + }
69.266 + return position;
69.267 + }
69.268 +
69.269 + /**
69.270 + * Skips ahead from startPos and returns the index of the next delimiter
69.271 + * character encountered, or maxPosition if no such delimiter is found.
69.272 + */
69.273 + private int scanToken(int startPos) {
69.274 + int position = startPos;
69.275 + while (position < maxPosition) {
69.276 + if (!hasSurrogates) {
69.277 + char c = str.charAt(position);
69.278 + if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
69.279 + break;
69.280 + position++;
69.281 + } else {
69.282 + int c = str.codePointAt(position);
69.283 + if ((c <= maxDelimCodePoint) && isDelimiter(c))
69.284 + break;
69.285 + position += Character.charCount(c);
69.286 + }
69.287 + }
69.288 + if (retDelims && (startPos == position)) {
69.289 + if (!hasSurrogates) {
69.290 + char c = str.charAt(position);
69.291 + if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
69.292 + position++;
69.293 + } else {
69.294 + int c = str.codePointAt(position);
69.295 + if ((c <= maxDelimCodePoint) && isDelimiter(c))
69.296 + position += Character.charCount(c);
69.297 + }
69.298 + }
69.299 + return position;
69.300 + }
69.301 +
69.302 + private boolean isDelimiter(int codePoint) {
69.303 + for (int i = 0; i < delimiterCodePoints.length; i++) {
69.304 + if (delimiterCodePoints[i] == codePoint) {
69.305 + return true;
69.306 + }
69.307 + }
69.308 + return false;
69.309 + }
69.310 +
69.311 + /**
69.312 + * Tests if there are more tokens available from this tokenizer's string.
69.313 + * If this method returns <tt>true</tt>, then a subsequent call to
69.314 + * <tt>nextToken</tt> with no argument will successfully return a token.
69.315 + *
69.316 + * @return <code>true</code> if and only if there is at least one token
69.317 + * in the string after the current position; <code>false</code>
69.318 + * otherwise.
69.319 + */
69.320 + public boolean hasMoreTokens() {
69.321 + /*
69.322 + * Temporarily store this position and use it in the following
69.323 + * nextToken() method only if the delimiters haven't been changed in
69.324 + * that nextToken() invocation.
69.325 + */
69.326 + newPosition = skipDelimiters(currentPosition);
69.327 + return (newPosition < maxPosition);
69.328 + }
69.329 +
69.330 + /**
69.331 + * Returns the next token from this string tokenizer.
69.332 + *
69.333 + * @return the next token from this string tokenizer.
69.334 + * @exception NoSuchElementException if there are no more tokens in this
69.335 + * tokenizer's string.
69.336 + */
69.337 + public String nextToken() {
69.338 + /*
69.339 + * If next position already computed in hasMoreElements() and
69.340 + * delimiters have changed between the computation and this invocation,
69.341 + * then use the computed value.
69.342 + */
69.343 +
69.344 + currentPosition = (newPosition >= 0 && !delimsChanged) ?
69.345 + newPosition : skipDelimiters(currentPosition);
69.346 +
69.347 + /* Reset these anyway */
69.348 + delimsChanged = false;
69.349 + newPosition = -1;
69.350 +
69.351 + if (currentPosition >= maxPosition)
69.352 + throw new NoSuchElementException();
69.353 + int start = currentPosition;
69.354 + currentPosition = scanToken(currentPosition);
69.355 + return str.substring(start, currentPosition);
69.356 + }
69.357 +
69.358 + /**
69.359 + * Returns the next token in this string tokenizer's string. First,
69.360 + * the set of characters considered to be delimiters by this
69.361 + * <tt>StringTokenizer</tt> object is changed to be the characters in
69.362 + * the string <tt>delim</tt>. Then the next token in the string
69.363 + * after the current position is returned. The current position is
69.364 + * advanced beyond the recognized token. The new delimiter set
69.365 + * remains the default after this call.
69.366 + *
69.367 + * @param delim the new delimiters.
69.368 + * @return the next token, after switching to the new delimiter set.
69.369 + * @exception NoSuchElementException if there are no more tokens in this
69.370 + * tokenizer's string.
69.371 + * @exception NullPointerException if delim is <CODE>null</CODE>
69.372 + */
69.373 + public String nextToken(String delim) {
69.374 + delimiters = delim;
69.375 +
69.376 + /* delimiter string specified, so set the appropriate flag. */
69.377 + delimsChanged = true;
69.378 +
69.379 + setMaxDelimCodePoint();
69.380 + return nextToken();
69.381 + }
69.382 +
69.383 + /**
69.384 + * Returns the same value as the <code>hasMoreTokens</code>
69.385 + * method. It exists so that this class can implement the
69.386 + * <code>Enumeration</code> interface.
69.387 + *
69.388 + * @return <code>true</code> if there are more tokens;
69.389 + * <code>false</code> otherwise.
69.390 + * @see java.util.Enumeration
69.391 + * @see java.util.StringTokenizer#hasMoreTokens()
69.392 + */
69.393 + public boolean hasMoreElements() {
69.394 + return hasMoreTokens();
69.395 + }
69.396 +
69.397 + /**
69.398 + * Returns the same value as the <code>nextToken</code> method,
69.399 + * except that its declared return value is <code>Object</code> rather than
69.400 + * <code>String</code>. It exists so that this class can implement the
69.401 + * <code>Enumeration</code> interface.
69.402 + *
69.403 + * @return the next token in the string.
69.404 + * @exception NoSuchElementException if there are no more tokens in this
69.405 + * tokenizer's string.
69.406 + * @see java.util.Enumeration
69.407 + * @see java.util.StringTokenizer#nextToken()
69.408 + */
69.409 + public Object nextElement() {
69.410 + return nextToken();
69.411 + }
69.412 +
69.413 + /**
69.414 + * Calculates the number of times that this tokenizer's
69.415 + * <code>nextToken</code> method can be called before it generates an
69.416 + * exception. The current position is not advanced.
69.417 + *
69.418 + * @return the number of tokens remaining in the string using the current
69.419 + * delimiter set.
69.420 + * @see java.util.StringTokenizer#nextToken()
69.421 + */
69.422 + public int countTokens() {
69.423 + int count = 0;
69.424 + int currpos = currentPosition;
69.425 + while (currpos < maxPosition) {
69.426 + currpos = skipDelimiters(currpos);
69.427 + if (currpos >= maxPosition)
69.428 + break;
69.429 + currpos = scanToken(currpos);
69.430 + count++;
69.431 + }
69.432 + return count;
69.433 + }
69.434 +}
70.1 --- a/emul/compact/src/main/java/java/util/TimSort.java Tue Feb 05 16:40:01 2013 +0100
70.2 +++ b/emul/compact/src/main/java/java/util/TimSort.java Tue Feb 05 17:04:22 2013 +0100
70.3 @@ -25,7 +25,6 @@
70.4
70.5 package java.util;
70.6
70.7 -import org.apidesign.bck2brwsr.emul.lang.System;
70.8
70.9 /**
70.10 * A stable, adaptive, iterative mergesort that requires far fewer than
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/emul/compact/src/main/java/java/util/Vector.java Tue Feb 05 17:04:22 2013 +0100
71.3 @@ -0,0 +1,1194 @@
71.4 +/*
71.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
71.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
71.7 + *
71.8 + * This code is free software; you can redistribute it and/or modify it
71.9 + * under the terms of the GNU General Public License version 2 only, as
71.10 + * published by the Free Software Foundation. Oracle designates this
71.11 + * particular file as subject to the "Classpath" exception as provided
71.12 + * by Oracle in the LICENSE file that accompanied this code.
71.13 + *
71.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
71.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
71.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
71.17 + * version 2 for more details (a copy is included in the LICENSE file that
71.18 + * accompanied this code).
71.19 + *
71.20 + * You should have received a copy of the GNU General Public License version
71.21 + * 2 along with this work; if not, write to the Free Software Foundation,
71.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
71.23 + *
71.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
71.25 + * or visit www.oracle.com if you need additional information or have any
71.26 + * questions.
71.27 + */
71.28 +
71.29 +package java.util;
71.30 +
71.31 +
71.32 +/**
71.33 + * The {@code Vector} class implements a growable array of
71.34 + * objects. Like an array, it contains components that can be
71.35 + * accessed using an integer index. However, the size of a
71.36 + * {@code Vector} can grow or shrink as needed to accommodate
71.37 + * adding and removing items after the {@code Vector} has been created.
71.38 + *
71.39 + * <p>Each vector tries to optimize storage management by maintaining a
71.40 + * {@code capacity} and a {@code capacityIncrement}. The
71.41 + * {@code capacity} is always at least as large as the vector
71.42 + * size; it is usually larger because as components are added to the
71.43 + * vector, the vector's storage increases in chunks the size of
71.44 + * {@code capacityIncrement}. An application can increase the
71.45 + * capacity of a vector before inserting a large number of
71.46 + * components; this reduces the amount of incremental reallocation.
71.47 + *
71.48 + * <p><a name="fail-fast"/>
71.49 + * The iterators returned by this class's {@link #iterator() iterator} and
71.50 + * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
71.51 + * if the vector is structurally modified at any time after the iterator is
71.52 + * created, in any way except through the iterator's own
71.53 + * {@link ListIterator#remove() remove} or
71.54 + * {@link ListIterator#add(Object) add} methods, the iterator will throw a
71.55 + * {@link ConcurrentModificationException}. Thus, in the face of
71.56 + * concurrent modification, the iterator fails quickly and cleanly, rather
71.57 + * than risking arbitrary, non-deterministic behavior at an undetermined
71.58 + * time in the future. The {@link Enumeration Enumerations} returned by
71.59 + * the {@link #elements() elements} method are <em>not</em> fail-fast.
71.60 + *
71.61 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
71.62 + * as it is, generally speaking, impossible to make any hard guarantees in the
71.63 + * presence of unsynchronized concurrent modification. Fail-fast iterators
71.64 + * throw {@code ConcurrentModificationException} on a best-effort basis.
71.65 + * Therefore, it would be wrong to write a program that depended on this
71.66 + * exception for its correctness: <i>the fail-fast behavior of iterators
71.67 + * should be used only to detect bugs.</i>
71.68 + *
71.69 + * <p>As of the Java 2 platform v1.2, this class was retrofitted to
71.70 + * implement the {@link List} interface, making it a member of the
71.71 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
71.72 + * Java Collections Framework</a>. Unlike the new collection
71.73 + * implementations, {@code Vector} is synchronized. If a thread-safe
71.74 + * implementation is not needed, it is recommended to use {@link
71.75 + * ArrayList} in place of {@code Vector}.
71.76 + *
71.77 + * @author Lee Boynton
71.78 + * @author Jonathan Payne
71.79 + * @see Collection
71.80 + * @see LinkedList
71.81 + * @since JDK1.0
71.82 + */
71.83 +public class Vector<E>
71.84 + extends AbstractList<E>
71.85 + implements List<E>, RandomAccess, Cloneable, java.io.Serializable
71.86 +{
71.87 + /**
71.88 + * The array buffer into which the components of the vector are
71.89 + * stored. The capacity of the vector is the length of this array buffer,
71.90 + * and is at least large enough to contain all the vector's elements.
71.91 + *
71.92 + * <p>Any array elements following the last element in the Vector are null.
71.93 + *
71.94 + * @serial
71.95 + */
71.96 + protected Object[] elementData;
71.97 +
71.98 + /**
71.99 + * The number of valid components in this {@code Vector} object.
71.100 + * Components {@code elementData[0]} through
71.101 + * {@code elementData[elementCount-1]} are the actual items.
71.102 + *
71.103 + * @serial
71.104 + */
71.105 + protected int elementCount;
71.106 +
71.107 + /**
71.108 + * The amount by which the capacity of the vector is automatically
71.109 + * incremented when its size becomes greater than its capacity. If
71.110 + * the capacity increment is less than or equal to zero, the capacity
71.111 + * of the vector is doubled each time it needs to grow.
71.112 + *
71.113 + * @serial
71.114 + */
71.115 + protected int capacityIncrement;
71.116 +
71.117 + /** use serialVersionUID from JDK 1.0.2 for interoperability */
71.118 + private static final long serialVersionUID = -2767605614048989439L;
71.119 +
71.120 + /**
71.121 + * Constructs an empty vector with the specified initial capacity and
71.122 + * capacity increment.
71.123 + *
71.124 + * @param initialCapacity the initial capacity of the vector
71.125 + * @param capacityIncrement the amount by which the capacity is
71.126 + * increased when the vector overflows
71.127 + * @throws IllegalArgumentException if the specified initial capacity
71.128 + * is negative
71.129 + */
71.130 + public Vector(int initialCapacity, int capacityIncrement) {
71.131 + super();
71.132 + if (initialCapacity < 0)
71.133 + throw new IllegalArgumentException("Illegal Capacity: "+
71.134 + initialCapacity);
71.135 + this.elementData = new Object[initialCapacity];
71.136 + this.capacityIncrement = capacityIncrement;
71.137 + }
71.138 +
71.139 + /**
71.140 + * Constructs an empty vector with the specified initial capacity and
71.141 + * with its capacity increment equal to zero.
71.142 + *
71.143 + * @param initialCapacity the initial capacity of the vector
71.144 + * @throws IllegalArgumentException if the specified initial capacity
71.145 + * is negative
71.146 + */
71.147 + public Vector(int initialCapacity) {
71.148 + this(initialCapacity, 0);
71.149 + }
71.150 +
71.151 + /**
71.152 + * Constructs an empty vector so that its internal data array
71.153 + * has size {@code 10} and its standard capacity increment is
71.154 + * zero.
71.155 + */
71.156 + public Vector() {
71.157 + this(10);
71.158 + }
71.159 +
71.160 + /**
71.161 + * Constructs a vector containing the elements of the specified
71.162 + * collection, in the order they are returned by the collection's
71.163 + * iterator.
71.164 + *
71.165 + * @param c the collection whose elements are to be placed into this
71.166 + * vector
71.167 + * @throws NullPointerException if the specified collection is null
71.168 + * @since 1.2
71.169 + */
71.170 + public Vector(Collection<? extends E> c) {
71.171 + elementData = c.toArray();
71.172 + elementCount = elementData.length;
71.173 + // c.toArray might (incorrectly) not return Object[] (see 6260652)
71.174 + if (elementData.getClass() != Object[].class)
71.175 + elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
71.176 + }
71.177 +
71.178 + /**
71.179 + * Copies the components of this vector into the specified array.
71.180 + * The item at index {@code k} in this vector is copied into
71.181 + * component {@code k} of {@code anArray}.
71.182 + *
71.183 + * @param anArray the array into which the components get copied
71.184 + * @throws NullPointerException if the given array is null
71.185 + * @throws IndexOutOfBoundsException if the specified array is not
71.186 + * large enough to hold all the components of this vector
71.187 + * @throws ArrayStoreException if a component of this vector is not of
71.188 + * a runtime type that can be stored in the specified array
71.189 + * @see #toArray(Object[])
71.190 + */
71.191 + public synchronized void copyInto(Object[] anArray) {
71.192 + System.arraycopy(elementData, 0, anArray, 0, elementCount);
71.193 + }
71.194 +
71.195 + /**
71.196 + * Trims the capacity of this vector to be the vector's current
71.197 + * size. If the capacity of this vector is larger than its current
71.198 + * size, then the capacity is changed to equal the size by replacing
71.199 + * its internal data array, kept in the field {@code elementData},
71.200 + * with a smaller one. An application can use this operation to
71.201 + * minimize the storage of a vector.
71.202 + */
71.203 + public synchronized void trimToSize() {
71.204 + modCount++;
71.205 + int oldCapacity = elementData.length;
71.206 + if (elementCount < oldCapacity) {
71.207 + elementData = Arrays.copyOf(elementData, elementCount);
71.208 + }
71.209 + }
71.210 +
71.211 + /**
71.212 + * Increases the capacity of this vector, if necessary, to ensure
71.213 + * that it can hold at least the number of components specified by
71.214 + * the minimum capacity argument.
71.215 + *
71.216 + * <p>If the current capacity of this vector is less than
71.217 + * {@code minCapacity}, then its capacity is increased by replacing its
71.218 + * internal data array, kept in the field {@code elementData}, with a
71.219 + * larger one. The size of the new data array will be the old size plus
71.220 + * {@code capacityIncrement}, unless the value of
71.221 + * {@code capacityIncrement} is less than or equal to zero, in which case
71.222 + * the new capacity will be twice the old capacity; but if this new size
71.223 + * is still smaller than {@code minCapacity}, then the new capacity will
71.224 + * be {@code minCapacity}.
71.225 + *
71.226 + * @param minCapacity the desired minimum capacity
71.227 + */
71.228 + public synchronized void ensureCapacity(int minCapacity) {
71.229 + if (minCapacity > 0) {
71.230 + modCount++;
71.231 + ensureCapacityHelper(minCapacity);
71.232 + }
71.233 + }
71.234 +
71.235 + /**
71.236 + * This implements the unsynchronized semantics of ensureCapacity.
71.237 + * Synchronized methods in this class can internally call this
71.238 + * method for ensuring capacity without incurring the cost of an
71.239 + * extra synchronization.
71.240 + *
71.241 + * @see #ensureCapacity(int)
71.242 + */
71.243 + private void ensureCapacityHelper(int minCapacity) {
71.244 + // overflow-conscious code
71.245 + if (minCapacity - elementData.length > 0)
71.246 + grow(minCapacity);
71.247 + }
71.248 +
71.249 + /**
71.250 + * The maximum size of array to allocate.
71.251 + * Some VMs reserve some header words in an array.
71.252 + * Attempts to allocate larger arrays may result in
71.253 + * OutOfMemoryError: Requested array size exceeds VM limit
71.254 + */
71.255 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
71.256 +
71.257 + private void grow(int minCapacity) {
71.258 + // overflow-conscious code
71.259 + int oldCapacity = elementData.length;
71.260 + int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
71.261 + capacityIncrement : oldCapacity);
71.262 + if (newCapacity - minCapacity < 0)
71.263 + newCapacity = minCapacity;
71.264 + if (newCapacity - MAX_ARRAY_SIZE > 0)
71.265 + newCapacity = hugeCapacity(minCapacity);
71.266 + elementData = Arrays.copyOf(elementData, newCapacity);
71.267 + }
71.268 +
71.269 + private static int hugeCapacity(int minCapacity) {
71.270 + if (minCapacity < 0) // overflow
71.271 + throw new OutOfMemoryError();
71.272 + return (minCapacity > MAX_ARRAY_SIZE) ?
71.273 + Integer.MAX_VALUE :
71.274 + MAX_ARRAY_SIZE;
71.275 + }
71.276 +
71.277 + /**
71.278 + * Sets the size of this vector. If the new size is greater than the
71.279 + * current size, new {@code null} items are added to the end of
71.280 + * the vector. If the new size is less than the current size, all
71.281 + * components at index {@code newSize} and greater are discarded.
71.282 + *
71.283 + * @param newSize the new size of this vector
71.284 + * @throws ArrayIndexOutOfBoundsException if the new size is negative
71.285 + */
71.286 + public synchronized void setSize(int newSize) {
71.287 + modCount++;
71.288 + if (newSize > elementCount) {
71.289 + ensureCapacityHelper(newSize);
71.290 + } else {
71.291 + for (int i = newSize ; i < elementCount ; i++) {
71.292 + elementData[i] = null;
71.293 + }
71.294 + }
71.295 + elementCount = newSize;
71.296 + }
71.297 +
71.298 + /**
71.299 + * Returns the current capacity of this vector.
71.300 + *
71.301 + * @return the current capacity (the length of its internal
71.302 + * data array, kept in the field {@code elementData}
71.303 + * of this vector)
71.304 + */
71.305 + public synchronized int capacity() {
71.306 + return elementData.length;
71.307 + }
71.308 +
71.309 + /**
71.310 + * Returns the number of components in this vector.
71.311 + *
71.312 + * @return the number of components in this vector
71.313 + */
71.314 + public synchronized int size() {
71.315 + return elementCount;
71.316 + }
71.317 +
71.318 + /**
71.319 + * Tests if this vector has no components.
71.320 + *
71.321 + * @return {@code true} if and only if this vector has
71.322 + * no components, that is, its size is zero;
71.323 + * {@code false} otherwise.
71.324 + */
71.325 + public synchronized boolean isEmpty() {
71.326 + return elementCount == 0;
71.327 + }
71.328 +
71.329 + /**
71.330 + * Returns an enumeration of the components of this vector. The
71.331 + * returned {@code Enumeration} object will generate all items in
71.332 + * this vector. The first item generated is the item at index {@code 0},
71.333 + * then the item at index {@code 1}, and so on.
71.334 + *
71.335 + * @return an enumeration of the components of this vector
71.336 + * @see Iterator
71.337 + */
71.338 + public Enumeration<E> elements() {
71.339 + return new Enumeration<E>() {
71.340 + int count = 0;
71.341 +
71.342 + public boolean hasMoreElements() {
71.343 + return count < elementCount;
71.344 + }
71.345 +
71.346 + public E nextElement() {
71.347 + synchronized (Vector.this) {
71.348 + if (count < elementCount) {
71.349 + return elementData(count++);
71.350 + }
71.351 + }
71.352 + throw new NoSuchElementException("Vector Enumeration");
71.353 + }
71.354 + };
71.355 + }
71.356 +
71.357 + /**
71.358 + * Returns {@code true} if this vector contains the specified element.
71.359 + * More formally, returns {@code true} if and only if this vector
71.360 + * contains at least one element {@code e} such that
71.361 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
71.362 + *
71.363 + * @param o element whose presence in this vector is to be tested
71.364 + * @return {@code true} if this vector contains the specified element
71.365 + */
71.366 + public boolean contains(Object o) {
71.367 + return indexOf(o, 0) >= 0;
71.368 + }
71.369 +
71.370 + /**
71.371 + * Returns the index of the first occurrence of the specified element
71.372 + * in this vector, or -1 if this vector does not contain the element.
71.373 + * More formally, returns the lowest index {@code i} such that
71.374 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
71.375 + * or -1 if there is no such index.
71.376 + *
71.377 + * @param o element to search for
71.378 + * @return the index of the first occurrence of the specified element in
71.379 + * this vector, or -1 if this vector does not contain the element
71.380 + */
71.381 + public int indexOf(Object o) {
71.382 + return indexOf(o, 0);
71.383 + }
71.384 +
71.385 + /**
71.386 + * Returns the index of the first occurrence of the specified element in
71.387 + * this vector, searching forwards from {@code index}, or returns -1 if
71.388 + * the element is not found.
71.389 + * More formally, returns the lowest index {@code i} such that
71.390 + * <tt>(i >= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
71.391 + * or -1 if there is no such index.
71.392 + *
71.393 + * @param o element to search for
71.394 + * @param index index to start searching from
71.395 + * @return the index of the first occurrence of the element in
71.396 + * this vector at position {@code index} or later in the vector;
71.397 + * {@code -1} if the element is not found.
71.398 + * @throws IndexOutOfBoundsException if the specified index is negative
71.399 + * @see Object#equals(Object)
71.400 + */
71.401 + public synchronized int indexOf(Object o, int index) {
71.402 + if (o == null) {
71.403 + for (int i = index ; i < elementCount ; i++)
71.404 + if (elementData[i]==null)
71.405 + return i;
71.406 + } else {
71.407 + for (int i = index ; i < elementCount ; i++)
71.408 + if (o.equals(elementData[i]))
71.409 + return i;
71.410 + }
71.411 + return -1;
71.412 + }
71.413 +
71.414 + /**
71.415 + * Returns the index of the last occurrence of the specified element
71.416 + * in this vector, or -1 if this vector does not contain the element.
71.417 + * More formally, returns the highest index {@code i} such that
71.418 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
71.419 + * or -1 if there is no such index.
71.420 + *
71.421 + * @param o element to search for
71.422 + * @return the index of the last occurrence of the specified element in
71.423 + * this vector, or -1 if this vector does not contain the element
71.424 + */
71.425 + public synchronized int lastIndexOf(Object o) {
71.426 + return lastIndexOf(o, elementCount-1);
71.427 + }
71.428 +
71.429 + /**
71.430 + * Returns the index of the last occurrence of the specified element in
71.431 + * this vector, searching backwards from {@code index}, or returns -1 if
71.432 + * the element is not found.
71.433 + * More formally, returns the highest index {@code i} such that
71.434 + * <tt>(i <= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
71.435 + * or -1 if there is no such index.
71.436 + *
71.437 + * @param o element to search for
71.438 + * @param index index to start searching backwards from
71.439 + * @return the index of the last occurrence of the element at position
71.440 + * less than or equal to {@code index} in this vector;
71.441 + * -1 if the element is not found.
71.442 + * @throws IndexOutOfBoundsException if the specified index is greater
71.443 + * than or equal to the current size of this vector
71.444 + */
71.445 + public synchronized int lastIndexOf(Object o, int index) {
71.446 + if (index >= elementCount)
71.447 + throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
71.448 +
71.449 + if (o == null) {
71.450 + for (int i = index; i >= 0; i--)
71.451 + if (elementData[i]==null)
71.452 + return i;
71.453 + } else {
71.454 + for (int i = index; i >= 0; i--)
71.455 + if (o.equals(elementData[i]))
71.456 + return i;
71.457 + }
71.458 + return -1;
71.459 + }
71.460 +
71.461 + /**
71.462 + * Returns the component at the specified index.
71.463 + *
71.464 + * <p>This method is identical in functionality to the {@link #get(int)}
71.465 + * method (which is part of the {@link List} interface).
71.466 + *
71.467 + * @param index an index into this vector
71.468 + * @return the component at the specified index
71.469 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.470 + * ({@code index < 0 || index >= size()})
71.471 + */
71.472 + public synchronized E elementAt(int index) {
71.473 + if (index >= elementCount) {
71.474 + throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
71.475 + }
71.476 +
71.477 + return elementData(index);
71.478 + }
71.479 +
71.480 + /**
71.481 + * Returns the first component (the item at index {@code 0}) of
71.482 + * this vector.
71.483 + *
71.484 + * @return the first component of this vector
71.485 + * @throws NoSuchElementException if this vector has no components
71.486 + */
71.487 + public synchronized E firstElement() {
71.488 + if (elementCount == 0) {
71.489 + throw new NoSuchElementException();
71.490 + }
71.491 + return elementData(0);
71.492 + }
71.493 +
71.494 + /**
71.495 + * Returns the last component of the vector.
71.496 + *
71.497 + * @return the last component of the vector, i.e., the component at index
71.498 + * <code>size() - 1</code>.
71.499 + * @throws NoSuchElementException if this vector is empty
71.500 + */
71.501 + public synchronized E lastElement() {
71.502 + if (elementCount == 0) {
71.503 + throw new NoSuchElementException();
71.504 + }
71.505 + return elementData(elementCount - 1);
71.506 + }
71.507 +
71.508 + /**
71.509 + * Sets the component at the specified {@code index} of this
71.510 + * vector to be the specified object. The previous component at that
71.511 + * position is discarded.
71.512 + *
71.513 + * <p>The index must be a value greater than or equal to {@code 0}
71.514 + * and less than the current size of the vector.
71.515 + *
71.516 + * <p>This method is identical in functionality to the
71.517 + * {@link #set(int, Object) set(int, E)}
71.518 + * method (which is part of the {@link List} interface). Note that the
71.519 + * {@code set} method reverses the order of the parameters, to more closely
71.520 + * match array usage. Note also that the {@code set} method returns the
71.521 + * old value that was stored at the specified position.
71.522 + *
71.523 + * @param obj what the component is to be set to
71.524 + * @param index the specified index
71.525 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.526 + * ({@code index < 0 || index >= size()})
71.527 + */
71.528 + public synchronized void setElementAt(E obj, int index) {
71.529 + if (index >= elementCount) {
71.530 + throw new ArrayIndexOutOfBoundsException(index + " >= " +
71.531 + elementCount);
71.532 + }
71.533 + elementData[index] = obj;
71.534 + }
71.535 +
71.536 + /**
71.537 + * Deletes the component at the specified index. Each component in
71.538 + * this vector with an index greater or equal to the specified
71.539 + * {@code index} is shifted downward to have an index one
71.540 + * smaller than the value it had previously. The size of this vector
71.541 + * is decreased by {@code 1}.
71.542 + *
71.543 + * <p>The index must be a value greater than or equal to {@code 0}
71.544 + * and less than the current size of the vector.
71.545 + *
71.546 + * <p>This method is identical in functionality to the {@link #remove(int)}
71.547 + * method (which is part of the {@link List} interface). Note that the
71.548 + * {@code remove} method returns the old value that was stored at the
71.549 + * specified position.
71.550 + *
71.551 + * @param index the index of the object to remove
71.552 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.553 + * ({@code index < 0 || index >= size()})
71.554 + */
71.555 + public synchronized void removeElementAt(int index) {
71.556 + modCount++;
71.557 + if (index >= elementCount) {
71.558 + throw new ArrayIndexOutOfBoundsException(index + " >= " +
71.559 + elementCount);
71.560 + }
71.561 + else if (index < 0) {
71.562 + throw new ArrayIndexOutOfBoundsException(index);
71.563 + }
71.564 + int j = elementCount - index - 1;
71.565 + if (j > 0) {
71.566 + System.arraycopy(elementData, index + 1, elementData, index, j);
71.567 + }
71.568 + elementCount--;
71.569 + elementData[elementCount] = null; /* to let gc do its work */
71.570 + }
71.571 +
71.572 + /**
71.573 + * Inserts the specified object as a component in this vector at the
71.574 + * specified {@code index}. Each component in this vector with
71.575 + * an index greater or equal to the specified {@code index} is
71.576 + * shifted upward to have an index one greater than the value it had
71.577 + * previously.
71.578 + *
71.579 + * <p>The index must be a value greater than or equal to {@code 0}
71.580 + * and less than or equal to the current size of the vector. (If the
71.581 + * index is equal to the current size of the vector, the new element
71.582 + * is appended to the Vector.)
71.583 + *
71.584 + * <p>This method is identical in functionality to the
71.585 + * {@link #add(int, Object) add(int, E)}
71.586 + * method (which is part of the {@link List} interface). Note that the
71.587 + * {@code add} method reverses the order of the parameters, to more closely
71.588 + * match array usage.
71.589 + *
71.590 + * @param obj the component to insert
71.591 + * @param index where to insert the new component
71.592 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.593 + * ({@code index < 0 || index > size()})
71.594 + */
71.595 + public synchronized void insertElementAt(E obj, int index) {
71.596 + modCount++;
71.597 + if (index > elementCount) {
71.598 + throw new ArrayIndexOutOfBoundsException(index
71.599 + + " > " + elementCount);
71.600 + }
71.601 + ensureCapacityHelper(elementCount + 1);
71.602 + System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
71.603 + elementData[index] = obj;
71.604 + elementCount++;
71.605 + }
71.606 +
71.607 + /**
71.608 + * Adds the specified component to the end of this vector,
71.609 + * increasing its size by one. The capacity of this vector is
71.610 + * increased if its size becomes greater than its capacity.
71.611 + *
71.612 + * <p>This method is identical in functionality to the
71.613 + * {@link #add(Object) add(E)}
71.614 + * method (which is part of the {@link List} interface).
71.615 + *
71.616 + * @param obj the component to be added
71.617 + */
71.618 + public synchronized void addElement(E obj) {
71.619 + modCount++;
71.620 + ensureCapacityHelper(elementCount + 1);
71.621 + elementData[elementCount++] = obj;
71.622 + }
71.623 +
71.624 + /**
71.625 + * Removes the first (lowest-indexed) occurrence of the argument
71.626 + * from this vector. If the object is found in this vector, each
71.627 + * component in the vector with an index greater or equal to the
71.628 + * object's index is shifted downward to have an index one smaller
71.629 + * than the value it had previously.
71.630 + *
71.631 + * <p>This method is identical in functionality to the
71.632 + * {@link #remove(Object)} method (which is part of the
71.633 + * {@link List} interface).
71.634 + *
71.635 + * @param obj the component to be removed
71.636 + * @return {@code true} if the argument was a component of this
71.637 + * vector; {@code false} otherwise.
71.638 + */
71.639 + public synchronized boolean removeElement(Object obj) {
71.640 + modCount++;
71.641 + int i = indexOf(obj);
71.642 + if (i >= 0) {
71.643 + removeElementAt(i);
71.644 + return true;
71.645 + }
71.646 + return false;
71.647 + }
71.648 +
71.649 + /**
71.650 + * Removes all components from this vector and sets its size to zero.
71.651 + *
71.652 + * <p>This method is identical in functionality to the {@link #clear}
71.653 + * method (which is part of the {@link List} interface).
71.654 + */
71.655 + public synchronized void removeAllElements() {
71.656 + modCount++;
71.657 + // Let gc do its work
71.658 + for (int i = 0; i < elementCount; i++)
71.659 + elementData[i] = null;
71.660 +
71.661 + elementCount = 0;
71.662 + }
71.663 +
71.664 + /**
71.665 + * Returns a clone of this vector. The copy will contain a
71.666 + * reference to a clone of the internal data array, not a reference
71.667 + * to the original internal data array of this {@code Vector} object.
71.668 + *
71.669 + * @return a clone of this vector
71.670 + */
71.671 + public synchronized Object clone() {
71.672 + try {
71.673 + @SuppressWarnings("unchecked")
71.674 + Vector<E> v = (Vector<E>) super.clone();
71.675 + v.elementData = Arrays.copyOf(elementData, elementCount);
71.676 + v.modCount = 0;
71.677 + return v;
71.678 + } catch (CloneNotSupportedException e) {
71.679 + // this shouldn't happen, since we are Cloneable
71.680 + throw new InternalError();
71.681 + }
71.682 + }
71.683 +
71.684 + /**
71.685 + * Returns an array containing all of the elements in this Vector
71.686 + * in the correct order.
71.687 + *
71.688 + * @since 1.2
71.689 + */
71.690 + public synchronized Object[] toArray() {
71.691 + return Arrays.copyOf(elementData, elementCount);
71.692 + }
71.693 +
71.694 + /**
71.695 + * Returns an array containing all of the elements in this Vector in the
71.696 + * correct order; the runtime type of the returned array is that of the
71.697 + * specified array. If the Vector fits in the specified array, it is
71.698 + * returned therein. Otherwise, a new array is allocated with the runtime
71.699 + * type of the specified array and the size of this Vector.
71.700 + *
71.701 + * <p>If the Vector fits in the specified array with room to spare
71.702 + * (i.e., the array has more elements than the Vector),
71.703 + * the element in the array immediately following the end of the
71.704 + * Vector is set to null. (This is useful in determining the length
71.705 + * of the Vector <em>only</em> if the caller knows that the Vector
71.706 + * does not contain any null elements.)
71.707 + *
71.708 + * @param a the array into which the elements of the Vector are to
71.709 + * be stored, if it is big enough; otherwise, a new array of the
71.710 + * same runtime type is allocated for this purpose.
71.711 + * @return an array containing the elements of the Vector
71.712 + * @throws ArrayStoreException if the runtime type of a is not a supertype
71.713 + * of the runtime type of every element in this Vector
71.714 + * @throws NullPointerException if the given array is null
71.715 + * @since 1.2
71.716 + */
71.717 + @SuppressWarnings("unchecked")
71.718 + public synchronized <T> T[] toArray(T[] a) {
71.719 + if (a.length < elementCount)
71.720 + return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
71.721 +
71.722 + System.arraycopy(elementData, 0, a, 0, elementCount);
71.723 +
71.724 + if (a.length > elementCount)
71.725 + a[elementCount] = null;
71.726 +
71.727 + return a;
71.728 + }
71.729 +
71.730 + // Positional Access Operations
71.731 +
71.732 + @SuppressWarnings("unchecked")
71.733 + E elementData(int index) {
71.734 + return (E) elementData[index];
71.735 + }
71.736 +
71.737 + /**
71.738 + * Returns the element at the specified position in this Vector.
71.739 + *
71.740 + * @param index index of the element to return
71.741 + * @return object at the specified index
71.742 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.743 + * ({@code index < 0 || index >= size()})
71.744 + * @since 1.2
71.745 + */
71.746 + public synchronized E get(int index) {
71.747 + if (index >= elementCount)
71.748 + throw new ArrayIndexOutOfBoundsException(index);
71.749 +
71.750 + return elementData(index);
71.751 + }
71.752 +
71.753 + /**
71.754 + * Replaces the element at the specified position in this Vector with the
71.755 + * specified element.
71.756 + *
71.757 + * @param index index of the element to replace
71.758 + * @param element element to be stored at the specified position
71.759 + * @return the element previously at the specified position
71.760 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.761 + * ({@code index < 0 || index >= size()})
71.762 + * @since 1.2
71.763 + */
71.764 + public synchronized E set(int index, E element) {
71.765 + if (index >= elementCount)
71.766 + throw new ArrayIndexOutOfBoundsException(index);
71.767 +
71.768 + E oldValue = elementData(index);
71.769 + elementData[index] = element;
71.770 + return oldValue;
71.771 + }
71.772 +
71.773 + /**
71.774 + * Appends the specified element to the end of this Vector.
71.775 + *
71.776 + * @param e element to be appended to this Vector
71.777 + * @return {@code true} (as specified by {@link Collection#add})
71.778 + * @since 1.2
71.779 + */
71.780 + public synchronized boolean add(E e) {
71.781 + modCount++;
71.782 + ensureCapacityHelper(elementCount + 1);
71.783 + elementData[elementCount++] = e;
71.784 + return true;
71.785 + }
71.786 +
71.787 + /**
71.788 + * Removes the first occurrence of the specified element in this Vector
71.789 + * If the Vector does not contain the element, it is unchanged. More
71.790 + * formally, removes the element with the lowest index i such that
71.791 + * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
71.792 + * an element exists).
71.793 + *
71.794 + * @param o element to be removed from this Vector, if present
71.795 + * @return true if the Vector contained the specified element
71.796 + * @since 1.2
71.797 + */
71.798 + public boolean remove(Object o) {
71.799 + return removeElement(o);
71.800 + }
71.801 +
71.802 + /**
71.803 + * Inserts the specified element at the specified position in this Vector.
71.804 + * Shifts the element currently at that position (if any) and any
71.805 + * subsequent elements to the right (adds one to their indices).
71.806 + *
71.807 + * @param index index at which the specified element is to be inserted
71.808 + * @param element element to be inserted
71.809 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.810 + * ({@code index < 0 || index > size()})
71.811 + * @since 1.2
71.812 + */
71.813 + public void add(int index, E element) {
71.814 + insertElementAt(element, index);
71.815 + }
71.816 +
71.817 + /**
71.818 + * Removes the element at the specified position in this Vector.
71.819 + * Shifts any subsequent elements to the left (subtracts one from their
71.820 + * indices). Returns the element that was removed from the Vector.
71.821 + *
71.822 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.823 + * ({@code index < 0 || index >= size()})
71.824 + * @param index the index of the element to be removed
71.825 + * @return element that was removed
71.826 + * @since 1.2
71.827 + */
71.828 + public synchronized E remove(int index) {
71.829 + modCount++;
71.830 + if (index >= elementCount)
71.831 + throw new ArrayIndexOutOfBoundsException(index);
71.832 + E oldValue = elementData(index);
71.833 +
71.834 + int numMoved = elementCount - index - 1;
71.835 + if (numMoved > 0)
71.836 + System.arraycopy(elementData, index+1, elementData, index,
71.837 + numMoved);
71.838 + elementData[--elementCount] = null; // Let gc do its work
71.839 +
71.840 + return oldValue;
71.841 + }
71.842 +
71.843 + /**
71.844 + * Removes all of the elements from this Vector. The Vector will
71.845 + * be empty after this call returns (unless it throws an exception).
71.846 + *
71.847 + * @since 1.2
71.848 + */
71.849 + public void clear() {
71.850 + removeAllElements();
71.851 + }
71.852 +
71.853 + // Bulk Operations
71.854 +
71.855 + /**
71.856 + * Returns true if this Vector contains all of the elements in the
71.857 + * specified Collection.
71.858 + *
71.859 + * @param c a collection whose elements will be tested for containment
71.860 + * in this Vector
71.861 + * @return true if this Vector contains all of the elements in the
71.862 + * specified collection
71.863 + * @throws NullPointerException if the specified collection is null
71.864 + */
71.865 + public synchronized boolean containsAll(Collection<?> c) {
71.866 + return super.containsAll(c);
71.867 + }
71.868 +
71.869 + /**
71.870 + * Appends all of the elements in the specified Collection to the end of
71.871 + * this Vector, in the order that they are returned by the specified
71.872 + * Collection's Iterator. The behavior of this operation is undefined if
71.873 + * the specified Collection is modified while the operation is in progress.
71.874 + * (This implies that the behavior of this call is undefined if the
71.875 + * specified Collection is this Vector, and this Vector is nonempty.)
71.876 + *
71.877 + * @param c elements to be inserted into this Vector
71.878 + * @return {@code true} if this Vector changed as a result of the call
71.879 + * @throws NullPointerException if the specified collection is null
71.880 + * @since 1.2
71.881 + */
71.882 + public synchronized boolean addAll(Collection<? extends E> c) {
71.883 + modCount++;
71.884 + Object[] a = c.toArray();
71.885 + int numNew = a.length;
71.886 + ensureCapacityHelper(elementCount + numNew);
71.887 + System.arraycopy(a, 0, elementData, elementCount, numNew);
71.888 + elementCount += numNew;
71.889 + return numNew != 0;
71.890 + }
71.891 +
71.892 + /**
71.893 + * Removes from this Vector all of its elements that are contained in the
71.894 + * specified Collection.
71.895 + *
71.896 + * @param c a collection of elements to be removed from the Vector
71.897 + * @return true if this Vector changed as a result of the call
71.898 + * @throws ClassCastException if the types of one or more elements
71.899 + * in this vector are incompatible with the specified
71.900 + * collection
71.901 + * (<a href="Collection.html#optional-restrictions">optional</a>)
71.902 + * @throws NullPointerException if this vector contains one or more null
71.903 + * elements and the specified collection does not support null
71.904 + * elements
71.905 + * (<a href="Collection.html#optional-restrictions">optional</a>),
71.906 + * or if the specified collection is null
71.907 + * @since 1.2
71.908 + */
71.909 + public synchronized boolean removeAll(Collection<?> c) {
71.910 + return super.removeAll(c);
71.911 + }
71.912 +
71.913 + /**
71.914 + * Retains only the elements in this Vector that are contained in the
71.915 + * specified Collection. In other words, removes from this Vector all
71.916 + * of its elements that are not contained in the specified Collection.
71.917 + *
71.918 + * @param c a collection of elements to be retained in this Vector
71.919 + * (all other elements are removed)
71.920 + * @return true if this Vector changed as a result of the call
71.921 + * @throws ClassCastException if the types of one or more elements
71.922 + * in this vector are incompatible with the specified
71.923 + * collection
71.924 + * (<a href="Collection.html#optional-restrictions">optional</a>)
71.925 + * @throws NullPointerException if this vector contains one or more null
71.926 + * elements and the specified collection does not support null
71.927 + * elements
71.928 + * (<a href="Collection.html#optional-restrictions">optional</a>),
71.929 + * or if the specified collection is null
71.930 + * @since 1.2
71.931 + */
71.932 + public synchronized boolean retainAll(Collection<?> c) {
71.933 + return super.retainAll(c);
71.934 + }
71.935 +
71.936 + /**
71.937 + * Inserts all of the elements in the specified Collection into this
71.938 + * Vector at the specified position. Shifts the element currently at
71.939 + * that position (if any) and any subsequent elements to the right
71.940 + * (increases their indices). The new elements will appear in the Vector
71.941 + * in the order that they are returned by the specified Collection's
71.942 + * iterator.
71.943 + *
71.944 + * @param index index at which to insert the first element from the
71.945 + * specified collection
71.946 + * @param c elements to be inserted into this Vector
71.947 + * @return {@code true} if this Vector changed as a result of the call
71.948 + * @throws ArrayIndexOutOfBoundsException if the index is out of range
71.949 + * ({@code index < 0 || index > size()})
71.950 + * @throws NullPointerException if the specified collection is null
71.951 + * @since 1.2
71.952 + */
71.953 + public synchronized boolean addAll(int index, Collection<? extends E> c) {
71.954 + modCount++;
71.955 + if (index < 0 || index > elementCount)
71.956 + throw new ArrayIndexOutOfBoundsException(index);
71.957 +
71.958 + Object[] a = c.toArray();
71.959 + int numNew = a.length;
71.960 + ensureCapacityHelper(elementCount + numNew);
71.961 +
71.962 + int numMoved = elementCount - index;
71.963 + if (numMoved > 0)
71.964 + System.arraycopy(elementData, index, elementData, index + numNew,
71.965 + numMoved);
71.966 +
71.967 + System.arraycopy(a, 0, elementData, index, numNew);
71.968 + elementCount += numNew;
71.969 + return numNew != 0;
71.970 + }
71.971 +
71.972 + /**
71.973 + * Compares the specified Object with this Vector for equality. Returns
71.974 + * true if and only if the specified Object is also a List, both Lists
71.975 + * have the same size, and all corresponding pairs of elements in the two
71.976 + * Lists are <em>equal</em>. (Two elements {@code e1} and
71.977 + * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
71.978 + * e1.equals(e2))}.) In other words, two Lists are defined to be
71.979 + * equal if they contain the same elements in the same order.
71.980 + *
71.981 + * @param o the Object to be compared for equality with this Vector
71.982 + * @return true if the specified Object is equal to this Vector
71.983 + */
71.984 + public synchronized boolean equals(Object o) {
71.985 + return super.equals(o);
71.986 + }
71.987 +
71.988 + /**
71.989 + * Returns the hash code value for this Vector.
71.990 + */
71.991 + public synchronized int hashCode() {
71.992 + return super.hashCode();
71.993 + }
71.994 +
71.995 + /**
71.996 + * Returns a string representation of this Vector, containing
71.997 + * the String representation of each element.
71.998 + */
71.999 + public synchronized String toString() {
71.1000 + return super.toString();
71.1001 + }
71.1002 +
71.1003 + /**
71.1004 + * Returns a view of the portion of this List between fromIndex,
71.1005 + * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are
71.1006 + * equal, the returned List is empty.) The returned List is backed by this
71.1007 + * List, so changes in the returned List are reflected in this List, and
71.1008 + * vice-versa. The returned List supports all of the optional List
71.1009 + * operations supported by this List.
71.1010 + *
71.1011 + * <p>This method eliminates the need for explicit range operations (of
71.1012 + * the sort that commonly exist for arrays). Any operation that expects
71.1013 + * a List can be used as a range operation by operating on a subList view
71.1014 + * instead of a whole List. For example, the following idiom
71.1015 + * removes a range of elements from a List:
71.1016 + * <pre>
71.1017 + * list.subList(from, to).clear();
71.1018 + * </pre>
71.1019 + * Similar idioms may be constructed for indexOf and lastIndexOf,
71.1020 + * and all of the algorithms in the Collections class can be applied to
71.1021 + * a subList.
71.1022 + *
71.1023 + * <p>The semantics of the List returned by this method become undefined if
71.1024 + * the backing list (i.e., this List) is <i>structurally modified</i> in
71.1025 + * any way other than via the returned List. (Structural modifications are
71.1026 + * those that change the size of the List, or otherwise perturb it in such
71.1027 + * a fashion that iterations in progress may yield incorrect results.)
71.1028 + *
71.1029 + * @param fromIndex low endpoint (inclusive) of the subList
71.1030 + * @param toIndex high endpoint (exclusive) of the subList
71.1031 + * @return a view of the specified range within this List
71.1032 + * @throws IndexOutOfBoundsException if an endpoint index value is out of range
71.1033 + * {@code (fromIndex < 0 || toIndex > size)}
71.1034 + * @throws IllegalArgumentException if the endpoint indices are out of order
71.1035 + * {@code (fromIndex > toIndex)}
71.1036 + */
71.1037 + public synchronized List<E> subList(int fromIndex, int toIndex) {
71.1038 + return Collections.synchronizedList(super.subList(fromIndex, toIndex),
71.1039 + this);
71.1040 + }
71.1041 +
71.1042 + /**
71.1043 + * Removes from this list all of the elements whose index is between
71.1044 + * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
71.1045 + * Shifts any succeeding elements to the left (reduces their index).
71.1046 + * This call shortens the list by {@code (toIndex - fromIndex)} elements.
71.1047 + * (If {@code toIndex==fromIndex}, this operation has no effect.)
71.1048 + */
71.1049 + protected synchronized void removeRange(int fromIndex, int toIndex) {
71.1050 + modCount++;
71.1051 + int numMoved = elementCount - toIndex;
71.1052 + System.arraycopy(elementData, toIndex, elementData, fromIndex,
71.1053 + numMoved);
71.1054 +
71.1055 + // Let gc do its work
71.1056 + int newElementCount = elementCount - (toIndex-fromIndex);
71.1057 + while (elementCount != newElementCount)
71.1058 + elementData[--elementCount] = null;
71.1059 + }
71.1060 +
71.1061 + /**
71.1062 + * Returns a list iterator over the elements in this list (in proper
71.1063 + * sequence), starting at the specified position in the list.
71.1064 + * The specified index indicates the first element that would be
71.1065 + * returned by an initial call to {@link ListIterator#next next}.
71.1066 + * An initial call to {@link ListIterator#previous previous} would
71.1067 + * return the element with the specified index minus one.
71.1068 + *
71.1069 + * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
71.1070 + *
71.1071 + * @throws IndexOutOfBoundsException {@inheritDoc}
71.1072 + */
71.1073 + public synchronized ListIterator<E> listIterator(int index) {
71.1074 + if (index < 0 || index > elementCount)
71.1075 + throw new IndexOutOfBoundsException("Index: "+index);
71.1076 + return new ListItr(index);
71.1077 + }
71.1078 +
71.1079 + /**
71.1080 + * Returns a list iterator over the elements in this list (in proper
71.1081 + * sequence).
71.1082 + *
71.1083 + * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
71.1084 + *
71.1085 + * @see #listIterator(int)
71.1086 + */
71.1087 + public synchronized ListIterator<E> listIterator() {
71.1088 + return new ListItr(0);
71.1089 + }
71.1090 +
71.1091 + /**
71.1092 + * Returns an iterator over the elements in this list in proper sequence.
71.1093 + *
71.1094 + * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
71.1095 + *
71.1096 + * @return an iterator over the elements in this list in proper sequence
71.1097 + */
71.1098 + public synchronized Iterator<E> iterator() {
71.1099 + return new Itr();
71.1100 + }
71.1101 +
71.1102 + /**
71.1103 + * An optimized version of AbstractList.Itr
71.1104 + */
71.1105 + private class Itr implements Iterator<E> {
71.1106 + int cursor; // index of next element to return
71.1107 + int lastRet = -1; // index of last element returned; -1 if no such
71.1108 + int expectedModCount = modCount;
71.1109 +
71.1110 + public boolean hasNext() {
71.1111 + // Racy but within spec, since modifications are checked
71.1112 + // within or after synchronization in next/previous
71.1113 + return cursor != elementCount;
71.1114 + }
71.1115 +
71.1116 + public E next() {
71.1117 + synchronized (Vector.this) {
71.1118 + checkForComodification();
71.1119 + int i = cursor;
71.1120 + if (i >= elementCount)
71.1121 + throw new NoSuchElementException();
71.1122 + cursor = i + 1;
71.1123 + return elementData(lastRet = i);
71.1124 + }
71.1125 + }
71.1126 +
71.1127 + public void remove() {
71.1128 + if (lastRet == -1)
71.1129 + throw new IllegalStateException();
71.1130 + synchronized (Vector.this) {
71.1131 + checkForComodification();
71.1132 + Vector.this.remove(lastRet);
71.1133 + expectedModCount = modCount;
71.1134 + }
71.1135 + cursor = lastRet;
71.1136 + lastRet = -1;
71.1137 + }
71.1138 +
71.1139 + final void checkForComodification() {
71.1140 + if (modCount != expectedModCount)
71.1141 + throw new ConcurrentModificationException();
71.1142 + }
71.1143 + }
71.1144 +
71.1145 + /**
71.1146 + * An optimized version of AbstractList.ListItr
71.1147 + */
71.1148 + final class ListItr extends Itr implements ListIterator<E> {
71.1149 + ListItr(int index) {
71.1150 + super();
71.1151 + cursor = index;
71.1152 + }
71.1153 +
71.1154 + public boolean hasPrevious() {
71.1155 + return cursor != 0;
71.1156 + }
71.1157 +
71.1158 + public int nextIndex() {
71.1159 + return cursor;
71.1160 + }
71.1161 +
71.1162 + public int previousIndex() {
71.1163 + return cursor - 1;
71.1164 + }
71.1165 +
71.1166 + public E previous() {
71.1167 + synchronized (Vector.this) {
71.1168 + checkForComodification();
71.1169 + int i = cursor - 1;
71.1170 + if (i < 0)
71.1171 + throw new NoSuchElementException();
71.1172 + cursor = i;
71.1173 + return elementData(lastRet = i);
71.1174 + }
71.1175 + }
71.1176 +
71.1177 + public void set(E e) {
71.1178 + if (lastRet == -1)
71.1179 + throw new IllegalStateException();
71.1180 + synchronized (Vector.this) {
71.1181 + checkForComodification();
71.1182 + Vector.this.set(lastRet, e);
71.1183 + }
71.1184 + }
71.1185 +
71.1186 + public void add(E e) {
71.1187 + int i = cursor;
71.1188 + synchronized (Vector.this) {
71.1189 + checkForComodification();
71.1190 + Vector.this.add(i, e);
71.1191 + expectedModCount = modCount;
71.1192 + }
71.1193 + cursor = i + 1;
71.1194 + lastRet = -1;
71.1195 + }
71.1196 + }
71.1197 +}
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
72.2 +++ b/emul/compact/src/main/java/java/util/concurrent/Callable.java Tue Feb 05 17:04:22 2013 +0100
72.3 @@ -0,0 +1,65 @@
72.4 +/*
72.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
72.6 + *
72.7 + * This code is free software; you can redistribute it and/or modify it
72.8 + * under the terms of the GNU General Public License version 2 only, as
72.9 + * published by the Free Software Foundation. Oracle designates this
72.10 + * particular file as subject to the "Classpath" exception as provided
72.11 + * by Oracle in the LICENSE file that accompanied this code.
72.12 + *
72.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
72.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
72.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
72.16 + * version 2 for more details (a copy is included in the LICENSE file that
72.17 + * accompanied this code).
72.18 + *
72.19 + * You should have received a copy of the GNU General Public License version
72.20 + * 2 along with this work; if not, write to the Free Software Foundation,
72.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
72.22 + *
72.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
72.24 + * or visit www.oracle.com if you need additional information or have any
72.25 + * questions.
72.26 + */
72.27 +
72.28 +/*
72.29 + * This file is available under and governed by the GNU General Public
72.30 + * License version 2 only, as published by the Free Software Foundation.
72.31 + * However, the following notice accompanied the original version of this
72.32 + * file:
72.33 + *
72.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
72.35 + * Expert Group and released to the public domain, as explained at
72.36 + * http://creativecommons.org/publicdomain/zero/1.0/
72.37 + */
72.38 +
72.39 +package java.util.concurrent;
72.40 +
72.41 +/**
72.42 + * A task that returns a result and may throw an exception.
72.43 + * Implementors define a single method with no arguments called
72.44 + * <tt>call</tt>.
72.45 + *
72.46 + * <p>The <tt>Callable</tt> interface is similar to {@link
72.47 + * java.lang.Runnable}, in that both are designed for classes whose
72.48 + * instances are potentially executed by another thread. A
72.49 + * <tt>Runnable</tt>, however, does not return a result and cannot
72.50 + * throw a checked exception.
72.51 + *
72.52 + * <p> The {@link Executors} class contains utility methods to
72.53 + * convert from other common forms to <tt>Callable</tt> classes.
72.54 + *
72.55 + * @see Executor
72.56 + * @since 1.5
72.57 + * @author Doug Lea
72.58 + * @param <V> the result type of method <tt>call</tt>
72.59 + */
72.60 +public interface Callable<V> {
72.61 + /**
72.62 + * Computes a result, or throws an exception if unable to do so.
72.63 + *
72.64 + * @return computed result
72.65 + * @throws Exception if unable to compute a result
72.66 + */
72.67 + V call() throws Exception;
72.68 +}
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
73.2 +++ b/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java Tue Feb 05 17:04:22 2013 +0100
73.3 @@ -0,0 +1,367 @@
73.4 +/*
73.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
73.6 + *
73.7 + * This code is free software; you can redistribute it and/or modify it
73.8 + * under the terms of the GNU General Public License version 2 only, as
73.9 + * published by the Free Software Foundation. Oracle designates this
73.10 + * particular file as subject to the "Classpath" exception as provided
73.11 + * by Oracle in the LICENSE file that accompanied this code.
73.12 + *
73.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
73.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
73.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
73.16 + * version 2 for more details (a copy is included in the LICENSE file that
73.17 + * accompanied this code).
73.18 + *
73.19 + * You should have received a copy of the GNU General Public License version
73.20 + * 2 along with this work; if not, write to the Free Software Foundation,
73.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
73.22 + *
73.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
73.24 + * or visit www.oracle.com if you need additional information or have any
73.25 + * questions.
73.26 + */
73.27 +
73.28 +/*
73.29 + * This file is available under and governed by the GNU General Public
73.30 + * License version 2 only, as published by the Free Software Foundation.
73.31 + * However, the following notice accompanied the original version of this
73.32 + * file:
73.33 + *
73.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
73.35 + * Expert Group and released to the public domain, as explained at
73.36 + * http://creativecommons.org/publicdomain/zero/1.0/
73.37 + */
73.38 +
73.39 +package java.util.concurrent;
73.40 +
73.41 +/**
73.42 + * A <tt>TimeUnit</tt> represents time durations at a given unit of
73.43 + * granularity and provides utility methods to convert across units,
73.44 + * and to perform timing and delay operations in these units. A
73.45 + * <tt>TimeUnit</tt> does not maintain time information, but only
73.46 + * helps organize and use time representations that may be maintained
73.47 + * separately across various contexts. A nanosecond is defined as one
73.48 + * thousandth of a microsecond, a microsecond as one thousandth of a
73.49 + * millisecond, a millisecond as one thousandth of a second, a minute
73.50 + * as sixty seconds, an hour as sixty minutes, and a day as twenty four
73.51 + * hours.
73.52 + *
73.53 + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
73.54 + * how a given timing parameter should be interpreted. For example,
73.55 + * the following code will timeout in 50 milliseconds if the {@link
73.56 + * java.util.concurrent.locks.Lock lock} is not available:
73.57 + *
73.58 + * <pre> Lock lock = ...;
73.59 + * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
73.60 + * </pre>
73.61 + * while this code will timeout in 50 seconds:
73.62 + * <pre>
73.63 + * Lock lock = ...;
73.64 + * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...
73.65 + * </pre>
73.66 + *
73.67 + * Note however, that there is no guarantee that a particular timeout
73.68 + * implementation will be able to notice the passage of time at the
73.69 + * same granularity as the given <tt>TimeUnit</tt>.
73.70 + *
73.71 + * @since 1.5
73.72 + * @author Doug Lea
73.73 + */
73.74 +public enum TimeUnit {
73.75 + NANOSECONDS {
73.76 + public long toNanos(long d) { return d; }
73.77 + public long toMicros(long d) { return d/(C1/C0); }
73.78 + public long toMillis(long d) { return d/(C2/C0); }
73.79 + public long toSeconds(long d) { return d/(C3/C0); }
73.80 + public long toMinutes(long d) { return d/(C4/C0); }
73.81 + public long toHours(long d) { return d/(C5/C0); }
73.82 + public long toDays(long d) { return d/(C6/C0); }
73.83 + public long convert(long d, TimeUnit u) { return u.toNanos(d); }
73.84 + int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
73.85 + },
73.86 + MICROSECONDS {
73.87 + public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
73.88 + public long toMicros(long d) { return d; }
73.89 + public long toMillis(long d) { return d/(C2/C1); }
73.90 + public long toSeconds(long d) { return d/(C3/C1); }
73.91 + public long toMinutes(long d) { return d/(C4/C1); }
73.92 + public long toHours(long d) { return d/(C5/C1); }
73.93 + public long toDays(long d) { return d/(C6/C1); }
73.94 + public long convert(long d, TimeUnit u) { return u.toMicros(d); }
73.95 + int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
73.96 + },
73.97 + MILLISECONDS {
73.98 + public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
73.99 + public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
73.100 + public long toMillis(long d) { return d; }
73.101 + public long toSeconds(long d) { return d/(C3/C2); }
73.102 + public long toMinutes(long d) { return d/(C4/C2); }
73.103 + public long toHours(long d) { return d/(C5/C2); }
73.104 + public long toDays(long d) { return d/(C6/C2); }
73.105 + public long convert(long d, TimeUnit u) { return u.toMillis(d); }
73.106 + int excessNanos(long d, long m) { return 0; }
73.107 + },
73.108 + SECONDS {
73.109 + public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
73.110 + public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
73.111 + public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
73.112 + public long toSeconds(long d) { return d; }
73.113 + public long toMinutes(long d) { return d/(C4/C3); }
73.114 + public long toHours(long d) { return d/(C5/C3); }
73.115 + public long toDays(long d) { return d/(C6/C3); }
73.116 + public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
73.117 + int excessNanos(long d, long m) { return 0; }
73.118 + },
73.119 + MINUTES {
73.120 + public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
73.121 + public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
73.122 + public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
73.123 + public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
73.124 + public long toMinutes(long d) { return d; }
73.125 + public long toHours(long d) { return d/(C5/C4); }
73.126 + public long toDays(long d) { return d/(C6/C4); }
73.127 + public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
73.128 + int excessNanos(long d, long m) { return 0; }
73.129 + },
73.130 + HOURS {
73.131 + public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
73.132 + public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
73.133 + public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
73.134 + public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
73.135 + public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
73.136 + public long toHours(long d) { return d; }
73.137 + public long toDays(long d) { return d/(C6/C5); }
73.138 + public long convert(long d, TimeUnit u) { return u.toHours(d); }
73.139 + int excessNanos(long d, long m) { return 0; }
73.140 + },
73.141 + DAYS {
73.142 + public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
73.143 + public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
73.144 + public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
73.145 + public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
73.146 + public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
73.147 + public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
73.148 + public long toDays(long d) { return d; }
73.149 + public long convert(long d, TimeUnit u) { return u.toDays(d); }
73.150 + int excessNanos(long d, long m) { return 0; }
73.151 + };
73.152 +
73.153 + // Handy constants for conversion methods
73.154 + static final long C0 = 1L;
73.155 + static final long C1 = C0 * 1000L;
73.156 + static final long C2 = C1 * 1000L;
73.157 + static final long C3 = C2 * 1000L;
73.158 + static final long C4 = C3 * 60L;
73.159 + static final long C5 = C4 * 60L;
73.160 + static final long C6 = C5 * 24L;
73.161 +
73.162 + static final long MAX = Long.MAX_VALUE;
73.163 +
73.164 + /**
73.165 + * Scale d by m, checking for overflow.
73.166 + * This has a short name to make above code more readable.
73.167 + */
73.168 + static long x(long d, long m, long over) {
73.169 + if (d > over) return Long.MAX_VALUE;
73.170 + if (d < -over) return Long.MIN_VALUE;
73.171 + return d * m;
73.172 + }
73.173 +
73.174 + // To maintain full signature compatibility with 1.5, and to improve the
73.175 + // clarity of the generated javadoc (see 6287639: Abstract methods in
73.176 + // enum classes should not be listed as abstract), method convert
73.177 + // etc. are not declared abstract but otherwise act as abstract methods.
73.178 +
73.179 + /**
73.180 + * Convert the given time duration in the given unit to this
73.181 + * unit. Conversions from finer to coarser granularities
73.182 + * truncate, so lose precision. For example converting
73.183 + * <tt>999</tt> milliseconds to seconds results in
73.184 + * <tt>0</tt>. Conversions from coarser to finer granularities
73.185 + * with arguments that would numerically overflow saturate to
73.186 + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
73.187 + * if positive.
73.188 + *
73.189 + * <p>For example, to convert 10 minutes to milliseconds, use:
73.190 + * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
73.191 + *
73.192 + * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
73.193 + * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
73.194 + * @return the converted duration in this unit,
73.195 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.196 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.197 + */
73.198 + public long convert(long sourceDuration, TimeUnit sourceUnit) {
73.199 + throw new AbstractMethodError();
73.200 + }
73.201 +
73.202 + /**
73.203 + * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
73.204 + * @param duration the duration
73.205 + * @return the converted duration,
73.206 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.207 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.208 + * @see #convert
73.209 + */
73.210 + public long toNanos(long duration) {
73.211 + throw new AbstractMethodError();
73.212 + }
73.213 +
73.214 + /**
73.215 + * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
73.216 + * @param duration the duration
73.217 + * @return the converted duration,
73.218 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.219 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.220 + * @see #convert
73.221 + */
73.222 + public long toMicros(long duration) {
73.223 + throw new AbstractMethodError();
73.224 + }
73.225 +
73.226 + /**
73.227 + * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
73.228 + * @param duration the duration
73.229 + * @return the converted duration,
73.230 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.231 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.232 + * @see #convert
73.233 + */
73.234 + public long toMillis(long duration) {
73.235 + throw new AbstractMethodError();
73.236 + }
73.237 +
73.238 + /**
73.239 + * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
73.240 + * @param duration the duration
73.241 + * @return the converted duration,
73.242 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.243 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.244 + * @see #convert
73.245 + */
73.246 + public long toSeconds(long duration) {
73.247 + throw new AbstractMethodError();
73.248 + }
73.249 +
73.250 + /**
73.251 + * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
73.252 + * @param duration the duration
73.253 + * @return the converted duration,
73.254 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.255 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.256 + * @see #convert
73.257 + * @since 1.6
73.258 + */
73.259 + public long toMinutes(long duration) {
73.260 + throw new AbstractMethodError();
73.261 + }
73.262 +
73.263 + /**
73.264 + * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
73.265 + * @param duration the duration
73.266 + * @return the converted duration,
73.267 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
73.268 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
73.269 + * @see #convert
73.270 + * @since 1.6
73.271 + */
73.272 + public long toHours(long duration) {
73.273 + throw new AbstractMethodError();
73.274 + }
73.275 +
73.276 + /**
73.277 + * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
73.278 + * @param duration the duration
73.279 + * @return the converted duration
73.280 + * @see #convert
73.281 + * @since 1.6
73.282 + */
73.283 + public long toDays(long duration) {
73.284 + throw new AbstractMethodError();
73.285 + }
73.286 +
73.287 + /**
73.288 + * Utility to compute the excess-nanosecond argument to wait,
73.289 + * sleep, join.
73.290 + * @param d the duration
73.291 + * @param m the number of milliseconds
73.292 + * @return the number of nanoseconds
73.293 + */
73.294 + abstract int excessNanos(long d, long m);
73.295 +
73.296 + /**
73.297 + * Performs a timed {@link Object#wait(long, int) Object.wait}
73.298 + * using this time unit.
73.299 + * This is a convenience method that converts timeout arguments
73.300 + * into the form required by the <tt>Object.wait</tt> method.
73.301 + *
73.302 + * <p>For example, you could implement a blocking <tt>poll</tt>
73.303 + * method (see {@link BlockingQueue#poll BlockingQueue.poll})
73.304 + * using:
73.305 + *
73.306 + * <pre> {@code
73.307 + * public synchronized Object poll(long timeout, TimeUnit unit)
73.308 + * throws InterruptedException {
73.309 + * while (empty) {
73.310 + * unit.timedWait(this, timeout);
73.311 + * ...
73.312 + * }
73.313 + * }}</pre>
73.314 + *
73.315 + * @param obj the object to wait on
73.316 + * @param timeout the maximum time to wait. If less than
73.317 + * or equal to zero, do not wait at all.
73.318 + * @throws InterruptedException if interrupted while waiting
73.319 + */
73.320 + public void timedWait(Object obj, long timeout)
73.321 + throws InterruptedException {
73.322 + if (timeout > 0) {
73.323 + long ms = toMillis(timeout);
73.324 + int ns = excessNanos(timeout, ms);
73.325 + obj.wait(ms, ns);
73.326 + }
73.327 + }
73.328 +
73.329 + /**
73.330 + * Performs a timed {@link Thread#join(long, int) Thread.join}
73.331 + * using this time unit.
73.332 + * This is a convenience method that converts time arguments into the
73.333 + * form required by the <tt>Thread.join</tt> method.
73.334 + *
73.335 + * @param thread the thread to wait for
73.336 + * @param timeout the maximum time to wait. If less than
73.337 + * or equal to zero, do not wait at all.
73.338 + * @throws InterruptedException if interrupted while waiting
73.339 + */
73.340 +// public void timedJoin(Thread thread, long timeout)
73.341 +// throws InterruptedException {
73.342 +// if (timeout > 0) {
73.343 +// long ms = toMillis(timeout);
73.344 +// int ns = excessNanos(timeout, ms);
73.345 +// thread.join(ms, ns);
73.346 +// }
73.347 +// }
73.348 +
73.349 + /**
73.350 + * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
73.351 + * this time unit.
73.352 + * This is a convenience method that converts time arguments into the
73.353 + * form required by the <tt>Thread.sleep</tt> method.
73.354 + *
73.355 + * @param timeout the minimum time to sleep. If less than
73.356 + * or equal to zero, do not sleep at all.
73.357 + * @throws InterruptedException if interrupted while sleeping
73.358 + */
73.359 + public void sleep(long timeout) throws InterruptedException {
73.360 + if (timeout > 0) {
73.361 + long ms = toMillis(timeout);
73.362 + int ns = excessNanos(timeout, ms);
73.363 + Object o = new Object();
73.364 + synchronized (o) {
73.365 + o.wait(ms, ns);
73.366 + }
73.367 + }
73.368 + }
73.369 +
73.370 +}
74.1 --- a/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/CollectionsTest.java Tue Feb 05 16:40:01 2013 +0100
74.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/CollectionsTest.java Tue Feb 05 17:04:22 2013 +0100
74.3 @@ -25,6 +25,8 @@
74.4 import java.util.HashSet;
74.5 import java.util.List;
74.6 import java.util.Map;
74.7 +import java.util.Map.Entry;
74.8 +import java.util.Vector;
74.9 import org.apidesign.bck2brwsr.vmtest.Compare;
74.10 import org.apidesign.bck2brwsr.vmtest.VMTest;
74.11 import org.testng.annotations.Factory;
74.12 @@ -92,10 +94,9 @@
74.13 map.put("nine", 9);
74.14 map.put("ten", 10);
74.15
74.16 - Map.Entry<String,Integer>[] arr = map.entrySet().toArray(new Map.Entry[map.size()]);
74.17 - Arrays.sort(arr, new C());
74.18 -
74.19 - return Arrays.asList(arr).toString();
74.20 + List<Entry<String,Integer>> arr = new Vector<>();
74.21 + arr.addAll(map.entrySet());
74.22 + return arr.toString();
74.23 }
74.24
74.25 @Factory
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/RandomTest.java Tue Feb 05 17:04:22 2013 +0100
75.3 @@ -0,0 +1,40 @@
75.4 +/**
75.5 + * Back 2 Browser Bytecode Translator
75.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
75.7 + *
75.8 + * This program is free software: you can redistribute it and/or modify
75.9 + * it under the terms of the GNU General Public License as published by
75.10 + * the Free Software Foundation, version 2 of the License.
75.11 + *
75.12 + * This program is distributed in the hope that it will be useful,
75.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
75.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75.15 + * GNU General Public License for more details.
75.16 + *
75.17 + * You should have received a copy of the GNU General Public License
75.18 + * along with this program. Look for COPYING file in the top folder.
75.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
75.20 + */
75.21 +package org.apidesign.bck2brwsr.compact.tck;
75.22 +
75.23 +import java.util.Random;
75.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
75.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
75.26 +import org.testng.annotations.Factory;
75.27 +
75.28 +/**
75.29 + *
75.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
75.31 + */
75.32 +public class RandomTest {
75.33 + @Compare public boolean canInstantiateRandom() {
75.34 + Random r = new Random();
75.35 + r.nextInt();
75.36 + return r != null;
75.37 + }
75.38 +
75.39 +
75.40 + @Factory public static Object[] create() {
75.41 + return VMTest.create(RandomTest.class);
75.42 + }
75.43 +}
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
76.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ReaderTest.java Tue Feb 05 17:04:22 2013 +0100
76.3 @@ -0,0 +1,60 @@
76.4 +/**
76.5 + * Back 2 Browser Bytecode Translator
76.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
76.7 + *
76.8 + * This program is free software: you can redistribute it and/or modify
76.9 + * it under the terms of the GNU General Public License as published by
76.10 + * the Free Software Foundation, version 2 of the License.
76.11 + *
76.12 + * This program is distributed in the hope that it will be useful,
76.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
76.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76.15 + * GNU General Public License for more details.
76.16 + *
76.17 + * You should have received a copy of the GNU General Public License
76.18 + * along with this program. Look for COPYING file in the top folder.
76.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
76.20 + */
76.21 +package org.apidesign.bck2brwsr.compact.tck;
76.22 +
76.23 +import java.io.ByteArrayInputStream;
76.24 +import java.io.IOException;
76.25 +import java.io.InputStreamReader;
76.26 +import java.util.Arrays;
76.27 +import org.apidesign.bck2brwsr.vmtest.Compare;
76.28 +import org.apidesign.bck2brwsr.vmtest.VMTest;
76.29 +import org.testng.annotations.Factory;
76.30 +
76.31 +/**
76.32 + *
76.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
76.34 + */
76.35 +public class ReaderTest {
76.36 + @Compare public String readUTFString() throws IOException {
76.37 + byte[] arr = {
76.38 + (byte)-59, (byte)-67, (byte)108, (byte)117, (byte)-59, (byte)-91,
76.39 + (byte)111, (byte)117, (byte)-60, (byte)-115, (byte)107, (byte)-61,
76.40 + (byte)-67, (byte)32, (byte)107, (byte)-59, (byte)-81, (byte)-59,
76.41 + (byte)-120
76.42 + };
76.43 + ByteArrayInputStream is = new ByteArrayInputStream(arr);
76.44 + InputStreamReader r = new InputStreamReader(is);
76.45 +
76.46 + StringBuilder sb = new StringBuilder();
76.47 + for (;;) {
76.48 + int ch = r.read();
76.49 + if (ch == -1) {
76.50 + break;
76.51 + }
76.52 + sb.append((char)ch);
76.53 + }
76.54 + return sb.toString().toString();
76.55 + }
76.56 + @Compare public String stringToBytes() {
76.57 + return Arrays.toString("Žluťoučký kůň".getBytes());
76.58 + }
76.59 +
76.60 + @Factory public static Object[] create() {
76.61 + return VMTest.create(ReaderTest.class);
76.62 + }
76.63 +}
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/emul/mini/src/main/java/java/lang/ArrayStoreException.java Tue Feb 05 17:04:22 2013 +0100
77.3 @@ -0,0 +1,60 @@
77.4 +/*
77.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
77.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
77.7 + *
77.8 + * This code is free software; you can redistribute it and/or modify it
77.9 + * under the terms of the GNU General Public License version 2 only, as
77.10 + * published by the Free Software Foundation. Oracle designates this
77.11 + * particular file as subject to the "Classpath" exception as provided
77.12 + * by Oracle in the LICENSE file that accompanied this code.
77.13 + *
77.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
77.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
77.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
77.17 + * version 2 for more details (a copy is included in the LICENSE file that
77.18 + * accompanied this code).
77.19 + *
77.20 + * You should have received a copy of the GNU General Public License version
77.21 + * 2 along with this work; if not, write to the Free Software Foundation,
77.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
77.23 + *
77.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
77.25 + * or visit www.oracle.com if you need additional information or have any
77.26 + * questions.
77.27 + */
77.28 +
77.29 +package java.lang;
77.30 +
77.31 +/**
77.32 + * Thrown to indicate that an attempt has been made to store the
77.33 + * wrong type of object into an array of objects. For example, the
77.34 + * following code generates an <code>ArrayStoreException</code>:
77.35 + * <p><blockquote><pre>
77.36 + * Object x[] = new String[3];
77.37 + * x[0] = new Integer(0);
77.38 + * </pre></blockquote>
77.39 + *
77.40 + * @author unascribed
77.41 + * @since JDK1.0
77.42 + */
77.43 +public
77.44 +class ArrayStoreException extends RuntimeException {
77.45 + private static final long serialVersionUID = -4522193890499838241L;
77.46 +
77.47 + /**
77.48 + * Constructs an <code>ArrayStoreException</code> with no detail message.
77.49 + */
77.50 + public ArrayStoreException() {
77.51 + super();
77.52 + }
77.53 +
77.54 + /**
77.55 + * Constructs an <code>ArrayStoreException</code> with the specified
77.56 + * detail message.
77.57 + *
77.58 + * @param s the detail message.
77.59 + */
77.60 + public ArrayStoreException(String s) {
77.61 + super(s);
77.62 + }
77.63 +}
78.1 --- a/emul/mini/src/main/java/java/lang/Class.java Tue Feb 05 16:40:01 2013 +0100
78.2 +++ b/emul/mini/src/main/java/java/lang/Class.java Tue Feb 05 17:04:22 2013 +0100
78.3 @@ -347,6 +347,9 @@
78.4 * @since JDK1.1
78.5 */
78.6 public boolean isInstance(Object obj) {
78.7 + if (obj == null) {
78.8 + return false;
78.9 + }
78.10 if (isArray()) {
78.11 return isAssignableFrom(obj.getClass());
78.12 }
78.13 @@ -909,7 +912,50 @@
78.14 }
78.15 return m;
78.16 }
78.17 -
78.18 +
78.19 + /**
78.20 + * Returns an array of {@code Method} objects reflecting all the
78.21 + * methods declared by the class or interface represented by this
78.22 + * {@code Class} object. This includes public, protected, default
78.23 + * (package) access, and private methods, but excludes inherited methods.
78.24 + * The elements in the array returned are not sorted and are not in any
78.25 + * particular order. This method returns an array of length 0 if the class
78.26 + * or interface declares no methods, or if this {@code Class} object
78.27 + * represents a primitive type, an array class, or void. The class
78.28 + * initialization method {@code <clinit>} is not included in the
78.29 + * returned array. If the class declares multiple public member methods
78.30 + * with the same parameter types, they are all included in the returned
78.31 + * array.
78.32 + *
78.33 + * <p> See <em>The Java Language Specification</em>, section 8.2.
78.34 + *
78.35 + * @return the array of {@code Method} objects representing all the
78.36 + * declared methods of this class
78.37 + * @exception SecurityException
78.38 + * If a security manager, <i>s</i>, is present and any of the
78.39 + * following conditions is met:
78.40 + *
78.41 + * <ul>
78.42 + *
78.43 + * <li> invocation of
78.44 + * {@link SecurityManager#checkMemberAccess
78.45 + * s.checkMemberAccess(this, Member.DECLARED)} denies
78.46 + * access to the declared methods within this class
78.47 + *
78.48 + * <li> the caller's class loader is not the same as or an
78.49 + * ancestor of the class loader for the current class and
78.50 + * invocation of {@link SecurityManager#checkPackageAccess
78.51 + * s.checkPackageAccess()} denies access to the package
78.52 + * of this class
78.53 + *
78.54 + * </ul>
78.55 + *
78.56 + * @since JDK1.1
78.57 + */
78.58 + public Method[] getDeclaredMethods() throws SecurityException {
78.59 + throw new SecurityException();
78.60 + }
78.61 +
78.62 /**
78.63 * Character.isDigit answers {@code true} to some non-ascii
78.64 * digits. This one does not.
78.65 @@ -1096,6 +1142,48 @@
78.66 public ClassLoader getClassLoader() {
78.67 throw new SecurityException();
78.68 }
78.69 +
78.70 + /**
78.71 + * Determines the interfaces implemented by the class or interface
78.72 + * represented by this object.
78.73 + *
78.74 + * <p> If this object represents a class, the return value is an array
78.75 + * containing objects representing all interfaces implemented by the
78.76 + * class. The order of the interface objects in the array corresponds to
78.77 + * the order of the interface names in the {@code implements} clause
78.78 + * of the declaration of the class represented by this object. For
78.79 + * example, given the declaration:
78.80 + * <blockquote>
78.81 + * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
78.82 + * </blockquote>
78.83 + * suppose the value of {@code s} is an instance of
78.84 + * {@code Shimmer}; the value of the expression:
78.85 + * <blockquote>
78.86 + * {@code s.getClass().getInterfaces()[0]}
78.87 + * </blockquote>
78.88 + * is the {@code Class} object that represents interface
78.89 + * {@code FloorWax}; and the value of:
78.90 + * <blockquote>
78.91 + * {@code s.getClass().getInterfaces()[1]}
78.92 + * </blockquote>
78.93 + * is the {@code Class} object that represents interface
78.94 + * {@code DessertTopping}.
78.95 + *
78.96 + * <p> If this object represents an interface, the array contains objects
78.97 + * representing all interfaces extended by the interface. The order of the
78.98 + * interface objects in the array corresponds to the order of the interface
78.99 + * names in the {@code extends} clause of the declaration of the
78.100 + * interface represented by this object.
78.101 + *
78.102 + * <p> If this object represents a class or interface that implements no
78.103 + * interfaces, the method returns an array of length 0.
78.104 + *
78.105 + * <p> If this object represents a primitive type or void, the method
78.106 + * returns an array of length 0.
78.107 + *
78.108 + * @return an array of interfaces implemented by this class.
78.109 + */
78.110 + public native Class<?>[] getInterfaces();
78.111
78.112 /**
78.113 * Returns the {@code Class} representing the component type of an
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/emul/mini/src/main/java/java/lang/Cloneable.java Tue Feb 05 17:04:22 2013 +0100
79.3 @@ -0,0 +1,54 @@
79.4 +/*
79.5 + * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
79.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
79.7 + *
79.8 + * This code is free software; you can redistribute it and/or modify it
79.9 + * under the terms of the GNU General Public License version 2 only, as
79.10 + * published by the Free Software Foundation. Oracle designates this
79.11 + * particular file as subject to the "Classpath" exception as provided
79.12 + * by Oracle in the LICENSE file that accompanied this code.
79.13 + *
79.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
79.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
79.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
79.17 + * version 2 for more details (a copy is included in the LICENSE file that
79.18 + * accompanied this code).
79.19 + *
79.20 + * You should have received a copy of the GNU General Public License version
79.21 + * 2 along with this work; if not, write to the Free Software Foundation,
79.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
79.23 + *
79.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
79.25 + * or visit www.oracle.com if you need additional information or have any
79.26 + * questions.
79.27 + */
79.28 +
79.29 +package java.lang;
79.30 +
79.31 +/**
79.32 + * A class implements the <code>Cloneable</code> interface to
79.33 + * indicate to the {@link java.lang.Object#clone()} method that it
79.34 + * is legal for that method to make a
79.35 + * field-for-field copy of instances of that class.
79.36 + * <p>
79.37 + * Invoking Object's clone method on an instance that does not implement the
79.38 + * <code>Cloneable</code> interface results in the exception
79.39 + * <code>CloneNotSupportedException</code> being thrown.
79.40 + * <p>
79.41 + * By convention, classes that implement this interface should override
79.42 + * <tt>Object.clone</tt> (which is protected) with a public method.
79.43 + * See {@link java.lang.Object#clone()} for details on overriding this
79.44 + * method.
79.45 + * <p>
79.46 + * Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
79.47 + * Therefore, it is not possible to clone an object merely by virtue of the
79.48 + * fact that it implements this interface. Even if the clone method is invoked
79.49 + * reflectively, there is no guarantee that it will succeed.
79.50 + *
79.51 + * @author unascribed
79.52 + * @see java.lang.CloneNotSupportedException
79.53 + * @see java.lang.Object#clone()
79.54 + * @since JDK1.0
79.55 + */
79.56 +public interface Cloneable {
79.57 +}
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
80.2 +++ b/emul/mini/src/main/java/java/lang/IllegalAccessError.java Tue Feb 05 17:04:22 2013 +0100
80.3 @@ -0,0 +1,58 @@
80.4 +/*
80.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
80.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
80.7 + *
80.8 + * This code is free software; you can redistribute it and/or modify it
80.9 + * under the terms of the GNU General Public License version 2 only, as
80.10 + * published by the Free Software Foundation. Oracle designates this
80.11 + * particular file as subject to the "Classpath" exception as provided
80.12 + * by Oracle in the LICENSE file that accompanied this code.
80.13 + *
80.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
80.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
80.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
80.17 + * version 2 for more details (a copy is included in the LICENSE file that
80.18 + * accompanied this code).
80.19 + *
80.20 + * You should have received a copy of the GNU General Public License version
80.21 + * 2 along with this work; if not, write to the Free Software Foundation,
80.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
80.23 + *
80.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
80.25 + * or visit www.oracle.com if you need additional information or have any
80.26 + * questions.
80.27 + */
80.28 +
80.29 +package java.lang;
80.30 +
80.31 +/**
80.32 + * Thrown if an application attempts to access or modify a field, or
80.33 + * to call a method that it does not have access to.
80.34 + * <p>
80.35 + * Normally, this error is caught by the compiler; this error can
80.36 + * only occur at run time if the definition of a class has
80.37 + * incompatibly changed.
80.38 + *
80.39 + * @author unascribed
80.40 + * @since JDK1.0
80.41 + */
80.42 +public class IllegalAccessError extends IncompatibleClassChangeError {
80.43 + private static final long serialVersionUID = -8988904074992417891L;
80.44 +
80.45 + /**
80.46 + * Constructs an <code>IllegalAccessError</code> with no detail message.
80.47 + */
80.48 + public IllegalAccessError() {
80.49 + super();
80.50 + }
80.51 +
80.52 + /**
80.53 + * Constructs an <code>IllegalAccessError</code> with the specified
80.54 + * detail message.
80.55 + *
80.56 + * @param s the detail message.
80.57 + */
80.58 + public IllegalAccessError(String s) {
80.59 + super(s);
80.60 + }
80.61 +}
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
81.2 +++ b/emul/mini/src/main/java/java/lang/IncompatibleClassChangeError.java Tue Feb 05 17:04:22 2013 +0100
81.3 @@ -0,0 +1,57 @@
81.4 +/*
81.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
81.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
81.7 + *
81.8 + * This code is free software; you can redistribute it and/or modify it
81.9 + * under the terms of the GNU General Public License version 2 only, as
81.10 + * published by the Free Software Foundation. Oracle designates this
81.11 + * particular file as subject to the "Classpath" exception as provided
81.12 + * by Oracle in the LICENSE file that accompanied this code.
81.13 + *
81.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
81.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
81.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
81.17 + * version 2 for more details (a copy is included in the LICENSE file that
81.18 + * accompanied this code).
81.19 + *
81.20 + * You should have received a copy of the GNU General Public License version
81.21 + * 2 along with this work; if not, write to the Free Software Foundation,
81.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
81.23 + *
81.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
81.25 + * or visit www.oracle.com if you need additional information or have any
81.26 + * questions.
81.27 + */
81.28 +
81.29 +package java.lang;
81.30 +
81.31 +/**
81.32 + * Thrown when an incompatible class change has occurred to some class
81.33 + * definition. The definition of some class, on which the currently
81.34 + * executing method depends, has since changed.
81.35 + *
81.36 + * @author unascribed
81.37 + * @since JDK1.0
81.38 + */
81.39 +public
81.40 +class IncompatibleClassChangeError extends LinkageError {
81.41 + private static final long serialVersionUID = -4914975503642802119L;
81.42 +
81.43 + /**
81.44 + * Constructs an <code>IncompatibleClassChangeError</code> with no
81.45 + * detail message.
81.46 + */
81.47 + public IncompatibleClassChangeError () {
81.48 + super();
81.49 + }
81.50 +
81.51 + /**
81.52 + * Constructs an <code>IncompatibleClassChangeError</code> with the
81.53 + * specified detail message.
81.54 + *
81.55 + * @param s the detail message.
81.56 + */
81.57 + public IncompatibleClassChangeError(String s) {
81.58 + super(s);
81.59 + }
81.60 +}
82.1 --- a/emul/mini/src/main/java/java/lang/Math.java Tue Feb 05 16:40:01 2013 +0100
82.2 +++ b/emul/mini/src/main/java/java/lang/Math.java Tue Feb 05 17:04:22 2013 +0100
82.3 @@ -375,6 +375,68 @@
82.4 public static double floor(double a) {
82.5 throw new UnsupportedOperationException();
82.6 }
82.7 + /**
82.8 + * Computes the remainder operation on two arguments as prescribed
82.9 + * by the IEEE 754 standard.
82.10 + * The remainder value is mathematically equal to
82.11 + * <code>f1 - f2</code> × <i>n</i>,
82.12 + * where <i>n</i> is the mathematical integer closest to the exact
82.13 + * mathematical value of the quotient {@code f1/f2}, and if two
82.14 + * mathematical integers are equally close to {@code f1/f2},
82.15 + * then <i>n</i> is the integer that is even. If the remainder is
82.16 + * zero, its sign is the same as the sign of the first argument.
82.17 + * Special cases:
82.18 + * <ul><li>If either argument is NaN, or the first argument is infinite,
82.19 + * or the second argument is positive zero or negative zero, then the
82.20 + * result is NaN.
82.21 + * <li>If the first argument is finite and the second argument is
82.22 + * infinite, then the result is the same as the first argument.</ul>
82.23 + *
82.24 + * @param f1 the dividend.
82.25 + * @param f2 the divisor.
82.26 + * @return the remainder when {@code f1} is divided by
82.27 + * {@code f2}.
82.28 + */
82.29 + public static double IEEEremainder(double f1, double f2) {
82.30 + return f1 - (f2 * Math.round(f1 / f2));
82.31 + }
82.32 +
82.33 + /**
82.34 + * Returns the {@code double} value that is closest in value
82.35 + * to the argument and is equal to a mathematical integer. If two
82.36 + * {@code double} values that are mathematical integers are
82.37 + * equally close, the result is the integer value that is
82.38 + * even. Special cases:
82.39 + * <ul><li>If the argument value is already equal to a mathematical
82.40 + * integer, then the result is the same as the argument.
82.41 + * <li>If the argument is NaN or an infinity or positive zero or negative
82.42 + * zero, then the result is the same as the argument.</ul>
82.43 + *
82.44 + * @param a a {@code double} value.
82.45 + * @return the closest floating-point value to {@code a} that is
82.46 + * equal to a mathematical integer.
82.47 + */
82.48 + public static double rint(double a) {
82.49 + double ceil = ceil(a);
82.50 + double floor = floor(a);
82.51 +
82.52 + double dc = ceil - a;
82.53 + double df = a - floor;
82.54 +
82.55 + if (dc < df) {
82.56 + return ceil;
82.57 + } else if (dc > df) {
82.58 + return floor;
82.59 + }
82.60 +
82.61 + int tenC = (int) (ceil % 10.0);
82.62 +
82.63 + if (tenC % 2 == 0) {
82.64 + return ceil;
82.65 + } else {
82.66 + return floor;
82.67 + }
82.68 + }
82.69
82.70 /**
82.71 * Returns the angle <i>theta</i> from the conversion of rectangular
82.72 @@ -929,9 +991,11 @@
82.73 * @author Joseph D. Darcy
82.74 * @since 1.5
82.75 */
82.76 -// public static double signum(double d) {
82.77 -// return sun.misc.FpUtils.signum(d);
82.78 -// }
82.79 + public static double signum(double d) {
82.80 + if (d < 0.0) { return -1.0; }
82.81 + if (d > 0.0) { return 1.0; }
82.82 + return d;
82.83 + }
82.84
82.85 /**
82.86 * Returns the signum function of the argument; zero if the argument
82.87 @@ -950,9 +1014,11 @@
82.88 * @author Joseph D. Darcy
82.89 * @since 1.5
82.90 */
82.91 -// public static float signum(float f) {
82.92 -// return sun.misc.FpUtils.signum(f);
82.93 -// }
82.94 + public static float signum(float f) {
82.95 + if (f < 0.0f) { return -1.0f; }
82.96 + if (f > 0.0f) { return 1.0f; }
82.97 + return f;
82.98 + }
82.99
82.100 /**
82.101 * Returns the first floating-point argument with the sign of the
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
83.2 +++ b/emul/mini/src/main/java/java/lang/Override.java Tue Feb 05 17:04:22 2013 +0100
83.3 @@ -0,0 +1,52 @@
83.4 +/*
83.5 + * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
83.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
83.7 + *
83.8 + * This code is free software; you can redistribute it and/or modify it
83.9 + * under the terms of the GNU General Public License version 2 only, as
83.10 + * published by the Free Software Foundation. Oracle designates this
83.11 + * particular file as subject to the "Classpath" exception as provided
83.12 + * by Oracle in the LICENSE file that accompanied this code.
83.13 + *
83.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
83.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
83.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
83.17 + * version 2 for more details (a copy is included in the LICENSE file that
83.18 + * accompanied this code).
83.19 + *
83.20 + * You should have received a copy of the GNU General Public License version
83.21 + * 2 along with this work; if not, write to the Free Software Foundation,
83.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
83.23 + *
83.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
83.25 + * or visit www.oracle.com if you need additional information or have any
83.26 + * questions.
83.27 + */
83.28 +
83.29 +package java.lang;
83.30 +
83.31 +import java.lang.annotation.*;
83.32 +
83.33 +/**
83.34 + * Indicates that a method declaration is intended to override a
83.35 + * method declaration in a supertype. If a method is annotated with
83.36 + * this annotation type compilers are required to generate an error
83.37 + * message unless at least one of the following conditions hold:
83.38 + *
83.39 + * <ul><li>
83.40 + * The method does override or implement a method declared in a
83.41 + * supertype.
83.42 + * </li><li>
83.43 + * The method has a signature that is override-equivalent to that of
83.44 + * any public method declared in {@linkplain Object}.
83.45 + * </li></ul>
83.46 + *
83.47 + * @author Peter von der Ahé
83.48 + * @author Joshua Bloch
83.49 + * @jls 9.6.1.4 Override
83.50 + * @since 1.5
83.51 + */
83.52 +@Target(ElementType.METHOD)
83.53 +@Retention(RetentionPolicy.SOURCE)
83.54 +public @interface Override {
83.55 +}
84.1 --- a/emul/mini/src/main/java/java/lang/String.java Tue Feb 05 16:40:01 2013 +0100
84.2 +++ b/emul/mini/src/main/java/java/lang/String.java Tue Feb 05 17:04:22 2013 +0100
84.3 @@ -25,6 +25,7 @@
84.4
84.5 package java.lang;
84.6
84.7 +import java.io.UnsupportedEncodingException;
84.8 import java.util.Comparator;
84.9 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
84.10 import org.apidesign.bck2brwsr.core.JavaScriptBody;
84.11 @@ -200,6 +201,10 @@
84.12 * If the {@code offset} and {@code count} arguments index
84.13 * characters outside the bounds of the {@code value} array
84.14 */
84.15 + public String(char value[], int offset, int count) {
84.16 + initFromCharArray(value, offset, count);
84.17 + }
84.18 +
84.19 @JavaScriptBody(args = { "charArr", "off", "cnt" }, body =
84.20 "var up = off + cnt;\n" +
84.21 "for (var i = off; i < up; i++) {\n" +
84.22 @@ -207,8 +212,7 @@
84.23 "}\n" +
84.24 "this._r(charArr.slice(off, up).join(\"\"));\n"
84.25 )
84.26 - public String(char value[], int offset, int count) {
84.27 - }
84.28 + private native void initFromCharArray(char value[], int offset, int count);
84.29
84.30 /**
84.31 * Allocates a new {@code String} that contains characters from a subarray
84.32 @@ -415,17 +419,11 @@
84.33 *
84.34 * @since JDK1.1
84.35 */
84.36 -// public String(byte bytes[], int offset, int length, String charsetName)
84.37 -// throws UnsupportedEncodingException
84.38 -// {
84.39 -// if (charsetName == null)
84.40 -// throw new NullPointerException("charsetName");
84.41 -// checkBounds(bytes, offset, length);
84.42 -// char[] v = StringCoding.decode(charsetName, bytes, offset, length);
84.43 -// this.offset = 0;
84.44 -// this.count = v.length;
84.45 -// this.value = v;
84.46 -// }
84.47 + public String(byte bytes[], int offset, int length, String charsetName)
84.48 + throws UnsupportedEncodingException
84.49 + {
84.50 + this(checkUTF8(bytes, charsetName), offset, length);
84.51 + }
84.52
84.53 /**
84.54 * Constructs a new {@code String} by decoding the specified subarray of
84.55 @@ -492,11 +490,11 @@
84.56 *
84.57 * @since JDK1.1
84.58 */
84.59 -// public String(byte bytes[], String charsetName)
84.60 -// throws UnsupportedEncodingException
84.61 -// {
84.62 -// this(bytes, 0, bytes.length, charsetName);
84.63 -// }
84.64 + public String(byte bytes[], String charsetName)
84.65 + throws UnsupportedEncodingException
84.66 + {
84.67 + this(bytes, 0, bytes.length, charsetName);
84.68 + }
84.69
84.70 /**
84.71 * Constructs a new {@code String} by decoding the specified array of
84.72 @@ -553,10 +551,14 @@
84.73 public String(byte bytes[], int offset, int length) {
84.74 checkBounds(bytes, offset, length);
84.75 char[] v = new char[length];
84.76 - for (int i = 0; i < length; i++) {
84.77 - v[i] = (char)bytes[offset++];
84.78 + int[] at = { offset };
84.79 + int end = offset + length;
84.80 + int chlen = 0;
84.81 + while (at[0] < end) {
84.82 + int ch = nextChar(bytes, at);
84.83 + v[chlen++] = (char)ch;
84.84 }
84.85 - this.r = new String(v, 0, v.length);
84.86 + initFromCharArray(v, 0, chlen);
84.87 }
84.88
84.89 /**
84.90 @@ -925,12 +927,12 @@
84.91 *
84.92 * @since JDK1.1
84.93 */
84.94 -// public byte[] getBytes(String charsetName)
84.95 -// throws UnsupportedEncodingException
84.96 -// {
84.97 -// if (charsetName == null) throw new NullPointerException();
84.98 -// return StringCoding.encode(charsetName, value, offset, count);
84.99 -// }
84.100 + public byte[] getBytes(String charsetName)
84.101 + throws UnsupportedEncodingException
84.102 + {
84.103 + checkUTF8(null, charsetName);
84.104 + return getBytes();
84.105 + }
84.106
84.107 /**
84.108 * Encodes this {@code String} into a sequence of bytes using the given
84.109 @@ -971,10 +973,24 @@
84.110 * @since JDK1.1
84.111 */
84.112 public byte[] getBytes() {
84.113 - byte[] arr = new byte[length()];
84.114 - for (int i = 0; i < arr.length; i++) {
84.115 - final char v = charAt(i);
84.116 - arr[i] = (byte)v;
84.117 + int len = length();
84.118 + byte[] arr = new byte[len];
84.119 + for (int i = 0, j = 0; j < len; j++) {
84.120 + final int v = charAt(j);
84.121 + if (v < 128) {
84.122 + arr[i++] = (byte) v;
84.123 + continue;
84.124 + }
84.125 + if (v < 0x0800) {
84.126 + arr = System.expandArray(arr, i + 1);
84.127 + arr[i++] = (byte) (0xC0 | (v >> 6));
84.128 + arr[i++] = (byte) (0x80 | (0x3F & v));
84.129 + continue;
84.130 + }
84.131 + arr = System.expandArray(arr, i + 2);
84.132 + arr[i++] = (byte) (0xE0 | (v >> 12));
84.133 + arr[i++] = (byte) (0x80 | ((v >> 6) & 0x7F));
84.134 + arr[i++] = (byte) (0x80 | (0x3F & v));
84.135 }
84.136 return arr;
84.137 }
84.138 @@ -1210,7 +1226,7 @@
84.139 private static int offset() {
84.140 return 0;
84.141 }
84.142 -
84.143 +
84.144 private static class CaseInsensitiveComparator
84.145 implements Comparator<String>, java.io.Serializable {
84.146 // use serialVersionUID from JDK 1.2.2 for interoperability
84.147 @@ -3007,4 +3023,57 @@
84.148 * guaranteed to be from a pool of unique strings.
84.149 */
84.150 public native String intern();
84.151 +
84.152 +
84.153 + private static <T> T checkUTF8(T data, String charsetName)
84.154 + throws UnsupportedEncodingException {
84.155 + if (charsetName == null) {
84.156 + throw new NullPointerException("charsetName");
84.157 + }
84.158 + if (!charsetName.equalsIgnoreCase("UTF-8")
84.159 + && !charsetName.equalsIgnoreCase("UTF8")) {
84.160 + throw new UnsupportedEncodingException(charsetName);
84.161 + }
84.162 + return data;
84.163 + }
84.164 +
84.165 + private static int nextChar(byte[] arr, int[] index) throws IndexOutOfBoundsException {
84.166 + int c = arr[index[0]++] & 0xff;
84.167 + switch (c >> 4) {
84.168 + case 0:
84.169 + case 1:
84.170 + case 2:
84.171 + case 3:
84.172 + case 4:
84.173 + case 5:
84.174 + case 6:
84.175 + case 7:
84.176 + /* 0xxxxxxx*/
84.177 + return c;
84.178 + case 12:
84.179 + case 13: {
84.180 + /* 110x xxxx 10xx xxxx*/
84.181 + int char2 = (int) arr[index[0]++];
84.182 + if ((char2 & 0xC0) != 0x80) {
84.183 + throw new IndexOutOfBoundsException("malformed input");
84.184 + }
84.185 + return (((c & 0x1F) << 6) | (char2 & 0x3F));
84.186 + }
84.187 + case 14: {
84.188 + /* 1110 xxxx 10xx xxxx 10xx xxxx */
84.189 + int char2 = arr[index[0]++];
84.190 + int char3 = arr[index[0]++];
84.191 + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
84.192 + throw new IndexOutOfBoundsException("malformed input");
84.193 + }
84.194 + return (((c & 0x0F) << 12)
84.195 + | ((char2 & 0x3F) << 6)
84.196 + | ((char3 & 0x3F) << 0));
84.197 + }
84.198 + default:
84.199 + /* 10xx xxxx, 1111 xxxx */
84.200 + throw new IndexOutOfBoundsException("malformed input");
84.201 + }
84.202 +
84.203 + }
84.204 }
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Constructor.java Tue Feb 05 17:04:22 2013 +0100
85.3 @@ -0,0 +1,567 @@
85.4 +/*
85.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
85.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
85.7 + *
85.8 + * This code is free software; you can redistribute it and/or modify it
85.9 + * under the terms of the GNU General Public License version 2 only, as
85.10 + * published by the Free Software Foundation. Oracle designates this
85.11 + * particular file as subject to the "Classpath" exception as provided
85.12 + * by Oracle in the LICENSE file that accompanied this code.
85.13 + *
85.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
85.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
85.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
85.17 + * version 2 for more details (a copy is included in the LICENSE file that
85.18 + * accompanied this code).
85.19 + *
85.20 + * You should have received a copy of the GNU General Public License version
85.21 + * 2 along with this work; if not, write to the Free Software Foundation,
85.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
85.23 + *
85.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
85.25 + * or visit www.oracle.com if you need additional information or have any
85.26 + * questions.
85.27 + */
85.28 +
85.29 +package java.lang.reflect;
85.30 +
85.31 +import java.lang.annotation.Annotation;
85.32 +import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
85.33 +
85.34 +/**
85.35 + * {@code Constructor} provides information about, and access to, a single
85.36 + * constructor for a class.
85.37 + *
85.38 + * <p>{@code Constructor} permits widening conversions to occur when matching the
85.39 + * actual parameters to newInstance() with the underlying
85.40 + * constructor's formal parameters, but throws an
85.41 + * {@code IllegalArgumentException} if a narrowing conversion would occur.
85.42 + *
85.43 + * @param <T> the class in which the constructor is declared
85.44 + *
85.45 + * @see Member
85.46 + * @see java.lang.Class
85.47 + * @see java.lang.Class#getConstructors()
85.48 + * @see java.lang.Class#getConstructor(Class[])
85.49 + * @see java.lang.Class#getDeclaredConstructors()
85.50 + *
85.51 + * @author Kenneth Russell
85.52 + * @author Nakul Saraiya
85.53 + */
85.54 +public final
85.55 + class Constructor<T> extends AccessibleObject implements
85.56 + GenericDeclaration,
85.57 + Member {
85.58 +
85.59 + private Class<T> clazz;
85.60 + private int slot;
85.61 + private Class<?>[] parameterTypes;
85.62 + private Class<?>[] exceptionTypes;
85.63 + private int modifiers;
85.64 + // Generics and annotations support
85.65 + private transient String signature;
85.66 + private byte[] annotations;
85.67 + private byte[] parameterAnnotations;
85.68 +
85.69 +
85.70 + // For sharing of ConstructorAccessors. This branching structure
85.71 + // is currently only two levels deep (i.e., one root Constructor
85.72 + // and potentially many Constructor objects pointing to it.)
85.73 + private Constructor<T> root;
85.74 +
85.75 + /**
85.76 + * Package-private constructor used by ReflectAccess to enable
85.77 + * instantiation of these objects in Java code from the java.lang
85.78 + * package via sun.reflect.LangReflectAccess.
85.79 + */
85.80 + Constructor(Class<T> declaringClass,
85.81 + Class<?>[] parameterTypes,
85.82 + Class<?>[] checkedExceptions,
85.83 + int modifiers,
85.84 + int slot,
85.85 + String signature,
85.86 + byte[] annotations,
85.87 + byte[] parameterAnnotations)
85.88 + {
85.89 + this.clazz = declaringClass;
85.90 + this.parameterTypes = parameterTypes;
85.91 + this.exceptionTypes = checkedExceptions;
85.92 + this.modifiers = modifiers;
85.93 + this.slot = slot;
85.94 + this.signature = signature;
85.95 + this.annotations = annotations;
85.96 + this.parameterAnnotations = parameterAnnotations;
85.97 + }
85.98 +
85.99 + /**
85.100 + * Package-private routine (exposed to java.lang.Class via
85.101 + * ReflectAccess) which returns a copy of this Constructor. The copy's
85.102 + * "root" field points to this Constructor.
85.103 + */
85.104 + Constructor<T> copy() {
85.105 + return this;
85.106 + }
85.107 +
85.108 + /**
85.109 + * Returns the {@code Class} object representing the class that declares
85.110 + * the constructor represented by this {@code Constructor} object.
85.111 + */
85.112 + public Class<T> getDeclaringClass() {
85.113 + return clazz;
85.114 + }
85.115 +
85.116 + /**
85.117 + * Returns the name of this constructor, as a string. This is
85.118 + * the binary name of the constructor's declaring class.
85.119 + */
85.120 + public String getName() {
85.121 + return getDeclaringClass().getName();
85.122 + }
85.123 +
85.124 + /**
85.125 + * Returns the Java language modifiers for the constructor
85.126 + * represented by this {@code Constructor} object, as an integer. The
85.127 + * {@code Modifier} class should be used to decode the modifiers.
85.128 + *
85.129 + * @see Modifier
85.130 + */
85.131 + public int getModifiers() {
85.132 + return modifiers;
85.133 + }
85.134 +
85.135 + /**
85.136 + * Returns an array of {@code TypeVariable} objects that represent the
85.137 + * type variables declared by the generic declaration represented by this
85.138 + * {@code GenericDeclaration} object, in declaration order. Returns an
85.139 + * array of length 0 if the underlying generic declaration declares no type
85.140 + * variables.
85.141 + *
85.142 + * @return an array of {@code TypeVariable} objects that represent
85.143 + * the type variables declared by this generic declaration
85.144 + * @throws GenericSignatureFormatError if the generic
85.145 + * signature of this generic declaration does not conform to
85.146 + * the format specified in
85.147 + * <cite>The Java™ Virtual Machine Specification</cite>
85.148 + * @since 1.5
85.149 + */
85.150 + public TypeVariable<Constructor<T>>[] getTypeParameters() {
85.151 + return TypeProvider.getDefault().getTypeParameters(this);
85.152 + }
85.153 +
85.154 +
85.155 + /**
85.156 + * Returns an array of {@code Class} objects that represent the formal
85.157 + * parameter types, in declaration order, of the constructor
85.158 + * represented by this {@code Constructor} object. Returns an array of
85.159 + * length 0 if the underlying constructor takes no parameters.
85.160 + *
85.161 + * @return the parameter types for the constructor this object
85.162 + * represents
85.163 + */
85.164 + public Class<?>[] getParameterTypes() {
85.165 + return (Class<?>[]) parameterTypes.clone();
85.166 + }
85.167 +
85.168 +
85.169 + /**
85.170 + * Returns an array of {@code Type} objects that represent the formal
85.171 + * parameter types, in declaration order, of the method represented by
85.172 + * this {@code Constructor} object. Returns an array of length 0 if the
85.173 + * underlying method takes no parameters.
85.174 + *
85.175 + * <p>If a formal parameter type is a parameterized type,
85.176 + * the {@code Type} object returned for it must accurately reflect
85.177 + * the actual type parameters used in the source code.
85.178 + *
85.179 + * <p>If a formal parameter type is a type variable or a parameterized
85.180 + * type, it is created. Otherwise, it is resolved.
85.181 + *
85.182 + * @return an array of {@code Type}s that represent the formal
85.183 + * parameter types of the underlying method, in declaration order
85.184 + * @throws GenericSignatureFormatError
85.185 + * if the generic method signature does not conform to the format
85.186 + * specified in
85.187 + * <cite>The Java™ Virtual Machine Specification</cite>
85.188 + * @throws TypeNotPresentException if any of the parameter
85.189 + * types of the underlying method refers to a non-existent type
85.190 + * declaration
85.191 + * @throws MalformedParameterizedTypeException if any of
85.192 + * the underlying method's parameter types refer to a parameterized
85.193 + * type that cannot be instantiated for any reason
85.194 + * @since 1.5
85.195 + */
85.196 + public Type[] getGenericParameterTypes() {
85.197 + return TypeProvider.getDefault().getGenericParameterTypes(this);
85.198 + }
85.199 +
85.200 +
85.201 + /**
85.202 + * Returns an array of {@code Class} objects that represent the types
85.203 + * of exceptions declared to be thrown by the underlying constructor
85.204 + * represented by this {@code Constructor} object. Returns an array of
85.205 + * length 0 if the constructor declares no exceptions in its {@code throws} clause.
85.206 + *
85.207 + * @return the exception types declared as being thrown by the
85.208 + * constructor this object represents
85.209 + */
85.210 + public Class<?>[] getExceptionTypes() {
85.211 + return (Class<?>[])exceptionTypes.clone();
85.212 + }
85.213 +
85.214 +
85.215 + /**
85.216 + * Returns an array of {@code Type} objects that represent the
85.217 + * exceptions declared to be thrown by this {@code Constructor} object.
85.218 + * Returns an array of length 0 if the underlying method declares
85.219 + * no exceptions in its {@code throws} clause.
85.220 + *
85.221 + * <p>If an exception type is a type variable or a parameterized
85.222 + * type, it is created. Otherwise, it is resolved.
85.223 + *
85.224 + * @return an array of Types that represent the exception types
85.225 + * thrown by the underlying method
85.226 + * @throws GenericSignatureFormatError
85.227 + * if the generic method signature does not conform to the format
85.228 + * specified in
85.229 + * <cite>The Java™ Virtual Machine Specification</cite>
85.230 + * @throws TypeNotPresentException if the underlying method's
85.231 + * {@code throws} clause refers to a non-existent type declaration
85.232 + * @throws MalformedParameterizedTypeException if
85.233 + * the underlying method's {@code throws} clause refers to a
85.234 + * parameterized type that cannot be instantiated for any reason
85.235 + * @since 1.5
85.236 + */
85.237 + public Type[] getGenericExceptionTypes() {
85.238 + return TypeProvider.getDefault().getGenericExceptionTypes(this);
85.239 + }
85.240 +
85.241 + /**
85.242 + * Compares this {@code Constructor} against the specified object.
85.243 + * Returns true if the objects are the same. Two {@code Constructor} objects are
85.244 + * the same if they were declared by the same class and have the
85.245 + * same formal parameter types.
85.246 + */
85.247 + public boolean equals(Object obj) {
85.248 + if (obj != null && obj instanceof Constructor) {
85.249 + Constructor<?> other = (Constructor<?>)obj;
85.250 + if (getDeclaringClass() == other.getDeclaringClass()) {
85.251 + /* Avoid unnecessary cloning */
85.252 + Class<?>[] params1 = parameterTypes;
85.253 + Class<?>[] params2 = other.parameterTypes;
85.254 + if (params1.length == params2.length) {
85.255 + for (int i = 0; i < params1.length; i++) {
85.256 + if (params1[i] != params2[i])
85.257 + return false;
85.258 + }
85.259 + return true;
85.260 + }
85.261 + }
85.262 + }
85.263 + return false;
85.264 + }
85.265 +
85.266 + /**
85.267 + * Returns a hashcode for this {@code Constructor}. The hashcode is
85.268 + * the same as the hashcode for the underlying constructor's
85.269 + * declaring class name.
85.270 + */
85.271 + public int hashCode() {
85.272 + return getDeclaringClass().getName().hashCode();
85.273 + }
85.274 +
85.275 + /**
85.276 + * Returns a string describing this {@code Constructor}. The string is
85.277 + * formatted as the constructor access modifiers, if any,
85.278 + * followed by the fully-qualified name of the declaring class,
85.279 + * followed by a parenthesized, comma-separated list of the
85.280 + * constructor's formal parameter types. For example:
85.281 + * <pre>
85.282 + * public java.util.Hashtable(int,float)
85.283 + * </pre>
85.284 + *
85.285 + * <p>The only possible modifiers for constructors are the access
85.286 + * modifiers {@code public}, {@code protected} or
85.287 + * {@code private}. Only one of these may appear, or none if the
85.288 + * constructor has default (package) access.
85.289 + */
85.290 + public String toString() {
85.291 + try {
85.292 + StringBuffer sb = new StringBuffer();
85.293 + int mod = getModifiers() & Modifier.constructorModifiers();
85.294 + if (mod != 0) {
85.295 + sb.append(Modifier.toString(mod) + " ");
85.296 + }
85.297 + sb.append(Field.getTypeName(getDeclaringClass()));
85.298 + sb.append("(");
85.299 + Class<?>[] params = parameterTypes; // avoid clone
85.300 + for (int j = 0; j < params.length; j++) {
85.301 + sb.append(Field.getTypeName(params[j]));
85.302 + if (j < (params.length - 1))
85.303 + sb.append(",");
85.304 + }
85.305 + sb.append(")");
85.306 + Class<?>[] exceptions = exceptionTypes; // avoid clone
85.307 + if (exceptions.length > 0) {
85.308 + sb.append(" throws ");
85.309 + for (int k = 0; k < exceptions.length; k++) {
85.310 + sb.append(exceptions[k].getName());
85.311 + if (k < (exceptions.length - 1))
85.312 + sb.append(",");
85.313 + }
85.314 + }
85.315 + return sb.toString();
85.316 + } catch (Exception e) {
85.317 + return "<" + e + ">";
85.318 + }
85.319 + }
85.320 +
85.321 + /**
85.322 + * Returns a string describing this {@code Constructor},
85.323 + * including type parameters. The string is formatted as the
85.324 + * constructor access modifiers, if any, followed by an
85.325 + * angle-bracketed comma separated list of the constructor's type
85.326 + * parameters, if any, followed by the fully-qualified name of the
85.327 + * declaring class, followed by a parenthesized, comma-separated
85.328 + * list of the constructor's generic formal parameter types.
85.329 + *
85.330 + * If this constructor was declared to take a variable number of
85.331 + * arguments, instead of denoting the last parameter as
85.332 + * "<tt><i>Type</i>[]</tt>", it is denoted as
85.333 + * "<tt><i>Type</i>...</tt>".
85.334 + *
85.335 + * A space is used to separate access modifiers from one another
85.336 + * and from the type parameters or return type. If there are no
85.337 + * type parameters, the type parameter list is elided; if the type
85.338 + * parameter list is present, a space separates the list from the
85.339 + * class name. If the constructor is declared to throw
85.340 + * exceptions, the parameter list is followed by a space, followed
85.341 + * by the word "{@code throws}" followed by a
85.342 + * comma-separated list of the thrown exception types.
85.343 + *
85.344 + * <p>The only possible modifiers for constructors are the access
85.345 + * modifiers {@code public}, {@code protected} or
85.346 + * {@code private}. Only one of these may appear, or none if the
85.347 + * constructor has default (package) access.
85.348 + *
85.349 + * @return a string describing this {@code Constructor},
85.350 + * include type parameters
85.351 + *
85.352 + * @since 1.5
85.353 + */
85.354 + public String toGenericString() {
85.355 + try {
85.356 + StringBuilder sb = new StringBuilder();
85.357 + int mod = getModifiers() & Modifier.constructorModifiers();
85.358 + if (mod != 0) {
85.359 + sb.append(Modifier.toString(mod) + " ");
85.360 + }
85.361 + TypeVariable<?>[] typeparms = getTypeParameters();
85.362 + if (typeparms.length > 0) {
85.363 + boolean first = true;
85.364 + sb.append("<");
85.365 + for(TypeVariable<?> typeparm: typeparms) {
85.366 + if (!first)
85.367 + sb.append(",");
85.368 + // Class objects can't occur here; no need to test
85.369 + // and call Class.getName().
85.370 + sb.append(typeparm.toString());
85.371 + first = false;
85.372 + }
85.373 + sb.append("> ");
85.374 + }
85.375 + sb.append(Field.getTypeName(getDeclaringClass()));
85.376 + sb.append("(");
85.377 + Type[] params = getGenericParameterTypes();
85.378 + for (int j = 0; j < params.length; j++) {
85.379 + String param = (params[j] instanceof Class<?>)?
85.380 + Field.getTypeName((Class<?>)params[j]):
85.381 + (params[j].toString());
85.382 + if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
85.383 + param = param.replaceFirst("\\[\\]$", "...");
85.384 + sb.append(param);
85.385 + if (j < (params.length - 1))
85.386 + sb.append(",");
85.387 + }
85.388 + sb.append(")");
85.389 + Type[] exceptions = getGenericExceptionTypes();
85.390 + if (exceptions.length > 0) {
85.391 + sb.append(" throws ");
85.392 + for (int k = 0; k < exceptions.length; k++) {
85.393 + sb.append((exceptions[k] instanceof Class)?
85.394 + ((Class<?>)exceptions[k]).getName():
85.395 + exceptions[k].toString());
85.396 + if (k < (exceptions.length - 1))
85.397 + sb.append(",");
85.398 + }
85.399 + }
85.400 + return sb.toString();
85.401 + } catch (Exception e) {
85.402 + return "<" + e + ">";
85.403 + }
85.404 + }
85.405 +
85.406 + /**
85.407 + * Uses the constructor represented by this {@code Constructor} object to
85.408 + * create and initialize a new instance of the constructor's
85.409 + * declaring class, with the specified initialization parameters.
85.410 + * Individual parameters are automatically unwrapped to match
85.411 + * primitive formal parameters, and both primitive and reference
85.412 + * parameters are subject to method invocation conversions as necessary.
85.413 + *
85.414 + * <p>If the number of formal parameters required by the underlying constructor
85.415 + * is 0, the supplied {@code initargs} array may be of length 0 or null.
85.416 + *
85.417 + * <p>If the constructor's declaring class is an inner class in a
85.418 + * non-static context, the first argument to the constructor needs
85.419 + * to be the enclosing instance; see section 15.9.3 of
85.420 + * <cite>The Java™ Language Specification</cite>.
85.421 + *
85.422 + * <p>If the required access and argument checks succeed and the
85.423 + * instantiation will proceed, the constructor's declaring class
85.424 + * is initialized if it has not already been initialized.
85.425 + *
85.426 + * <p>If the constructor completes normally, returns the newly
85.427 + * created and initialized instance.
85.428 + *
85.429 + * @param initargs array of objects to be passed as arguments to
85.430 + * the constructor call; values of primitive types are wrapped in
85.431 + * a wrapper object of the appropriate type (e.g. a {@code float}
85.432 + * in a {@link java.lang.Float Float})
85.433 + *
85.434 + * @return a new object created by calling the constructor
85.435 + * this object represents
85.436 + *
85.437 + * @exception IllegalAccessException if this {@code Constructor} object
85.438 + * is enforcing Java language access control and the underlying
85.439 + * constructor is inaccessible.
85.440 + * @exception IllegalArgumentException if the number of actual
85.441 + * and formal parameters differ; if an unwrapping
85.442 + * conversion for primitive arguments fails; or if,
85.443 + * after possible unwrapping, a parameter value
85.444 + * cannot be converted to the corresponding formal
85.445 + * parameter type by a method invocation conversion; if
85.446 + * this constructor pertains to an enum type.
85.447 + * @exception InstantiationException if the class that declares the
85.448 + * underlying constructor represents an abstract class.
85.449 + * @exception InvocationTargetException if the underlying constructor
85.450 + * throws an exception.
85.451 + * @exception ExceptionInInitializerError if the initialization provoked
85.452 + * by this method fails.
85.453 + */
85.454 + public T newInstance(Object ... initargs)
85.455 + throws InstantiationException, IllegalAccessException,
85.456 + IllegalArgumentException, InvocationTargetException
85.457 + {
85.458 + throw new SecurityException();
85.459 + }
85.460 +
85.461 + /**
85.462 + * Returns {@code true} if this constructor was declared to take
85.463 + * a variable number of arguments; returns {@code false}
85.464 + * otherwise.
85.465 + *
85.466 + * @return {@code true} if an only if this constructor was declared to
85.467 + * take a variable number of arguments.
85.468 + * @since 1.5
85.469 + */
85.470 + public boolean isVarArgs() {
85.471 + return (getModifiers() & Modifier.VARARGS) != 0;
85.472 + }
85.473 +
85.474 + /**
85.475 + * Returns {@code true} if this constructor is a synthetic
85.476 + * constructor; returns {@code false} otherwise.
85.477 + *
85.478 + * @return true if and only if this constructor is a synthetic
85.479 + * constructor as defined by
85.480 + * <cite>The Java™ Language Specification</cite>.
85.481 + * @since 1.5
85.482 + */
85.483 + public boolean isSynthetic() {
85.484 + return Modifier.isSynthetic(getModifiers());
85.485 + }
85.486 +
85.487 + int getSlot() {
85.488 + return slot;
85.489 + }
85.490 +
85.491 + String getSignature() {
85.492 + return signature;
85.493 + }
85.494 +
85.495 + byte[] getRawAnnotations() {
85.496 + return annotations;
85.497 + }
85.498 +
85.499 + byte[] getRawParameterAnnotations() {
85.500 + return parameterAnnotations;
85.501 + }
85.502 +
85.503 + /**
85.504 + * @throws NullPointerException {@inheritDoc}
85.505 + * @since 1.5
85.506 + */
85.507 + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
85.508 + if (annotationClass == null)
85.509 + throw new NullPointerException();
85.510 +
85.511 + return null; // XXX (T) declaredAnnotations().get(annotationClass);
85.512 + }
85.513 +
85.514 + /**
85.515 + * @since 1.5
85.516 + */
85.517 + public Annotation[] getDeclaredAnnotations() {
85.518 + return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations());
85.519 + }
85.520 +
85.521 + /**
85.522 + * Returns an array of arrays that represent the annotations on the formal
85.523 + * parameters, in declaration order, of the method represented by
85.524 + * this {@code Constructor} object. (Returns an array of length zero if the
85.525 + * underlying method is parameterless. If the method has one or more
85.526 + * parameters, a nested array of length zero is returned for each parameter
85.527 + * with no annotations.) The annotation objects contained in the returned
85.528 + * arrays are serializable. The caller of this method is free to modify
85.529 + * the returned arrays; it will have no effect on the arrays returned to
85.530 + * other callers.
85.531 + *
85.532 + * @return an array of arrays that represent the annotations on the formal
85.533 + * parameters, in declaration order, of the method represented by this
85.534 + * Constructor object
85.535 + * @since 1.5
85.536 + */
85.537 + public Annotation[][] getParameterAnnotations() {
85.538 + int numParameters = parameterTypes.length;
85.539 + if (parameterAnnotations == null)
85.540 + return new Annotation[numParameters][0];
85.541 +
85.542 + return new Annotation[numParameters][0]; // XXX
85.543 +/*
85.544 + Annotation[][] result = AnnotationParser.parseParameterAnnotations(
85.545 + parameterAnnotations,
85.546 + sun.misc.SharedSecrets.getJavaLangAccess().
85.547 + getConstantPool(getDeclaringClass()),
85.548 + getDeclaringClass());
85.549 + if (result.length != numParameters) {
85.550 + Class<?> declaringClass = getDeclaringClass();
85.551 + if (declaringClass.isEnum() ||
85.552 + declaringClass.isAnonymousClass() ||
85.553 + declaringClass.isLocalClass() )
85.554 + ; // Can't do reliable parameter counting
85.555 + else {
85.556 + if (!declaringClass.isMemberClass() || // top-level
85.557 + // Check for the enclosing instance parameter for
85.558 + // non-static member classes
85.559 + (declaringClass.isMemberClass() &&
85.560 + ((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
85.561 + result.length + 1 != numParameters) ) {
85.562 + throw new AnnotationFormatError(
85.563 + "Parameter annotations don't match number of parameters");
85.564 + }
85.565 + }
85.566 + }
85.567 + return result;
85.568 + */
85.569 + }
85.570 +}
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/emul/mini/src/main/java/java/lang/reflect/InvocationHandler.java Tue Feb 05 17:04:22 2013 +0100
86.3 @@ -0,0 +1,95 @@
86.4 +/*
86.5 + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
86.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
86.7 + *
86.8 + * This code is free software; you can redistribute it and/or modify it
86.9 + * under the terms of the GNU General Public License version 2 only, as
86.10 + * published by the Free Software Foundation. Oracle designates this
86.11 + * particular file as subject to the "Classpath" exception as provided
86.12 + * by Oracle in the LICENSE file that accompanied this code.
86.13 + *
86.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
86.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
86.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
86.17 + * version 2 for more details (a copy is included in the LICENSE file that
86.18 + * accompanied this code).
86.19 + *
86.20 + * You should have received a copy of the GNU General Public License version
86.21 + * 2 along with this work; if not, write to the Free Software Foundation,
86.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
86.23 + *
86.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
86.25 + * or visit www.oracle.com if you need additional information or have any
86.26 + * questions.
86.27 + */
86.28 +
86.29 +package java.lang.reflect;
86.30 +
86.31 +/**
86.32 + * {@code InvocationHandler} is the interface implemented by
86.33 + * the <i>invocation handler</i> of a proxy instance.
86.34 + *
86.35 + * <p>Each proxy instance has an associated invocation handler.
86.36 + * When a method is invoked on a proxy instance, the method
86.37 + * invocation is encoded and dispatched to the {@code invoke}
86.38 + * method of its invocation handler.
86.39 + *
86.40 + * @author Peter Jones
86.41 + * @see Proxy
86.42 + * @since 1.3
86.43 + */
86.44 +public interface InvocationHandler {
86.45 +
86.46 + /**
86.47 + * Processes a method invocation on a proxy instance and returns
86.48 + * the result. This method will be invoked on an invocation handler
86.49 + * when a method is invoked on a proxy instance that it is
86.50 + * associated with.
86.51 + *
86.52 + * @param proxy the proxy instance that the method was invoked on
86.53 + *
86.54 + * @param method the {@code Method} instance corresponding to
86.55 + * the interface method invoked on the proxy instance. The declaring
86.56 + * class of the {@code Method} object will be the interface that
86.57 + * the method was declared in, which may be a superinterface of the
86.58 + * proxy interface that the proxy class inherits the method through.
86.59 + *
86.60 + * @param args an array of objects containing the values of the
86.61 + * arguments passed in the method invocation on the proxy instance,
86.62 + * or {@code null} if interface method takes no arguments.
86.63 + * Arguments of primitive types are wrapped in instances of the
86.64 + * appropriate primitive wrapper class, such as
86.65 + * {@code java.lang.Integer} or {@code java.lang.Boolean}.
86.66 + *
86.67 + * @return the value to return from the method invocation on the
86.68 + * proxy instance. If the declared return type of the interface
86.69 + * method is a primitive type, then the value returned by
86.70 + * this method must be an instance of the corresponding primitive
86.71 + * wrapper class; otherwise, it must be a type assignable to the
86.72 + * declared return type. If the value returned by this method is
86.73 + * {@code null} and the interface method's return type is
86.74 + * primitive, then a {@code NullPointerException} will be
86.75 + * thrown by the method invocation on the proxy instance. If the
86.76 + * value returned by this method is otherwise not compatible with
86.77 + * the interface method's declared return type as described above,
86.78 + * a {@code ClassCastException} will be thrown by the method
86.79 + * invocation on the proxy instance.
86.80 + *
86.81 + * @throws Throwable the exception to throw from the method
86.82 + * invocation on the proxy instance. The exception's type must be
86.83 + * assignable either to any of the exception types declared in the
86.84 + * {@code throws} clause of the interface method or to the
86.85 + * unchecked exception types {@code java.lang.RuntimeException}
86.86 + * or {@code java.lang.Error}. If a checked exception is
86.87 + * thrown by this method that is not assignable to any of the
86.88 + * exception types declared in the {@code throws} clause of
86.89 + * the interface method, then an
86.90 + * {@link UndeclaredThrowableException} containing the
86.91 + * exception that was thrown by this method will be thrown by the
86.92 + * method invocation on the proxy instance.
86.93 + *
86.94 + * @see UndeclaredThrowableException
86.95 + */
86.96 + public Object invoke(Object proxy, Method method, Object[] args)
86.97 + throws Throwable;
86.98 +}
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Proxy.java Tue Feb 05 17:04:22 2013 +0100
87.3 @@ -0,0 +1,407 @@
87.4 +/*
87.5 + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
87.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
87.7 + *
87.8 + * This code is free software; you can redistribute it and/or modify it
87.9 + * under the terms of the GNU General Public License version 2 only, as
87.10 + * published by the Free Software Foundation. Oracle designates this
87.11 + * particular file as subject to the "Classpath" exception as provided
87.12 + * by Oracle in the LICENSE file that accompanied this code.
87.13 + *
87.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
87.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
87.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
87.17 + * version 2 for more details (a copy is included in the LICENSE file that
87.18 + * accompanied this code).
87.19 + *
87.20 + * You should have received a copy of the GNU General Public License version
87.21 + * 2 along with this work; if not, write to the Free Software Foundation,
87.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
87.23 + *
87.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
87.25 + * or visit www.oracle.com if you need additional information or have any
87.26 + * questions.
87.27 + */
87.28 +
87.29 +package java.lang.reflect;
87.30 +
87.31 +
87.32 +/**
87.33 + * {@code Proxy} provides static methods for creating dynamic proxy
87.34 + * classes and instances, and it is also the superclass of all
87.35 + * dynamic proxy classes created by those methods.
87.36 + *
87.37 + * <p>To create a proxy for some interface {@code Foo}:
87.38 + * <pre>
87.39 + * InvocationHandler handler = new MyInvocationHandler(...);
87.40 + * Class proxyClass = Proxy.getProxyClass(
87.41 + * Foo.class.getClassLoader(), new Class[] { Foo.class });
87.42 + * Foo f = (Foo) proxyClass.
87.43 + * getConstructor(new Class[] { InvocationHandler.class }).
87.44 + * newInstance(new Object[] { handler });
87.45 + * </pre>
87.46 + * or more simply:
87.47 + * <pre>
87.48 + * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
87.49 + * new Class[] { Foo.class },
87.50 + * handler);
87.51 + * </pre>
87.52 + *
87.53 + * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
87.54 + * class</i> below) is a class that implements a list of interfaces
87.55 + * specified at runtime when the class is created, with behavior as
87.56 + * described below.
87.57 + *
87.58 + * A <i>proxy interface</i> is such an interface that is implemented
87.59 + * by a proxy class.
87.60 + *
87.61 + * A <i>proxy instance</i> is an instance of a proxy class.
87.62 + *
87.63 + * Each proxy instance has an associated <i>invocation handler</i>
87.64 + * object, which implements the interface {@link InvocationHandler}.
87.65 + * A method invocation on a proxy instance through one of its proxy
87.66 + * interfaces will be dispatched to the {@link InvocationHandler#invoke
87.67 + * invoke} method of the instance's invocation handler, passing the proxy
87.68 + * instance, a {@code java.lang.reflect.Method} object identifying
87.69 + * the method that was invoked, and an array of type {@code Object}
87.70 + * containing the arguments. The invocation handler processes the
87.71 + * encoded method invocation as appropriate and the result that it
87.72 + * returns will be returned as the result of the method invocation on
87.73 + * the proxy instance.
87.74 + *
87.75 + * <p>A proxy class has the following properties:
87.76 + *
87.77 + * <ul>
87.78 + * <li>Proxy classes are public, final, and not abstract.
87.79 + *
87.80 + * <li>The unqualified name of a proxy class is unspecified. The space
87.81 + * of class names that begin with the string {@code "$Proxy"}
87.82 + * should be, however, reserved for proxy classes.
87.83 + *
87.84 + * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
87.85 + *
87.86 + * <li>A proxy class implements exactly the interfaces specified at its
87.87 + * creation, in the same order.
87.88 + *
87.89 + * <li>If a proxy class implements a non-public interface, then it will
87.90 + * be defined in the same package as that interface. Otherwise, the
87.91 + * package of a proxy class is also unspecified. Note that package
87.92 + * sealing will not prevent a proxy class from being successfully defined
87.93 + * in a particular package at runtime, and neither will classes already
87.94 + * defined by the same class loader and the same package with particular
87.95 + * signers.
87.96 + *
87.97 + * <li>Since a proxy class implements all of the interfaces specified at
87.98 + * its creation, invoking {@code getInterfaces} on its
87.99 + * {@code Class} object will return an array containing the same
87.100 + * list of interfaces (in the order specified at its creation), invoking
87.101 + * {@code getMethods} on its {@code Class} object will return
87.102 + * an array of {@code Method} objects that include all of the
87.103 + * methods in those interfaces, and invoking {@code getMethod} will
87.104 + * find methods in the proxy interfaces as would be expected.
87.105 + *
87.106 + * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
87.107 + * return true if it is passed a proxy class-- a class returned by
87.108 + * {@code Proxy.getProxyClass} or the class of an object returned by
87.109 + * {@code Proxy.newProxyInstance}-- and false otherwise.
87.110 + *
87.111 + * <li>The {@code java.security.ProtectionDomain} of a proxy class
87.112 + * is the same as that of system classes loaded by the bootstrap class
87.113 + * loader, such as {@code java.lang.Object}, because the code for a
87.114 + * proxy class is generated by trusted system code. This protection
87.115 + * domain will typically be granted
87.116 + * {@code java.security.AllPermission}.
87.117 + *
87.118 + * <li>Each proxy class has one public constructor that takes one argument,
87.119 + * an implementation of the interface {@link InvocationHandler}, to set
87.120 + * the invocation handler for a proxy instance. Rather than having to use
87.121 + * the reflection API to access the public constructor, a proxy instance
87.122 + * can be also be created by calling the {@link Proxy#newProxyInstance
87.123 + * Proxy.newProxyInstance} method, which combines the actions of calling
87.124 + * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
87.125 + * constructor with an invocation handler.
87.126 + * </ul>
87.127 + *
87.128 + * <p>A proxy instance has the following properties:
87.129 + *
87.130 + * <ul>
87.131 + * <li>Given a proxy instance {@code proxy} and one of the
87.132 + * interfaces implemented by its proxy class {@code Foo}, the
87.133 + * following expression will return true:
87.134 + * <pre>
87.135 + * {@code proxy instanceof Foo}
87.136 + * </pre>
87.137 + * and the following cast operation will succeed (rather than throwing
87.138 + * a {@code ClassCastException}):
87.139 + * <pre>
87.140 + * {@code (Foo) proxy}
87.141 + * </pre>
87.142 + *
87.143 + * <li>Each proxy instance has an associated invocation handler, the one
87.144 + * that was passed to its constructor. The static
87.145 + * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
87.146 + * will return the invocation handler associated with the proxy instance
87.147 + * passed as its argument.
87.148 + *
87.149 + * <li>An interface method invocation on a proxy instance will be
87.150 + * encoded and dispatched to the invocation handler's {@link
87.151 + * InvocationHandler#invoke invoke} method as described in the
87.152 + * documentation for that method.
87.153 + *
87.154 + * <li>An invocation of the {@code hashCode},
87.155 + * {@code equals}, or {@code toString} methods declared in
87.156 + * {@code java.lang.Object} on a proxy instance will be encoded and
87.157 + * dispatched to the invocation handler's {@code invoke} method in
87.158 + * the same manner as interface method invocations are encoded and
87.159 + * dispatched, as described above. The declaring class of the
87.160 + * {@code Method} object passed to {@code invoke} will be
87.161 + * {@code java.lang.Object}. Other public methods of a proxy
87.162 + * instance inherited from {@code java.lang.Object} are not
87.163 + * overridden by a proxy class, so invocations of those methods behave
87.164 + * like they do for instances of {@code java.lang.Object}.
87.165 + * </ul>
87.166 + *
87.167 + * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
87.168 + *
87.169 + * <p>When two or more interfaces of a proxy class contain a method with
87.170 + * the same name and parameter signature, the order of the proxy class's
87.171 + * interfaces becomes significant. When such a <i>duplicate method</i>
87.172 + * is invoked on a proxy instance, the {@code Method} object passed
87.173 + * to the invocation handler will not necessarily be the one whose
87.174 + * declaring class is assignable from the reference type of the interface
87.175 + * that the proxy's method was invoked through. This limitation exists
87.176 + * because the corresponding method implementation in the generated proxy
87.177 + * class cannot determine which interface it was invoked through.
87.178 + * Therefore, when a duplicate method is invoked on a proxy instance,
87.179 + * the {@code Method} object for the method in the foremost interface
87.180 + * that contains the method (either directly or inherited through a
87.181 + * superinterface) in the proxy class's list of interfaces is passed to
87.182 + * the invocation handler's {@code invoke} method, regardless of the
87.183 + * reference type through which the method invocation occurred.
87.184 + *
87.185 + * <p>If a proxy interface contains a method with the same name and
87.186 + * parameter signature as the {@code hashCode}, {@code equals},
87.187 + * or {@code toString} methods of {@code java.lang.Object},
87.188 + * when such a method is invoked on a proxy instance, the
87.189 + * {@code Method} object passed to the invocation handler will have
87.190 + * {@code java.lang.Object} as its declaring class. In other words,
87.191 + * the public, non-final methods of {@code java.lang.Object}
87.192 + * logically precede all of the proxy interfaces for the determination of
87.193 + * which {@code Method} object to pass to the invocation handler.
87.194 + *
87.195 + * <p>Note also that when a duplicate method is dispatched to an
87.196 + * invocation handler, the {@code invoke} method may only throw
87.197 + * checked exception types that are assignable to one of the exception
87.198 + * types in the {@code throws} clause of the method in <i>all</i> of
87.199 + * the proxy interfaces that it can be invoked through. If the
87.200 + * {@code invoke} method throws a checked exception that is not
87.201 + * assignable to any of the exception types declared by the method in one
87.202 + * of the proxy interfaces that it can be invoked through, then an
87.203 + * unchecked {@code UndeclaredThrowableException} will be thrown by
87.204 + * the invocation on the proxy instance. This restriction means that not
87.205 + * all of the exception types returned by invoking
87.206 + * {@code getExceptionTypes} on the {@code Method} object
87.207 + * passed to the {@code invoke} method can necessarily be thrown
87.208 + * successfully by the {@code invoke} method.
87.209 + *
87.210 + * @author Peter Jones
87.211 + * @see InvocationHandler
87.212 + * @since 1.3
87.213 + */
87.214 +public class Proxy implements java.io.Serializable {
87.215 +
87.216 + private static final long serialVersionUID = -2222568056686623797L;
87.217 +
87.218 +
87.219 +
87.220 + /**
87.221 + * the invocation handler for this proxy instance.
87.222 + * @serial
87.223 + */
87.224 + protected InvocationHandler h;
87.225 +
87.226 + /**
87.227 + * Prohibits instantiation.
87.228 + */
87.229 + private Proxy() {
87.230 + }
87.231 +
87.232 + /**
87.233 + * Constructs a new {@code Proxy} instance from a subclass
87.234 + * (typically, a dynamic proxy class) with the specified value
87.235 + * for its invocation handler.
87.236 + *
87.237 + * @param h the invocation handler for this proxy instance
87.238 + */
87.239 + protected Proxy(InvocationHandler h) {
87.240 + this.h = h;
87.241 + }
87.242 +
87.243 + /**
87.244 + * Returns the {@code java.lang.Class} object for a proxy class
87.245 + * given a class loader and an array of interfaces. The proxy class
87.246 + * will be defined by the specified class loader and will implement
87.247 + * all of the supplied interfaces. If a proxy class for the same
87.248 + * permutation of interfaces has already been defined by the class
87.249 + * loader, then the existing proxy class will be returned; otherwise,
87.250 + * a proxy class for those interfaces will be generated dynamically
87.251 + * and defined by the class loader.
87.252 + *
87.253 + * <p>There are several restrictions on the parameters that may be
87.254 + * passed to {@code Proxy.getProxyClass}:
87.255 + *
87.256 + * <ul>
87.257 + * <li>All of the {@code Class} objects in the
87.258 + * {@code interfaces} array must represent interfaces, not
87.259 + * classes or primitive types.
87.260 + *
87.261 + * <li>No two elements in the {@code interfaces} array may
87.262 + * refer to identical {@code Class} objects.
87.263 + *
87.264 + * <li>All of the interface types must be visible by name through the
87.265 + * specified class loader. In other words, for class loader
87.266 + * {@code cl} and every interface {@code i}, the following
87.267 + * expression must be true:
87.268 + * <pre>
87.269 + * Class.forName(i.getName(), false, cl) == i
87.270 + * </pre>
87.271 + *
87.272 + * <li>All non-public interfaces must be in the same package;
87.273 + * otherwise, it would not be possible for the proxy class to
87.274 + * implement all of the interfaces, regardless of what package it is
87.275 + * defined in.
87.276 + *
87.277 + * <li>For any set of member methods of the specified interfaces
87.278 + * that have the same signature:
87.279 + * <ul>
87.280 + * <li>If the return type of any of the methods is a primitive
87.281 + * type or void, then all of the methods must have that same
87.282 + * return type.
87.283 + * <li>Otherwise, one of the methods must have a return type that
87.284 + * is assignable to all of the return types of the rest of the
87.285 + * methods.
87.286 + * </ul>
87.287 + *
87.288 + * <li>The resulting proxy class must not exceed any limits imposed
87.289 + * on classes by the virtual machine. For example, the VM may limit
87.290 + * the number of interfaces that a class may implement to 65535; in
87.291 + * that case, the size of the {@code interfaces} array must not
87.292 + * exceed 65535.
87.293 + * </ul>
87.294 + *
87.295 + * <p>If any of these restrictions are violated,
87.296 + * {@code Proxy.getProxyClass} will throw an
87.297 + * {@code IllegalArgumentException}. If the {@code interfaces}
87.298 + * array argument or any of its elements are {@code null}, a
87.299 + * {@code NullPointerException} will be thrown.
87.300 + *
87.301 + * <p>Note that the order of the specified proxy interfaces is
87.302 + * significant: two requests for a proxy class with the same combination
87.303 + * of interfaces but in a different order will result in two distinct
87.304 + * proxy classes.
87.305 + *
87.306 + * @param loader the class loader to define the proxy class
87.307 + * @param interfaces the list of interfaces for the proxy class
87.308 + * to implement
87.309 + * @return a proxy class that is defined in the specified class loader
87.310 + * and that implements the specified interfaces
87.311 + * @throws IllegalArgumentException if any of the restrictions on the
87.312 + * parameters that may be passed to {@code getProxyClass}
87.313 + * are violated
87.314 + * @throws NullPointerException if the {@code interfaces} array
87.315 + * argument or any of its elements are {@code null}
87.316 + */
87.317 + public static Class<?> getProxyClass(ClassLoader loader,
87.318 + Class<?>... interfaces)
87.319 + throws IllegalArgumentException
87.320 + {
87.321 + throw new IllegalArgumentException();
87.322 + }
87.323 +
87.324 + /**
87.325 + * Returns an instance of a proxy class for the specified interfaces
87.326 + * that dispatches method invocations to the specified invocation
87.327 + * handler. This method is equivalent to:
87.328 + * <pre>
87.329 + * Proxy.getProxyClass(loader, interfaces).
87.330 + * getConstructor(new Class[] { InvocationHandler.class }).
87.331 + * newInstance(new Object[] { handler });
87.332 + * </pre>
87.333 + *
87.334 + * <p>{@code Proxy.newProxyInstance} throws
87.335 + * {@code IllegalArgumentException} for the same reasons that
87.336 + * {@code Proxy.getProxyClass} does.
87.337 + *
87.338 + * @param loader the class loader to define the proxy class
87.339 + * @param interfaces the list of interfaces for the proxy class
87.340 + * to implement
87.341 + * @param h the invocation handler to dispatch method invocations to
87.342 + * @return a proxy instance with the specified invocation handler of a
87.343 + * proxy class that is defined by the specified class loader
87.344 + * and that implements the specified interfaces
87.345 + * @throws IllegalArgumentException if any of the restrictions on the
87.346 + * parameters that may be passed to {@code getProxyClass}
87.347 + * are violated
87.348 + * @throws NullPointerException if the {@code interfaces} array
87.349 + * argument or any of its elements are {@code null}, or
87.350 + * if the invocation handler, {@code h}, is
87.351 + * {@code null}
87.352 + */
87.353 + public static Object newProxyInstance(ClassLoader loader,
87.354 + Class<?>[] interfaces,
87.355 + InvocationHandler h)
87.356 + throws IllegalArgumentException
87.357 + {
87.358 + if (h == null) {
87.359 + throw new NullPointerException();
87.360 + }
87.361 + throw new IllegalArgumentException();
87.362 + }
87.363 +
87.364 + /**
87.365 + * Returns true if and only if the specified class was dynamically
87.366 + * generated to be a proxy class using the {@code getProxyClass}
87.367 + * method or the {@code newProxyInstance} method.
87.368 + *
87.369 + * <p>The reliability of this method is important for the ability
87.370 + * to use it to make security decisions, so its implementation should
87.371 + * not just test if the class in question extends {@code Proxy}.
87.372 + *
87.373 + * @param cl the class to test
87.374 + * @return {@code true} if the class is a proxy class and
87.375 + * {@code false} otherwise
87.376 + * @throws NullPointerException if {@code cl} is {@code null}
87.377 + */
87.378 + public static boolean isProxyClass(Class<?> cl) {
87.379 + if (cl == null) {
87.380 + throw new NullPointerException();
87.381 + }
87.382 +
87.383 + return false;
87.384 + }
87.385 +
87.386 + /**
87.387 + * Returns the invocation handler for the specified proxy instance.
87.388 + *
87.389 + * @param proxy the proxy instance to return the invocation handler for
87.390 + * @return the invocation handler for the proxy instance
87.391 + * @throws IllegalArgumentException if the argument is not a
87.392 + * proxy instance
87.393 + */
87.394 + public static InvocationHandler getInvocationHandler(Object proxy)
87.395 + throws IllegalArgumentException
87.396 + {
87.397 + /*
87.398 + * Verify that the object is actually a proxy instance.
87.399 + */
87.400 + if (!isProxyClass(proxy.getClass())) {
87.401 + throw new IllegalArgumentException("not a proxy instance");
87.402 + }
87.403 +
87.404 + Proxy p = (Proxy) proxy;
87.405 + return p.h;
87.406 + }
87.407 +
87.408 + private static native Class defineClass0(ClassLoader loader, String name,
87.409 + byte[] b, int off, int len);
87.410 +}
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/emul/mini/src/main/java/java/lang/reflect/UndeclaredThrowableException.java Tue Feb 05 17:04:22 2013 +0100
88.3 @@ -0,0 +1,119 @@
88.4 +/*
88.5 + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
88.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
88.7 + *
88.8 + * This code is free software; you can redistribute it and/or modify it
88.9 + * under the terms of the GNU General Public License version 2 only, as
88.10 + * published by the Free Software Foundation. Oracle designates this
88.11 + * particular file as subject to the "Classpath" exception as provided
88.12 + * by Oracle in the LICENSE file that accompanied this code.
88.13 + *
88.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
88.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
88.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
88.17 + * version 2 for more details (a copy is included in the LICENSE file that
88.18 + * accompanied this code).
88.19 + *
88.20 + * You should have received a copy of the GNU General Public License version
88.21 + * 2 along with this work; if not, write to the Free Software Foundation,
88.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
88.23 + *
88.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
88.25 + * or visit www.oracle.com if you need additional information or have any
88.26 + * questions.
88.27 + */
88.28 +
88.29 +package java.lang.reflect;
88.30 +
88.31 +/**
88.32 + * Thrown by a method invocation on a proxy instance if its invocation
88.33 + * handler's {@link InvocationHandler#invoke invoke} method throws a
88.34 + * checked exception (a {@code Throwable} that is not assignable
88.35 + * to {@code RuntimeException} or {@code Error}) that
88.36 + * is not assignable to any of the exception types declared in the
88.37 + * {@code throws} clause of the method that was invoked on the
88.38 + * proxy instance and dispatched to the invocation handler.
88.39 + *
88.40 + * <p>An {@code UndeclaredThrowableException} instance contains
88.41 + * the undeclared checked exception that was thrown by the invocation
88.42 + * handler, and it can be retrieved with the
88.43 + * {@code getUndeclaredThrowable()} method.
88.44 + * {@code UndeclaredThrowableException} extends
88.45 + * {@code RuntimeException}, so it is an unchecked exception
88.46 + * that wraps a checked exception.
88.47 + *
88.48 + * <p>As of release 1.4, this exception has been retrofitted to
88.49 + * conform to the general purpose exception-chaining mechanism. The
88.50 + * "undeclared checked exception that was thrown by the invocation
88.51 + * handler" that may be provided at construction time and accessed via
88.52 + * the {@link #getUndeclaredThrowable()} method is now known as the
88.53 + * <i>cause</i>, and may be accessed via the {@link
88.54 + * Throwable#getCause()} method, as well as the aforementioned "legacy
88.55 + * method."
88.56 + *
88.57 + * @author Peter Jones
88.58 + * @see InvocationHandler
88.59 + * @since 1.3
88.60 + */
88.61 +public class UndeclaredThrowableException extends RuntimeException {
88.62 + static final long serialVersionUID = 330127114055056639L;
88.63 +
88.64 + /**
88.65 + * the undeclared checked exception that was thrown
88.66 + * @serial
88.67 + */
88.68 + private Throwable undeclaredThrowable;
88.69 +
88.70 + /**
88.71 + * Constructs an {@code UndeclaredThrowableException} with the
88.72 + * specified {@code Throwable}.
88.73 + *
88.74 + * @param undeclaredThrowable the undeclared checked exception
88.75 + * that was thrown
88.76 + */
88.77 + public UndeclaredThrowableException(Throwable undeclaredThrowable) {
88.78 + super((Throwable) null); // Disallow initCause
88.79 + this.undeclaredThrowable = undeclaredThrowable;
88.80 + }
88.81 +
88.82 + /**
88.83 + * Constructs an {@code UndeclaredThrowableException} with the
88.84 + * specified {@code Throwable} and a detail message.
88.85 + *
88.86 + * @param undeclaredThrowable the undeclared checked exception
88.87 + * that was thrown
88.88 + * @param s the detail message
88.89 + */
88.90 + public UndeclaredThrowableException(Throwable undeclaredThrowable,
88.91 + String s)
88.92 + {
88.93 + super(s, null); // Disallow initCause
88.94 + this.undeclaredThrowable = undeclaredThrowable;
88.95 + }
88.96 +
88.97 + /**
88.98 + * Returns the {@code Throwable} instance wrapped in this
88.99 + * {@code UndeclaredThrowableException}, which may be {@code null}.
88.100 + *
88.101 + * <p>This method predates the general-purpose exception chaining facility.
88.102 + * The {@link Throwable#getCause()} method is now the preferred means of
88.103 + * obtaining this information.
88.104 + *
88.105 + * @return the undeclared checked exception that was thrown
88.106 + */
88.107 + public Throwable getUndeclaredThrowable() {
88.108 + return undeclaredThrowable;
88.109 + }
88.110 +
88.111 + /**
88.112 + * Returns the cause of this exception (the {@code Throwable}
88.113 + * instance wrapped in this {@code UndeclaredThrowableException},
88.114 + * which may be {@code null}).
88.115 + *
88.116 + * @return the cause of this exception.
88.117 + * @since 1.4
88.118 + */
88.119 + public Throwable getCause() {
88.120 + return undeclaredThrowable;
88.121 + }
88.122 +}
89.1 --- a/emul/mini/src/main/java/java/net/URL.java Tue Feb 05 16:40:01 2013 +0100
89.2 +++ b/emul/mini/src/main/java/java/net/URL.java Tue Feb 05 17:04:22 2013 +0100
89.3 @@ -25,6 +25,7 @@
89.4
89.5 package java.net;
89.6
89.7 +import java.io.ByteArrayInputStream;
89.8 import java.io.IOException;
89.9 import java.io.InputStream;
89.10 import org.apidesign.bck2brwsr.core.JavaScriptBody;
89.11 @@ -505,6 +506,17 @@
89.12 public URL(URL context, String spec, URLStreamHandler handler)
89.13 throws MalformedURLException
89.14 {
89.15 + this(findContext(context), spec, handler != null);
89.16 + }
89.17 +
89.18 + private URL(URL context, String spec, boolean ishandler)
89.19 + throws MalformedURLException {
89.20 + // Check for permission to specify a handler
89.21 + if (ishandler) {
89.22 + throw new SecurityException();
89.23 + }
89.24 + URLStreamHandler handler = null;
89.25 +
89.26 String original = spec;
89.27 int i, limit, c;
89.28 int start = 0;
89.29 @@ -512,10 +524,6 @@
89.30 boolean aRef=false;
89.31 boolean isRelative = false;
89.32
89.33 - // Check for permission to specify a handler
89.34 - if (handler != null) {
89.35 - throw new SecurityException();
89.36 - }
89.37
89.38 try {
89.39 limit = spec.length();
89.40 @@ -962,7 +970,11 @@
89.41 if (is != null) {
89.42 return is;
89.43 }
89.44 - throw new IOException();
89.45 + byte[] arr = (byte[]) getContent(new Class[] { byte[].class });
89.46 + if (arr == null) {
89.47 + throw new IOException();
89.48 + }
89.49 + return new ByteArrayInputStream(arr);
89.50 }
89.51
89.52 /**
89.53 @@ -987,6 +999,17 @@
89.54 )
89.55 private static native String loadText(String url) throws IOException;
89.56
89.57 + @JavaScriptBody(args = { "url", "arr" }, body = ""
89.58 + + "var request = new XMLHttpRequest();\n"
89.59 + + "request.open('GET', url, false);\n"
89.60 + + "request.overrideMimeType('text\\/plain; charset=x-user-defined');\n"
89.61 + + "request.send();\n"
89.62 + + "var t = request.responseText;\n"
89.63 + + "for (var i = 0; i < t.length; i++) arr.push(t.charCodeAt(i) & 0xff);\n"
89.64 + + "return arr;\n"
89.65 + )
89.66 + private static native Object loadBytes(String url, byte[] arr) throws IOException;
89.67 +
89.68 /**
89.69 * Gets the contents of this URL. This method is a shorthand for:
89.70 * <blockquote><pre>
89.71 @@ -1005,7 +1028,10 @@
89.72 throws java.io.IOException {
89.73 for (Class<?> c : classes) {
89.74 if (c == String.class) {
89.75 - return getContent();
89.76 + return loadText(toExternalForm());
89.77 + }
89.78 + if (c == byte[].class) {
89.79 + return loadBytes(toExternalForm(), new byte[0]);
89.80 }
89.81 }
89.82 return null;
89.83 @@ -1016,6 +1042,23 @@
89.84 return universal;
89.85 }
89.86
89.87 + private static URL findContext(URL context) throws MalformedURLException {
89.88 + if (context == null) {
89.89 + String base = findBaseURL();
89.90 + if (base != null) {
89.91 + context = new URL(null, base, false);
89.92 + }
89.93 + }
89.94 + return context;
89.95 + }
89.96 +
89.97 + @JavaScriptBody(args = {}, body =
89.98 + "if (typeof window !== 'object') return null;\n"
89.99 + + "if (!window.location) return null;\n"
89.100 + + "if (!window.location.href) return null;\n"
89.101 + + "return window.location.href;\n"
89.102 + )
89.103 + private static native String findBaseURL();
89.104 }
89.105 class Parts {
89.106 String path, query, ref;
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/emul/mini/src/main/java/java/util/zip/Adler32.java Tue Feb 05 17:04:22 2013 +0100
90.3 @@ -0,0 +1,205 @@
90.4 +/* Adler32.java - Computes Adler32 data checksum of a data stream
90.5 + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
90.6 +
90.7 +This file is part of GNU Classpath.
90.8 +
90.9 +GNU Classpath is free software; you can redistribute it and/or modify
90.10 +it under the terms of the GNU General Public License as published by
90.11 +the Free Software Foundation; either version 2, or (at your option)
90.12 +any later version.
90.13 +
90.14 +GNU Classpath is distributed in the hope that it will be useful, but
90.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
90.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90.17 +General Public License for more details.
90.18 +
90.19 +You should have received a copy of the GNU General Public License
90.20 +along with GNU Classpath; see the file COPYING. If not, write to the
90.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
90.22 +02111-1307 USA.
90.23 +
90.24 +Linking this library statically or dynamically with other modules is
90.25 +making a combined work based on this library. Thus, the terms and
90.26 +conditions of the GNU General Public License cover the whole
90.27 +combination.
90.28 +
90.29 +As a special exception, the copyright holders of this library give you
90.30 +permission to link this library with independent modules to produce an
90.31 +executable, regardless of the license terms of these independent
90.32 +modules, and to copy and distribute the resulting executable under
90.33 +terms of your choice, provided that you also meet, for each linked
90.34 +independent module, the terms and conditions of the license of that
90.35 +module. An independent module is a module which is not derived from
90.36 +or based on this library. If you modify this library, you may extend
90.37 +this exception to your version of the library, but you are not
90.38 +obligated to do so. If you do not wish to do so, delete this
90.39 +exception statement from your version. */
90.40 +
90.41 +package java.util.zip;
90.42 +
90.43 +/*
90.44 + * Written using on-line Java Platform 1.2 API Specification, as well
90.45 + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
90.46 + * The actual Adler32 algorithm is taken from RFC 1950.
90.47 + * Status: Believed complete and correct.
90.48 + */
90.49 +
90.50 +/**
90.51 + * Computes Adler32 checksum for a stream of data. An Adler32
90.52 + * checksum is not as reliable as a CRC32 checksum, but a lot faster to
90.53 + * compute.
90.54 + *<p>
90.55 + * The specification for Adler32 may be found in RFC 1950.
90.56 + * (ZLIB Compressed Data Format Specification version 3.3)
90.57 + *<p>
90.58 + *<p>
90.59 + * From that document:
90.60 + *<p>
90.61 + * "ADLER32 (Adler-32 checksum)
90.62 + * This contains a checksum value of the uncompressed data
90.63 + * (excluding any dictionary data) computed according to Adler-32
90.64 + * algorithm. This algorithm is a 32-bit extension and improvement
90.65 + * of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
90.66 + * standard.
90.67 + *<p>
90.68 + * Adler-32 is composed of two sums accumulated per byte: s1 is
90.69 + * the sum of all bytes, s2 is the sum of all s1 values. Both sums
90.70 + * are done modulo 65521. s1 is initialized to 1, s2 to zero. The
90.71 + * Adler-32 checksum is stored as s2*65536 + s1 in most-
90.72 + * significant-byte first (network) order."
90.73 + *<p>
90.74 + * "8.2. The Adler-32 algorithm
90.75 + *<p>
90.76 + * The Adler-32 algorithm is much faster than the CRC32 algorithm yet
90.77 + * still provides an extremely low probability of undetected errors.
90.78 + *<p>
90.79 + * The modulo on unsigned long accumulators can be delayed for 5552
90.80 + * bytes, so the modulo operation time is negligible. If the bytes
90.81 + * are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
90.82 + * and order sensitive, unlike the first sum, which is just a
90.83 + * checksum. That 65521 is prime is important to avoid a possible
90.84 + * large class of two-byte errors that leave the check unchanged.
90.85 + * (The Fletcher checksum uses 255, which is not prime and which also
90.86 + * makes the Fletcher check insensitive to single byte changes 0 <->
90.87 + * 255.)
90.88 + *<p>
90.89 + * The sum s1 is initialized to 1 instead of zero to make the length
90.90 + * of the sequence part of s2, so that the length does not have to be
90.91 + * checked separately. (Any sequence of zeroes has a Fletcher
90.92 + * checksum of zero.)"
90.93 + *
90.94 + * @author John Leuner, Per Bothner
90.95 + * @since JDK 1.1
90.96 + *
90.97 + * @see InflaterInputStream
90.98 + * @see DeflaterOutputStream
90.99 + */
90.100 +public class Adler32 implements Checksum
90.101 +{
90.102 +
90.103 + /** largest prime smaller than 65536 */
90.104 + private static final int BASE = 65521;
90.105 +
90.106 + private int checksum; //we do all in int.
90.107 +
90.108 + //Note that java doesn't have unsigned integers,
90.109 + //so we have to be careful with what arithmetic
90.110 + //we do. We return the checksum as a long to
90.111 + //avoid sign confusion.
90.112 +
90.113 + /**
90.114 + * Creates a new instance of the <code>Adler32</code> class.
90.115 + * The checksum starts off with a value of 1.
90.116 + */
90.117 + public Adler32 ()
90.118 + {
90.119 + reset();
90.120 + }
90.121 +
90.122 + /**
90.123 + * Resets the Adler32 checksum to the initial value.
90.124 + */
90.125 + public void reset ()
90.126 + {
90.127 + checksum = 1; //Initialize to 1
90.128 + }
90.129 +
90.130 + /**
90.131 + * Updates the checksum with the byte b.
90.132 + *
90.133 + * @param bval the data value to add. The high byte of the int is ignored.
90.134 + */
90.135 + public void update (int bval)
90.136 + {
90.137 + //We could make a length 1 byte array and call update again, but I
90.138 + //would rather not have that overhead
90.139 + int s1 = checksum & 0xffff;
90.140 + int s2 = checksum >>> 16;
90.141 +
90.142 + s1 = (s1 + (bval & 0xFF)) % BASE;
90.143 + s2 = (s1 + s2) % BASE;
90.144 +
90.145 + checksum = (s2 << 16) + s1;
90.146 + }
90.147 +
90.148 + /**
90.149 + * Updates the checksum with the bytes taken from the array.
90.150 + *
90.151 + * @param buffer an array of bytes
90.152 + */
90.153 + public void update (byte[] buffer)
90.154 + {
90.155 + update(buffer, 0, buffer.length);
90.156 + }
90.157 +
90.158 + /**
90.159 + * Updates the checksum with the bytes taken from the array.
90.160 + *
90.161 + * @param buf an array of bytes
90.162 + * @param off the start of the data used for this update
90.163 + * @param len the number of bytes to use for this update
90.164 + */
90.165 + public void update (byte[] buf, int off, int len)
90.166 + {
90.167 + //(By Per Bothner)
90.168 + int s1 = checksum & 0xffff;
90.169 + int s2 = checksum >>> 16;
90.170 +
90.171 + while (len > 0)
90.172 + {
90.173 + // We can defer the modulo operation:
90.174 + // s1 maximally grows from 65521 to 65521 + 255 * 3800
90.175 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
90.176 + int n = 3800;
90.177 + if (n > len)
90.178 + n = len;
90.179 + len -= n;
90.180 + while (--n >= 0)
90.181 + {
90.182 + s1 = s1 + (buf[off++] & 0xFF);
90.183 + s2 = s2 + s1;
90.184 + }
90.185 + s1 %= BASE;
90.186 + s2 %= BASE;
90.187 + }
90.188 +
90.189 + /*Old implementation, borrowed from somewhere:
90.190 + int n;
90.191 +
90.192 + while (len-- > 0) {
90.193 +
90.194 + s1 = (s1 + (bs[offset++] & 0xff)) % BASE;
90.195 + s2 = (s2 + s1) % BASE;
90.196 + }*/
90.197 +
90.198 + checksum = (s2 << 16) | s1;
90.199 + }
90.200 +
90.201 + /**
90.202 + * Returns the Adler32 data checksum computed so far.
90.203 + */
90.204 + public long getValue()
90.205 + {
90.206 + return (long) checksum & 0xffffffffL;
90.207 + }
90.208 +}
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/emul/mini/src/main/java/java/util/zip/CRC32.java Tue Feb 05 17:04:22 2013 +0100
91.3 @@ -0,0 +1,132 @@
91.4 +/* CRC32.java - Computes CRC32 data checksum of a data stream
91.5 + Copyright (C) 1999. 2000, 2001 Free Software Foundation, Inc.
91.6 +
91.7 +This file is part of GNU Classpath.
91.8 +
91.9 +GNU Classpath is free software; you can redistribute it and/or modify
91.10 +it under the terms of the GNU General Public License as published by
91.11 +the Free Software Foundation; either version 2, or (at your option)
91.12 +any later version.
91.13 +
91.14 +GNU Classpath is distributed in the hope that it will be useful, but
91.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
91.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
91.17 +General Public License for more details.
91.18 +
91.19 +You should have received a copy of the GNU General Public License
91.20 +along with GNU Classpath; see the file COPYING. If not, write to the
91.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
91.22 +02111-1307 USA.
91.23 +
91.24 +Linking this library statically or dynamically with other modules is
91.25 +making a combined work based on this library. Thus, the terms and
91.26 +conditions of the GNU General Public License cover the whole
91.27 +combination.
91.28 +
91.29 +As a special exception, the copyright holders of this library give you
91.30 +permission to link this library with independent modules to produce an
91.31 +executable, regardless of the license terms of these independent
91.32 +modules, and to copy and distribute the resulting executable under
91.33 +terms of your choice, provided that you also meet, for each linked
91.34 +independent module, the terms and conditions of the license of that
91.35 +module. An independent module is a module which is not derived from
91.36 +or based on this library. If you modify this library, you may extend
91.37 +this exception to your version of the library, but you are not
91.38 +obligated to do so. If you do not wish to do so, delete this
91.39 +exception statement from your version. */
91.40 +
91.41 +package java.util.zip;
91.42 +
91.43 +/*
91.44 + * Written using on-line Java Platform 1.2 API Specification, as well
91.45 + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
91.46 + * The actual CRC32 algorithm is taken from RFC 1952.
91.47 + * Status: Believed complete and correct.
91.48 + */
91.49 +
91.50 +/**
91.51 + * Computes CRC32 data checksum of a data stream.
91.52 + * The actual CRC32 algorithm is described in RFC 1952
91.53 + * (GZIP file format specification version 4.3).
91.54 + * Can be used to get the CRC32 over a stream if used with checked input/output
91.55 + * streams.
91.56 + *
91.57 + * @see InflaterInputStream
91.58 + * @see DeflaterOutputStream
91.59 + *
91.60 + * @author Per Bothner
91.61 + * @date April 1, 1999.
91.62 + */
91.63 +public class CRC32 implements Checksum
91.64 +{
91.65 + /** The crc data checksum so far. */
91.66 + private int crc = 0;
91.67 +
91.68 + /** The fast CRC table. Computed once when the CRC32 class is loaded. */
91.69 + private static int[] crc_table = make_crc_table();
91.70 +
91.71 + /** Make the table for a fast CRC. */
91.72 + private static int[] make_crc_table ()
91.73 + {
91.74 + int[] crc_table = new int[256];
91.75 + for (int n = 0; n < 256; n++)
91.76 + {
91.77 + int c = n;
91.78 + for (int k = 8; --k >= 0; )
91.79 + {
91.80 + if ((c & 1) != 0)
91.81 + c = 0xedb88320 ^ (c >>> 1);
91.82 + else
91.83 + c = c >>> 1;
91.84 + }
91.85 + crc_table[n] = c;
91.86 + }
91.87 + return crc_table;
91.88 + }
91.89 +
91.90 + /**
91.91 + * Returns the CRC32 data checksum computed so far.
91.92 + */
91.93 + public long getValue ()
91.94 + {
91.95 + return (long) crc & 0xffffffffL;
91.96 + }
91.97 +
91.98 + /**
91.99 + * Resets the CRC32 data checksum as if no update was ever called.
91.100 + */
91.101 + public void reset () { crc = 0; }
91.102 +
91.103 + /**
91.104 + * Updates the checksum with the int bval.
91.105 + *
91.106 + * @param bval (the byte is taken as the lower 8 bits of bval)
91.107 + */
91.108 +
91.109 + public void update (int bval)
91.110 + {
91.111 + int c = ~crc;
91.112 + c = crc_table[(c ^ bval) & 0xff] ^ (c >>> 8);
91.113 + crc = ~c;
91.114 + }
91.115 +
91.116 + /**
91.117 + * Adds the byte array to the data checksum.
91.118 + *
91.119 + * @param buf the buffer which contains the data
91.120 + * @param off the offset in the buffer where the data starts
91.121 + * @param len the length of the data
91.122 + */
91.123 + public void update (byte[] buf, int off, int len)
91.124 + {
91.125 + int c = ~crc;
91.126 + while (--len >= 0)
91.127 + c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8);
91.128 + crc = ~c;
91.129 + }
91.130 +
91.131 + /**
91.132 + * Adds the complete byte array to the data checksum.
91.133 + */
91.134 + public void update (byte[] buf) { update(buf, 0, buf.length); }
91.135 +}
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/emul/mini/src/main/java/java/util/zip/Checksum.java Tue Feb 05 17:04:22 2013 +0100
92.3 @@ -0,0 +1,60 @@
92.4 +/*
92.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
92.7 + *
92.8 + * This code is free software; you can redistribute it and/or modify it
92.9 + * under the terms of the GNU General Public License version 2 only, as
92.10 + * published by the Free Software Foundation. Oracle designates this
92.11 + * particular file as subject to the "Classpath" exception as provided
92.12 + * by Oracle in the LICENSE file that accompanied this code.
92.13 + *
92.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
92.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
92.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
92.17 + * version 2 for more details (a copy is included in the LICENSE file that
92.18 + * accompanied this code).
92.19 + *
92.20 + * You should have received a copy of the GNU General Public License version
92.21 + * 2 along with this work; if not, write to the Free Software Foundation,
92.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
92.23 + *
92.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
92.25 + * or visit www.oracle.com if you need additional information or have any
92.26 + * questions.
92.27 + */
92.28 +
92.29 +package java.util.zip;
92.30 +
92.31 +/**
92.32 + * An interface representing a data checksum.
92.33 + *
92.34 + * @author David Connelly
92.35 + */
92.36 +public
92.37 +interface Checksum {
92.38 + /**
92.39 + * Updates the current checksum with the specified byte.
92.40 + *
92.41 + * @param b the byte to update the checksum with
92.42 + */
92.43 + public void update(int b);
92.44 +
92.45 + /**
92.46 + * Updates the current checksum with the specified array of bytes.
92.47 + * @param b the byte array to update the checksum with
92.48 + * @param off the start offset of the data
92.49 + * @param len the number of bytes to use for the update
92.50 + */
92.51 + public void update(byte[] b, int off, int len);
92.52 +
92.53 + /**
92.54 + * Returns the current checksum value.
92.55 + * @return the current checksum value
92.56 + */
92.57 + public long getValue();
92.58 +
92.59 + /**
92.60 + * Resets the checksum to its initial value.
92.61 + */
92.62 + public void reset();
92.63 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/emul/mini/src/main/java/java/util/zip/DataFormatException.java Tue Feb 05 17:04:22 2013 +0100
93.3 @@ -0,0 +1,52 @@
93.4 +/*
93.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
93.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
93.7 + *
93.8 + * This code is free software; you can redistribute it and/or modify it
93.9 + * under the terms of the GNU General Public License version 2 only, as
93.10 + * published by the Free Software Foundation. Oracle designates this
93.11 + * particular file as subject to the "Classpath" exception as provided
93.12 + * by Oracle in the LICENSE file that accompanied this code.
93.13 + *
93.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
93.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
93.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
93.17 + * version 2 for more details (a copy is included in the LICENSE file that
93.18 + * accompanied this code).
93.19 + *
93.20 + * You should have received a copy of the GNU General Public License version
93.21 + * 2 along with this work; if not, write to the Free Software Foundation,
93.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
93.23 + *
93.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
93.25 + * or visit www.oracle.com if you need additional information or have any
93.26 + * questions.
93.27 + */
93.28 +
93.29 +package java.util.zip;
93.30 +
93.31 +/**
93.32 + * Signals that a data format error has occurred.
93.33 + *
93.34 + * @author David Connelly
93.35 + */
93.36 +public
93.37 +class DataFormatException extends Exception {
93.38 + private static final long serialVersionUID = 2219632870893641452L;
93.39 +
93.40 + /**
93.41 + * Constructs a DataFormatException with no detail message.
93.42 + */
93.43 + public DataFormatException() {
93.44 + super();
93.45 + }
93.46 +
93.47 + /**
93.48 + * Constructs a DataFormatException with the specified detail message.
93.49 + * A detail message is a String that describes this particular exception.
93.50 + * @param s the String containing a detail message
93.51 + */
93.52 + public DataFormatException(String s) {
93.53 + super(s);
93.54 + }
93.55 +}
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/emul/mini/src/main/java/java/util/zip/Inflater.java Tue Feb 05 17:04:22 2013 +0100
94.3 @@ -0,0 +1,1475 @@
94.4 +/* Inflater.java - Decompress a data stream
94.5 + Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
94.6 +
94.7 +This file is part of GNU Classpath.
94.8 +
94.9 +GNU Classpath is free software; you can redistribute it and/or modify
94.10 +it under the terms of the GNU General Public License as published by
94.11 +the Free Software Foundation; either version 2, or (at your option)
94.12 +any later version.
94.13 +
94.14 +GNU Classpath is distributed in the hope that it will be useful, but
94.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
94.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
94.17 +General Public License for more details.
94.18 +
94.19 +You should have received a copy of the GNU General Public License
94.20 +along with GNU Classpath; see the file COPYING. If not, write to the
94.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
94.22 +02111-1307 USA.
94.23 +
94.24 +Linking this library statically or dynamically with other modules is
94.25 +making a combined work based on this library. Thus, the terms and
94.26 +conditions of the GNU General Public License cover the whole
94.27 +combination.
94.28 +
94.29 +As a special exception, the copyright holders of this library give you
94.30 +permission to link this library with independent modules to produce an
94.31 +executable, regardless of the license terms of these independent
94.32 +modules, and to copy and distribute the resulting executable under
94.33 +terms of your choice, provided that you also meet, for each linked
94.34 +independent module, the terms and conditions of the license of that
94.35 +module. An independent module is a module which is not derived from
94.36 +or based on this library. If you modify this library, you may extend
94.37 +this exception to your version of the library, but you are not
94.38 +obligated to do so. If you do not wish to do so, delete this
94.39 +exception statement from your version. */
94.40 +
94.41 +package java.util.zip;
94.42 +
94.43 +import org.apidesign.bck2brwsr.emul.lang.System;
94.44 +
94.45 +/**
94.46 + * This class provides support for general purpose decompression using the
94.47 + * popular ZLIB compression library. The ZLIB compression library was
94.48 + * initially developed as part of the PNG graphics standard and is not
94.49 + * protected by patents. It is fully described in the specifications at
94.50 + * the <a href="package-summary.html#package_description">java.util.zip
94.51 + * package description</a>.
94.52 + *
94.53 + * <p>The following code fragment demonstrates a trivial compression
94.54 + * and decompression of a string using <tt>Deflater</tt> and
94.55 + * <tt>Inflater</tt>.
94.56 + *
94.57 + * <blockquote><pre>
94.58 + * try {
94.59 + * // Encode a String into bytes
94.60 + * String inputString = "blahblahblah\u20AC\u20AC";
94.61 + * byte[] input = inputString.getBytes("UTF-8");
94.62 + *
94.63 + * // Compress the bytes
94.64 + * byte[] output = new byte[100];
94.65 + * Deflater compresser = new Deflater();
94.66 + * compresser.setInput(input);
94.67 + * compresser.finish();
94.68 + * int compressedDataLength = compresser.deflate(output);
94.69 + *
94.70 + * // Decompress the bytes
94.71 + * Inflater decompresser = new Inflater();
94.72 + * decompresser.setInput(output, 0, compressedDataLength);
94.73 + * byte[] result = new byte[100];
94.74 + * int resultLength = decompresser.inflate(result);
94.75 + * decompresser.end();
94.76 + *
94.77 + * // Decode the bytes into a String
94.78 + * String outputString = new String(result, 0, resultLength, "UTF-8");
94.79 + * } catch(java.io.UnsupportedEncodingException ex) {
94.80 + * // handle
94.81 + * } catch (java.util.zip.DataFormatException ex) {
94.82 + * // handle
94.83 + * }
94.84 + * </pre></blockquote>
94.85 + *
94.86 + * @see Deflater
94.87 + * @author David Connelly
94.88 + *
94.89 + */
94.90 +
94.91 +/* Written using on-line Java Platform 1.2 API Specification
94.92 + * and JCL book.
94.93 + * Believed complete and correct.
94.94 + */
94.95 +
94.96 +/**
94.97 + * Inflater is used to decompress data that has been compressed according
94.98 + * to the "deflate" standard described in rfc1950.
94.99 + *
94.100 + * The usage is as following. First you have to set some input with
94.101 + * <code>setInput()</code>, then inflate() it. If inflate doesn't
94.102 + * inflate any bytes there may be three reasons:
94.103 + * <ul>
94.104 + * <li>needsInput() returns true because the input buffer is empty.
94.105 + * You have to provide more input with <code>setInput()</code>.
94.106 + * NOTE: needsInput() also returns true when, the stream is finished.
94.107 + * </li>
94.108 + * <li>needsDictionary() returns true, you have to provide a preset
94.109 + * dictionary with <code>setDictionary()</code>.</li>
94.110 + * <li>finished() returns true, the inflater has finished.</li>
94.111 + * </ul>
94.112 + * Once the first output byte is produced, a dictionary will not be
94.113 + * needed at a later stage.
94.114 + *
94.115 + * @author John Leuner, Jochen Hoenicke
94.116 + * @author Tom Tromey
94.117 + * @date May 17, 1999
94.118 + * @since JDK 1.1
94.119 + */
94.120 +public class Inflater
94.121 +{
94.122 + /* Copy lengths for literal codes 257..285 */
94.123 + private static final int CPLENS[] =
94.124 + {
94.125 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
94.126 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
94.127 + };
94.128 +
94.129 + /* Extra bits for literal codes 257..285 */
94.130 + private static final int CPLEXT[] =
94.131 + {
94.132 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
94.133 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
94.134 + };
94.135 +
94.136 + /* Copy offsets for distance codes 0..29 */
94.137 + private static final int CPDIST[] = {
94.138 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
94.139 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
94.140 + 8193, 12289, 16385, 24577
94.141 + };
94.142 +
94.143 + /* Extra bits for distance codes */
94.144 + private static final int CPDEXT[] = {
94.145 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
94.146 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
94.147 + 12, 12, 13, 13
94.148 + };
94.149 +
94.150 + /* This are the state in which the inflater can be. */
94.151 + private static final int DECODE_HEADER = 0;
94.152 + private static final int DECODE_DICT = 1;
94.153 + private static final int DECODE_BLOCKS = 2;
94.154 + private static final int DECODE_STORED_LEN1 = 3;
94.155 + private static final int DECODE_STORED_LEN2 = 4;
94.156 + private static final int DECODE_STORED = 5;
94.157 + private static final int DECODE_DYN_HEADER = 6;
94.158 + private static final int DECODE_HUFFMAN = 7;
94.159 + private static final int DECODE_HUFFMAN_LENBITS = 8;
94.160 + private static final int DECODE_HUFFMAN_DIST = 9;
94.161 + private static final int DECODE_HUFFMAN_DISTBITS = 10;
94.162 + private static final int DECODE_CHKSUM = 11;
94.163 + private static final int FINISHED = 12;
94.164 +
94.165 + /** This variable contains the current state. */
94.166 + private int mode;
94.167 +
94.168 + /**
94.169 + * The adler checksum of the dictionary or of the decompressed
94.170 + * stream, as it is written in the header resp. footer of the
94.171 + * compressed stream. <br>
94.172 + *
94.173 + * Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
94.174 + */
94.175 + private int readAdler;
94.176 + /**
94.177 + * The number of bits needed to complete the current state. This
94.178 + * is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
94.179 + * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.
94.180 + */
94.181 + private int neededBits;
94.182 + private int repLength, repDist;
94.183 + private int uncomprLen;
94.184 + /**
94.185 + * True, if the last block flag was set in the last block of the
94.186 + * inflated stream. This means that the stream ends after the
94.187 + * current block.
94.188 + */
94.189 + private boolean isLastBlock;
94.190 +
94.191 + /**
94.192 + * The total number of inflated bytes.
94.193 + */
94.194 + private long totalOut;
94.195 + /**
94.196 + * The total number of bytes set with setInput(). This is not the
94.197 + * value returned by getTotalIn(), since this also includes the
94.198 + * unprocessed input.
94.199 + */
94.200 + private long totalIn;
94.201 + /**
94.202 + * This variable stores the nowrap flag that was given to the constructor.
94.203 + * True means, that the inflated stream doesn't contain a header nor the
94.204 + * checksum in the footer.
94.205 + */
94.206 + private boolean nowrap;
94.207 +
94.208 + private StreamManipulator input;
94.209 + private OutputWindow outputWindow;
94.210 + private InflaterDynHeader dynHeader;
94.211 + private InflaterHuffmanTree litlenTree, distTree;
94.212 + private Adler32 adler;
94.213 +
94.214 + /**
94.215 + * Creates a new inflater.
94.216 + */
94.217 + public Inflater ()
94.218 + {
94.219 + this (false);
94.220 + }
94.221 +
94.222 + /**
94.223 + * Creates a new inflater.
94.224 + * @param nowrap true if no header and checksum field appears in the
94.225 + * stream. This is used for GZIPed input. For compatibility with
94.226 + * Sun JDK you should provide one byte of input more than needed in
94.227 + * this case.
94.228 + */
94.229 + public Inflater (boolean nowrap)
94.230 + {
94.231 + this.nowrap = nowrap;
94.232 + this.adler = new Adler32();
94.233 + input = new StreamManipulator();
94.234 + outputWindow = new OutputWindow();
94.235 + mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
94.236 + }
94.237 +
94.238 + /**
94.239 + * Finalizes this object.
94.240 + */
94.241 + protected void finalize ()
94.242 + {
94.243 + /* Exists only for compatibility */
94.244 + }
94.245 +
94.246 + /**
94.247 + * Frees all objects allocated by the inflater. There's no reason
94.248 + * to call this, since you can just rely on garbage collection (even
94.249 + * for the Sun implementation). Exists only for compatibility
94.250 + * with Sun's JDK, where the compressor allocates native memory.
94.251 + * If you call any method (even reset) afterwards the behaviour is
94.252 + * <i>undefined</i>.
94.253 + * @deprecated Just clear all references to inflater instead.
94.254 + */
94.255 + public void end ()
94.256 + {
94.257 + outputWindow = null;
94.258 + input = null;
94.259 + dynHeader = null;
94.260 + litlenTree = null;
94.261 + distTree = null;
94.262 + adler = null;
94.263 + }
94.264 +
94.265 + /**
94.266 + * Returns true, if the inflater has finished. This means, that no
94.267 + * input is needed and no output can be produced.
94.268 + */
94.269 + public boolean finished()
94.270 + {
94.271 + return mode == FINISHED && outputWindow.getAvailable() == 0;
94.272 + }
94.273 +
94.274 + /**
94.275 + * Gets the adler checksum. This is either the checksum of all
94.276 + * uncompressed bytes returned by inflate(), or if needsDictionary()
94.277 + * returns true (and thus no output was yet produced) this is the
94.278 + * adler checksum of the expected dictionary.
94.279 + * @returns the adler checksum.
94.280 + */
94.281 + public int getAdler()
94.282 + {
94.283 + return needsDictionary() ? readAdler : (int) adler.getValue();
94.284 + }
94.285 +
94.286 + /**
94.287 + * Gets the number of unprocessed input. Useful, if the end of the
94.288 + * stream is reached and you want to further process the bytes after
94.289 + * the deflate stream.
94.290 + * @return the number of bytes of the input which were not processed.
94.291 + */
94.292 + public int getRemaining()
94.293 + {
94.294 + return input.getAvailableBytes();
94.295 + }
94.296 +
94.297 + /**
94.298 + * Gets the total number of processed compressed input bytes.
94.299 + * @return the total number of bytes of processed input bytes.
94.300 + */
94.301 + public int getTotalIn()
94.302 + {
94.303 + return (int)getBytesRead();
94.304 + }
94.305 +
94.306 + /**
94.307 + * Gets the total number of output bytes returned by inflate().
94.308 + * @return the total number of output bytes.
94.309 + */
94.310 + public int getTotalOut()
94.311 + {
94.312 + return (int)totalOut;
94.313 + }
94.314 +
94.315 + public long getBytesWritten() {
94.316 + return totalOut;
94.317 + }
94.318 +
94.319 + public long getBytesRead() {
94.320 + return totalIn - getRemaining();
94.321 + }
94.322 +
94.323 +
94.324 + /**
94.325 + * Inflates the compressed stream to the output buffer. If this
94.326 + * returns 0, you should check, whether needsDictionary(),
94.327 + * needsInput() or finished() returns true, to determine why no
94.328 + * further output is produced.
94.329 + * @param buffer the output buffer.
94.330 + * @return the number of bytes written to the buffer, 0 if no further
94.331 + * output can be produced.
94.332 + * @exception DataFormatException if deflated stream is invalid.
94.333 + * @exception IllegalArgumentException if buf has length 0.
94.334 + */
94.335 + public int inflate (byte[] buf) throws DataFormatException
94.336 + {
94.337 + return inflate (buf, 0, buf.length);
94.338 + }
94.339 +
94.340 + /**
94.341 + * Inflates the compressed stream to the output buffer. If this
94.342 + * returns 0, you should check, whether needsDictionary(),
94.343 + * needsInput() or finished() returns true, to determine why no
94.344 + * further output is produced.
94.345 + * @param buffer the output buffer.
94.346 + * @param off the offset into buffer where the output should start.
94.347 + * @param len the maximum length of the output.
94.348 + * @return the number of bytes written to the buffer, 0 if no further
94.349 + * output can be produced.
94.350 + * @exception DataFormatException if deflated stream is invalid.
94.351 + * @exception IndexOutOfBoundsException if the off and/or len are wrong.
94.352 + */
94.353 + public int inflate (byte[] buf, int off, int len) throws DataFormatException
94.354 + {
94.355 + /* Special case: len may be zero */
94.356 + if (len == 0)
94.357 + return 0;
94.358 + /* Check for correct buff, off, len triple */
94.359 + if (0 > off || off > off + len || off + len > buf.length)
94.360 + throw new ArrayIndexOutOfBoundsException();
94.361 + int count = 0;
94.362 + int more;
94.363 + do
94.364 + {
94.365 + if (mode != DECODE_CHKSUM)
94.366 + {
94.367 + /* Don't give away any output, if we are waiting for the
94.368 + * checksum in the input stream.
94.369 + *
94.370 + * With this trick we have always:
94.371 + * needsInput() and not finished()
94.372 + * implies more output can be produced.
94.373 + */
94.374 + more = outputWindow.copyOutput(buf, off, len);
94.375 + adler.update(buf, off, more);
94.376 + off += more;
94.377 + count += more;
94.378 + totalOut += more;
94.379 + len -= more;
94.380 + if (len == 0)
94.381 + return count;
94.382 + }
94.383 + }
94.384 + while (decode() || (outputWindow.getAvailable() > 0
94.385 + && mode != DECODE_CHKSUM));
94.386 + return count;
94.387 + }
94.388 +
94.389 + /**
94.390 + * Returns true, if a preset dictionary is needed to inflate the input.
94.391 + */
94.392 + public boolean needsDictionary ()
94.393 + {
94.394 + return mode == DECODE_DICT && neededBits == 0;
94.395 + }
94.396 +
94.397 + /**
94.398 + * Returns true, if the input buffer is empty.
94.399 + * You should then call setInput(). <br>
94.400 + *
94.401 + * <em>NOTE</em>: This method also returns true when the stream is finished.
94.402 + */
94.403 + public boolean needsInput ()
94.404 + {
94.405 + return input.needsInput ();
94.406 + }
94.407 +
94.408 + /**
94.409 + * Resets the inflater so that a new stream can be decompressed. All
94.410 + * pending input and output will be discarded.
94.411 + */
94.412 + public void reset ()
94.413 + {
94.414 + mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
94.415 + totalIn = totalOut = 0;
94.416 + input.reset();
94.417 + outputWindow.reset();
94.418 + dynHeader = null;
94.419 + litlenTree = null;
94.420 + distTree = null;
94.421 + isLastBlock = false;
94.422 + adler.reset();
94.423 + }
94.424 +
94.425 + /**
94.426 + * Sets the preset dictionary. This should only be called, if
94.427 + * needsDictionary() returns true and it should set the same
94.428 + * dictionary, that was used for deflating. The getAdler()
94.429 + * function returns the checksum of the dictionary needed.
94.430 + * @param buffer the dictionary.
94.431 + * @exception IllegalStateException if no dictionary is needed.
94.432 + * @exception IllegalArgumentException if the dictionary checksum is
94.433 + * wrong.
94.434 + */
94.435 + public void setDictionary (byte[] buffer)
94.436 + {
94.437 + setDictionary(buffer, 0, buffer.length);
94.438 + }
94.439 +
94.440 + /**
94.441 + * Sets the preset dictionary. This should only be called, if
94.442 + * needsDictionary() returns true and it should set the same
94.443 + * dictionary, that was used for deflating. The getAdler()
94.444 + * function returns the checksum of the dictionary needed.
94.445 + * @param buffer the dictionary.
94.446 + * @param off the offset into buffer where the dictionary starts.
94.447 + * @param len the length of the dictionary.
94.448 + * @exception IllegalStateException if no dictionary is needed.
94.449 + * @exception IllegalArgumentException if the dictionary checksum is
94.450 + * wrong.
94.451 + * @exception IndexOutOfBoundsException if the off and/or len are wrong.
94.452 + */
94.453 + public void setDictionary (byte[] buffer, int off, int len)
94.454 + {
94.455 + if (!needsDictionary())
94.456 + throw new IllegalStateException();
94.457 +
94.458 + adler.update(buffer, off, len);
94.459 + if ((int) adler.getValue() != readAdler)
94.460 + throw new IllegalArgumentException("Wrong adler checksum");
94.461 + adler.reset();
94.462 + outputWindow.copyDict(buffer, off, len);
94.463 + mode = DECODE_BLOCKS;
94.464 + }
94.465 +
94.466 + /**
94.467 + * Sets the input. This should only be called, if needsInput()
94.468 + * returns true.
94.469 + * @param buffer the input.
94.470 + * @exception IllegalStateException if no input is needed.
94.471 + */
94.472 + public void setInput (byte[] buf)
94.473 + {
94.474 + setInput (buf, 0, buf.length);
94.475 + }
94.476 +
94.477 + /**
94.478 + * Sets the input. This should only be called, if needsInput()
94.479 + * returns true.
94.480 + * @param buffer the input.
94.481 + * @param off the offset into buffer where the input starts.
94.482 + * @param len the length of the input.
94.483 + * @exception IllegalStateException if no input is needed.
94.484 + * @exception IndexOutOfBoundsException if the off and/or len are wrong.
94.485 + */
94.486 + public void setInput (byte[] buf, int off, int len)
94.487 + {
94.488 + input.setInput (buf, off, len);
94.489 + totalIn += len;
94.490 + }
94.491 + private static final int DEFLATED = 8;
94.492 + /**
94.493 + * Decodes the deflate header.
94.494 + * @return false if more input is needed.
94.495 + * @exception DataFormatException if header is invalid.
94.496 + */
94.497 + private boolean decodeHeader () throws DataFormatException
94.498 + {
94.499 + int header = input.peekBits(16);
94.500 + if (header < 0)
94.501 + return false;
94.502 + input.dropBits(16);
94.503 +
94.504 + /* The header is written in "wrong" byte order */
94.505 + header = ((header << 8) | (header >> 8)) & 0xffff;
94.506 + if (header % 31 != 0)
94.507 + throw new DataFormatException("Header checksum illegal");
94.508 +
94.509 + if ((header & 0x0f00) != (DEFLATED << 8))
94.510 + throw new DataFormatException("Compression Method unknown");
94.511 +
94.512 + /* Maximum size of the backwards window in bits.
94.513 + * We currently ignore this, but we could use it to make the
94.514 + * inflater window more space efficient. On the other hand the
94.515 + * full window (15 bits) is needed most times, anyway.
94.516 + int max_wbits = ((header & 0x7000) >> 12) + 8;
94.517 + */
94.518 +
94.519 + if ((header & 0x0020) == 0) // Dictionary flag?
94.520 + {
94.521 + mode = DECODE_BLOCKS;
94.522 + }
94.523 + else
94.524 + {
94.525 + mode = DECODE_DICT;
94.526 + neededBits = 32;
94.527 + }
94.528 + return true;
94.529 + }
94.530 +
94.531 + /**
94.532 + * Decodes the dictionary checksum after the deflate header.
94.533 + * @return false if more input is needed.
94.534 + */
94.535 + private boolean decodeDict ()
94.536 + {
94.537 + while (neededBits > 0)
94.538 + {
94.539 + int dictByte = input.peekBits(8);
94.540 + if (dictByte < 0)
94.541 + return false;
94.542 + input.dropBits(8);
94.543 + readAdler = (readAdler << 8) | dictByte;
94.544 + neededBits -= 8;
94.545 + }
94.546 + return false;
94.547 + }
94.548 +
94.549 + /**
94.550 + * Decodes the huffman encoded symbols in the input stream.
94.551 + * @return false if more input is needed, true if output window is
94.552 + * full or the current block ends.
94.553 + * @exception DataFormatException if deflated stream is invalid.
94.554 + */
94.555 + private boolean decodeHuffman () throws DataFormatException
94.556 + {
94.557 + int free = outputWindow.getFreeSpace();
94.558 + while (free >= 258)
94.559 + {
94.560 + int symbol;
94.561 + switch (mode)
94.562 + {
94.563 + case DECODE_HUFFMAN:
94.564 + /* This is the inner loop so it is optimized a bit */
94.565 + while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0)
94.566 + {
94.567 + outputWindow.write(symbol);
94.568 + if (--free < 258)
94.569 + return true;
94.570 + }
94.571 + if (symbol < 257)
94.572 + {
94.573 + if (symbol < 0)
94.574 + return false;
94.575 + else
94.576 + {
94.577 + /* symbol == 256: end of block */
94.578 + distTree = null;
94.579 + litlenTree = null;
94.580 + mode = DECODE_BLOCKS;
94.581 + return true;
94.582 + }
94.583 + }
94.584 +
94.585 + try
94.586 + {
94.587 + repLength = CPLENS[symbol - 257];
94.588 + neededBits = CPLEXT[symbol - 257];
94.589 + }
94.590 + catch (ArrayIndexOutOfBoundsException ex)
94.591 + {
94.592 + throw new DataFormatException("Illegal rep length code");
94.593 + }
94.594 + /* fall through */
94.595 + case DECODE_HUFFMAN_LENBITS:
94.596 + if (neededBits > 0)
94.597 + {
94.598 + mode = DECODE_HUFFMAN_LENBITS;
94.599 + int i = input.peekBits(neededBits);
94.600 + if (i < 0)
94.601 + return false;
94.602 + input.dropBits(neededBits);
94.603 + repLength += i;
94.604 + }
94.605 + mode = DECODE_HUFFMAN_DIST;
94.606 + /* fall through */
94.607 + case DECODE_HUFFMAN_DIST:
94.608 + symbol = distTree.getSymbol(input);
94.609 + if (symbol < 0)
94.610 + return false;
94.611 + try
94.612 + {
94.613 + repDist = CPDIST[symbol];
94.614 + neededBits = CPDEXT[symbol];
94.615 + }
94.616 + catch (ArrayIndexOutOfBoundsException ex)
94.617 + {
94.618 + throw new DataFormatException("Illegal rep dist code");
94.619 + }
94.620 + /* fall through */
94.621 + case DECODE_HUFFMAN_DISTBITS:
94.622 + if (neededBits > 0)
94.623 + {
94.624 + mode = DECODE_HUFFMAN_DISTBITS;
94.625 + int i = input.peekBits(neededBits);
94.626 + if (i < 0)
94.627 + return false;
94.628 + input.dropBits(neededBits);
94.629 + repDist += i;
94.630 + }
94.631 + outputWindow.repeat(repLength, repDist);
94.632 + free -= repLength;
94.633 + mode = DECODE_HUFFMAN;
94.634 + break;
94.635 + default:
94.636 + throw new IllegalStateException();
94.637 + }
94.638 + }
94.639 + return true;
94.640 + }
94.641 +
94.642 + /**
94.643 + * Decodes the adler checksum after the deflate stream.
94.644 + * @return false if more input is needed.
94.645 + * @exception DataFormatException if checksum doesn't match.
94.646 + */
94.647 + private boolean decodeChksum () throws DataFormatException
94.648 + {
94.649 + while (neededBits > 0)
94.650 + {
94.651 + int chkByte = input.peekBits(8);
94.652 + if (chkByte < 0)
94.653 + return false;
94.654 + input.dropBits(8);
94.655 + readAdler = (readAdler << 8) | chkByte;
94.656 + neededBits -= 8;
94.657 + }
94.658 + if ((int) adler.getValue() != readAdler)
94.659 + throw new DataFormatException("Adler chksum doesn't match: "
94.660 + +Integer.toHexString((int)adler.getValue())
94.661 + +" vs. "+Integer.toHexString(readAdler));
94.662 + mode = FINISHED;
94.663 + return false;
94.664 + }
94.665 +
94.666 + /**
94.667 + * Decodes the deflated stream.
94.668 + * @return false if more input is needed, or if finished.
94.669 + * @exception DataFormatException if deflated stream is invalid.
94.670 + */
94.671 + private boolean decode () throws DataFormatException
94.672 + {
94.673 + switch (mode)
94.674 + {
94.675 + case DECODE_HEADER:
94.676 + return decodeHeader();
94.677 + case DECODE_DICT:
94.678 + return decodeDict();
94.679 + case DECODE_CHKSUM:
94.680 + return decodeChksum();
94.681 +
94.682 + case DECODE_BLOCKS:
94.683 + if (isLastBlock)
94.684 + {
94.685 + if (nowrap)
94.686 + {
94.687 + mode = FINISHED;
94.688 + return false;
94.689 + }
94.690 + else
94.691 + {
94.692 + input.skipToByteBoundary();
94.693 + neededBits = 32;
94.694 + mode = DECODE_CHKSUM;
94.695 + return true;
94.696 + }
94.697 + }
94.698 +
94.699 + int type = input.peekBits(3);
94.700 + if (type < 0)
94.701 + return false;
94.702 + input.dropBits(3);
94.703 +
94.704 + if ((type & 1) != 0)
94.705 + isLastBlock = true;
94.706 + switch (type >> 1)
94.707 + {
94.708 + case DeflaterConstants.STORED_BLOCK:
94.709 + input.skipToByteBoundary();
94.710 + mode = DECODE_STORED_LEN1;
94.711 + break;
94.712 + case DeflaterConstants.STATIC_TREES:
94.713 + litlenTree = InflaterHuffmanTree.defLitLenTree;
94.714 + distTree = InflaterHuffmanTree.defDistTree;
94.715 + mode = DECODE_HUFFMAN;
94.716 + break;
94.717 + case DeflaterConstants.DYN_TREES:
94.718 + dynHeader = new InflaterDynHeader();
94.719 + mode = DECODE_DYN_HEADER;
94.720 + break;
94.721 + default:
94.722 + throw new DataFormatException("Unknown block type "+type);
94.723 + }
94.724 + return true;
94.725 +
94.726 + case DECODE_STORED_LEN1:
94.727 + {
94.728 + if ((uncomprLen = input.peekBits(16)) < 0)
94.729 + return false;
94.730 + input.dropBits(16);
94.731 + mode = DECODE_STORED_LEN2;
94.732 + }
94.733 + /* fall through */
94.734 + case DECODE_STORED_LEN2:
94.735 + {
94.736 + int nlen = input.peekBits(16);
94.737 + if (nlen < 0)
94.738 + return false;
94.739 + input.dropBits(16);
94.740 + if (nlen != (uncomprLen ^ 0xffff))
94.741 + throw new DataFormatException("broken uncompressed block");
94.742 + mode = DECODE_STORED;
94.743 + }
94.744 + /* fall through */
94.745 + case DECODE_STORED:
94.746 + {
94.747 + int more = outputWindow.copyStored(input, uncomprLen);
94.748 + uncomprLen -= more;
94.749 + if (uncomprLen == 0)
94.750 + {
94.751 + mode = DECODE_BLOCKS;
94.752 + return true;
94.753 + }
94.754 + return !input.needsInput();
94.755 + }
94.756 +
94.757 + case DECODE_DYN_HEADER:
94.758 + if (!dynHeader.decode(input))
94.759 + return false;
94.760 + litlenTree = dynHeader.buildLitLenTree();
94.761 + distTree = dynHeader.buildDistTree();
94.762 + mode = DECODE_HUFFMAN;
94.763 + /* fall through */
94.764 + case DECODE_HUFFMAN:
94.765 + case DECODE_HUFFMAN_LENBITS:
94.766 + case DECODE_HUFFMAN_DIST:
94.767 + case DECODE_HUFFMAN_DISTBITS:
94.768 + return decodeHuffman();
94.769 + case FINISHED:
94.770 + return false;
94.771 + default:
94.772 + throw new IllegalStateException();
94.773 + }
94.774 + }
94.775 +
94.776 +
94.777 + interface DeflaterConstants {
94.778 + final static boolean DEBUGGING = false;
94.779 +
94.780 + final static int STORED_BLOCK = 0;
94.781 + final static int STATIC_TREES = 1;
94.782 + final static int DYN_TREES = 2;
94.783 + final static int PRESET_DICT = 0x20;
94.784 +
94.785 + final static int DEFAULT_MEM_LEVEL = 8;
94.786 +
94.787 + final static int MAX_MATCH = 258;
94.788 + final static int MIN_MATCH = 3;
94.789 +
94.790 + final static int MAX_WBITS = 15;
94.791 + final static int WSIZE = 1 << MAX_WBITS;
94.792 + final static int WMASK = WSIZE - 1;
94.793 +
94.794 + final static int HASH_BITS = DEFAULT_MEM_LEVEL + 7;
94.795 + final static int HASH_SIZE = 1 << HASH_BITS;
94.796 + final static int HASH_MASK = HASH_SIZE - 1;
94.797 + final static int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH;
94.798 +
94.799 + final static int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
94.800 + final static int MAX_DIST = WSIZE - MIN_LOOKAHEAD;
94.801 +
94.802 + final static int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8);
94.803 + final static int MAX_BLOCK_SIZE = Math.min(65535, PENDING_BUF_SIZE-5);
94.804 +
94.805 + final static int DEFLATE_STORED = 0;
94.806 + final static int DEFLATE_FAST = 1;
94.807 + final static int DEFLATE_SLOW = 2;
94.808 +
94.809 + final static int GOOD_LENGTH[] = { 0,4, 4, 4, 4, 8, 8, 8, 32, 32 };
94.810 + final static int MAX_LAZY[] = { 0,4, 5, 6, 4,16, 16, 32, 128, 258 };
94.811 + final static int NICE_LENGTH[] = { 0,8,16,32,16,32,128,128, 258, 258 };
94.812 + final static int MAX_CHAIN[] = { 0,4, 8,32,16,32,128,256,1024,4096 };
94.813 + final static int COMPR_FUNC[] = { 0,1, 1, 1, 1, 2, 2, 2, 2, 2 };
94.814 + }
94.815 + private static class InflaterHuffmanTree {
94.816 + private final static int MAX_BITLEN = 15;
94.817 + private short[] tree;
94.818 +
94.819 + public static InflaterHuffmanTree defLitLenTree, defDistTree;
94.820 +
94.821 + static
94.822 + {
94.823 + try
94.824 + {
94.825 + byte[] codeLengths = new byte[288];
94.826 + int i = 0;
94.827 + while (i < 144)
94.828 + codeLengths[i++] = 8;
94.829 + while (i < 256)
94.830 + codeLengths[i++] = 9;
94.831 + while (i < 280)
94.832 + codeLengths[i++] = 7;
94.833 + while (i < 288)
94.834 + codeLengths[i++] = 8;
94.835 + defLitLenTree = new InflaterHuffmanTree(codeLengths);
94.836 +
94.837 + codeLengths = new byte[32];
94.838 + i = 0;
94.839 + while (i < 32)
94.840 + codeLengths[i++] = 5;
94.841 + defDistTree = new InflaterHuffmanTree(codeLengths);
94.842 + }
94.843 + catch (DataFormatException ex)
94.844 + {
94.845 + throw new IllegalStateException
94.846 + ("InflaterHuffmanTree: static tree length illegal");
94.847 + }
94.848 + }
94.849 +
94.850 + /**
94.851 + * Constructs a Huffman tree from the array of code lengths.
94.852 + *
94.853 + * @param codeLengths the array of code lengths
94.854 + */
94.855 + public InflaterHuffmanTree(byte[] codeLengths) throws DataFormatException
94.856 + {
94.857 + buildTree(codeLengths);
94.858 + }
94.859 +
94.860 + private void buildTree(byte[] codeLengths) throws DataFormatException
94.861 + {
94.862 + int[] blCount = new int[MAX_BITLEN+1];
94.863 + int[] nextCode = new int[MAX_BITLEN+1];
94.864 + for (int i = 0; i < codeLengths.length; i++)
94.865 + {
94.866 + int bits = codeLengths[i];
94.867 + if (bits > 0)
94.868 + blCount[bits]++;
94.869 + }
94.870 +
94.871 + int code = 0;
94.872 + int treeSize = 512;
94.873 + for (int bits = 1; bits <= MAX_BITLEN; bits++)
94.874 + {
94.875 + nextCode[bits] = code;
94.876 + code += blCount[bits] << (16 - bits);
94.877 + if (bits >= 10)
94.878 + {
94.879 + /* We need an extra table for bit lengths >= 10. */
94.880 + int start = nextCode[bits] & 0x1ff80;
94.881 + int end = code & 0x1ff80;
94.882 + treeSize += (end - start) >> (16 - bits);
94.883 + }
94.884 + }
94.885 + if (code != 65536)
94.886 + throw new DataFormatException("Code lengths don't add up properly.");
94.887 +
94.888 + /* Now create and fill the extra tables from longest to shortest
94.889 + * bit len. This way the sub trees will be aligned.
94.890 + */
94.891 + tree = new short[treeSize];
94.892 + int treePtr = 512;
94.893 + for (int bits = MAX_BITLEN; bits >= 10; bits--)
94.894 + {
94.895 + int end = code & 0x1ff80;
94.896 + code -= blCount[bits] << (16 - bits);
94.897 + int start = code & 0x1ff80;
94.898 + for (int i = start; i < end; i += 1 << 7)
94.899 + {
94.900 + tree[bitReverse(i)]
94.901 + = (short) ((-treePtr << 4) | bits);
94.902 + treePtr += 1 << (bits-9);
94.903 + }
94.904 + }
94.905 +
94.906 + for (int i = 0; i < codeLengths.length; i++)
94.907 + {
94.908 + int bits = codeLengths[i];
94.909 + if (bits == 0)
94.910 + continue;
94.911 + code = nextCode[bits];
94.912 + int revcode = bitReverse(code);
94.913 + if (bits <= 9)
94.914 + {
94.915 + do
94.916 + {
94.917 + tree[revcode] = (short) ((i << 4) | bits);
94.918 + revcode += 1 << bits;
94.919 + }
94.920 + while (revcode < 512);
94.921 + }
94.922 + else
94.923 + {
94.924 + int subTree = tree[revcode & 511];
94.925 + int treeLen = 1 << (subTree & 15);
94.926 + subTree = -(subTree >> 4);
94.927 + do
94.928 + {
94.929 + tree[subTree | (revcode >> 9)] = (short) ((i << 4) | bits);
94.930 + revcode += 1 << bits;
94.931 + }
94.932 + while (revcode < treeLen);
94.933 + }
94.934 + nextCode[bits] = code + (1 << (16 - bits));
94.935 + }
94.936 + }
94.937 + private final static String bit4Reverse =
94.938 + "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017";
94.939 + static short bitReverse(int value) {
94.940 + return (short) (bit4Reverse.charAt(value & 0xf) << 12
94.941 + | bit4Reverse.charAt((value >> 4) & 0xf) << 8
94.942 + | bit4Reverse.charAt((value >> 8) & 0xf) << 4
94.943 + | bit4Reverse.charAt(value >> 12));
94.944 + }
94.945 +
94.946 + /**
94.947 + * Reads the next symbol from input. The symbol is encoded using the
94.948 + * huffman tree.
94.949 + * @param input the input source.
94.950 + * @return the next symbol, or -1 if not enough input is available.
94.951 + */
94.952 + public int getSymbol(StreamManipulator input) throws DataFormatException
94.953 + {
94.954 + int lookahead, symbol;
94.955 + if ((lookahead = input.peekBits(9)) >= 0)
94.956 + {
94.957 + if ((symbol = tree[lookahead]) >= 0)
94.958 + {
94.959 + input.dropBits(symbol & 15);
94.960 + return symbol >> 4;
94.961 + }
94.962 + int subtree = -(symbol >> 4);
94.963 + int bitlen = symbol & 15;
94.964 + if ((lookahead = input.peekBits(bitlen)) >= 0)
94.965 + {
94.966 + symbol = tree[subtree | (lookahead >> 9)];
94.967 + input.dropBits(symbol & 15);
94.968 + return symbol >> 4;
94.969 + }
94.970 + else
94.971 + {
94.972 + int bits = input.getAvailableBits();
94.973 + lookahead = input.peekBits(bits);
94.974 + symbol = tree[subtree | (lookahead >> 9)];
94.975 + if ((symbol & 15) <= bits)
94.976 + {
94.977 + input.dropBits(symbol & 15);
94.978 + return symbol >> 4;
94.979 + }
94.980 + else
94.981 + return -1;
94.982 + }
94.983 + }
94.984 + else
94.985 + {
94.986 + int bits = input.getAvailableBits();
94.987 + lookahead = input.peekBits(bits);
94.988 + symbol = tree[lookahead];
94.989 + if (symbol >= 0 && (symbol & 15) <= bits)
94.990 + {
94.991 + input.dropBits(symbol & 15);
94.992 + return symbol >> 4;
94.993 + }
94.994 + else
94.995 + return -1;
94.996 + }
94.997 + }
94.998 + }
94.999 + private static class InflaterDynHeader
94.1000 + {
94.1001 + private static final int LNUM = 0;
94.1002 + private static final int DNUM = 1;
94.1003 + private static final int BLNUM = 2;
94.1004 + private static final int BLLENS = 3;
94.1005 + private static final int LENS = 4;
94.1006 + private static final int REPS = 5;
94.1007 +
94.1008 + private static final int repMin[] = { 3, 3, 11 };
94.1009 + private static final int repBits[] = { 2, 3, 7 };
94.1010 +
94.1011 +
94.1012 + private byte[] blLens;
94.1013 + private byte[] litdistLens;
94.1014 +
94.1015 + private InflaterHuffmanTree blTree;
94.1016 +
94.1017 + private int mode;
94.1018 + private int lnum, dnum, blnum, num;
94.1019 + private int repSymbol;
94.1020 + private byte lastLen;
94.1021 + private int ptr;
94.1022 +
94.1023 + private static final int[] BL_ORDER =
94.1024 + { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
94.1025 +
94.1026 + public InflaterDynHeader()
94.1027 + {
94.1028 + }
94.1029 +
94.1030 + public boolean decode(StreamManipulator input) throws DataFormatException
94.1031 + {
94.1032 + decode_loop:
94.1033 + for (;;)
94.1034 + {
94.1035 + switch (mode)
94.1036 + {
94.1037 + case LNUM:
94.1038 + lnum = input.peekBits(5);
94.1039 + if (lnum < 0)
94.1040 + return false;
94.1041 + lnum += 257;
94.1042 + input.dropBits(5);
94.1043 + // System.err.println("LNUM: "+lnum);
94.1044 + mode = DNUM;
94.1045 + /* fall through */
94.1046 + case DNUM:
94.1047 + dnum = input.peekBits(5);
94.1048 + if (dnum < 0)
94.1049 + return false;
94.1050 + dnum++;
94.1051 + input.dropBits(5);
94.1052 + // System.err.println("DNUM: "+dnum);
94.1053 + num = lnum+dnum;
94.1054 + litdistLens = new byte[num];
94.1055 + mode = BLNUM;
94.1056 + /* fall through */
94.1057 + case BLNUM:
94.1058 + blnum = input.peekBits(4);
94.1059 + if (blnum < 0)
94.1060 + return false;
94.1061 + blnum += 4;
94.1062 + input.dropBits(4);
94.1063 + blLens = new byte[19];
94.1064 + ptr = 0;
94.1065 + // System.err.println("BLNUM: "+blnum);
94.1066 + mode = BLLENS;
94.1067 + /* fall through */
94.1068 + case BLLENS:
94.1069 + while (ptr < blnum)
94.1070 + {
94.1071 + int len = input.peekBits(3);
94.1072 + if (len < 0)
94.1073 + return false;
94.1074 + input.dropBits(3);
94.1075 + // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
94.1076 + blLens[BL_ORDER[ptr]] = (byte) len;
94.1077 + ptr++;
94.1078 + }
94.1079 + blTree = new InflaterHuffmanTree(blLens);
94.1080 + blLens = null;
94.1081 + ptr = 0;
94.1082 + mode = LENS;
94.1083 + /* fall through */
94.1084 + case LENS:
94.1085 + {
94.1086 + int symbol;
94.1087 + while (((symbol = blTree.getSymbol(input)) & ~15) == 0)
94.1088 + {
94.1089 + /* Normal case: symbol in [0..15] */
94.1090 +
94.1091 + // System.err.println("litdistLens["+ptr+"]: "+symbol);
94.1092 + litdistLens[ptr++] = lastLen = (byte) symbol;
94.1093 +
94.1094 + if (ptr == num)
94.1095 + {
94.1096 + /* Finished */
94.1097 + return true;
94.1098 + }
94.1099 + }
94.1100 +
94.1101 + /* need more input ? */
94.1102 + if (symbol < 0)
94.1103 + return false;
94.1104 +
94.1105 + /* otherwise repeat code */
94.1106 + if (symbol >= 17)
94.1107 + {
94.1108 + /* repeat zero */
94.1109 + // System.err.println("repeating zero");
94.1110 + lastLen = 0;
94.1111 + }
94.1112 + else
94.1113 + {
94.1114 + if (ptr == 0)
94.1115 + throw new DataFormatException();
94.1116 + }
94.1117 + repSymbol = symbol-16;
94.1118 + mode = REPS;
94.1119 + }
94.1120 + /* fall through */
94.1121 +
94.1122 + case REPS:
94.1123 + {
94.1124 + int bits = repBits[repSymbol];
94.1125 + int count = input.peekBits(bits);
94.1126 + if (count < 0)
94.1127 + return false;
94.1128 + input.dropBits(bits);
94.1129 + count += repMin[repSymbol];
94.1130 + // System.err.println("litdistLens repeated: "+count);
94.1131 +
94.1132 + if (ptr + count > num)
94.1133 + throw new DataFormatException();
94.1134 + while (count-- > 0)
94.1135 + litdistLens[ptr++] = lastLen;
94.1136 +
94.1137 + if (ptr == num)
94.1138 + {
94.1139 + /* Finished */
94.1140 + return true;
94.1141 + }
94.1142 + }
94.1143 + mode = LENS;
94.1144 + continue decode_loop;
94.1145 + }
94.1146 + }
94.1147 + }
94.1148 +
94.1149 + public InflaterHuffmanTree buildLitLenTree() throws DataFormatException
94.1150 + {
94.1151 + byte[] litlenLens = new byte[lnum];
94.1152 + System.arraycopy(litdistLens, 0, litlenLens, 0, lnum);
94.1153 + return new InflaterHuffmanTree(litlenLens);
94.1154 + }
94.1155 +
94.1156 + public InflaterHuffmanTree buildDistTree() throws DataFormatException
94.1157 + {
94.1158 + byte[] distLens = new byte[dnum];
94.1159 + System.arraycopy(litdistLens, lnum, distLens, 0, dnum);
94.1160 + return new InflaterHuffmanTree(distLens);
94.1161 + }
94.1162 + }
94.1163 + /**
94.1164 + * This class allows us to retrieve a specified amount of bits from
94.1165 + * the input buffer, as well as copy big byte blocks.
94.1166 + *
94.1167 + * It uses an int buffer to store up to 31 bits for direct
94.1168 + * manipulation. This guarantees that we can get at least 16 bits,
94.1169 + * but we only need at most 15, so this is all safe.
94.1170 + *
94.1171 + * There are some optimizations in this class, for example, you must
94.1172 + * never peek more then 8 bits more than needed, and you must first
94.1173 + * peek bits before you may drop them. This is not a general purpose
94.1174 + * class but optimized for the behaviour of the Inflater.
94.1175 + *
94.1176 + * @author John Leuner, Jochen Hoenicke
94.1177 + */
94.1178 +
94.1179 + private static class StreamManipulator
94.1180 + {
94.1181 + private byte[] window;
94.1182 + private int window_start = 0;
94.1183 + private int window_end = 0;
94.1184 +
94.1185 + private int buffer = 0;
94.1186 + private int bits_in_buffer = 0;
94.1187 +
94.1188 + /**
94.1189 + * Get the next n bits but don't increase input pointer. n must be
94.1190 + * less or equal 16 and if you if this call succeeds, you must drop
94.1191 + * at least n-8 bits in the next call.
94.1192 + *
94.1193 + * @return the value of the bits, or -1 if not enough bits available. */
94.1194 + public final int peekBits(int n)
94.1195 + {
94.1196 + if (bits_in_buffer < n)
94.1197 + {
94.1198 + if (window_start == window_end)
94.1199 + return -1;
94.1200 + buffer |= (window[window_start++] & 0xff
94.1201 + | (window[window_start++] & 0xff) << 8) << bits_in_buffer;
94.1202 + bits_in_buffer += 16;
94.1203 + }
94.1204 + return buffer & ((1 << n) - 1);
94.1205 + }
94.1206 +
94.1207 + /* Drops the next n bits from the input. You should have called peekBits
94.1208 + * with a bigger or equal n before, to make sure that enough bits are in
94.1209 + * the bit buffer.
94.1210 + */
94.1211 + public final void dropBits(int n)
94.1212 + {
94.1213 + buffer >>>= n;
94.1214 + bits_in_buffer -= n;
94.1215 + }
94.1216 +
94.1217 + /**
94.1218 + * Gets the next n bits and increases input pointer. This is equivalent
94.1219 + * to peekBits followed by dropBits, except for correct error handling.
94.1220 + * @return the value of the bits, or -1 if not enough bits available.
94.1221 + */
94.1222 + public final int getBits(int n)
94.1223 + {
94.1224 + int bits = peekBits(n);
94.1225 + if (bits >= 0)
94.1226 + dropBits(n);
94.1227 + return bits;
94.1228 + }
94.1229 + /**
94.1230 + * Gets the number of bits available in the bit buffer. This must be
94.1231 + * only called when a previous peekBits() returned -1.
94.1232 + * @return the number of bits available.
94.1233 + */
94.1234 + public final int getAvailableBits()
94.1235 + {
94.1236 + return bits_in_buffer;
94.1237 + }
94.1238 +
94.1239 + /**
94.1240 + * Gets the number of bytes available.
94.1241 + * @return the number of bytes available.
94.1242 + */
94.1243 + public final int getAvailableBytes()
94.1244 + {
94.1245 + return window_end - window_start + (bits_in_buffer >> 3);
94.1246 + }
94.1247 +
94.1248 + /**
94.1249 + * Skips to the next byte boundary.
94.1250 + */
94.1251 + public void skipToByteBoundary()
94.1252 + {
94.1253 + buffer >>= (bits_in_buffer & 7);
94.1254 + bits_in_buffer &= ~7;
94.1255 + }
94.1256 +
94.1257 + public final boolean needsInput() {
94.1258 + return window_start == window_end;
94.1259 + }
94.1260 +
94.1261 +
94.1262 + /* Copies length bytes from input buffer to output buffer starting
94.1263 + * at output[offset]. You have to make sure, that the buffer is
94.1264 + * byte aligned. If not enough bytes are available, copies fewer
94.1265 + * bytes.
94.1266 + * @param length the length to copy, 0 is allowed.
94.1267 + * @return the number of bytes copied, 0 if no byte is available.
94.1268 + */
94.1269 + public int copyBytes(byte[] output, int offset, int length)
94.1270 + {
94.1271 + if (length < 0)
94.1272 + throw new IllegalArgumentException("length negative");
94.1273 + if ((bits_in_buffer & 7) != 0)
94.1274 + /* bits_in_buffer may only be 0 or 8 */
94.1275 + throw new IllegalStateException("Bit buffer is not aligned!");
94.1276 +
94.1277 + int count = 0;
94.1278 + while (bits_in_buffer > 0 && length > 0)
94.1279 + {
94.1280 + output[offset++] = (byte) buffer;
94.1281 + buffer >>>= 8;
94.1282 + bits_in_buffer -= 8;
94.1283 + length--;
94.1284 + count++;
94.1285 + }
94.1286 + if (length == 0)
94.1287 + return count;
94.1288 +
94.1289 + int avail = window_end - window_start;
94.1290 + if (length > avail)
94.1291 + length = avail;
94.1292 + System.arraycopy(window, window_start, output, offset, length);
94.1293 + window_start += length;
94.1294 +
94.1295 + if (((window_start - window_end) & 1) != 0)
94.1296 + {
94.1297 + /* We always want an even number of bytes in input, see peekBits */
94.1298 + buffer = (window[window_start++] & 0xff);
94.1299 + bits_in_buffer = 8;
94.1300 + }
94.1301 + return count + length;
94.1302 + }
94.1303 +
94.1304 + public StreamManipulator()
94.1305 + {
94.1306 + }
94.1307 +
94.1308 + public void reset()
94.1309 + {
94.1310 + window_start = window_end = buffer = bits_in_buffer = 0;
94.1311 + }
94.1312 +
94.1313 + public void setInput(byte[] buf, int off, int len)
94.1314 + {
94.1315 + if (window_start < window_end)
94.1316 + throw new IllegalStateException
94.1317 + ("Old input was not completely processed");
94.1318 +
94.1319 + int end = off + len;
94.1320 +
94.1321 + /* We want to throw an ArrayIndexOutOfBoundsException early. The
94.1322 + * check is very tricky: it also handles integer wrap around.
94.1323 + */
94.1324 + if (0 > off || off > end || end > buf.length)
94.1325 + throw new ArrayIndexOutOfBoundsException();
94.1326 +
94.1327 + if ((len & 1) != 0)
94.1328 + {
94.1329 + /* We always want an even number of bytes in input, see peekBits */
94.1330 + buffer |= (buf[off++] & 0xff) << bits_in_buffer;
94.1331 + bits_in_buffer += 8;
94.1332 + }
94.1333 +
94.1334 + window = buf;
94.1335 + window_start = off;
94.1336 + window_end = end;
94.1337 + }
94.1338 + }
94.1339 + /*
94.1340 + * Contains the output from the Inflation process.
94.1341 + *
94.1342 + * We need to have a window so that we can refer backwards into the output stream
94.1343 + * to repeat stuff.
94.1344 + *
94.1345 + * @author John Leuner
94.1346 + * @since JDK 1.1
94.1347 + */
94.1348 +
94.1349 + private static class OutputWindow
94.1350 + {
94.1351 + private final int WINDOW_SIZE = 1 << 15;
94.1352 + private final int WINDOW_MASK = WINDOW_SIZE - 1;
94.1353 +
94.1354 + private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
94.1355 + private int window_end = 0;
94.1356 + private int window_filled = 0;
94.1357 +
94.1358 + public void write(int abyte)
94.1359 + {
94.1360 + if (window_filled++ == WINDOW_SIZE)
94.1361 + throw new IllegalStateException("Window full");
94.1362 + window[window_end++] = (byte) abyte;
94.1363 + window_end &= WINDOW_MASK;
94.1364 + }
94.1365 +
94.1366 +
94.1367 + private final void slowRepeat(int rep_start, int len, int dist)
94.1368 + {
94.1369 + while (len-- > 0)
94.1370 + {
94.1371 + window[window_end++] = window[rep_start++];
94.1372 + window_end &= WINDOW_MASK;
94.1373 + rep_start &= WINDOW_MASK;
94.1374 + }
94.1375 + }
94.1376 +
94.1377 + public void repeat(int len, int dist)
94.1378 + {
94.1379 + if ((window_filled += len) > WINDOW_SIZE)
94.1380 + throw new IllegalStateException("Window full");
94.1381 +
94.1382 + int rep_start = (window_end - dist) & WINDOW_MASK;
94.1383 + int border = WINDOW_SIZE - len;
94.1384 + if (rep_start <= border && window_end < border)
94.1385 + {
94.1386 + if (len <= dist)
94.1387 + {
94.1388 + System.arraycopy(window, rep_start, window, window_end, len);
94.1389 + window_end += len;
94.1390 + }
94.1391 + else
94.1392 + {
94.1393 + /* We have to copy manually, since the repeat pattern overlaps.
94.1394 + */
94.1395 + while (len-- > 0)
94.1396 + window[window_end++] = window[rep_start++];
94.1397 + }
94.1398 + }
94.1399 + else
94.1400 + slowRepeat(rep_start, len, dist);
94.1401 + }
94.1402 +
94.1403 + public int copyStored(StreamManipulator input, int len)
94.1404 + {
94.1405 + len = Math.min(Math.min(len, WINDOW_SIZE - window_filled),
94.1406 + input.getAvailableBytes());
94.1407 + int copied;
94.1408 +
94.1409 + int tailLen = WINDOW_SIZE - window_end;
94.1410 + if (len > tailLen)
94.1411 + {
94.1412 + copied = input.copyBytes(window, window_end, tailLen);
94.1413 + if (copied == tailLen)
94.1414 + copied += input.copyBytes(window, 0, len - tailLen);
94.1415 + }
94.1416 + else
94.1417 + copied = input.copyBytes(window, window_end, len);
94.1418 +
94.1419 + window_end = (window_end + copied) & WINDOW_MASK;
94.1420 + window_filled += copied;
94.1421 + return copied;
94.1422 + }
94.1423 +
94.1424 + public void copyDict(byte[] dict, int offset, int len)
94.1425 + {
94.1426 + if (window_filled > 0)
94.1427 + throw new IllegalStateException();
94.1428 +
94.1429 + if (len > WINDOW_SIZE)
94.1430 + {
94.1431 + offset += len - WINDOW_SIZE;
94.1432 + len = WINDOW_SIZE;
94.1433 + }
94.1434 + System.arraycopy(dict, offset, window, 0, len);
94.1435 + window_end = len & WINDOW_MASK;
94.1436 + }
94.1437 +
94.1438 + public int getFreeSpace()
94.1439 + {
94.1440 + return WINDOW_SIZE - window_filled;
94.1441 + }
94.1442 +
94.1443 + public int getAvailable()
94.1444 + {
94.1445 + return window_filled;
94.1446 + }
94.1447 +
94.1448 + public int copyOutput(byte[] output, int offset, int len)
94.1449 + {
94.1450 + int copy_end = window_end;
94.1451 + if (len > window_filled)
94.1452 + len = window_filled;
94.1453 + else
94.1454 + copy_end = (window_end - window_filled + len) & WINDOW_MASK;
94.1455 +
94.1456 + int copied = len;
94.1457 + int tailLen = len - copy_end;
94.1458 +
94.1459 + if (tailLen > 0)
94.1460 + {
94.1461 + System.arraycopy(window, WINDOW_SIZE - tailLen,
94.1462 + output, offset, tailLen);
94.1463 + offset += tailLen;
94.1464 + len = copy_end;
94.1465 + }
94.1466 + System.arraycopy(window, copy_end - len, output, offset, len);
94.1467 + window_filled -= copied;
94.1468 + if (window_filled < 0)
94.1469 + throw new IllegalStateException();
94.1470 + return copied;
94.1471 + }
94.1472 +
94.1473 + public void reset() {
94.1474 + window_filled = window_end = 0;
94.1475 + }
94.1476 + }
94.1477 +
94.1478 +}
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/emul/mini/src/main/java/java/util/zip/InflaterInputStream.java Tue Feb 05 17:04:22 2013 +0100
95.3 @@ -0,0 +1,288 @@
95.4 +/*
95.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
95.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
95.7 + *
95.8 + * This code is free software; you can redistribute it and/or modify it
95.9 + * under the terms of the GNU General Public License version 2 only, as
95.10 + * published by the Free Software Foundation. Oracle designates this
95.11 + * particular file as subject to the "Classpath" exception as provided
95.12 + * by Oracle in the LICENSE file that accompanied this code.
95.13 + *
95.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
95.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
95.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
95.17 + * version 2 for more details (a copy is included in the LICENSE file that
95.18 + * accompanied this code).
95.19 + *
95.20 + * You should have received a copy of the GNU General Public License version
95.21 + * 2 along with this work; if not, write to the Free Software Foundation,
95.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
95.23 + *
95.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
95.25 + * or visit www.oracle.com if you need additional information or have any
95.26 + * questions.
95.27 + */
95.28 +
95.29 +package java.util.zip;
95.30 +
95.31 +import java.io.FilterInputStream;
95.32 +import java.io.InputStream;
95.33 +import java.io.IOException;
95.34 +import java.io.EOFException;
95.35 +
95.36 +/**
95.37 + * This class implements a stream filter for uncompressing data in the
95.38 + * "deflate" compression format. It is also used as the basis for other
95.39 + * decompression filters, such as GZIPInputStream.
95.40 + *
95.41 + * @see Inflater
95.42 + * @author David Connelly
95.43 + */
95.44 +public
95.45 +class InflaterInputStream extends FilterInputStream {
95.46 + /**
95.47 + * Decompressor for this stream.
95.48 + */
95.49 + protected Inflater inf;
95.50 +
95.51 + /**
95.52 + * Input buffer for decompression.
95.53 + */
95.54 + protected byte[] buf;
95.55 +
95.56 + /**
95.57 + * Length of input buffer.
95.58 + */
95.59 + protected int len;
95.60 +
95.61 + private boolean closed = false;
95.62 + // this flag is set to true after EOF has reached
95.63 + private boolean reachEOF = false;
95.64 +
95.65 + /**
95.66 + * Check to make sure that this stream has not been closed
95.67 + */
95.68 + private void ensureOpen() throws IOException {
95.69 + if (closed) {
95.70 + throw new IOException("Stream closed");
95.71 + }
95.72 + }
95.73 +
95.74 +
95.75 + /**
95.76 + * Creates a new input stream with the specified decompressor and
95.77 + * buffer size.
95.78 + * @param in the input stream
95.79 + * @param inf the decompressor ("inflater")
95.80 + * @param size the input buffer size
95.81 + * @exception IllegalArgumentException if size is <= 0
95.82 + */
95.83 + public InflaterInputStream(InputStream in, Inflater inf, int size) {
95.84 + super(in);
95.85 + if (in == null || inf == null) {
95.86 + throw new NullPointerException();
95.87 + } else if (size <= 0) {
95.88 + throw new IllegalArgumentException("buffer size <= 0");
95.89 + }
95.90 + this.inf = inf;
95.91 + buf = new byte[size];
95.92 + }
95.93 +
95.94 + /**
95.95 + * Creates a new input stream with the specified decompressor and a
95.96 + * default buffer size.
95.97 + * @param in the input stream
95.98 + * @param inf the decompressor ("inflater")
95.99 + */
95.100 + public InflaterInputStream(InputStream in, Inflater inf) {
95.101 + this(in, inf, 512);
95.102 + }
95.103 +
95.104 + boolean usesDefaultInflater = false;
95.105 +
95.106 + /**
95.107 + * Creates a new input stream with a default decompressor and buffer size.
95.108 + * @param in the input stream
95.109 + */
95.110 + public InflaterInputStream(InputStream in) {
95.111 + this(in, new Inflater());
95.112 + usesDefaultInflater = true;
95.113 + }
95.114 +
95.115 + private byte[] singleByteBuf = new byte[1];
95.116 +
95.117 + /**
95.118 + * Reads a byte of uncompressed data. This method will block until
95.119 + * enough input is available for decompression.
95.120 + * @return the byte read, or -1 if end of compressed input is reached
95.121 + * @exception IOException if an I/O error has occurred
95.122 + */
95.123 + public int read() throws IOException {
95.124 + ensureOpen();
95.125 + return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff;
95.126 + }
95.127 +
95.128 + /**
95.129 + * Reads uncompressed data into an array of bytes. If <code>len</code> is not
95.130 + * zero, the method will block until some input can be decompressed; otherwise,
95.131 + * no bytes are read and <code>0</code> is returned.
95.132 + * @param b the buffer into which the data is read
95.133 + * @param off the start offset in the destination array <code>b</code>
95.134 + * @param len the maximum number of bytes read
95.135 + * @return the actual number of bytes read, or -1 if the end of the
95.136 + * compressed input is reached or a preset dictionary is needed
95.137 + * @exception NullPointerException If <code>b</code> is <code>null</code>.
95.138 + * @exception IndexOutOfBoundsException If <code>off</code> is negative,
95.139 + * <code>len</code> is negative, or <code>len</code> is greater than
95.140 + * <code>b.length - off</code>
95.141 + * @exception ZipException if a ZIP format error has occurred
95.142 + * @exception IOException if an I/O error has occurred
95.143 + */
95.144 + public int read(byte[] b, int off, int len) throws IOException {
95.145 + ensureOpen();
95.146 + if (b == null) {
95.147 + throw new NullPointerException();
95.148 + } else if (off < 0 || len < 0 || len > b.length - off) {
95.149 + throw new IndexOutOfBoundsException();
95.150 + } else if (len == 0) {
95.151 + return 0;
95.152 + }
95.153 + try {
95.154 + int n;
95.155 + while ((n = inf.inflate(b, off, len)) == 0) {
95.156 + if (inf.finished() || inf.needsDictionary()) {
95.157 + reachEOF = true;
95.158 + return -1;
95.159 + }
95.160 + if (inf.needsInput()) {
95.161 + fill();
95.162 + }
95.163 + }
95.164 + return n;
95.165 + } catch (DataFormatException e) {
95.166 + String s = e.getMessage();
95.167 + throw new ZipException(s != null ? s : "Invalid ZLIB data format");
95.168 + }
95.169 + }
95.170 +
95.171 + /**
95.172 + * Returns 0 after EOF has been reached, otherwise always return 1.
95.173 + * <p>
95.174 + * Programs should not count on this method to return the actual number
95.175 + * of bytes that could be read without blocking.
95.176 + *
95.177 + * @return 1 before EOF and 0 after EOF.
95.178 + * @exception IOException if an I/O error occurs.
95.179 + *
95.180 + */
95.181 + public int available() throws IOException {
95.182 + ensureOpen();
95.183 + if (reachEOF) {
95.184 + return 0;
95.185 + } else {
95.186 + return 1;
95.187 + }
95.188 + }
95.189 +
95.190 + private byte[] b = new byte[512];
95.191 +
95.192 + /**
95.193 + * Skips specified number of bytes of uncompressed data.
95.194 + * @param n the number of bytes to skip
95.195 + * @return the actual number of bytes skipped.
95.196 + * @exception IOException if an I/O error has occurred
95.197 + * @exception IllegalArgumentException if n < 0
95.198 + */
95.199 + public long skip(long n) throws IOException {
95.200 + if (n < 0) {
95.201 + throw new IllegalArgumentException("negative skip length");
95.202 + }
95.203 + ensureOpen();
95.204 + int max = (int)Math.min(n, Integer.MAX_VALUE);
95.205 + int total = 0;
95.206 + while (total < max) {
95.207 + int len = max - total;
95.208 + if (len > b.length) {
95.209 + len = b.length;
95.210 + }
95.211 + len = read(b, 0, len);
95.212 + if (len == -1) {
95.213 + reachEOF = true;
95.214 + break;
95.215 + }
95.216 + total += len;
95.217 + }
95.218 + return total;
95.219 + }
95.220 +
95.221 + /**
95.222 + * Closes this input stream and releases any system resources associated
95.223 + * with the stream.
95.224 + * @exception IOException if an I/O error has occurred
95.225 + */
95.226 + public void close() throws IOException {
95.227 + if (!closed) {
95.228 + if (usesDefaultInflater)
95.229 + inf.end();
95.230 + in.close();
95.231 + closed = true;
95.232 + }
95.233 + }
95.234 +
95.235 + /**
95.236 + * Fills input buffer with more data to decompress.
95.237 + * @exception IOException if an I/O error has occurred
95.238 + */
95.239 + protected void fill() throws IOException {
95.240 + ensureOpen();
95.241 + len = in.read(buf, 0, buf.length);
95.242 + if (len == -1) {
95.243 + throw new EOFException("Unexpected end of ZLIB input stream");
95.244 + }
95.245 + inf.setInput(buf, 0, len);
95.246 + }
95.247 +
95.248 + /**
95.249 + * Tests if this input stream supports the <code>mark</code> and
95.250 + * <code>reset</code> methods. The <code>markSupported</code>
95.251 + * method of <code>InflaterInputStream</code> returns
95.252 + * <code>false</code>.
95.253 + *
95.254 + * @return a <code>boolean</code> indicating if this stream type supports
95.255 + * the <code>mark</code> and <code>reset</code> methods.
95.256 + * @see java.io.InputStream#mark(int)
95.257 + * @see java.io.InputStream#reset()
95.258 + */
95.259 + public boolean markSupported() {
95.260 + return false;
95.261 + }
95.262 +
95.263 + /**
95.264 + * Marks the current position in this input stream.
95.265 + *
95.266 + * <p> The <code>mark</code> method of <code>InflaterInputStream</code>
95.267 + * does nothing.
95.268 + *
95.269 + * @param readlimit the maximum limit of bytes that can be read before
95.270 + * the mark position becomes invalid.
95.271 + * @see java.io.InputStream#reset()
95.272 + */
95.273 + public synchronized void mark(int readlimit) {
95.274 + }
95.275 +
95.276 + /**
95.277 + * Repositions this stream to the position at the time the
95.278 + * <code>mark</code> method was last called on this input stream.
95.279 + *
95.280 + * <p> The method <code>reset</code> for class
95.281 + * <code>InflaterInputStream</code> does nothing except throw an
95.282 + * <code>IOException</code>.
95.283 + *
95.284 + * @exception IOException if this method is invoked.
95.285 + * @see java.io.InputStream#mark(int)
95.286 + * @see java.io.IOException
95.287 + */
95.288 + public synchronized void reset() throws IOException {
95.289 + throw new IOException("mark/reset not supported");
95.290 + }
95.291 +}
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/emul/mini/src/main/java/java/util/zip/ZStreamRef.java Tue Feb 05 17:04:22 2013 +0100
96.3 @@ -0,0 +1,46 @@
96.4 +/*
96.5 + * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
96.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
96.7 + *
96.8 + * This code is free software; you can redistribute it and/or modify it
96.9 + * under the terms of the GNU General Public License version 2 only, as
96.10 + * published by the Free Software Foundation. Oracle designates this
96.11 + * particular file as subject to the "Classpath" exception as provided
96.12 + * by Oracle in the LICENSE file that accompanied this code.
96.13 + *
96.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
96.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
96.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
96.17 + * version 2 for more details (a copy is included in the LICENSE file that
96.18 + * accompanied this code).
96.19 + *
96.20 + * You should have received a copy of the GNU General Public License version
96.21 + * 2 along with this work; if not, write to the Free Software Foundation,
96.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
96.23 + *
96.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
96.25 + * or visit www.oracle.com if you need additional information or have any
96.26 + * questions.
96.27 + */
96.28 +
96.29 +package java.util.zip;
96.30 +
96.31 +/**
96.32 + * A reference to the native zlib's z_stream structure.
96.33 + */
96.34 +
96.35 +class ZStreamRef {
96.36 +
96.37 + private long address;
96.38 + ZStreamRef (long address) {
96.39 + this.address = address;
96.40 + }
96.41 +
96.42 + long address() {
96.43 + return address;
96.44 + }
96.45 +
96.46 + void clear() {
96.47 + address = 0;
96.48 + }
96.49 +}
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipConstants.java Tue Feb 05 17:04:22 2013 +0100
97.3 @@ -0,0 +1,98 @@
97.4 +/*
97.5 + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
97.7 + *
97.8 + * This code is free software; you can redistribute it and/or modify it
97.9 + * under the terms of the GNU General Public License version 2 only, as
97.10 + * published by the Free Software Foundation. Oracle designates this
97.11 + * particular file as subject to the "Classpath" exception as provided
97.12 + * by Oracle in the LICENSE file that accompanied this code.
97.13 + *
97.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
97.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
97.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
97.17 + * version 2 for more details (a copy is included in the LICENSE file that
97.18 + * accompanied this code).
97.19 + *
97.20 + * You should have received a copy of the GNU General Public License version
97.21 + * 2 along with this work; if not, write to the Free Software Foundation,
97.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
97.23 + *
97.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
97.25 + * or visit www.oracle.com if you need additional information or have any
97.26 + * questions.
97.27 + */
97.28 +
97.29 +package java.util.zip;
97.30 +
97.31 +/*
97.32 + * This interface defines the constants that are used by the classes
97.33 + * which manipulate ZIP files.
97.34 + *
97.35 + * @author David Connelly
97.36 + */
97.37 +interface ZipConstants {
97.38 + /*
97.39 + * Header signatures
97.40 + */
97.41 + static long LOCSIG = 0x04034b50L; // "PK\003\004"
97.42 + static long EXTSIG = 0x08074b50L; // "PK\007\008"
97.43 + static long CENSIG = 0x02014b50L; // "PK\001\002"
97.44 + static long ENDSIG = 0x06054b50L; // "PK\005\006"
97.45 +
97.46 + /*
97.47 + * Header sizes in bytes (including signatures)
97.48 + */
97.49 + static final int LOCHDR = 30; // LOC header size
97.50 + static final int EXTHDR = 16; // EXT header size
97.51 + static final int CENHDR = 46; // CEN header size
97.52 + static final int ENDHDR = 22; // END header size
97.53 +
97.54 + /*
97.55 + * Local file (LOC) header field offsets
97.56 + */
97.57 + static final int LOCVER = 4; // version needed to extract
97.58 + static final int LOCFLG = 6; // general purpose bit flag
97.59 + static final int LOCHOW = 8; // compression method
97.60 + static final int LOCTIM = 10; // modification time
97.61 + static final int LOCCRC = 14; // uncompressed file crc-32 value
97.62 + static final int LOCSIZ = 18; // compressed size
97.63 + static final int LOCLEN = 22; // uncompressed size
97.64 + static final int LOCNAM = 26; // filename length
97.65 + static final int LOCEXT = 28; // extra field length
97.66 +
97.67 + /*
97.68 + * Extra local (EXT) header field offsets
97.69 + */
97.70 + static final int EXTCRC = 4; // uncompressed file crc-32 value
97.71 + static final int EXTSIZ = 8; // compressed size
97.72 + static final int EXTLEN = 12; // uncompressed size
97.73 +
97.74 + /*
97.75 + * Central directory (CEN) header field offsets
97.76 + */
97.77 + static final int CENVEM = 4; // version made by
97.78 + static final int CENVER = 6; // version needed to extract
97.79 + static final int CENFLG = 8; // encrypt, decrypt flags
97.80 + static final int CENHOW = 10; // compression method
97.81 + static final int CENTIM = 12; // modification time
97.82 + static final int CENCRC = 16; // uncompressed file crc-32 value
97.83 + static final int CENSIZ = 20; // compressed size
97.84 + static final int CENLEN = 24; // uncompressed size
97.85 + static final int CENNAM = 28; // filename length
97.86 + static final int CENEXT = 30; // extra field length
97.87 + static final int CENCOM = 32; // comment length
97.88 + static final int CENDSK = 34; // disk number start
97.89 + static final int CENATT = 36; // internal file attributes
97.90 + static final int CENATX = 38; // external file attributes
97.91 + static final int CENOFF = 42; // LOC header offset
97.92 +
97.93 + /*
97.94 + * End of central directory (END) header field offsets
97.95 + */
97.96 + static final int ENDSUB = 8; // number of entries on this disk
97.97 + static final int ENDTOT = 10; // total number of entries
97.98 + static final int ENDSIZ = 12; // central directory size in bytes
97.99 + static final int ENDOFF = 16; // offset of first CEN header
97.100 + static final int ENDCOM = 20; // zip file comment length
97.101 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipConstants64.java Tue Feb 05 17:04:22 2013 +0100
98.3 @@ -0,0 +1,84 @@
98.4 +/*
98.5 + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
98.7 + *
98.8 + * This code is free software; you can redistribute it and/or modify it
98.9 + * under the terms of the GNU General Public License version 2 only, as
98.10 + * published by the Free Software Foundation. Oracle designates this
98.11 + * particular file as subject to the "Classpath" exception as provided
98.12 + * by Oracle in the LICENSE file that accompanied this code.
98.13 + *
98.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
98.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
98.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
98.17 + * version 2 for more details (a copy is included in the LICENSE file that
98.18 + * accompanied this code).
98.19 + *
98.20 + * You should have received a copy of the GNU General Public License version
98.21 + * 2 along with this work; if not, write to the Free Software Foundation,
98.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
98.23 + *
98.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
98.25 + * or visit www.oracle.com if you need additional information or have any
98.26 + * questions.
98.27 + */
98.28 +
98.29 +package java.util.zip;
98.30 +
98.31 +/*
98.32 + * This class defines the constants that are used by the classes
98.33 + * which manipulate Zip64 files.
98.34 + */
98.35 +
98.36 +class ZipConstants64 {
98.37 +
98.38 + /*
98.39 + * ZIP64 constants
98.40 + */
98.41 + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
98.42 + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
98.43 + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
98.44 + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
98.45 + static final int ZIP64_EXTHDR = 24; // EXT header size
98.46 + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
98.47 +
98.48 + static final int ZIP64_MAGICCOUNT = 0xFFFF;
98.49 + static final long ZIP64_MAGICVAL = 0xFFFFFFFFL;
98.50 +
98.51 + /*
98.52 + * Zip64 End of central directory (END) header field offsets
98.53 + */
98.54 + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
98.55 + static final int ZIP64_ENDVEM = 12; // version made by
98.56 + static final int ZIP64_ENDVER = 14; // version needed to extract
98.57 + static final int ZIP64_ENDNMD = 16; // number of this disk
98.58 + static final int ZIP64_ENDDSK = 20; // disk number of start
98.59 + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
98.60 + static final int ZIP64_ENDTOT = 32; // total number of entries
98.61 + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
98.62 + static final int ZIP64_ENDOFF = 48; // offset of first CEN header
98.63 + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
98.64 +
98.65 + /*
98.66 + * Zip64 End of central directory locator field offsets
98.67 + */
98.68 + static final int ZIP64_LOCDSK = 4; // disk number start
98.69 + static final int ZIP64_LOCOFF = 8; // offset of zip64 end
98.70 + static final int ZIP64_LOCTOT = 16; // total number of disks
98.71 +
98.72 + /*
98.73 + * Zip64 Extra local (EXT) header field offsets
98.74 + */
98.75 + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
98.76 + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
98.77 + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
98.78 +
98.79 + /*
98.80 + * Language encoding flag EFS
98.81 + */
98.82 + static final int EFS = 0x800; // If this bit is set the filename and
98.83 + // comment fields for this file must be
98.84 + // encoded using UTF-8.
98.85 +
98.86 + private ZipConstants64() {}
98.87 +}
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipEntry.java Tue Feb 05 17:04:22 2013 +0100
99.3 @@ -0,0 +1,331 @@
99.4 +/*
99.5 + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
99.7 + *
99.8 + * This code is free software; you can redistribute it and/or modify it
99.9 + * under the terms of the GNU General Public License version 2 only, as
99.10 + * published by the Free Software Foundation. Oracle designates this
99.11 + * particular file as subject to the "Classpath" exception as provided
99.12 + * by Oracle in the LICENSE file that accompanied this code.
99.13 + *
99.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
99.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
99.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
99.17 + * version 2 for more details (a copy is included in the LICENSE file that
99.18 + * accompanied this code).
99.19 + *
99.20 + * You should have received a copy of the GNU General Public License version
99.21 + * 2 along with this work; if not, write to the Free Software Foundation,
99.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
99.23 + *
99.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
99.25 + * or visit www.oracle.com if you need additional information or have any
99.26 + * questions.
99.27 + */
99.28 +
99.29 +package java.util.zip;
99.30 +
99.31 +/**
99.32 + * This class is used to represent a ZIP file entry.
99.33 + *
99.34 + * @author David Connelly
99.35 + */
99.36 +public
99.37 +class ZipEntry implements ZipConstants, Cloneable {
99.38 + String name; // entry name
99.39 + long time = -1; // modification time (in DOS time)
99.40 + long crc = -1; // crc-32 of entry data
99.41 + long size = -1; // uncompressed size of entry data
99.42 + long csize = -1; // compressed size of entry data
99.43 + int method = -1; // compression method
99.44 + int flag = 0; // general purpose flag
99.45 + byte[] extra; // optional extra field data for entry
99.46 + String comment; // optional comment string for entry
99.47 +
99.48 + /**
99.49 + * Compression method for uncompressed entries.
99.50 + */
99.51 + public static final int STORED = 0;
99.52 +
99.53 + /**
99.54 + * Compression method for compressed (deflated) entries.
99.55 + */
99.56 + public static final int DEFLATED = 8;
99.57 +
99.58 + /**
99.59 + * Creates a new zip entry with the specified name.
99.60 + *
99.61 + * @param name the entry name
99.62 + * @exception NullPointerException if the entry name is null
99.63 + * @exception IllegalArgumentException if the entry name is longer than
99.64 + * 0xFFFF bytes
99.65 + */
99.66 + public ZipEntry(String name) {
99.67 + if (name == null) {
99.68 + throw new NullPointerException();
99.69 + }
99.70 + if (name.length() > 0xFFFF) {
99.71 + throw new IllegalArgumentException("entry name too long");
99.72 + }
99.73 + this.name = name;
99.74 + }
99.75 +
99.76 + /**
99.77 + * Creates a new zip entry with fields taken from the specified
99.78 + * zip entry.
99.79 + * @param e a zip Entry object
99.80 + */
99.81 + public ZipEntry(ZipEntry e) {
99.82 + name = e.name;
99.83 + time = e.time;
99.84 + crc = e.crc;
99.85 + size = e.size;
99.86 + csize = e.csize;
99.87 + method = e.method;
99.88 + flag = e.flag;
99.89 + extra = e.extra;
99.90 + comment = e.comment;
99.91 + }
99.92 +
99.93 + /*
99.94 + * Creates a new un-initialized zip entry
99.95 + */
99.96 + ZipEntry() {}
99.97 +
99.98 + /**
99.99 + * Returns the name of the entry.
99.100 + * @return the name of the entry
99.101 + */
99.102 + public String getName() {
99.103 + return name;
99.104 + }
99.105 +
99.106 + /**
99.107 + * Sets the modification time of the entry.
99.108 + * @param time the entry modification time in number of milliseconds
99.109 + * since the epoch
99.110 + * @see #getTime()
99.111 + */
99.112 + public void setTime(long time) {
99.113 + this.time = javaToDosTime(time);
99.114 + }
99.115 +
99.116 + /**
99.117 + * Returns the modification time of the entry, or -1 if not specified.
99.118 + * @return the modification time of the entry, or -1 if not specified
99.119 + * @see #setTime(long)
99.120 + */
99.121 + public long getTime() {
99.122 + return time != -1 ? dosToJavaTime(time) : -1;
99.123 + }
99.124 +
99.125 + /**
99.126 + * Sets the uncompressed size of the entry data.
99.127 + * @param size the uncompressed size in bytes
99.128 + * @exception IllegalArgumentException if the specified size is less
99.129 + * than 0, is greater than 0xFFFFFFFF when
99.130 + * <a href="package-summary.html#zip64">ZIP64 format</a> is not supported,
99.131 + * or is less than 0 when ZIP64 is supported
99.132 + * @see #getSize()
99.133 + */
99.134 + public void setSize(long size) {
99.135 + if (size < 0) {
99.136 + throw new IllegalArgumentException("invalid entry size");
99.137 + }
99.138 + this.size = size;
99.139 + }
99.140 +
99.141 + /**
99.142 + * Returns the uncompressed size of the entry data, or -1 if not known.
99.143 + * @return the uncompressed size of the entry data, or -1 if not known
99.144 + * @see #setSize(long)
99.145 + */
99.146 + public long getSize() {
99.147 + return size;
99.148 + }
99.149 +
99.150 + /**
99.151 + * Returns the size of the compressed entry data, or -1 if not known.
99.152 + * In the case of a stored entry, the compressed size will be the same
99.153 + * as the uncompressed size of the entry.
99.154 + * @return the size of the compressed entry data, or -1 if not known
99.155 + * @see #setCompressedSize(long)
99.156 + */
99.157 + public long getCompressedSize() {
99.158 + return csize;
99.159 + }
99.160 +
99.161 + /**
99.162 + * Sets the size of the compressed entry data.
99.163 + * @param csize the compressed size to set to
99.164 + * @see #getCompressedSize()
99.165 + */
99.166 + public void setCompressedSize(long csize) {
99.167 + this.csize = csize;
99.168 + }
99.169 +
99.170 + /**
99.171 + * Sets the CRC-32 checksum of the uncompressed entry data.
99.172 + * @param crc the CRC-32 value
99.173 + * @exception IllegalArgumentException if the specified CRC-32 value is
99.174 + * less than 0 or greater than 0xFFFFFFFF
99.175 + * @see #getCrc()
99.176 + */
99.177 + public void setCrc(long crc) {
99.178 + if (crc < 0 || crc > 0xFFFFFFFFL) {
99.179 + throw new IllegalArgumentException("invalid entry crc-32");
99.180 + }
99.181 + this.crc = crc;
99.182 + }
99.183 +
99.184 + /**
99.185 + * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if
99.186 + * not known.
99.187 + * @return the CRC-32 checksum of the uncompressed entry data, or -1 if
99.188 + * not known
99.189 + * @see #setCrc(long)
99.190 + */
99.191 + public long getCrc() {
99.192 + return crc;
99.193 + }
99.194 +
99.195 + /**
99.196 + * Sets the compression method for the entry.
99.197 + * @param method the compression method, either STORED or DEFLATED
99.198 + * @exception IllegalArgumentException if the specified compression
99.199 + * method is invalid
99.200 + * @see #getMethod()
99.201 + */
99.202 + public void setMethod(int method) {
99.203 + if (method != STORED && method != DEFLATED) {
99.204 + throw new IllegalArgumentException("invalid compression method");
99.205 + }
99.206 + this.method = method;
99.207 + }
99.208 +
99.209 + /**
99.210 + * Returns the compression method of the entry, or -1 if not specified.
99.211 + * @return the compression method of the entry, or -1 if not specified
99.212 + * @see #setMethod(int)
99.213 + */
99.214 + public int getMethod() {
99.215 + return method;
99.216 + }
99.217 +
99.218 + /**
99.219 + * Sets the optional extra field data for the entry.
99.220 + * @param extra the extra field data bytes
99.221 + * @exception IllegalArgumentException if the length of the specified
99.222 + * extra field data is greater than 0xFFFF bytes
99.223 + * @see #getExtra()
99.224 + */
99.225 + public void setExtra(byte[] extra) {
99.226 + if (extra != null && extra.length > 0xFFFF) {
99.227 + throw new IllegalArgumentException("invalid extra field length");
99.228 + }
99.229 + this.extra = extra;
99.230 + }
99.231 +
99.232 + /**
99.233 + * Returns the extra field data for the entry, or null if none.
99.234 + * @return the extra field data for the entry, or null if none
99.235 + * @see #setExtra(byte[])
99.236 + */
99.237 + public byte[] getExtra() {
99.238 + return extra;
99.239 + }
99.240 +
99.241 + /**
99.242 + * Sets the optional comment string for the entry.
99.243 + *
99.244 + * <p>ZIP entry comments have maximum length of 0xffff. If the length of the
99.245 + * specified comment string is greater than 0xFFFF bytes after encoding, only
99.246 + * the first 0xFFFF bytes are output to the ZIP file entry.
99.247 + *
99.248 + * @param comment the comment string
99.249 + *
99.250 + * @see #getComment()
99.251 + */
99.252 + public void setComment(String comment) {
99.253 + this.comment = comment;
99.254 + }
99.255 +
99.256 + /**
99.257 + * Returns the comment string for the entry, or null if none.
99.258 + * @return the comment string for the entry, or null if none
99.259 + * @see #setComment(String)
99.260 + */
99.261 + public String getComment() {
99.262 + return comment;
99.263 + }
99.264 +
99.265 + /**
99.266 + * Returns true if this is a directory entry. A directory entry is
99.267 + * defined to be one whose name ends with a '/'.
99.268 + * @return true if this is a directory entry
99.269 + */
99.270 + public boolean isDirectory() {
99.271 + return name.endsWith("/");
99.272 + }
99.273 +
99.274 + /**
99.275 + * Returns a string representation of the ZIP entry.
99.276 + */
99.277 + public String toString() {
99.278 + return getName();
99.279 + }
99.280 +
99.281 + /*
99.282 + * Converts DOS time to Java time (number of milliseconds since epoch).
99.283 + */
99.284 + private static long dosToJavaTime(long dtime) {
99.285 + return dtime;
99.286 + /* XXX:
99.287 + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
99.288 + (int)(((dtime >> 21) & 0x0f) - 1),
99.289 + (int)((dtime >> 16) & 0x1f),
99.290 + (int)((dtime >> 11) & 0x1f),
99.291 + (int)((dtime >> 5) & 0x3f),
99.292 + (int)((dtime << 1) & 0x3e));
99.293 + return d.getTime();
99.294 + */
99.295 + }
99.296 +
99.297 + /*
99.298 + * Converts Java time to DOS time.
99.299 + */
99.300 + private static long javaToDosTime(long time) {
99.301 + return time;
99.302 + /* XXX:
99.303 + Date d = new Date(time);
99.304 + int year = d.getYear() + 1900;
99.305 + if (year < 1980) {
99.306 + return (1 << 21) | (1 << 16);
99.307 + }
99.308 + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
99.309 + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
99.310 + d.getSeconds() >> 1;
99.311 + */
99.312 + }
99.313 +
99.314 + /**
99.315 + * Returns the hash code value for this entry.
99.316 + */
99.317 + public int hashCode() {
99.318 + return name.hashCode();
99.319 + }
99.320 +
99.321 + /**
99.322 + * Returns a copy of this entry.
99.323 + */
99.324 + public Object clone() {
99.325 + try {
99.326 + ZipEntry e = (ZipEntry)super.clone();
99.327 + e.extra = (extra == null) ? null : extra.clone();
99.328 + return e;
99.329 + } catch (CloneNotSupportedException e) {
99.330 + // This should never happen, since we are Cloneable
99.331 + throw new IllegalStateException();
99.332 + }
99.333 + }
99.334 +}
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipException.java Tue Feb 05 17:04:22 2013 +0100
100.3 @@ -0,0 +1,60 @@
100.4 +/*
100.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
100.7 + *
100.8 + * This code is free software; you can redistribute it and/or modify it
100.9 + * under the terms of the GNU General Public License version 2 only, as
100.10 + * published by the Free Software Foundation. Oracle designates this
100.11 + * particular file as subject to the "Classpath" exception as provided
100.12 + * by Oracle in the LICENSE file that accompanied this code.
100.13 + *
100.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
100.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
100.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
100.17 + * version 2 for more details (a copy is included in the LICENSE file that
100.18 + * accompanied this code).
100.19 + *
100.20 + * You should have received a copy of the GNU General Public License version
100.21 + * 2 along with this work; if not, write to the Free Software Foundation,
100.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
100.23 + *
100.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
100.25 + * or visit www.oracle.com if you need additional information or have any
100.26 + * questions.
100.27 + */
100.28 +
100.29 +package java.util.zip;
100.30 +
100.31 +import java.io.IOException;
100.32 +
100.33 +/**
100.34 + * Signals that a Zip exception of some sort has occurred.
100.35 + *
100.36 + * @author unascribed
100.37 + * @see java.io.IOException
100.38 + * @since JDK1.0
100.39 + */
100.40 +
100.41 +public
100.42 +class ZipException extends IOException {
100.43 + private static final long serialVersionUID = 8000196834066748623L;
100.44 +
100.45 + /**
100.46 + * Constructs a <code>ZipException</code> with <code>null</code>
100.47 + * as its error detail message.
100.48 + */
100.49 + public ZipException() {
100.50 + super();
100.51 + }
100.52 +
100.53 + /**
100.54 + * Constructs a <code>ZipException</code> with the specified detail
100.55 + * message.
100.56 + *
100.57 + * @param s the detail message.
100.58 + */
100.59 +
100.60 + public ZipException(String s) {
100.61 + super(s);
100.62 + }
100.63 +}
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Tue Feb 05 17:04:22 2013 +0100
101.3 @@ -0,0 +1,467 @@
101.4 +/*
101.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
101.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
101.7 + *
101.8 + * This code is free software; you can redistribute it and/or modify it
101.9 + * under the terms of the GNU General Public License version 2 only, as
101.10 + * published by the Free Software Foundation. Oracle designates this
101.11 + * particular file as subject to the "Classpath" exception as provided
101.12 + * by Oracle in the LICENSE file that accompanied this code.
101.13 + *
101.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
101.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
101.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
101.17 + * version 2 for more details (a copy is included in the LICENSE file that
101.18 + * accompanied this code).
101.19 + *
101.20 + * You should have received a copy of the GNU General Public License version
101.21 + * 2 along with this work; if not, write to the Free Software Foundation,
101.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
101.23 + *
101.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
101.25 + * or visit www.oracle.com if you need additional information or have any
101.26 + * questions.
101.27 + */
101.28 +
101.29 +package java.util.zip;
101.30 +
101.31 +import java.io.InputStream;
101.32 +import java.io.IOException;
101.33 +import java.io.EOFException;
101.34 +import java.io.PushbackInputStream;
101.35 +import static java.util.zip.ZipConstants64.*;
101.36 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
101.37 +
101.38 +/**
101.39 + * This class implements an input stream filter for reading files in the
101.40 + * ZIP file format. Includes support for both compressed and uncompressed
101.41 + * entries.
101.42 + *
101.43 + * @author David Connelly
101.44 + */
101.45 +public
101.46 +class ZipInputStream extends InflaterInputStream implements ZipConstants {
101.47 + private ZipEntry entry;
101.48 + private int flag;
101.49 + private CRC32 crc = new CRC32();
101.50 + private long remaining;
101.51 + private byte[] tmpbuf = new byte[512];
101.52 +
101.53 + private static final int STORED = ZipEntry.STORED;
101.54 + private static final int DEFLATED = ZipEntry.DEFLATED;
101.55 +
101.56 + private boolean closed = false;
101.57 + // this flag is set to true after EOF has reached for
101.58 + // one entry
101.59 + private boolean entryEOF = false;
101.60 +
101.61 + /**
101.62 + * Check to make sure that this stream has not been closed
101.63 + */
101.64 + private void ensureOpen() throws IOException {
101.65 + if (closed) {
101.66 + throw new IOException("Stream closed");
101.67 + }
101.68 + }
101.69 +
101.70 + /**
101.71 + * Creates a new ZIP input stream.
101.72 + *
101.73 + * <p>The UTF-8 {@link java.nio.charset.Charset charset} is used to
101.74 + * decode the entry names.
101.75 + *
101.76 + * @param in the actual input stream
101.77 + */
101.78 + public ZipInputStream(InputStream in) {
101.79 +// this(in, "UTF-8");
101.80 + super(new PushbackInputStream(in, 512), new Inflater(true), 512);
101.81 + usesDefaultInflater = true;
101.82 + if(in == null) {
101.83 + throw new NullPointerException("in is null");
101.84 + }
101.85 + }
101.86 +
101.87 + /**
101.88 + * Creates a new ZIP input stream.
101.89 + *
101.90 + * @param in the actual input stream
101.91 + *
101.92 + * @param charset
101.93 + * The {@linkplain java.nio.charset.Charset charset} to be
101.94 + * used to decode the ZIP entry name (ignored if the
101.95 + * <a href="package-summary.html#lang_encoding"> language
101.96 + * encoding bit</a> of the ZIP entry's general purpose bit
101.97 + * flag is set).
101.98 + *
101.99 + * @since 1.7
101.100 + *
101.101 + public ZipInputStream(InputStream in, Charset charset) {
101.102 + super(new PushbackInputStream(in, 512), new Inflater(true), 512);
101.103 + usesDefaultInflater = true;
101.104 + if(in == null) {
101.105 + throw new NullPointerException("in is null");
101.106 + }
101.107 + if (charset == null)
101.108 + throw new NullPointerException("charset is null");
101.109 + this.zc = ZipCoder.get(charset);
101.110 + }
101.111 + */
101.112 +
101.113 + /**
101.114 + * Reads the next ZIP file entry and positions the stream at the
101.115 + * beginning of the entry data.
101.116 + * @return the next ZIP file entry, or null if there are no more entries
101.117 + * @exception ZipException if a ZIP file error has occurred
101.118 + * @exception IOException if an I/O error has occurred
101.119 + */
101.120 + public ZipEntry getNextEntry() throws IOException {
101.121 + ensureOpen();
101.122 + if (entry != null) {
101.123 + closeEntry();
101.124 + }
101.125 + crc.reset();
101.126 + inf.reset();
101.127 + if ((entry = readLOC()) == null) {
101.128 + return null;
101.129 + }
101.130 + if (entry.method == STORED) {
101.131 + remaining = entry.size;
101.132 + }
101.133 + entryEOF = false;
101.134 + return entry;
101.135 + }
101.136 +
101.137 + /**
101.138 + * Closes the current ZIP entry and positions the stream for reading the
101.139 + * next entry.
101.140 + * @exception ZipException if a ZIP file error has occurred
101.141 + * @exception IOException if an I/O error has occurred
101.142 + */
101.143 + public void closeEntry() throws IOException {
101.144 + ensureOpen();
101.145 + while (read(tmpbuf, 0, tmpbuf.length) != -1) ;
101.146 + entryEOF = true;
101.147 + }
101.148 +
101.149 + /**
101.150 + * Returns 0 after EOF has reached for the current entry data,
101.151 + * otherwise always return 1.
101.152 + * <p>
101.153 + * Programs should not count on this method to return the actual number
101.154 + * of bytes that could be read without blocking.
101.155 + *
101.156 + * @return 1 before EOF and 0 after EOF has reached for current entry.
101.157 + * @exception IOException if an I/O error occurs.
101.158 + *
101.159 + */
101.160 + public int available() throws IOException {
101.161 + ensureOpen();
101.162 + if (entryEOF) {
101.163 + return 0;
101.164 + } else {
101.165 + return 1;
101.166 + }
101.167 + }
101.168 +
101.169 + /**
101.170 + * Reads from the current ZIP entry into an array of bytes.
101.171 + * If <code>len</code> is not zero, the method
101.172 + * blocks until some input is available; otherwise, no
101.173 + * bytes are read and <code>0</code> is returned.
101.174 + * @param b the buffer into which the data is read
101.175 + * @param off the start offset in the destination array <code>b</code>
101.176 + * @param len the maximum number of bytes read
101.177 + * @return the actual number of bytes read, or -1 if the end of the
101.178 + * entry is reached
101.179 + * @exception NullPointerException if <code>b</code> is <code>null</code>.
101.180 + * @exception IndexOutOfBoundsException if <code>off</code> is negative,
101.181 + * <code>len</code> is negative, or <code>len</code> is greater than
101.182 + * <code>b.length - off</code>
101.183 + * @exception ZipException if a ZIP file error has occurred
101.184 + * @exception IOException if an I/O error has occurred
101.185 + */
101.186 + public int read(byte[] b, int off, int len) throws IOException {
101.187 + ensureOpen();
101.188 + if (off < 0 || len < 0 || off > b.length - len) {
101.189 + throw new IndexOutOfBoundsException();
101.190 + } else if (len == 0) {
101.191 + return 0;
101.192 + }
101.193 +
101.194 + if (entry == null) {
101.195 + return -1;
101.196 + }
101.197 + switch (entry.method) {
101.198 + case DEFLATED:
101.199 + len = super.read(b, off, len);
101.200 + if (len == -1) {
101.201 + readEnd(entry);
101.202 + entryEOF = true;
101.203 + entry = null;
101.204 + } else {
101.205 + crc.update(b, off, len);
101.206 + }
101.207 + return len;
101.208 + case STORED:
101.209 + if (remaining <= 0) {
101.210 + entryEOF = true;
101.211 + entry = null;
101.212 + return -1;
101.213 + }
101.214 + if (len > remaining) {
101.215 + len = (int)remaining;
101.216 + }
101.217 + len = in.read(b, off, len);
101.218 + if (len == -1) {
101.219 + throw new ZipException("unexpected EOF");
101.220 + }
101.221 + crc.update(b, off, len);
101.222 + remaining -= len;
101.223 + if (remaining == 0 && entry.crc != crc.getValue()) {
101.224 + throw new ZipException(
101.225 + "invalid entry CRC (expected 0x" + Long.toHexString(entry.crc) +
101.226 + " but got 0x" + Long.toHexString(crc.getValue()) + ")");
101.227 + }
101.228 + return len;
101.229 + default:
101.230 + throw new ZipException("invalid compression method");
101.231 + }
101.232 + }
101.233 +
101.234 + /**
101.235 + * Skips specified number of bytes in the current ZIP entry.
101.236 + * @param n the number of bytes to skip
101.237 + * @return the actual number of bytes skipped
101.238 + * @exception ZipException if a ZIP file error has occurred
101.239 + * @exception IOException if an I/O error has occurred
101.240 + * @exception IllegalArgumentException if n < 0
101.241 + */
101.242 + public long skip(long n) throws IOException {
101.243 + if (n < 0) {
101.244 + throw new IllegalArgumentException("negative skip length");
101.245 + }
101.246 + ensureOpen();
101.247 + int max = (int)Math.min(n, Integer.MAX_VALUE);
101.248 + int total = 0;
101.249 + while (total < max) {
101.250 + int len = max - total;
101.251 + if (len > tmpbuf.length) {
101.252 + len = tmpbuf.length;
101.253 + }
101.254 + len = read(tmpbuf, 0, len);
101.255 + if (len == -1) {
101.256 + entryEOF = true;
101.257 + break;
101.258 + }
101.259 + total += len;
101.260 + }
101.261 + return total;
101.262 + }
101.263 +
101.264 + /**
101.265 + * Closes this input stream and releases any system resources associated
101.266 + * with the stream.
101.267 + * @exception IOException if an I/O error has occurred
101.268 + */
101.269 + public void close() throws IOException {
101.270 + if (!closed) {
101.271 + super.close();
101.272 + closed = true;
101.273 + }
101.274 + }
101.275 +
101.276 + private byte[] b = new byte[256];
101.277 +
101.278 + /*
101.279 + * Reads local file (LOC) header for next entry.
101.280 + */
101.281 + private ZipEntry readLOC() throws IOException {
101.282 + try {
101.283 + readFully(tmpbuf, 0, LOCHDR);
101.284 + } catch (EOFException e) {
101.285 + return null;
101.286 + }
101.287 + if (get32(tmpbuf, 0) != LOCSIG) {
101.288 + return null;
101.289 + }
101.290 + // get flag first, we need check EFS.
101.291 + flag = get16(tmpbuf, LOCFLG);
101.292 + // get the entry name and create the ZipEntry first
101.293 + int len = get16(tmpbuf, LOCNAM);
101.294 + int blen = b.length;
101.295 + if (len > blen) {
101.296 + do
101.297 + blen = blen * 2;
101.298 + while (len > blen);
101.299 + b = new byte[blen];
101.300 + }
101.301 + readFully(b, 0, len);
101.302 + // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
101.303 + ZipEntry e = createZipEntry(((flag & EFS) != 0)
101.304 + ? toStringUTF8(b, len)
101.305 + : toString(b, len));
101.306 + // now get the remaining fields for the entry
101.307 + if ((flag & 1) == 1) {
101.308 + throw new ZipException("encrypted ZIP entry not supported");
101.309 + }
101.310 + e.method = get16(tmpbuf, LOCHOW);
101.311 + e.time = get32(tmpbuf, LOCTIM);
101.312 + if ((flag & 8) == 8) {
101.313 + /* "Data Descriptor" present */
101.314 + if (e.method != DEFLATED) {
101.315 + throw new ZipException(
101.316 + "only DEFLATED entries can have EXT descriptor");
101.317 + }
101.318 + } else {
101.319 + e.crc = get32(tmpbuf, LOCCRC);
101.320 + e.csize = get32(tmpbuf, LOCSIZ);
101.321 + e.size = get32(tmpbuf, LOCLEN);
101.322 + }
101.323 + len = get16(tmpbuf, LOCEXT);
101.324 + if (len > 0) {
101.325 + byte[] bb = new byte[len];
101.326 + readFully(bb, 0, len);
101.327 + e.setExtra(bb);
101.328 + // extra fields are in "HeaderID(2)DataSize(2)Data... format
101.329 + if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
101.330 + int off = 0;
101.331 + while (off + 4 < len) {
101.332 + int sz = get16(bb, off + 2);
101.333 + if (get16(bb, off) == ZIP64_EXTID) {
101.334 + off += 4;
101.335 + // LOC extra zip64 entry MUST include BOTH original and
101.336 + // compressed file size fields
101.337 + if (sz < 16 || (off + sz) > len ) {
101.338 + // Invalid zip64 extra fields, simply skip. Even it's
101.339 + // rare, it's possible the entry size happens to be
101.340 + // the magic value and it "accidnetly" has some bytes
101.341 + // in extra match the id.
101.342 + return e;
101.343 + }
101.344 + e.size = get64(bb, off);
101.345 + e.csize = get64(bb, off + 8);
101.346 + break;
101.347 + }
101.348 + off += (sz + 4);
101.349 + }
101.350 + }
101.351 + }
101.352 + return e;
101.353 + }
101.354 +
101.355 + /**
101.356 + * Creates a new <code>ZipEntry</code> object for the specified
101.357 + * entry name.
101.358 + *
101.359 + * @param name the ZIP file entry name
101.360 + * @return the ZipEntry just created
101.361 + */
101.362 + protected ZipEntry createZipEntry(String name) {
101.363 + return new ZipEntry(name);
101.364 + }
101.365 +
101.366 + /*
101.367 + * Reads end of deflated entry as well as EXT descriptor if present.
101.368 + */
101.369 + private void readEnd(ZipEntry e) throws IOException {
101.370 + int n = inf.getRemaining();
101.371 + if (n > 0) {
101.372 + ((PushbackInputStream)in).unread(buf, len - n, n);
101.373 + }
101.374 + if ((flag & 8) == 8) {
101.375 + /* "Data Descriptor" present */
101.376 + if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
101.377 + inf.getBytesRead() > ZIP64_MAGICVAL) {
101.378 + // ZIP64 format
101.379 + readFully(tmpbuf, 0, ZIP64_EXTHDR);
101.380 + long sig = get32(tmpbuf, 0);
101.381 + if (sig != EXTSIG) { // no EXTSIG present
101.382 + e.crc = sig;
101.383 + e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC);
101.384 + e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC);
101.385 + ((PushbackInputStream)in).unread(
101.386 + tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
101.387 + } else {
101.388 + e.crc = get32(tmpbuf, ZIP64_EXTCRC);
101.389 + e.csize = get64(tmpbuf, ZIP64_EXTSIZ);
101.390 + e.size = get64(tmpbuf, ZIP64_EXTLEN);
101.391 + }
101.392 + } else {
101.393 + readFully(tmpbuf, 0, EXTHDR);
101.394 + long sig = get32(tmpbuf, 0);
101.395 + if (sig != EXTSIG) { // no EXTSIG present
101.396 + e.crc = sig;
101.397 + e.csize = get32(tmpbuf, EXTSIZ - EXTCRC);
101.398 + e.size = get32(tmpbuf, EXTLEN - EXTCRC);
101.399 + ((PushbackInputStream)in).unread(
101.400 + tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC);
101.401 + } else {
101.402 + e.crc = get32(tmpbuf, EXTCRC);
101.403 + e.csize = get32(tmpbuf, EXTSIZ);
101.404 + e.size = get32(tmpbuf, EXTLEN);
101.405 + }
101.406 + }
101.407 + }
101.408 + if (e.size != inf.getBytesWritten()) {
101.409 + throw new ZipException(
101.410 + "invalid entry size (expected " + e.size +
101.411 + " but got " + inf.getBytesWritten() + " bytes)");
101.412 + }
101.413 + if (e.csize != inf.getBytesRead()) {
101.414 + throw new ZipException(
101.415 + "invalid entry compressed size (expected " + e.csize +
101.416 + " but got " + inf.getBytesRead() + " bytes)");
101.417 + }
101.418 + if (e.crc != crc.getValue()) {
101.419 + throw new ZipException(
101.420 + "invalid entry CRC (expected 0x" + Long.toHexString(e.crc) +
101.421 + " but got 0x" + Long.toHexString(crc.getValue()) + ")");
101.422 + }
101.423 + }
101.424 +
101.425 + /*
101.426 + * Reads bytes, blocking until all bytes are read.
101.427 + */
101.428 + private void readFully(byte[] b, int off, int len) throws IOException {
101.429 + while (len > 0) {
101.430 + int n = in.read(b, off, len);
101.431 + if (n == -1) {
101.432 + throw new EOFException();
101.433 + }
101.434 + off += n;
101.435 + len -= n;
101.436 + }
101.437 + }
101.438 +
101.439 + /*
101.440 + * Fetches unsigned 16-bit value from byte array at specified offset.
101.441 + * The bytes are assumed to be in Intel (little-endian) byte order.
101.442 + */
101.443 + private static final int get16(byte b[], int off) {
101.444 + return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
101.445 + }
101.446 +
101.447 + /*
101.448 + * Fetches unsigned 32-bit value from byte array at specified offset.
101.449 + * The bytes are assumed to be in Intel (little-endian) byte order.
101.450 + */
101.451 + private static final long get32(byte b[], int off) {
101.452 + return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
101.453 + }
101.454 +
101.455 + /*
101.456 + * Fetches signed 64-bit value from byte array at specified offset.
101.457 + * The bytes are assumed to be in Intel (little-endian) byte order.
101.458 + */
101.459 + private static final long get64(byte b[], int off) {
101.460 + return get32(b, off) | (get32(b, off+4) << 32);
101.461 + }
101.462 +
101.463 + private static String toStringUTF8(byte[] arr, int len) {
101.464 + return new String(arr, 0, len);
101.465 + }
101.466 +
101.467 + private static String toString(byte[] b, int len) {
101.468 + return new String(b, 0, len);
101.469 + }
101.470 +}
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/emul/mini/src/main/java/java/util/zip/package.html Tue Feb 05 17:04:22 2013 +0100
102.3 @@ -0,0 +1,98 @@
102.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
102.5 +<html>
102.6 +<head>
102.7 +<!--
102.8 +Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
102.9 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
102.10 +
102.11 +This code is free software; you can redistribute it and/or modify it
102.12 +under the terms of the GNU General Public License version 2 only, as
102.13 +published by the Free Software Foundation. Oracle designates this
102.14 +particular file as subject to the "Classpath" exception as provided
102.15 +by Oracle in the LICENSE file that accompanied this code.
102.16 +
102.17 +This code is distributed in the hope that it will be useful, but WITHOUT
102.18 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
102.19 +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
102.20 +version 2 for more details (a copy is included in the LICENSE file that
102.21 +accompanied this code).
102.22 +
102.23 +You should have received a copy of the GNU General Public License version
102.24 +2 along with this work; if not, write to the Free Software Foundation,
102.25 +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
102.26 +
102.27 +Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
102.28 +or visit www.oracle.com if you need additional information or have any
102.29 +questions.
102.30 +-->
102.31 +
102.32 +</head>
102.33 +<body bgcolor="white">
102.34 +
102.35 +Provides classes for reading and writing the standard ZIP and GZIP
102.36 +file formats. Also includes classes for compressing and decompressing
102.37 +data using the DEFLATE compression algorithm, which is used by the
102.38 +ZIP and GZIP file formats. Additionally, there are utility classes
102.39 +for computing the CRC-32 and Adler-32 checksums of arbitrary
102.40 +input streams.
102.41 +
102.42 +
102.43 +<h2>Package Specification</h2>
102.44 +
102.45 +</a>
102.46 +<ul>
102.47 + <li><a href="ftp://ftp.uu.net/pub/archiving/zip/doc/appnote-970311-iz.zip">
102.48 + Info-ZIP Application Note 970311
102.49 + </a> - a detailed description of the Info-ZIP format upon which
102.50 + the <code>java.util.zip</code> classes are based.
102.51 +<p>
102.52 + <a name="zip64">
102.53 + <li>An implementation may optionally support the ZIP64(tm) format extensions
102.54 + defined by the
102.55 + <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
102.56 + PKWARE ZIP File Format Specification</a>. The ZIP64(tm) format extensions
102.57 + are used to overcome the size limitations of the original ZIP format.
102.58 +<p>
102.59 + <a name="lang_encoding">
102.60 + <li>APPENDIX D of <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
102.61 + PKWARE ZIP File Format Specification</a> - Language Encoding Flag (EFS) to
102.62 + encode ZIP entry filename and comment fields using UTF-8.
102.63 +<p>
102.64 + <li><a href="http://www.ietf.org/rfc/rfc1950.txt">
102.65 + ZLIB Compressed Data Format Specification version 3.3</a>
102.66 +
102.67 + <a href="http://www.ietf.org/rfc/rfc1950.txt.pdf">(pdf)</a>
102.68 + (RFC 1950)
102.69 +<p>
102.70 + <li><a href="http://www.ietf.org/rfc/rfc1951.txt">
102.71 + DEFLATE Compressed Data Format Specification version 1.3</a>
102.72 +
102.73 + <a href="http://www.ietf.org/rfc/rfc1951.txt.pdf">(pdf)</a>
102.74 + (RFC 1951)
102.75 +<p>
102.76 + <li><a href="http://www.ietf.org/rfc/rfc1952.txt">
102.77 + GZIP file format specification version 4.3</a>
102.78 +
102.79 + <a href="http://www.ietf.org/rfc/rfc1952.txt.pdf">(pdf)</a>
102.80 + (RFC 1952)
102.81 +<p>
102.82 + <li>CRC-32 checksum is described in RFC 1952 (above)
102.83 +<p>
102.84 + <li>Adler-32 checksum is described in RFC 1950 (above)
102.85 +</ul>
102.86 +
102.87 +
102.88 +<!--
102.89 +<h2>Related Documentation</h2>
102.90 +
102.91 +For overviews, tutorials, examples, guides, and tool documentation, please see:
102.92 +<ul>
102.93 + <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
102.94 +</ul>
102.95 +-->
102.96 +
102.97 +@since JDK1.1
102.98 +</body>
102.99 +</html>
102.100 +
102.101 +
103.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Tue Feb 05 16:40:01 2013 +0100
103.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Tue Feb 05 17:04:22 2013 +0100
103.3 @@ -39,4 +39,19 @@
103.4 "}"
103.5 )
103.6 public static native void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count);
103.7 +
103.8 + @JavaScriptBody(args = { "arr", "expectedSize" }, body =
103.9 + "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
103.10 + )
103.11 + public static native byte[] expandArray(byte[] arr, int expectedSize);
103.12 +
103.13 + @JavaScriptBody(args = {}, body = "new Date().getMilliseconds();")
103.14 + public static native long currentTimeMillis();
103.15 +
103.16 + public static long nanoTime() {
103.17 + return 1000000L * currentTimeMillis();
103.18 + }
103.19 + @JavaScriptBody(args = { "obj" }, body="return vm.java_lang_Object(false).hashCode__I.call(obj);")
103.20 + public static native int identityHashCode(Object obj);
103.21 +
103.22 }
104.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Tue Feb 05 16:40:01 2013 +0100
104.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Tue Feb 05 17:04:22 2013 +0100
104.3 @@ -1,26 +1,19 @@
104.4 -/*
104.5 - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
104.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
104.7 +/**
104.8 + * Back 2 Browser Bytecode Translator
104.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
104.10 *
104.11 - * This code is free software; you can redistribute it and/or modify it
104.12 - * under the terms of the GNU General Public License version 2 only, as
104.13 - * published by the Free Software Foundation. Oracle designates this
104.14 - * particular file as subject to the "Classpath" exception as provided
104.15 - * by Oracle in the LICENSE file that accompanied this code.
104.16 + * This program is free software: you can redistribute it and/or modify
104.17 + * it under the terms of the GNU General Public License as published by
104.18 + * the Free Software Foundation, version 2 of the License.
104.19 *
104.20 - * This code is distributed in the hope that it will be useful, but WITHOUT
104.21 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
104.22 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
104.23 - * version 2 for more details (a copy is included in the LICENSE file that
104.24 - * accompanied this code).
104.25 + * This program is distributed in the hope that it will be useful,
104.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
104.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104.28 + * GNU General Public License for more details.
104.29 *
104.30 - * You should have received a copy of the GNU General Public License version
104.31 - * 2 along with this work; if not, write to the Free Software Foundation,
104.32 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
104.33 - *
104.34 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
104.35 - * or visit www.oracle.com if you need additional information or have any
104.36 - * questions.
104.37 + * You should have received a copy of the GNU General Public License
104.38 + * along with this program. Look for COPYING file in the top folder.
104.39 + * If not, see http://opensource.org/licenses/GPL-2.0.
104.40 */
104.41 package org.apidesign.bck2brwsr.emul.reflect;
104.42
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
105.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java Tue Feb 05 17:04:22 2013 +0100
105.3 @@ -0,0 +1,40 @@
105.4 +/**
105.5 + * Back 2 Browser Bytecode Translator
105.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
105.7 + *
105.8 + * This program is free software: you can redistribute it and/or modify
105.9 + * it under the terms of the GNU General Public License as published by
105.10 + * the Free Software Foundation, version 2 of the License.
105.11 + *
105.12 + * This program is distributed in the hope that it will be useful,
105.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
105.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
105.15 + * GNU General Public License for more details.
105.16 + *
105.17 + * You should have received a copy of the GNU General Public License
105.18 + * along with this program. Look for COPYING file in the top folder.
105.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
105.20 + */
105.21 +package org.apidesign.bck2brwsr.emul.reflect;
105.22 +
105.23 +import java.lang.reflect.Constructor;
105.24 +import java.lang.reflect.Type;
105.25 +import java.lang.reflect.TypeVariable;
105.26 +
105.27 +/**
105.28 + *
105.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
105.30 + */
105.31 +public abstract class TypeProvider {
105.32 + private TypeProvider() {
105.33 + }
105.34 +
105.35 + public static TypeProvider getDefault() {
105.36 + return null;
105.37 + }
105.38 +
105.39 + public abstract <T> TypeVariable<Constructor<T>>[] getTypeParameters(Constructor<T> c);
105.40 + public abstract <T> Type[] getGenericParameterTypes(Constructor<T> c);
105.41 + public abstract <T> Type[] getGenericExceptionTypes(Constructor<T> c);
105.42 +
105.43 +}
106.1 --- a/javaquery/api/pom.xml Tue Feb 05 16:40:01 2013 +0100
106.2 +++ b/javaquery/api/pom.xml Tue Feb 05 17:04:22 2013 +0100
106.3 @@ -43,6 +43,7 @@
106.4 <dependency>
106.5 <groupId>org.netbeans.api</groupId>
106.6 <artifactId>org-openide-util-lookup</artifactId>
106.7 + <scope>provided</scope>
106.8 </dependency>
106.9 <dependency>
106.10 <groupId>org.apidesign.bck2brwsr</groupId>
107.1 --- a/javaquery/demo-calculator/nbactions.xml Tue Feb 05 16:40:01 2013 +0100
107.2 +++ b/javaquery/demo-calculator/nbactions.xml Tue Feb 05 17:04:22 2013 +0100
107.3 @@ -23,7 +23,7 @@
107.4 <actionName>run</actionName>
107.5 <goals>
107.6 <goal>process-classes</goal>
107.7 - <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
107.8 + <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
107.9 </goals>
107.10 </action>
107.11 </actions>
108.1 --- a/javaquery/demo-calculator/pom.xml Tue Feb 05 16:40:01 2013 +0100
108.2 +++ b/javaquery/demo-calculator/pom.xml Tue Feb 05 17:04:22 2013 +0100
108.3 @@ -16,34 +16,21 @@
108.4 </properties>
108.5 <build>
108.6 <plugins>
108.7 - <plugin>
108.8 - <groupId>org.apidesign.bck2brwsr</groupId>
108.9 - <artifactId>mojo</artifactId>
108.10 - <version>0.3-SNAPSHOT</version>
108.11 - <executions>
108.12 - <execution>
108.13 - <goals>
108.14 - <goal>j2js</goal>
108.15 - </goals>
108.16 - </execution>
108.17 - </executions>
108.18 - </plugin>
108.19 <plugin>
108.20 - <groupId>org.codehaus.mojo</groupId>
108.21 - <artifactId>exec-maven-plugin</artifactId>
108.22 - <version>1.2.1</version>
108.23 + <groupId>org.apidesign.bck2brwsr</groupId>
108.24 + <artifactId>mojo</artifactId>
108.25 + <version>0.3-SNAPSHOT</version>
108.26 <executions>
108.27 <execution>
108.28 <goals>
108.29 - <goal>exec</goal>
108.30 + <goal>j2js</goal>
108.31 + <goal>brwsr</goal>
108.32 </goals>
108.33 </execution>
108.34 </executions>
108.35 <configuration>
108.36 - <executable>xdg-open</executable>
108.37 - <arguments>
108.38 - <argument>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</argument>
108.39 - </arguments>
108.40 + <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/</directory>
108.41 + <startpage>index.xhtml</startpage>
108.42 </configuration>
108.43 </plugin>
108.44 <plugin>
108.45 @@ -55,6 +42,24 @@
108.46 <target>1.7</target>
108.47 </configuration>
108.48 </plugin>
108.49 + <plugin>
108.50 + <artifactId>maven-assembly-plugin</artifactId>
108.51 + <version>2.4</version>
108.52 + <executions>
108.53 + <execution>
108.54 + <id>distro-assembly</id>
108.55 + <phase>package</phase>
108.56 + <goals>
108.57 + <goal>single</goal>
108.58 + </goals>
108.59 + <configuration>
108.60 + <descriptors>
108.61 + <descriptor>src/main/assembly/bck2brwsr.xml</descriptor>
108.62 + </descriptors>
108.63 + </configuration>
108.64 + </execution>
108.65 + </executions>
108.66 + </plugin>
108.67 </plugins>
108.68 </build>
108.69
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109.2 +++ b/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml Tue Feb 05 17:04:22 2013 +0100
109.3 @@ -0,0 +1,54 @@
109.4 +<?xml version="1.0"?>
109.5 +<!--
109.6 +
109.7 + Back 2 Browser Bytecode Translator
109.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
109.9 +
109.10 + This program is free software: you can redistribute it and/or modify
109.11 + it under the terms of the GNU General Public License as published by
109.12 + the Free Software Foundation, version 2 of the License.
109.13 +
109.14 + This program is distributed in the hope that it will be useful,
109.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
109.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109.17 + GNU General Public License for more details.
109.18 +
109.19 + You should have received a copy of the GNU General Public License
109.20 + along with this program. Look for COPYING file in the top folder.
109.21 + If not, see http://opensource.org/licenses/GPL-2.0.
109.22 +
109.23 +-->
109.24 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
109.25 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
109.26 +
109.27 + <id>bck2brwsr</id>
109.28 + <formats>
109.29 + <format>zip</format>
109.30 + <format>dir</format>
109.31 + </formats>
109.32 + <baseDirectory>public_html</baseDirectory>
109.33 + <dependencySets>
109.34 + <dependencySet>
109.35 + <useProjectArtifact>false</useProjectArtifact>
109.36 + <scope>runtime</scope>
109.37 + <outputDirectory>lib</outputDirectory>
109.38 + </dependencySet>
109.39 + </dependencySets>
109.40 + <files>
109.41 + <file>
109.42 + <source>${project.build.directory}/${project.build.finalName}.jar</source>
109.43 + <outputDirectory>/</outputDirectory>
109.44 + </file>
109.45 + <file>
109.46 + <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</source>
109.47 + <outputDirectory>/</outputDirectory>
109.48 + <destName>index.xhtml</destName>
109.49 + </file>
109.50 + <file>
109.51 + <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/bootjava.js</source>
109.52 + <outputDirectory>/</outputDirectory>
109.53 + <destName>bck2brwsr.js</destName>
109.54 + </file>
109.55 + </files>
109.56 +
109.57 +</assembly>
109.58 \ No newline at end of file
110.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Tue Feb 05 16:40:01 2013 +0100
110.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Tue Feb 05 17:04:22 2013 +0100
110.3 @@ -77,78 +77,6 @@
110.4 </tbody>
110.5 </table>
110.6 <div data-bind="text: displayPreview"></div>
110.7 - <script src="bootjava.js"/>
110.8 -
110.9 - <hr/>
110.10 - <pre>
110.11 - <span class="keyword-directive">package</span> org.apidesign.bck2brwsr.mavenhtml;
110.12 -
110.13 - <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.OnClick;
110.14 - <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.Page;
110.15 -
110.16 - <span class="comment">/**</span> <span class="comment">HTML5</span><span class="comment"> & </span><span class="comment">Java</span> <span class="comment">demo</span> <span class="comment">showing</span> <span class="comment">the</span> <span class="comment">power</span> <span class="comment">of</span> <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
110.17 - <span class="comment"> * </span><span class="comment">as</span> <span class="comment">well</span> <span class="comment">as</span> <span class="comment">other</span> <span class="comment">goodies</span><span class="comment">, including type-safe association between</span>
110.18 - <span class="comment"> * </span><span class="comment">an XHTML page and Java.</span>
110.19 - <span class="comment"> * </span>
110.20 - <span class="comment"> * </span><span class="ST1">@author</span> <span class="comment">Jaroslav</span> <span class="comment">Tulach</span> <span class="ST0"><jaroslav.tulach@apidesign.org></span>
110.21 - <span class="comment">*/</span>
110.22 - @Page(xhtml=<span class="string">"</span><span class="string">Calculator.xhtml</span><span class="string">"</span>)
110.23 - <span class="keyword-directive">public</span> <span class="keyword-directive">class</span> App {
110.24 - <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> memory;
110.25 - <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> String operation;
110.26 -
110.27 - @OnClick(id=<span class="string">"</span><span class="string">clear</span><span class="string">"</span>)
110.28 - <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> clear() {
110.29 - memory = <span class="number">0</span>;
110.30 - operation = <span class="keyword-directive">null</span>;
110.31 - Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">0</span><span class="string">"</span>);
110.32 - }
110.33 -
110.34 - @OnClick(id= { <span class="string">"</span><span class="string">plus</span><span class="string">"</span>, <span class="string">"</span><span class="string">minus</span><span class="string">"</span>, <span class="string">"</span><span class="string">mul</span><span class="string">"</span>, <span class="string">"</span><span class="string">div</span><span class="string">"</span> })
110.35 - <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> applyOp(String op) {
110.36 - memory = getValue();
110.37 - operation = op;
110.38 - Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">0</span><span class="string">"</span>);
110.39 - }
110.40 -
110.41 - @OnClick(id=<span class="string">"</span><span class="string">result</span><span class="string">"</span>)
110.42 - <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> computeTheValue() {
110.43 - <span class="keyword-directive">switch</span> (operation) {
110.44 - <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">plus</span><span class="string">"</span>: setValue(memory + getValue()); <span class="keyword-directive">break</span>;
110.45 - <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">minus</span><span class="string">"</span>: setValue(memory - getValue()); <span class="keyword-directive">break</span>;
110.46 - <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">mul</span><span class="string">"</span>: setValue(memory * getValue()); <span class="keyword-directive">break</span>;
110.47 - <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">div</span><span class="string">"</span>: setValue(memory / getValue()); <span class="keyword-directive">break</span>;
110.48 - <span class="keyword-directive">default</span>: <span class="keyword-directive">throw</span> <span class="keyword-directive">new</span> IllegalStateException(operation);
110.49 - }
110.50 - }
110.51 -
110.52 - @OnClick(id={<span class="string">"</span><span class="string">n0</span><span class="string">"</span>, <span class="string">"</span><span class="string">n1</span><span class="string">"</span>, <span class="string">"</span><span class="string">n2</span><span class="string">"</span>, <span class="string">"</span><span class="string">n3</span><span class="string">"</span>, <span class="string">"</span><span class="string">n4</span><span class="string">"</span>, <span class="string">"</span><span class="string">n5</span><span class="string">"</span>, <span class="string">"</span><span class="string">n6</span><span class="string">"</span>, <span class="string">"</span><span class="string">n7</span><span class="string">"</span>, <span class="string">"</span><span class="string">n8</span><span class="string">"</span>, <span class="string">"</span><span class="string">n9</span><span class="string">"</span>})
110.53 - <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> addDigit(String digit) {
110.54 - digit = digit.substring(<span class="number">1</span>);
110.55 - String v = Calculator.DISPLAY.getValue();
110.56 - <span class="keyword-directive">if</span> (getValue() == <span class="number">0.0</span>) {
110.57 - Calculator.DISPLAY.setValue(digit);
110.58 - } <span class="keyword-directive">else</span> {
110.59 - Calculator.DISPLAY.setValue(v + digit);
110.60 - }
110.61 - }
110.62 -
110.63 - <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> setValue(<span class="keyword-directive">double</span> v) {
110.64 - StringBuilder sb = <span class="keyword-directive">new</span> StringBuilder();
110.65 - sb.append(v);
110.66 - Calculator.DISPLAY.setValue(sb.toString());
110.67 - }
110.68 -
110.69 - <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> getValue() {
110.70 - <span class="keyword-directive">try</span> {
110.71 - <span class="keyword-directive">return</span> Double.parseDouble(Calculator.DISPLAY.getValue());
110.72 - } <span class="keyword-directive">catch</span> (NumberFormatException ex) {
110.73 - Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">err</span><span class="string">"</span>);
110.74 - <span class="keyword-directive">return</span> <span class="number">0.0</span>;
110.75 - }
110.76 - }
110.77 - }
110.78 -
110.79 - </pre>
110.80 + <script src="bck2brwsr.js"/>
110.81 </body>
110.82 </html>
111.1 --- a/launcher/pom.xml Tue Feb 05 16:40:01 2013 +0100
111.2 +++ b/launcher/pom.xml Tue Feb 05 17:04:22 2013 +0100
111.3 @@ -23,6 +23,14 @@
111.4 <target>1.7</target>
111.5 </configuration>
111.6 </plugin>
111.7 + <plugin>
111.8 + <groupId>org.apache.maven.plugins</groupId>
111.9 + <artifactId>maven-javadoc-plugin</artifactId>
111.10 + <version>2.8.1</version>
111.11 + <configuration>
111.12 + <excludePackageNames>org.apidesign.bck2brwsr.launcher.impl</excludePackageNames>
111.13 + </configuration>
111.14 + </plugin>
111.15 </plugins>
111.16 </build>
111.17 <properties>
112.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Tue Feb 05 16:40:01 2013 +0100
112.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Tue Feb 05 17:04:22 2013 +0100
112.3 @@ -55,24 +55,23 @@
112.4 */
112.5 final class Bck2BrwsrLauncher extends Launcher implements Closeable {
112.6 private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
112.7 - private static final MethodInvocation END = new MethodInvocation(null, null, null);
112.8 - private Set<ClassLoader> loaders = new LinkedHashSet<>();
112.9 - private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
112.10 + private static final InvocationContext END = new InvocationContext(null, null, null);
112.11 + private final Set<ClassLoader> loaders = new LinkedHashSet<>();
112.12 + private final BlockingQueue<InvocationContext> methods = new LinkedBlockingQueue<>();
112.13 private long timeOut;
112.14 private final Res resources = new Res();
112.15 private final String cmd;
112.16 private Object[] brwsr;
112.17 private HttpServer server;
112.18 private CountDownLatch wait;
112.19 -
112.20 +
112.21 public Bck2BrwsrLauncher(String cmd) {
112.22 this.cmd = cmd;
112.23 }
112.24
112.25 @Override
112.26 - MethodInvocation addMethod(Class<?> clazz, String method, String html) throws IOException {
112.27 - loaders.add(clazz.getClassLoader());
112.28 - MethodInvocation c = new MethodInvocation(clazz.getName(), method, html);
112.29 + InvocationContext runMethod(InvocationContext c) throws IOException {
112.30 + loaders.add(c.clazz.getClassLoader());
112.31 methods.add(c);
112.32 try {
112.33 c.await(timeOut);
112.34 @@ -94,7 +93,7 @@
112.35 if (!startpage.startsWith("/")) {
112.36 startpage = "/" + startpage;
112.37 }
112.38 - HttpServer s = initServer();
112.39 + HttpServer s = initServer(".", true);
112.40 s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
112.41 try {
112.42 launchServerAndBrwsr(s, startpage);
112.43 @@ -103,6 +102,18 @@
112.44 }
112.45 }
112.46
112.47 + void showDirectory(File dir, String startpage) throws IOException {
112.48 + if (!startpage.startsWith("/")) {
112.49 + startpage = "/" + startpage;
112.50 + }
112.51 + HttpServer s = initServer(dir.getPath(), false);
112.52 + try {
112.53 + launchServerAndBrwsr(s, startpage);
112.54 + } catch (URISyntaxException | InterruptedException ex) {
112.55 + throw new IOException(ex);
112.56 + }
112.57 + }
112.58 +
112.59 @Override
112.60 public void initialize() throws IOException {
112.61 try {
112.62 @@ -122,25 +133,54 @@
112.63 }
112.64 }
112.65
112.66 - private HttpServer initServer() throws IOException {
112.67 - HttpServer s = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
112.68 + private HttpServer initServer(String path, boolean addClasses) throws IOException {
112.69 + HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
112.70
112.71 final ServerConfiguration conf = s.getServerConfiguration();
112.72 - conf.addHttpHandler(new VM(resources), "/vm.js");
112.73 - conf.addHttpHandler(new Classes(resources), "/classes/");
112.74 + if (addClasses) {
112.75 + conf.addHttpHandler(new VM(resources), "/vm.js");
112.76 + conf.addHttpHandler(new Classes(resources), "/classes/");
112.77 + }
112.78 return s;
112.79 }
112.80
112.81 private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
112.82 wait = new CountDownLatch(1);
112.83 - server = initServer();
112.84 - ServerConfiguration conf = server.getServerConfiguration();
112.85 + server = initServer(".", true);
112.86 + final ServerConfiguration conf = server.getServerConfiguration();
112.87 +
112.88 + class DynamicResourceHandler extends HttpHandler {
112.89 + private final InvocationContext ic;
112.90 + public DynamicResourceHandler(InvocationContext ic) {
112.91 + if (ic == null || ic.httpPath == null) {
112.92 + throw new NullPointerException();
112.93 + }
112.94 + this.ic = ic;
112.95 + conf.addHttpHandler(this, ic.httpPath);
112.96 + }
112.97 +
112.98 + public void close() {
112.99 + conf.removeHttpHandler(this);
112.100 + }
112.101 +
112.102 + @Override
112.103 + public void service(Request request, Response response) throws Exception {
112.104 + if (ic.httpPath.equals(request.getRequestURI())) {
112.105 + LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
112.106 + response.setContentType(ic.httpType);
112.107 + copyStream(ic.httpContent, response.getOutputStream(), null);
112.108 + }
112.109 + }
112.110 + }
112.111 +
112.112 conf.addHttpHandler(new Page(resources,
112.113 "org/apidesign/bck2brwsr/launcher/harness.xhtml"
112.114 ), "/execute");
112.115 +
112.116 conf.addHttpHandler(new HttpHandler() {
112.117 int cnt;
112.118 - List<MethodInvocation> cases = new ArrayList<>();
112.119 + List<InvocationContext> cases = new ArrayList<>();
112.120 + DynamicResourceHandler prev;
112.121 @Override
112.122 public void service(Request request, Response response) throws Exception {
112.123 String id = request.getParameter("request");
112.124 @@ -152,7 +192,12 @@
112.125 cases.get(Integer.parseInt(id)).result(value, null);
112.126 }
112.127
112.128 - MethodInvocation mi = methods.take();
112.129 + if (prev != null) {
112.130 + prev.close();
112.131 + prev = null;
112.132 + }
112.133 +
112.134 + InvocationContext mi = methods.take();
112.135 if (mi == END) {
112.136 response.getWriter().write("");
112.137 wait.countDown();
112.138 @@ -161,8 +206,12 @@
112.139 return;
112.140 }
112.141
112.142 + if (mi.httpPath != null) {
112.143 + prev = new DynamicResourceHandler(mi);
112.144 + }
112.145 +
112.146 cases.add(mi);
112.147 - final String cn = mi.className;
112.148 + final String cn = mi.clazz.getName();
112.149 final String mn = mi.methodName;
112.150 LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
112.151 response.getWriter().write("{"
113.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java Tue Feb 05 16:40:01 2013 +0100
113.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
113.3 @@ -1,253 +0,0 @@
113.4 -/**
113.5 - * Back 2 Browser Bytecode Translator
113.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
113.7 - *
113.8 - * This program is free software: you can redistribute it and/or modify
113.9 - * it under the terms of the GNU General Public License as published by
113.10 - * the Free Software Foundation, version 2 of the License.
113.11 - *
113.12 - * This program is distributed in the hope that it will be useful,
113.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
113.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113.15 - * GNU General Public License for more details.
113.16 - *
113.17 - * You should have received a copy of the GNU General Public License
113.18 - * along with this program. Look for COPYING file in the top folder.
113.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
113.20 - */
113.21 -package org.apidesign.bck2brwsr.launcher;
113.22 -
113.23 -import java.io.IOException;
113.24 -import java.io.InputStream;
113.25 -import java.lang.reflect.InvocationTargetException;
113.26 -import java.lang.reflect.Method;
113.27 -import java.lang.reflect.Modifier;
113.28 -import java.net.URL;
113.29 -import java.util.Enumeration;
113.30 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
113.31 -
113.32 -/**
113.33 - *
113.34 - * @author Jaroslav Tulach <jtulach@netbeans.org>
113.35 - */
113.36 -public class Console {
113.37 - static {
113.38 - turnAssetionStatusOn();
113.39 - }
113.40 -
113.41 - @JavaScriptBody(args = {"id", "attr"}, body =
113.42 - "return window.document.getElementById(id)[attr].toString();")
113.43 - private static native Object getAttr(String id, String attr);
113.44 -
113.45 - @JavaScriptBody(args = {"id", "attr", "value"}, body =
113.46 - "window.document.getElementById(id)[attr] = value;")
113.47 - private static native void setAttr(String id, String attr, Object value);
113.48 -
113.49 - @JavaScriptBody(args = {}, body = "return; window.close();")
113.50 - private static native void closeWindow();
113.51 -
113.52 - private static void log(String newText) {
113.53 - String id = "bck2brwsr.result";
113.54 - String attr = "value";
113.55 - setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
113.56 - setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
113.57 - }
113.58 -
113.59 - public static void execute() throws Exception {
113.60 - String clazz = (String) getAttr("clazz", "value");
113.61 - String method = (String) getAttr("method", "value");
113.62 - Object res = invokeMethod(clazz, method);
113.63 - setAttr("bck2brwsr.result", "value", res);
113.64 - }
113.65 -
113.66 - @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
113.67 - + "var request = new XMLHttpRequest();\n"
113.68 - + "request.open('GET', url, true);\n"
113.69 - + "request.onreadystatechange = function() {\n"
113.70 - + " if (this.readyState!==4) return;\n"
113.71 - + " arr[0] = this.responseText;\n"
113.72 - + " callback.run__V();\n"
113.73 - + "};"
113.74 - + "request.send();"
113.75 - )
113.76 - private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
113.77 -
113.78 - public static void harness(String url) throws IOException {
113.79 - log("Connecting to " + url);
113.80 - Request r = new Request(url);
113.81 - }
113.82 -
113.83 - private static class Request implements Runnable {
113.84 - private final String[] arr = { null };
113.85 - private final String url;
113.86 -
113.87 - private Request(String url) throws IOException {
113.88 - this.url = url;
113.89 - loadText(url, this, arr);
113.90 - }
113.91 -
113.92 - @Override
113.93 - public void run() {
113.94 - try {
113.95 - String data = arr[0];
113.96 - log("\nGot \"" + data + "\"");
113.97 -
113.98 - if (data == null) {
113.99 - log("Some error exiting");
113.100 - closeWindow();
113.101 - return;
113.102 - }
113.103 -
113.104 - if (data.isEmpty()) {
113.105 - log("No data, exiting");
113.106 - closeWindow();
113.107 - return;
113.108 - }
113.109 -
113.110 - Case c = Case.parseData(data);
113.111 - if (c.getHtmlFragment() != null) {
113.112 - setAttr("bck2brwsr.fragment", "innerHTML", c.getHtmlFragment());
113.113 - }
113.114 - log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
113.115 -
113.116 - Object result = invokeMethod(c.getClassName(), c.getMethodName());
113.117 -
113.118 - setAttr("bck2brwsr.fragment", "innerHTML", "");
113.119 - log("Result: " + result);
113.120 -
113.121 - result = encodeURL("" + result);
113.122 -
113.123 - log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
113.124 - String u = url + "?request=" + c.getRequestId() + "&result=" + result;
113.125 -
113.126 - loadText(u, this, arr);
113.127 -
113.128 - } catch (Exception ex) {
113.129 - log(ex.getMessage());
113.130 - }
113.131 - }
113.132 - }
113.133 -
113.134 - private static String encodeURL(String r) {
113.135 - StringBuilder sb = new StringBuilder();
113.136 - for (int i = 0; i < r.length(); i++) {
113.137 - int ch = r.charAt(i);
113.138 - if (ch < 32 || ch == '%' || ch == '+') {
113.139 - sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
113.140 - } else {
113.141 - if (ch == 32) {
113.142 - sb.append("+");
113.143 - } else {
113.144 - sb.append((char)ch);
113.145 - }
113.146 - }
113.147 - }
113.148 - return sb.toString();
113.149 - }
113.150 -
113.151 - static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
113.152 - final Object r = invokeMethod(clazz, method);
113.153 - return r == null ? "null" : r.toString().toString();
113.154 - }
113.155 -
113.156 - /** Helper method that inspects the classpath and loads given resource
113.157 - * (usually a class file). Used while running tests in Rhino.
113.158 - *
113.159 - * @param name resource name to find
113.160 - * @return the array of bytes in the given resource
113.161 - * @throws IOException I/O in case something goes wrong
113.162 - */
113.163 - public static byte[] read(String name) throws IOException {
113.164 - URL u = null;
113.165 - Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
113.166 - while (en.hasMoreElements()) {
113.167 - u = en.nextElement();
113.168 - }
113.169 - if (u == null) {
113.170 - throw new IOException("Can't find " + name);
113.171 - }
113.172 - try (InputStream is = u.openStream()) {
113.173 - byte[] arr;
113.174 - arr = new byte[is.available()];
113.175 - int offset = 0;
113.176 - while (offset < arr.length) {
113.177 - int len = is.read(arr, offset, arr.length - offset);
113.178 - if (len == -1) {
113.179 - throw new IOException("Can't read " + name);
113.180 - }
113.181 - offset += len;
113.182 - }
113.183 - return arr;
113.184 - }
113.185 - }
113.186 -
113.187 - private static Object invokeMethod(String clazz, String method)
113.188 - throws ClassNotFoundException, InvocationTargetException,
113.189 - SecurityException, IllegalAccessException, IllegalArgumentException,
113.190 - InstantiationException {
113.191 - Method found = null;
113.192 - Class<?> c = Class.forName(clazz);
113.193 - for (Method m : c.getMethods()) {
113.194 - if (m.getName().equals(method)) {
113.195 - found = m;
113.196 - }
113.197 - }
113.198 - Object res;
113.199 - if (found != null) {
113.200 - try {
113.201 - if ((found.getModifiers() & Modifier.STATIC) != 0) {
113.202 - res = found.invoke(null);
113.203 - } else {
113.204 - res = found.invoke(c.newInstance());
113.205 - }
113.206 - } catch (Throwable ex) {
113.207 - res = ex.getClass().getName() + ":" + ex.getMessage();
113.208 - }
113.209 - } else {
113.210 - res = "Can't find method " + method + " in " + clazz;
113.211 - }
113.212 - return res;
113.213 - }
113.214 -
113.215 - @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
113.216 - private static void turnAssetionStatusOn() {
113.217 - }
113.218 -
113.219 - private static final class Case {
113.220 - private final Object data;
113.221 -
113.222 - private Case(Object data) {
113.223 - this.data = data;
113.224 - }
113.225 -
113.226 - public static Case parseData(String s) {
113.227 - return new Case(toJSON(s));
113.228 - }
113.229 -
113.230 - public String getMethodName() {
113.231 - return value("methodName", data);
113.232 - }
113.233 -
113.234 - public String getClassName() {
113.235 - return value("className", data);
113.236 - }
113.237 -
113.238 - public String getRequestId() {
113.239 - return value("request", data);
113.240 - }
113.241 -
113.242 - public String getHtmlFragment() {
113.243 - return value("html", data);
113.244 - }
113.245 -
113.246 - @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
113.247 - private static native Object toJSON(String s);
113.248 -
113.249 - @JavaScriptBody(args = {"p", "d"}, body =
113.250 - "var v = d[p];\n"
113.251 - + "if (typeof v === 'undefined') return null;\n"
113.252 - + "return v.toString();"
113.253 - )
113.254 - private static native String value(String p, Object d);
113.255 - }
113.256 -}
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java Tue Feb 05 17:04:22 2013 +0100
114.3 @@ -0,0 +1,101 @@
114.4 +/**
114.5 + * Back 2 Browser Bytecode Translator
114.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
114.7 + *
114.8 + * This program is free software: you can redistribute it and/or modify
114.9 + * it under the terms of the GNU General Public License as published by
114.10 + * the Free Software Foundation, version 2 of the License.
114.11 + *
114.12 + * This program is distributed in the hope that it will be useful,
114.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
114.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
114.15 + * GNU General Public License for more details.
114.16 + *
114.17 + * You should have received a copy of the GNU General Public License
114.18 + * along with this program. Look for COPYING file in the top folder.
114.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
114.20 + */
114.21 +package org.apidesign.bck2brwsr.launcher;
114.22 +
114.23 +import java.io.IOException;
114.24 +import java.io.InputStream;
114.25 +import java.util.concurrent.CountDownLatch;
114.26 +import java.util.concurrent.TimeUnit;
114.27 +
114.28 +/** Represents individual method invocation, its context and its result.
114.29 + *
114.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
114.31 + */
114.32 +public final class InvocationContext {
114.33 + final CountDownLatch wait = new CountDownLatch(1);
114.34 + final Class<?> clazz;
114.35 + final String methodName;
114.36 + private final Launcher launcher;
114.37 + private String result;
114.38 + private Throwable exception;
114.39 + String html;
114.40 + InputStream httpContent;
114.41 + String httpType;
114.42 + String httpPath;
114.43 +
114.44 + InvocationContext(Launcher launcher, Class<?> clazz, String methodName) {
114.45 + this.launcher = launcher;
114.46 + this.clazz = clazz;
114.47 + this.methodName = methodName;
114.48 + }
114.49 +
114.50 + /** An HTML fragment to be available for the execution. Useful primarily when
114.51 + * executing in a browser via {@link Launcher#createBrowser(java.lang.String)}.
114.52 + * @param html the html fragment
114.53 + */
114.54 + public void setHtmlFragment(String html) {
114.55 + this.html = html;
114.56 + }
114.57 +
114.58 + /** HTTP resource to be available during execution. An invocation may
114.59 + * perform an HTTP query and obtain a resource relative to the page.
114.60 + */
114.61 + public void setHttpResource(String relativePath, String mimeType, InputStream content) {
114.62 + if (relativePath == null || mimeType == null || content == null) {
114.63 + throw new NullPointerException();
114.64 + }
114.65 + this.httpPath = relativePath;
114.66 + this.httpType = mimeType;
114.67 + this.httpContent = content;
114.68 + }
114.69 +
114.70 + /** Invokes the associated method.
114.71 + * @return the textual result of the invocation
114.72 + */
114.73 + public String invoke() throws IOException {
114.74 + launcher.runMethod(this);
114.75 + return toString();
114.76 + }
114.77 +
114.78 + /** Obtains textual result of the invocation.
114.79 + * @return text representing the exception or result value
114.80 + */
114.81 + @Override
114.82 + public String toString() {
114.83 + if (exception != null) {
114.84 + return exception.toString();
114.85 + }
114.86 + return result;
114.87 + }
114.88 +
114.89 + /**
114.90 + * @param timeOut
114.91 + * @throws InterruptedException
114.92 + */
114.93 + void await(long timeOut) throws InterruptedException {
114.94 + wait.await(timeOut, TimeUnit.MILLISECONDS);
114.95 + }
114.96 +
114.97 + void result(String r, Throwable e) {
114.98 + this.result = r;
114.99 + this.exception = e;
114.100 + wait.countDown();
114.101 + }
114.102 +
114.103 +
114.104 +}
115.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java Tue Feb 05 16:40:01 2013 +0100
115.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java Tue Feb 05 17:04:22 2013 +0100
115.3 @@ -17,12 +17,14 @@
115.4 */
115.5 package org.apidesign.bck2brwsr.launcher;
115.6
115.7 +import org.apidesign.bck2brwsr.launcher.impl.Console;
115.8 import java.io.IOException;
115.9 import java.io.InputStream;
115.10 import java.net.URL;
115.11 import java.util.Enumeration;
115.12 import java.util.LinkedHashSet;
115.13 import java.util.Set;
115.14 +import java.util.logging.Level;
115.15 import java.util.logging.Logger;
115.16 import javax.script.Invocable;
115.17 import javax.script.ScriptEngine;
115.18 @@ -42,14 +44,18 @@
115.19 private Object console;
115.20
115.21
115.22 - @Override MethodInvocation addMethod(Class<?> clazz, String method, String html) {
115.23 - loaders.add(clazz.getClassLoader());
115.24 - MethodInvocation mi = new MethodInvocation(clazz.getName(), method, html);
115.25 + @Override InvocationContext runMethod(InvocationContext mi) {
115.26 + loaders.add(mi.clazz.getClassLoader());
115.27 try {
115.28 - mi.result(code.invokeMethod(
115.29 + long time = System.currentTimeMillis();
115.30 + LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
115.31 + String res = code.invokeMethod(
115.32 console,
115.33 "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
115.34 - mi.className, mi.methodName).toString(), null);
115.35 + mi.clazz.getName(), mi.methodName).toString();
115.36 + time = System.currentTimeMillis() - time;
115.37 + LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
115.38 + mi.result(res, null);
115.39 } catch (ScriptException | NoSuchMethodException ex) {
115.40 mi.result(null, ex);
115.41 }
115.42 @@ -83,7 +89,7 @@
115.43 ScriptEngine mach = sem.getEngineByExtension("js");
115.44
115.45 sb.append(
115.46 - "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.Console.read);"
115.47 + "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
115.48 + "\nfunction initVM() { return vm; };"
115.49 + "\n");
115.50
116.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Tue Feb 05 16:40:01 2013 +0100
116.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Tue Feb 05 17:04:22 2013 +0100
116.3 @@ -18,12 +18,14 @@
116.4 package org.apidesign.bck2brwsr.launcher;
116.5
116.6 import java.io.Closeable;
116.7 +import java.io.File;
116.8 import java.io.IOException;
116.9 import java.net.URLClassLoader;
116.10 import org.apidesign.vm4brwsr.Bck2Brwsr;
116.11
116.12 /** An abstraction for executing tests in a Bck2Brwsr virtual machine.
116.13 - * Either in JavaScript engine, or in external browser.
116.14 + * Either in {@linkm Launcher#createJavaScript JavaScript engine},
116.15 + * or in {@linkm Launcher#createBrowser external browser}.
116.16 *
116.17 * @author Jaroslav Tulach <jtulach@netbeans.org>
116.18 */
116.19 @@ -31,33 +33,83 @@
116.20
116.21 Launcher() {
116.22 }
116.23 +
116.24 + /** Initializes the launcher. This may mean starting a web browser or
116.25 + * initializing execution engine.
116.26 + * @throws IOException if something goes wrong
116.27 + */
116.28 + public abstract void initialize() throws IOException;
116.29
116.30 - abstract MethodInvocation addMethod(Class<?> clazz, String method, String html) throws IOException;
116.31 -
116.32 - public abstract void initialize() throws IOException;
116.33 + /** Shuts down the launcher.
116.34 + * @throws IOException if something goes wrong
116.35 + */
116.36 public abstract void shutdown() throws IOException;
116.37 - public MethodInvocation invokeMethod(Class<?> clazz, String method, String html) throws IOException {
116.38 - return addMethod(clazz, method, html);
116.39 +
116.40 +
116.41 + /** Builds an invocation context. The context can later be customized
116.42 + * and {@link InvocationContext#invoke() invoked}.
116.43 + *
116.44 + * @param clazz the class to execute method from
116.45 + * @param method the method to execute
116.46 + * @return the context pointing to the selected method
116.47 + */
116.48 + public InvocationContext createInvocation(Class<?> clazz, String method) {
116.49 + return new InvocationContext(this, clazz, method);
116.50 }
116.51
116.52 -
116.53
116.54 + /** Creates launcher that uses internal JavaScript engine (Rhino).
116.55 + * @return the launcher
116.56 + */
116.57 public static Launcher createJavaScript() {
116.58 final JSLauncher l = new JSLauncher();
116.59 l.addClassLoader(Bck2Brwsr.class.getClassLoader());
116.60 return l;
116.61 }
116.62
116.63 + /** Creates launcher that is using external browser.
116.64 + *
116.65 + * @param cmd <code>null</code> to use <code>java.awt.Desktop</code> to show the launcher
116.66 + * or a string to execute in an external process (with a parameter to the URL)
116.67 + * @return launcher executing in external browser.
116.68 + */
116.69 public static Launcher createBrowser(String cmd) {
116.70 final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
116.71 l.addClassLoader(Bck2Brwsr.class.getClassLoader());
116.72 l.setTimeout(180000);
116.73 return l;
116.74 }
116.75 +
116.76 + /** Starts an HTTP server which provides access to classes and resources
116.77 + * available in the <code>classes</code> URL and shows a start page
116.78 + * available as {@link ClassLoader#getResource(java.lang.String)} from the
116.79 + * provide classloader. Opens a browser with URL showing the start page.
116.80 + *
116.81 + * @param classes classloader offering access to classes and resources
116.82 + * @param startpage page to show in the browser
116.83 + * @return interface that allows one to stop the server
116.84 + * @throws IOException if something goes wrong
116.85 + */
116.86 public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
116.87 Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
116.88 l.addClassLoader(classes);
116.89 l.showURL(startpage);
116.90 return l;
116.91 }
116.92 + /** Starts an HTTP server which provides access to certain directory.
116.93 + * The <code>startpage</code> should be relative location inside the root
116.94 + * driecotry
116.95 + * Opens a browser with URL showing the start page.
116.96 + *
116.97 + * @param directory the root directory on disk
116.98 + * @praam startpage relative path from the root to the page
116.99 + * @exception IOException if something goes wrong.
116.100 + */
116.101 + public static Closeable showDir(File directory, String startpage) throws IOException {
116.102 + Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
116.103 + l.showDirectory(directory, startpage);
116.104 + return l;
116.105 + }
116.106 +
116.107 + abstract InvocationContext runMethod(InvocationContext c) throws IOException;
116.108 }
117.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java Tue Feb 05 16:40:01 2013 +0100
117.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
117.3 @@ -1,59 +0,0 @@
117.4 -/**
117.5 - * Back 2 Browser Bytecode Translator
117.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
117.7 - *
117.8 - * This program is free software: you can redistribute it and/or modify
117.9 - * it under the terms of the GNU General Public License as published by
117.10 - * the Free Software Foundation, version 2 of the License.
117.11 - *
117.12 - * This program is distributed in the hope that it will be useful,
117.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
117.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
117.15 - * GNU General Public License for more details.
117.16 - *
117.17 - * You should have received a copy of the GNU General Public License
117.18 - * along with this program. Look for COPYING file in the top folder.
117.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
117.20 - */
117.21 -package org.apidesign.bck2brwsr.launcher;
117.22 -
117.23 -import java.util.concurrent.CountDownLatch;
117.24 -import java.util.concurrent.TimeUnit;
117.25 -
117.26 -/**
117.27 - *
117.28 - * @author Jaroslav Tulach <jtulach@netbeans.org>
117.29 - */
117.30 -public final class MethodInvocation {
117.31 - final CountDownLatch wait = new CountDownLatch(1);
117.32 - final String className;
117.33 - final String methodName;
117.34 - final String html;
117.35 - private String result;
117.36 - private Throwable exception;
117.37 -
117.38 - MethodInvocation(String className, String methodName, String html) {
117.39 - this.className = className;
117.40 - this.methodName = methodName;
117.41 - this.html = html;
117.42 - }
117.43 -
117.44 - void await(long timeOut) throws InterruptedException {
117.45 - wait.await(timeOut, TimeUnit.MILLISECONDS);
117.46 - }
117.47 -
117.48 - void result(String r, Throwable e) {
117.49 - this.result = r;
117.50 - this.exception = e;
117.51 - wait.countDown();
117.52 - }
117.53 -
117.54 - @Override
117.55 - public String toString() {
117.56 - if (exception != null) {
117.57 - return exception.toString();
117.58 - }
117.59 - return result;
117.60 - }
117.61 -
117.62 -}
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java Tue Feb 05 17:04:22 2013 +0100
118.3 @@ -0,0 +1,255 @@
118.4 +/**
118.5 + * Back 2 Browser Bytecode Translator
118.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
118.7 + *
118.8 + * This program is free software: you can redistribute it and/or modify
118.9 + * it under the terms of the GNU General Public License as published by
118.10 + * the Free Software Foundation, version 2 of the License.
118.11 + *
118.12 + * This program is distributed in the hope that it will be useful,
118.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
118.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
118.15 + * GNU General Public License for more details.
118.16 + *
118.17 + * You should have received a copy of the GNU General Public License
118.18 + * along with this program. Look for COPYING file in the top folder.
118.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
118.20 + */
118.21 +package org.apidesign.bck2brwsr.launcher.impl;
118.22 +
118.23 +import java.io.IOException;
118.24 +import java.io.InputStream;
118.25 +import java.lang.reflect.InvocationTargetException;
118.26 +import java.lang.reflect.Method;
118.27 +import java.lang.reflect.Modifier;
118.28 +import java.net.URL;
118.29 +import java.util.Enumeration;
118.30 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
118.31 +
118.32 +/**
118.33 + *
118.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
118.35 + */
118.36 +public class Console {
118.37 + private Console() {
118.38 + }
118.39 + static {
118.40 + turnAssetionStatusOn();
118.41 + }
118.42 +
118.43 + @JavaScriptBody(args = {"id", "attr"}, body =
118.44 + "return window.document.getElementById(id)[attr].toString();")
118.45 + private static native Object getAttr(String id, String attr);
118.46 +
118.47 + @JavaScriptBody(args = {"id", "attr", "value"}, body =
118.48 + "window.document.getElementById(id)[attr] = value;")
118.49 + private static native void setAttr(String id, String attr, Object value);
118.50 +
118.51 + @JavaScriptBody(args = {}, body = "return; window.close();")
118.52 + private static native void closeWindow();
118.53 +
118.54 + private static void log(String newText) {
118.55 + String id = "bck2brwsr.result";
118.56 + String attr = "value";
118.57 + setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
118.58 + setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
118.59 + }
118.60 +
118.61 + public static void execute() throws Exception {
118.62 + String clazz = (String) getAttr("clazz", "value");
118.63 + String method = (String) getAttr("method", "value");
118.64 + Object res = invokeMethod(clazz, method);
118.65 + setAttr("bck2brwsr.result", "value", res);
118.66 + }
118.67 +
118.68 + @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
118.69 + + "var request = new XMLHttpRequest();\n"
118.70 + + "request.open('GET', url, true);\n"
118.71 + + "request.onreadystatechange = function() {\n"
118.72 + + " if (this.readyState!==4) return;\n"
118.73 + + " arr[0] = this.responseText;\n"
118.74 + + " callback.run__V();\n"
118.75 + + "};"
118.76 + + "request.send();"
118.77 + )
118.78 + private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
118.79 +
118.80 + public static void harness(String url) throws IOException {
118.81 + log("Connecting to " + url);
118.82 + Request r = new Request(url);
118.83 + }
118.84 +
118.85 + private static class Request implements Runnable {
118.86 + private final String[] arr = { null };
118.87 + private final String url;
118.88 +
118.89 + private Request(String url) throws IOException {
118.90 + this.url = url;
118.91 + loadText(url, this, arr);
118.92 + }
118.93 +
118.94 + @Override
118.95 + public void run() {
118.96 + try {
118.97 + String data = arr[0];
118.98 + log("\nGot \"" + data + "\"");
118.99 +
118.100 + if (data == null) {
118.101 + log("Some error exiting");
118.102 + closeWindow();
118.103 + return;
118.104 + }
118.105 +
118.106 + if (data.isEmpty()) {
118.107 + log("No data, exiting");
118.108 + closeWindow();
118.109 + return;
118.110 + }
118.111 +
118.112 + Case c = Case.parseData(data);
118.113 + if (c.getHtmlFragment() != null) {
118.114 + setAttr("bck2brwsr.fragment", "innerHTML", c.getHtmlFragment());
118.115 + }
118.116 + log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
118.117 +
118.118 + Object result = invokeMethod(c.getClassName(), c.getMethodName());
118.119 +
118.120 + setAttr("bck2brwsr.fragment", "innerHTML", "");
118.121 + log("Result: " + result);
118.122 +
118.123 + result = encodeURL("" + result);
118.124 +
118.125 + log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
118.126 + String u = url + "?request=" + c.getRequestId() + "&result=" + result;
118.127 +
118.128 + loadText(u, this, arr);
118.129 +
118.130 + } catch (Exception ex) {
118.131 + log(ex.getMessage());
118.132 + }
118.133 + }
118.134 + }
118.135 +
118.136 + private static String encodeURL(String r) {
118.137 + StringBuilder sb = new StringBuilder();
118.138 + for (int i = 0; i < r.length(); i++) {
118.139 + int ch = r.charAt(i);
118.140 + if (ch < 32 || ch == '%' || ch == '+') {
118.141 + sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
118.142 + } else {
118.143 + if (ch == 32) {
118.144 + sb.append("+");
118.145 + } else {
118.146 + sb.append((char)ch);
118.147 + }
118.148 + }
118.149 + }
118.150 + return sb.toString();
118.151 + }
118.152 +
118.153 + static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
118.154 + final Object r = invokeMethod(clazz, method);
118.155 + return r == null ? "null" : r.toString().toString();
118.156 + }
118.157 +
118.158 + /** Helper method that inspects the classpath and loads given resource
118.159 + * (usually a class file). Used while running tests in Rhino.
118.160 + *
118.161 + * @param name resource name to find
118.162 + * @return the array of bytes in the given resource
118.163 + * @throws IOException I/O in case something goes wrong
118.164 + */
118.165 + public static byte[] read(String name) throws IOException {
118.166 + URL u = null;
118.167 + Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
118.168 + while (en.hasMoreElements()) {
118.169 + u = en.nextElement();
118.170 + }
118.171 + if (u == null) {
118.172 + throw new IOException("Can't find " + name);
118.173 + }
118.174 + try (InputStream is = u.openStream()) {
118.175 + byte[] arr;
118.176 + arr = new byte[is.available()];
118.177 + int offset = 0;
118.178 + while (offset < arr.length) {
118.179 + int len = is.read(arr, offset, arr.length - offset);
118.180 + if (len == -1) {
118.181 + throw new IOException("Can't read " + name);
118.182 + }
118.183 + offset += len;
118.184 + }
118.185 + return arr;
118.186 + }
118.187 + }
118.188 +
118.189 + private static Object invokeMethod(String clazz, String method)
118.190 + throws ClassNotFoundException, InvocationTargetException,
118.191 + SecurityException, IllegalAccessException, IllegalArgumentException,
118.192 + InstantiationException {
118.193 + Method found = null;
118.194 + Class<?> c = Class.forName(clazz);
118.195 + for (Method m : c.getMethods()) {
118.196 + if (m.getName().equals(method)) {
118.197 + found = m;
118.198 + }
118.199 + }
118.200 + Object res;
118.201 + if (found != null) {
118.202 + try {
118.203 + if ((found.getModifiers() & Modifier.STATIC) != 0) {
118.204 + res = found.invoke(null);
118.205 + } else {
118.206 + res = found.invoke(c.newInstance());
118.207 + }
118.208 + } catch (Throwable ex) {
118.209 + res = ex.getClass().getName() + ":" + ex.getMessage();
118.210 + }
118.211 + } else {
118.212 + res = "Can't find method " + method + " in " + clazz;
118.213 + }
118.214 + return res;
118.215 + }
118.216 +
118.217 + @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
118.218 + private static void turnAssetionStatusOn() {
118.219 + }
118.220 +
118.221 + private static final class Case {
118.222 + private final Object data;
118.223 +
118.224 + private Case(Object data) {
118.225 + this.data = data;
118.226 + }
118.227 +
118.228 + public static Case parseData(String s) {
118.229 + return new Case(toJSON(s));
118.230 + }
118.231 +
118.232 + public String getMethodName() {
118.233 + return value("methodName", data);
118.234 + }
118.235 +
118.236 + public String getClassName() {
118.237 + return value("className", data);
118.238 + }
118.239 +
118.240 + public String getRequestId() {
118.241 + return value("request", data);
118.242 + }
118.243 +
118.244 + public String getHtmlFragment() {
118.245 + return value("html", data);
118.246 + }
118.247 +
118.248 + @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
118.249 + private static native Object toJSON(String s);
118.250 +
118.251 + @JavaScriptBody(args = {"p", "d"}, body =
118.252 + "var v = d[p];\n"
118.253 + + "if (typeof v === 'undefined') return null;\n"
118.254 + + "return v.toString();"
118.255 + )
118.256 + private static native String value(String p, Object d);
118.257 + }
118.258 +}
119.1 --- a/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Tue Feb 05 16:40:01 2013 +0100
119.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Tue Feb 05 17:04:22 2013 +0100
119.3 @@ -34,7 +34,7 @@
119.4 <div id="bck2brwsr.fragment"/>
119.5
119.6 <script type="text/javascript">
119.7 - vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
119.8 + vm.loadClass('org.apidesign.bck2brwsr.launcher.impl.Console').harness__VLjava_lang_String_2('$U/../data');
119.9 </script>
119.10 </body>
119.11 </html>
120.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Tue Feb 05 16:40:01 2013 +0100
120.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Tue Feb 05 17:04:22 2013 +0100
120.3 @@ -51,21 +51,28 @@
120.4 /** Root of the class files */
120.5 @Parameter(defaultValue="${project.build.directory}/classes")
120.6 private File classes;
120.7 +
120.8 + /** Root of all pages, and files, etc. */
120.9 + @Parameter
120.10 + private File directory;
120.11
120.12 @Override
120.13 public void execute() throws MojoExecutionException {
120.14 if (startpage == null) {
120.15 throw new MojoExecutionException("You have to provide a start page");
120.16 }
120.17 -
120.18 +
120.19 try {
120.20 - URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
120.21 -
120.22 Closeable httpServer;
120.23 - try {
120.24 - httpServer = Launcher.showURL(url, startpage());
120.25 - } catch (Exception ex) {
120.26 - throw new MojoExecutionException("Can't open " + startpage(), ex);
120.27 + if (directory != null) {
120.28 + httpServer = Launcher.showDir(directory, startpage);
120.29 + } else {
120.30 + URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
120.31 + try {
120.32 + httpServer = Launcher.showURL(url, startpage());
120.33 + } catch (Exception ex) {
120.34 + throw new MojoExecutionException("Can't open " + startpage(), ex);
120.35 + }
120.36 }
120.37 System.in.read();
120.38 httpServer.close();
121.1 --- a/mojo/src/main/resources/archetype-resources/pom.xml Tue Feb 05 16:40:01 2013 +0100
121.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml Tue Feb 05 17:04:22 2013 +0100
121.3 @@ -60,7 +60,7 @@
121.4 <scope>test</scope>
121.5 </dependency>
121.6 <dependency>
121.7 - <groupId>${project.groupId}</groupId>
121.8 + <groupId>org.apidesign.bck2brwsr</groupId>
121.9 <artifactId>vmtest</artifactId>
121.10 <version>0.3-SNAPSHOT</version>
121.11 <scope>test</scope>
122.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Feb 05 16:40:01 2013 +0100
122.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Feb 05 17:04:22 2013 +0100
122.3 @@ -1278,7 +1278,7 @@
122.4 int indx = readIntArg(byteCodes, i);
122.5 final String type = jc.getClassName(indx);
122.6 if (!type.startsWith("[")) {
122.7 - emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;",
122.8 + emit(out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
122.9 smapper.popA(), smapper.pushI(),
122.10 type.replace('/', '_'));
122.11 } else {
123.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue Feb 05 16:40:01 2013 +0100
123.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue Feb 05 17:04:22 2013 +0100
123.3 @@ -32,6 +32,7 @@
123.4 static {
123.5 // uses VMLazy to load dynamic classes
123.6 VMLazy.init();
123.7 + Zips.init();
123.8 }
123.9
123.10 @Override
123.11 @@ -116,6 +117,12 @@
123.12 + " var args = arguments;\n"
123.13 + " var loader = {};\n"
123.14 + " loader.vm = vm;\n"
123.15 + + " if (args.length == 1 && typeof args[0] !== 'function') {;\n"
123.16 + + " var classpath = args[0];\n"
123.17 + + " args[0] = function(name) {\n"
123.18 + + " return vm.org_apidesign_vm4brwsr_Zips(false).loadFromCp___3B_3Ljava_lang_Object_2Ljava_lang_String_2(classpath, name);\n"
123.19 + + " };\n"
123.20 + + " };\n"
123.21 + " loader.loadClass = function(name) {\n"
123.22 + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
123.23 + " var fn = vm[attr];\n"
124.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java Tue Feb 05 17:04:22 2013 +0100
124.3 @@ -0,0 +1,97 @@
124.4 +/**
124.5 + * Back 2 Browser Bytecode Translator
124.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
124.7 + *
124.8 + * This program is free software: you can redistribute it and/or modify
124.9 + * it under the terms of the GNU General Public License as published by
124.10 + * the Free Software Foundation, version 2 of the License.
124.11 + *
124.12 + * This program is distributed in the hope that it will be useful,
124.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
124.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124.15 + * GNU General Public License for more details.
124.16 + *
124.17 + * You should have received a copy of the GNU General Public License
124.18 + * along with this program. Look for COPYING file in the top folder.
124.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
124.20 + */
124.21 +package org.apidesign.vm4brwsr;
124.22 +
124.23 +import java.io.IOException;
124.24 +import java.net.URL;
124.25 +import java.util.zip.ZipEntry;
124.26 +import java.util.zip.ZipInputStream;
124.27 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
124.28 +
124.29 +/** Conversion from classpath to load function.
124.30 + *
124.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
124.32 + */
124.33 +final class Zips {
124.34 + private Zips() {
124.35 + }
124.36 +
124.37 + public static void init() {
124.38 + }
124.39 +
124.40 + public static byte[] loadFromCp(Object[] classpath, String res) {
124.41 + for (int i = 0; i < classpath.length; i++) {
124.42 + Object c = classpath[i];
124.43 + if (c instanceof String) {
124.44 + try {
124.45 + c = classpath[i] = toZip((String)c);
124.46 + } catch (IOException ex) {
124.47 + classpath[i] = ex;
124.48 + }
124.49 + }
124.50 + if (c instanceof Zips) {
124.51 + Object checkRes = ((Zips)c).findRes(res);
124.52 + if (checkRes instanceof byte[]) {
124.53 + return (byte[])checkRes;
124.54 + }
124.55 + }
124.56 + }
124.57 + return null;
124.58 + }
124.59 +
124.60 + @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;")
124.61 + private native byte[] findRes(String res);
124.62 +
124.63 + @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;")
124.64 + private native void putRes(String res, byte[] arr);
124.65 +
124.66 + private static Zips toZip(String path) throws IOException {
124.67 + URL u = new URL(path);
124.68 + ZipInputStream zip = new ZipInputStream(u.openStream());
124.69 + Zips z = new Zips();
124.70 + for (;;) {
124.71 + ZipEntry entry = zip.getNextEntry();
124.72 + if (entry == null) {
124.73 + break;
124.74 + }
124.75 + byte[] arr = new byte[4096];
124.76 + int offset = 0;
124.77 + for (;;) {
124.78 + int len = zip.read(arr, offset, arr.length - offset);
124.79 + if (len == -1) {
124.80 + break;
124.81 + }
124.82 + offset += len;
124.83 + if (offset == arr.length) {
124.84 + enlargeArray(arr, arr.length + 4096);
124.85 + }
124.86 + }
124.87 + sliceArray(arr, offset);
124.88 + z.putRes(entry.getName(), arr);
124.89 + }
124.90 + return z;
124.91 + }
124.92 +
124.93 + @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);")
124.94 + private static native void enlargeArray(byte[] arr, int len);
124.95 +
124.96 + @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);")
124.97 + private static native void sliceArray(byte[] arr, int len);
124.98 +
124.99 +
124.100 +}
125.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Tue Feb 05 16:40:01 2013 +0100
125.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Tue Feb 05 17:04:22 2013 +0100
125.3 @@ -68,12 +68,12 @@
125.4 GetByte i = new InstanceSub(7, 2.2d);
125.5 return i.getByte();
125.6 }
125.7 - public static boolean instanceOf(boolean sub) {
125.8 + public static boolean instanceOf(int sub) {
125.9 Instance i = createInstance(sub);
125.10 return isInstanceSubOf(i);
125.11 }
125.12 public static int castsWork(boolean interfc) {
125.13 - Instance i = createInstance(true);
125.14 + Instance i = createInstance(2);
125.15 if (interfc) {
125.16 GetByte b = (GetByte)i;
125.17 } else {
125.18 @@ -85,11 +85,16 @@
125.19 private static boolean isInstanceSubOf(Instance instance) {
125.20 return instance instanceof InstanceSub;
125.21 }
125.22 - private static Instance createInstance(boolean sub) {
125.23 - return sub ? new InstanceSub(3, 0) : new Instance();
125.24 + private static Instance createInstance(int type) {
125.25 + switch (type) {
125.26 + case 0: return null;
125.27 + case 1: return new Instance();
125.28 + case 2: return new InstanceSub(3, 0);
125.29 + }
125.30 + throw new IllegalArgumentException();
125.31 }
125.32 private static boolean isNull() {
125.33 - return createInstance(true) == null;
125.34 + return createInstance(2) == null;
125.35 }
125.36
125.37 @JavaScriptBody(args = "obj", body = "return obj.constructor;")
126.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Tue Feb 05 16:40:01 2013 +0100
126.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Tue Feb 05 17:04:22 2013 +0100
126.3 @@ -80,16 +80,23 @@
126.4 @Test public void isInstanceOf() throws Exception {
126.5 assertExec(
126.6 "Yes, we are instance",
126.7 - Instance.class, "instanceOf__ZZ",
126.8 - Double.valueOf(1.0), true
126.9 + Instance.class, "instanceOf__ZI",
126.10 + Double.valueOf(1.0), 2
126.11 );
126.12 }
126.13
126.14 @Test public void notInstanceOf() throws Exception {
126.15 assertExec(
126.16 "No, we are not an instance",
126.17 - Instance.class, "instanceOf__ZZ",
126.18 - Double.valueOf(0.0), false
126.19 + Instance.class, "instanceOf__ZI",
126.20 + Double.valueOf(0.0), 1
126.21 + );
126.22 + }
126.23 + @Test public void nullInstanceOf() throws Exception {
126.24 + assertExec(
126.25 + "No, null is not an instance",
126.26 + Instance.class, "instanceOf__ZI",
126.27 + Double.valueOf(0.0), 0
126.28 );
126.29 }
126.30
127.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Feb 05 16:40:01 2013 +0100
127.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Feb 05 17:04:22 2013 +0100
127.3 @@ -78,6 +78,89 @@
127.4 3.0d, 1l
127.5 );
127.6 }
127.7 +
127.8 + @Test public void rintNegativeUp() throws Exception {
127.9 + final double cnts = -453904.634;
127.10 + assertExec(
127.11 + "Should round up to end with 5",
127.12 + Math.class, "rint__DD",
127.13 + -453905.0, cnts
127.14 + );
127.15 + }
127.16 +
127.17 + @Test public void rintNegativeDown() throws Exception {
127.18 + final double cnts = -453904.434;
127.19 + assertExec(
127.20 + "Should round up to end with 4",
127.21 + Math.class, "rint__DD",
127.22 + -453904.0, cnts
127.23 + );
127.24 + }
127.25 +
127.26 + @Test public void rintPositiveUp() throws Exception {
127.27 + final double cnts = 453904.634;
127.28 + assertExec(
127.29 + "Should round up to end with 5",
127.30 + Math.class, "rint__DD",
127.31 + 453905.0, cnts
127.32 + );
127.33 + }
127.34 + @Test public void rintPositiveDown() throws Exception {
127.35 + final double cnts = 453904.434;
127.36 + assertExec(
127.37 + "Should round up to end with 4",
127.38 + Math.class, "rint__DD",
127.39 + 453904.0, cnts
127.40 + );
127.41 + }
127.42 + @Test public void rintOneHalf() throws Exception {
127.43 + final double cnts = 1.5;
127.44 + assertExec(
127.45 + "Should round up to end with 2",
127.46 + Math.class, "rint__DD",
127.47 + 2.0, cnts
127.48 + );
127.49 + }
127.50 + @Test public void rintNegativeOneHalf() throws Exception {
127.51 + final double cnts = -1.5;
127.52 + assertExec(
127.53 + "Should round up to end with 2",
127.54 + Math.class, "rint__DD",
127.55 + -2.0, cnts
127.56 + );
127.57 + }
127.58 + @Test public void rintTwoAndHalf() throws Exception {
127.59 + final double cnts = 2.5;
127.60 + assertExec(
127.61 + "Should round up to end with 2",
127.62 + Math.class, "rint__DD",
127.63 + 2.0, cnts
127.64 + );
127.65 + }
127.66 + @Test public void rintNegativeTwoOneHalf() throws Exception {
127.67 + final double cnts = -2.5;
127.68 + assertExec(
127.69 + "Should round up to end with 2",
127.70 + Math.class, "rint__DD",
127.71 + -2.0, cnts
127.72 + );
127.73 + }
127.74 +
127.75 + @Test public void ieeeReminder1() throws Exception {
127.76 + assertExec(
127.77 + "Same result 1",
127.78 + Math.class, "IEEEremainder__DDD",
127.79 + Math.IEEEremainder(10.0, 4.5), 10.0, 4.5
127.80 + );
127.81 + }
127.82 +
127.83 + @Test public void ieeeReminder2() throws Exception {
127.84 + assertExec(
127.85 + "Same result 1",
127.86 + Math.class, "IEEEremainder__DDD",
127.87 + Math.IEEEremainder(Integer.MAX_VALUE, -4.5), Integer.MAX_VALUE, -4.5
127.88 + );
127.89 + }
127.90
127.91 @Test public void divAndRound() throws Exception {
127.92 assertExec(
128.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java Tue Feb 05 16:40:01 2013 +0100
128.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java Tue Feb 05 17:04:22 2013 +0100
128.3 @@ -68,6 +68,15 @@
128.4 return chars('a', (char)30, 'b') instanceof String;
128.5 }
128.6
128.7 + public static String getBytes(String s) {
128.8 + byte[] arr = s.getBytes();
128.9 + StringBuilder sb = new StringBuilder();
128.10 + for (int i = 0; i < arr.length; i++) {
128.11 + sb.append(arr[i]).append(" ");
128.12 + }
128.13 + return sb.toString().toString();
128.14 + }
128.15 +
128.16 public static String insertBuffer() {
128.17 StringBuilder sb = new StringBuilder();
128.18 sb.append("Jardo!");
129.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Tue Feb 05 16:40:01 2013 +0100
129.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Tue Feb 05 17:04:22 2013 +0100
129.3 @@ -75,6 +75,16 @@
129.4 );
129.5 }
129.6
129.7 + @Test public void getBytes() throws Exception {
129.8 + final String horse = "Žluťoučký kůň";
129.9 + final String expected = StringSample.getBytes(horse);
129.10 + assertExec(
129.11 + "Bytes look simplar",
129.12 + StringSample.class, "getBytes__Ljava_lang_String_2Ljava_lang_String_2",
129.13 + expected, horse
129.14 + );
129.15 + }
129.16 +
129.17 @Test(timeOut=10000) public void toStringConcatenation() throws Exception {
129.18 assertExec(
129.19 "Five executions should generate 5Hello World!",
130.1 --- a/vmtest/pom.xml Tue Feb 05 16:40:01 2013 +0100
130.2 +++ b/vmtest/pom.xml Tue Feb 05 17:04:22 2013 +0100
130.3 @@ -58,5 +58,10 @@
130.4 <artifactId>launcher</artifactId>
130.5 <version>${project.version}</version>
130.6 </dependency>
130.7 + <dependency>
130.8 + <groupId>org.netbeans.api</groupId>
130.9 + <artifactId>org-openide-util-lookup</artifactId>
130.10 + <scope>provided</scope>
130.11 + </dependency>
130.12 </dependencies>
130.13 </project>
131.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
131.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/HttpResource.java Tue Feb 05 17:04:22 2013 +0100
131.3 @@ -0,0 +1,43 @@
131.4 +/**
131.5 + * Back 2 Browser Bytecode Translator
131.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
131.7 + *
131.8 + * This program is free software: you can redistribute it and/or modify
131.9 + * it under the terms of the GNU General Public License as published by
131.10 + * the Free Software Foundation, version 2 of the License.
131.11 + *
131.12 + * This program is distributed in the hope that it will be useful,
131.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
131.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
131.15 + * GNU General Public License for more details.
131.16 + *
131.17 + * You should have received a copy of the GNU General Public License
131.18 + * along with this program. Look for COPYING file in the top folder.
131.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
131.20 + */
131.21 +package org.apidesign.bck2brwsr.vmtest;
131.22 +
131.23 +import java.lang.annotation.ElementType;
131.24 +import java.lang.annotation.Retention;
131.25 +import java.lang.annotation.RetentionPolicy;
131.26 +import java.lang.annotation.Target;
131.27 +
131.28 +/** Exposes an HTTP page to the running {@link BrwsrTest}, so it can access
131.29 + * under the relative path.
131.30 + *
131.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
131.32 + */
131.33 +@Retention(RetentionPolicy.RUNTIME)
131.34 +@Target({ ElementType.METHOD, ElementType.TYPE})
131.35 +public @interface HttpResource {
131.36 + /** path on the server that the test can use to access the exposed resource */
131.37 + String path();
131.38 + /** the content of the HttpResource */
131.39 + String content();
131.40 + /** resource relative to the class that should be used instead of <code>content</code>.
131.41 + * Leave content equal to empty string.
131.42 + */
131.43 + String resource() default "";
131.44 + /** mime type of the resource */
131.45 + String mimeType();
131.46 +}
132.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Tue Feb 05 16:40:01 2013 +0100
132.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Tue Feb 05 17:04:22 2013 +0100
132.3 @@ -17,16 +17,18 @@
132.4 */
132.5 package org.apidesign.bck2brwsr.vmtest.impl;
132.6
132.7 +import java.io.ByteArrayInputStream;
132.8 import java.io.File;
132.9 import java.io.FileWriter;
132.10 import java.io.IOException;
132.11 +import java.io.InputStream;
132.12 import java.lang.reflect.Constructor;
132.13 import java.lang.reflect.InvocationTargetException;
132.14 import java.lang.reflect.Method;
132.15 -import java.util.Map;
132.16 -import java.util.WeakHashMap;
132.17 import org.apidesign.bck2brwsr.launcher.Launcher;
132.18 -import org.apidesign.bck2brwsr.launcher.MethodInvocation;
132.19 +import org.apidesign.bck2brwsr.launcher.InvocationContext;
132.20 +import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
132.21 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
132.22 import org.testng.ITest;
132.23 import org.testng.annotations.Test;
132.24
132.25 @@ -39,22 +41,36 @@
132.26 private final Launcher l;
132.27 private final String type;
132.28 private final boolean fail;
132.29 + private final HtmlFragment html;
132.30 + private final HttpResource http;
132.31 Object value;
132.32 - private final String html;
132.33
132.34 - Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, String html) {
132.35 + Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, HtmlFragment html, HttpResource http) {
132.36 this.l = l;
132.37 this.m = m;
132.38 this.type = type;
132.39 this.fail = fail;
132.40 this.html = html;
132.41 + this.http = http;
132.42 }
132.43
132.44 @Test(groups = "run")
132.45 public void executeCode() throws Throwable {
132.46 if (l != null) {
132.47 - MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName(), html);
132.48 - String res = c.toString();
132.49 + InvocationContext c = l.createInvocation(m.getDeclaringClass(), m.getName());
132.50 + if (html != null) {
132.51 + c.setHtmlFragment(html.value());
132.52 + }
132.53 + if (http != null) {
132.54 + if (!http.content().isEmpty()) {
132.55 + InputStream is = new ByteArrayInputStream(http.content().getBytes("UTF-8"));
132.56 + c.setHttpResource(http.path(), http.mimeType(), is);
132.57 + } else {
132.58 + InputStream is = m.getDeclaringClass().getResourceAsStream(http.resource());
132.59 + c.setHttpResource(http.path(), http.mimeType(), is);
132.60 + }
132.61 + }
132.62 + String res = c.invoke();
132.63 value = res;
132.64 if (fail) {
132.65 int idx = res.indexOf(':');
132.66 @@ -94,6 +110,9 @@
132.67 } catch (InvocationTargetException ex) {
132.68 Throwable t = ex.getTargetException();
132.69 value = t.getClass().getName() + ":" + t.getMessage();
132.70 + if (t instanceof AssertionError) {
132.71 + throw t;
132.72 + }
132.73 }
132.74 }
132.75 }
133.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Tue Feb 05 16:40:01 2013 +0100
133.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Tue Feb 05 17:04:22 2013 +0100
133.3 @@ -111,17 +111,17 @@
133.4 if (c == null) {
133.5 return;
133.6 }
133.7 - final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null);
133.8 + final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null, null);
133.9 ret.add(real);
133.10 if (c.scripting()) {
133.11 - final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null);
133.12 + final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null, null);
133.13 ret.add(js);
133.14 ret.add(new CompareCase(m, real, js));
133.15 }
133.16 for (String b : brwsr) {
133.17 final Launcher s = l.brwsr(b);
133.18 ret.add(s);
133.19 - final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null);
133.20 + final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null, null);
133.21 ret.add(cse);
133.22 ret.add(new CompareCase(m, real, cse));
133.23 }
133.24 @@ -135,16 +135,19 @@
133.25 if (f == null) {
133.26 f = m.getDeclaringClass().getAnnotation(HtmlFragment.class);
133.27 }
133.28 - String html = f == null ? null : f.value();
133.29 + HttpResource r = m.getAnnotation(HttpResource.class);
133.30 + if (r == null) {
133.31 + r = m.getDeclaringClass().getAnnotation(HttpResource.class);
133.32 + }
133.33 if (brwsr.length == 0) {
133.34 final Launcher s = l.brwsr(null);
133.35 ret.add(s);
133.36 - ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, html));
133.37 + ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, f, r));
133.38 } else {
133.39 for (String b : brwsr) {
133.40 final Launcher s = l.brwsr(b);
133.41 ret.add(s);
133.42 - ret.add(new Bck2BrwsrCase(m, b, s, true, html));
133.43 + ret.add(new Bck2BrwsrCase(m, b, s, true, f, r));
133.44 }
133.45 }
133.46 }
134.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZip.java Tue Feb 05 17:04:22 2013 +0100
134.3 @@ -0,0 +1,36 @@
134.4 +/**
134.5 + * Back 2 Browser Bytecode Translator
134.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
134.7 + *
134.8 + * This program is free software: you can redistribute it and/or modify
134.9 + * it under the terms of the GNU General Public License as published by
134.10 + * the Free Software Foundation, version 2 of the License.
134.11 + *
134.12 + * This program is distributed in the hope that it will be useful,
134.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
134.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134.15 + * GNU General Public License for more details.
134.16 + *
134.17 + * You should have received a copy of the GNU General Public License
134.18 + * along with this program. Look for COPYING file in the top folder.
134.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
134.20 + */
134.21 +package org.apidesign.bck2brwsr.vmtest.impl;
134.22 +
134.23 +import java.lang.annotation.Retention;
134.24 +import java.lang.annotation.RetentionPolicy;
134.25 +
134.26 +/** Annotation to generate a ZIP or JAR file during build.
134.27 + *
134.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
134.29 + */
134.30 +@Retention(RetentionPolicy.SOURCE)
134.31 +@interface GenerateZip {
134.32 + String name();
134.33 +
134.34 + /** manifest for the file */
134.35 + String manifest() default "";
134.36 +
134.37 + /** Array of names (at odd positions) and their content (on even) */
134.38 + String[] contents();
134.39 +}
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
135.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java Tue Feb 05 17:04:22 2013 +0100
135.3 @@ -0,0 +1,98 @@
135.4 +/**
135.5 + * Back 2 Browser Bytecode Translator
135.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
135.7 + *
135.8 + * This program is free software: you can redistribute it and/or modify
135.9 + * it under the terms of the GNU General Public License as published by
135.10 + * the Free Software Foundation, version 2 of the License.
135.11 + *
135.12 + * This program is distributed in the hope that it will be useful,
135.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
135.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
135.15 + * GNU General Public License for more details.
135.16 + *
135.17 + * You should have received a copy of the GNU General Public License
135.18 + * along with this program. Look for COPYING file in the top folder.
135.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
135.20 + */
135.21 +package org.apidesign.bck2brwsr.vmtest.impl;
135.22 +
135.23 +import java.io.ByteArrayInputStream;
135.24 +import java.io.IOException;
135.25 +import java.io.OutputStream;
135.26 +import java.util.Set;
135.27 +import java.util.jar.JarEntry;
135.28 +import java.util.jar.JarOutputStream;
135.29 +import java.util.jar.Manifest;
135.30 +import javax.annotation.processing.AbstractProcessor;
135.31 +import javax.annotation.processing.Processor;
135.32 +import javax.annotation.processing.RoundEnvironment;
135.33 +import javax.annotation.processing.SupportedAnnotationTypes;
135.34 +import javax.lang.model.element.Element;
135.35 +import javax.lang.model.element.ElementKind;
135.36 +import javax.lang.model.element.PackageElement;
135.37 +import javax.lang.model.element.TypeElement;
135.38 +import javax.tools.Diagnostic;
135.39 +import javax.tools.FileObject;
135.40 +import javax.tools.StandardLocation;
135.41 +import org.openide.util.lookup.ServiceProvider;
135.42 +
135.43 +/**
135.44 + *
135.45 + * @author Jaroslav Tulach <jtulach@netbeans.org>
135.46 + */
135.47 +@ServiceProvider(service = Processor.class)
135.48 +@SupportedAnnotationTypes("org.apidesign.bck2brwsr.vmtest.impl.GenerateZip")
135.49 +public class GenerateZipProcessor extends AbstractProcessor {
135.50 +
135.51 + @Override
135.52 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
135.53 + for (Element e : roundEnv.getElementsAnnotatedWith(GenerateZip.class)) {
135.54 + GenerateZip gz = e.getAnnotation(GenerateZip.class);
135.55 + if (gz == null) {
135.56 + continue;
135.57 + }
135.58 + PackageElement pe = findPackage(e);
135.59 + try {
135.60 + generateJar(pe, gz, e);
135.61 + } catch (IOException ex) {
135.62 + processingEnv.getMessager().printMessage(
135.63 + Diagnostic.Kind.ERROR,
135.64 + "Can't generate JAR " + gz.name() + ": " + ex.getMessage()
135.65 + );
135.66 + }
135.67 + }
135.68 + return true;
135.69 + }
135.70 +
135.71 + private static PackageElement findPackage(Element e) {
135.72 + while (e.getKind() != ElementKind.PACKAGE) {
135.73 + e = e.getEnclosingElement();
135.74 + }
135.75 + return (PackageElement)e;
135.76 + }
135.77 +
135.78 + private void generateJar(PackageElement pe, GenerateZip gz, Element e) throws IOException {
135.79 + FileObject res = processingEnv.getFiler().createResource(
135.80 + StandardLocation.CLASS_OUTPUT,
135.81 + pe.getQualifiedName().toString(),
135.82 + gz.name(), e
135.83 + );
135.84 + OutputStream os = res.openOutputStream();
135.85 + JarOutputStream jar;
135.86 + if (gz.manifest().isEmpty()) {
135.87 + jar = new JarOutputStream(os);
135.88 + } else {
135.89 + Manifest mf = new Manifest(new ByteArrayInputStream(gz.manifest().getBytes("UTF-8")));
135.90 + jar = new JarOutputStream(os, mf);
135.91 + }
135.92 + String[] arr = gz.contents();
135.93 + for (int i = 0; i < arr.length; i += 2) {
135.94 + JarEntry je = new JarEntry(arr[i]);
135.95 + jar.putNextEntry(je);
135.96 + jar.write(arr[i + 1].getBytes("UTF-8"));
135.97 + jar.closeEntry();
135.98 + }
135.99 + }
135.100 +
135.101 +}
136.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java Tue Feb 05 16:40:01 2013 +0100
136.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java Tue Feb 05 17:04:22 2013 +0100
136.3 @@ -28,8 +28,12 @@
136.4 public class AssertionTest {
136.5
136.6 @Compare public Object checkAssert() throws ClassNotFoundException {
136.7 - assert false : "Is assertion status on?";
136.8 - return null;
136.9 + try {
136.10 + assert false : "Is assertion status on?";
136.11 + return null;
136.12 + } catch (AssertionError ex) {
136.13 + return ex.getClass().getName();
136.14 + }
136.15 }
136.16
136.17 @Factory
137.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Tue Feb 05 16:40:01 2013 +0100
137.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Tue Feb 05 17:04:22 2013 +0100
137.3 @@ -17,6 +17,7 @@
137.4 */
137.5 package org.apidesign.bck2brwsr.tck;
137.6
137.7 +import java.io.UnsupportedEncodingException;
137.8 import java.net.MalformedURLException;
137.9 import java.net.URL;
137.10 import org.apidesign.bck2brwsr.vmtest.Compare;
137.11 @@ -120,6 +121,21 @@
137.12 NullField nf = new NullField();
137.13 return ("" + nf.name).toString();
137.14 }
137.15 + @Compare
137.16 + public String toUTFString() throws UnsupportedEncodingException {
137.17 + byte[] arr = {
137.18 + (byte) -59, (byte) -67, (byte) 108, (byte) 117, (byte) -59, (byte) -91,
137.19 + (byte) 111, (byte) 117, (byte) -60, (byte) -115, (byte) 107, (byte) -61,
137.20 + (byte) -67, (byte) 32, (byte) 107, (byte) -59, (byte) -81, (byte) -59,
137.21 + (byte) -120
137.22 + };
137.23 + return new String(arr, "utf-8");
137.24 + }
137.25 +
137.26 + @Compare
137.27 + public int stringToBytesLenght() throws UnsupportedEncodingException {
137.28 + return "Žluťoučký kůň".getBytes("utf8").length;
137.29 + }
137.30
137.31 @Factory
137.32 public static Object[] create() {
138.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
138.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java Tue Feb 05 17:04:22 2013 +0100
138.3 @@ -0,0 +1,94 @@
138.4 +/**
138.5 + * Back 2 Browser Bytecode Translator
138.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
138.7 + *
138.8 + * This program is free software: you can redistribute it and/or modify
138.9 + * it under the terms of the GNU General Public License as published by
138.10 + * the Free Software Foundation, version 2 of the License.
138.11 + *
138.12 + * This program is distributed in the hope that it will be useful,
138.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
138.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
138.15 + * GNU General Public License for more details.
138.16 + *
138.17 + * You should have received a copy of the GNU General Public License
138.18 + * along with this program. Look for COPYING file in the top folder.
138.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
138.20 + */
138.21 +package org.apidesign.bck2brwsr.tck;
138.22 +
138.23 +import java.io.InputStream;
138.24 +import java.net.URL;
138.25 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
138.26 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
138.27 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
138.28 +import org.apidesign.bck2brwsr.vmtest.VMTest;
138.29 +import org.testng.annotations.Factory;
138.30 +
138.31 +/**
138.32 + *
138.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
138.34 + */
138.35 +public class HttpResourceTest {
138.36 +
138.37 + @HttpResource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
138.38 + @BrwsrTest
138.39 + public String testReadContentViaXHR() throws Exception {
138.40 + String msg = read("/xhr");
138.41 + assert "Hello Brwsr!".equals(msg) : "The message was " + msg;
138.42 + return msg;
138.43 + }
138.44 +
138.45 + @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
138.46 + @BrwsrTest
138.47 + public String testReadContentViaURL() throws Exception {
138.48 + URL url = new URL("http:/url");
138.49 + String msg = (String) url.getContent();
138.50 + assert "Hello via URL!".equals(msg) : "The message was " + msg;
138.51 + return msg;
138.52 + }
138.53 + @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
138.54 + @BrwsrTest
138.55 + public String testReadContentViaURLWithStringParam() throws Exception {
138.56 + URL url = new URL("http:/url");
138.57 + String msg = (String) url.getContent(new Class[] { String.class });
138.58 + assert "Hello via URL!".equals(msg) : "The message was " + msg;
138.59 + return msg;
138.60 + }
138.61 +
138.62 + @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
138.63 + @BrwsrTest
138.64 + public void testReadByte() throws Exception {
138.65 + URL url = new URL("http:/bytes");
138.66 + final Object res = url.getContent(new Class[] { byte[].class });
138.67 + assert res instanceof byte[] : "Expecting byte[]: " + res;
138.68 + byte[] arr = (byte[]) res;
138.69 + assert arr.length == 1 : "One byte " + arr.length;
138.70 + assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
138.71 + }
138.72 +
138.73 + @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
138.74 + @BrwsrTest
138.75 + public void testReadByteViaInputStream() throws Exception {
138.76 + URL url = new URL("http:/bytes");
138.77 + InputStream is = url.openStream();
138.78 + byte[] arr = new byte[10];
138.79 + int len = is.read(arr);
138.80 + assert len == 1 : "One byte " + len;
138.81 + assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
138.82 + }
138.83 +
138.84 + @JavaScriptBody(args = { "url" }, body =
138.85 + "var req = new XMLHttpRequest();\n"
138.86 + + "req.open('GET', url, false);\n"
138.87 + + "req.send();\n"
138.88 + + "return req.responseText;"
138.89 + )
138.90 + private static native String read(String url);
138.91 +
138.92 +
138.93 + @Factory
138.94 + public static Object[] create() {
138.95 + return VMTest.create(HttpResourceTest.class);
138.96 + }
138.97 +}
139.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java Tue Feb 05 17:04:22 2013 +0100
139.3 @@ -0,0 +1,41 @@
139.4 +/**
139.5 + * Back 2 Browser Bytecode Translator
139.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
139.7 + *
139.8 + * This program is free software: you can redistribute it and/or modify
139.9 + * it under the terms of the GNU General Public License as published by
139.10 + * the Free Software Foundation, version 2 of the License.
139.11 + *
139.12 + * This program is distributed in the hope that it will be useful,
139.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
139.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139.15 + * GNU General Public License for more details.
139.16 + *
139.17 + * You should have received a copy of the GNU General Public License
139.18 + * along with this program. Look for COPYING file in the top folder.
139.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
139.20 + */
139.21 +package org.apidesign.bck2brwsr.vmtest.impl;
139.22 +
139.23 +import java.io.UnsupportedEncodingException;
139.24 +import java.util.zip.CRC32;
139.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
139.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
139.27 +import org.testng.annotations.Factory;
139.28 +
139.29 +/**
139.30 + *
139.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
139.32 + */
139.33 +public class CRC32Test {
139.34 +
139.35 + @Compare public long crc1() throws UnsupportedEncodingException {
139.36 + CRC32 crc = new CRC32();
139.37 + crc.update("Hello World!".getBytes("UTF-8"));
139.38 + return crc.getValue();
139.39 + }
139.40 +
139.41 + @Factory public static Object[] create() {
139.42 + return VMTest.create(CRC32Test.class);
139.43 + }
139.44 +}
140.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
140.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Tue Feb 05 17:04:22 2013 +0100
140.3 @@ -0,0 +1,84 @@
140.4 +/**
140.5 + * Back 2 Browser Bytecode Translator
140.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
140.7 + *
140.8 + * This program is free software: you can redistribute it and/or modify
140.9 + * it under the terms of the GNU General Public License as published by
140.10 + * the Free Software Foundation, version 2 of the License.
140.11 + *
140.12 + * This program is distributed in the hope that it will be useful,
140.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
140.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
140.15 + * GNU General Public License for more details.
140.16 + *
140.17 + * You should have received a copy of the GNU General Public License
140.18 + * along with this program. Look for COPYING file in the top folder.
140.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
140.20 + */
140.21 +package org.apidesign.bck2brwsr.vmtest.impl;
140.22 +
140.23 +import java.io.IOException;
140.24 +import java.io.InputStream;
140.25 +import java.util.Objects;
140.26 +import java.util.zip.ZipEntry;
140.27 +import java.util.zip.ZipInputStream;
140.28 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
140.29 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
140.30 +import org.apidesign.bck2brwsr.vmtest.Compare;
140.31 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
140.32 +import org.apidesign.bck2brwsr.vmtest.VMTest;
140.33 +import org.testng.annotations.Factory;
140.34 +
140.35 +/**
140.36 + *
140.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
140.38 + */
140.39 +@GenerateZip(name = "readAnEntry.zip", contents = {
140.40 + "my/main/file.txt", "Hello World!"
140.41 +})
140.42 +public class ZipFileTest {
140.43 +
140.44 + @Compare public String readAnEntry() throws IOException {
140.45 + InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip");
140.46 + ZipInputStream zip = new ZipInputStream(is);
140.47 + ZipEntry entry = zip.getNextEntry();
140.48 + assertEquals(entry.getName(), "my/main/file.txt", "Correct entry");
140.49 +
140.50 + byte[] arr = new byte[4096];
140.51 + int len = zip.read(arr);
140.52 +
140.53 + assertEquals(zip.getNextEntry(), null, "No next entry");
140.54 +
140.55 + final String ret = new String(arr, 0, len, "UTF-8");
140.56 + return ret;
140.57 + }
140.58 +
140.59 + @JavaScriptBody(args = { "res", "path" }, body =
140.60 + "var myvm = new bck2brwsr(path);\n"
140.61 + + "var cls = myvm.loadClass('java.lang.String');\n"
140.62 + + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n"
140.63 + )
140.64 + private static native Object loadVMResource(String res, String...path);
140.65 +
140.66 + @HttpResource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
140.67 + @BrwsrTest public void canVmLoadResourceFromZip() throws IOException {
140.68 + Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar");
140.69 + assert res instanceof InputStream : "Got array of bytes: " + res;
140.70 + InputStream is = (InputStream)res;
140.71 +
140.72 + byte[] arr = new byte[4096];
140.73 + int len = is.read(arr);
140.74 +
140.75 + final String ret = new String(arr, 0, len, "UTF-8");
140.76 +
140.77 + assertEquals(ret, "Hello World!", "Can read the bytes");
140.78 + }
140.79 +
140.80 + private static void assertEquals(Object real, Object exp, String msg) {
140.81 + assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real;
140.82 + }
140.83 +
140.84 + @Factory public static Object[] create() {
140.85 + return VMTest.create(ZipFileTest.class);
140.86 + }
140.87 +}
141.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
141.2 +++ b/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/0xfe Tue Feb 05 17:04:22 2013 +0100
141.3 @@ -0,0 +1,1 @@
141.4 +
141.5 \ No newline at end of file