You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(97) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(127) |
Feb
(34) |
Mar
(16) |
Apr
(26) |
May
(55) |
Jun
(107) |
Jul
(36) |
Aug
(72) |
Sep
(90) |
Oct
(41) |
Nov
(27) |
Dec
(13) |
2008 |
Jan
(37) |
Feb
(39) |
Mar
(98) |
Apr
(115) |
May
(134) |
Jun
(120) |
Jul
(86) |
Aug
(149) |
Sep
(68) |
Oct
(66) |
Nov
(104) |
Dec
(49) |
2009 |
Jan
(131) |
Feb
(132) |
Mar
(125) |
Apr
(172) |
May
(161) |
Jun
(43) |
Jul
(47) |
Aug
(38) |
Sep
(18) |
Oct
(6) |
Nov
(1) |
Dec
(15) |
2010 |
Jan
(21) |
Feb
(8) |
Mar
(10) |
Apr
(4) |
May
(9) |
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(4) |
2011 |
Jan
(23) |
Feb
(10) |
Mar
(13) |
Apr
(3) |
May
|
Jun
(19) |
Jul
(11) |
Aug
(22) |
Sep
|
Oct
(4) |
Nov
(2) |
Dec
(12) |
2012 |
Jan
(3) |
Feb
(4) |
Mar
(7) |
Apr
(3) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(30) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(8) |
2013 |
Jan
(3) |
Feb
(40) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
From: <ls...@us...> - 2007-01-07 05:41:45
|
Revision: 2994 http://jnode.svn.sourceforge.net/jnode/?rev=2994&view=rev Author: lsantha Date: 2007-01-06 21:41:44 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/java/java/lang/System.java trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java trunk/core/src/classpath/vm/java/lang/Thread.java Modified: trunk/core/src/classpath/java/java/lang/System.java =================================================================== --- trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 05:41:17 UTC (rev 2993) +++ trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 05:41:44 UTC (rev 2994) @@ -44,6 +44,14 @@ import java.io.InputStream; import java.io.PrintStream; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.Properties; import java.util.PropertyPermission; @@ -98,6 +106,11 @@ public static final PrintStream err = VMSystem.makeStandardErrorStream(); /** + * A cached copy of the environment variable map. + */ + private static Map<String,String> environmentMap; + + /** * This class is uninstantiable. */ private System() @@ -118,6 +131,7 @@ SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPermission(new RuntimePermission("setIO")); + VMSystem.setIn(in); } @@ -223,6 +237,38 @@ } /** + * <p> + * Returns the current value of a nanosecond-precise system timer. + * The value of the timer is an offset relative to some arbitrary fixed + * time, which may be in the future (making the value negative). This + * method is useful for timing events where nanosecond precision is + * required. This is achieved by calling this method before and after the + * event, and taking the difference betweent the two times: + * </p> + * <p> + * <code>long startTime = System.nanoTime();</code><br /> + * <code>... <emph>event code</emph> ...</code><br /> + * <code>long endTime = System.nanoTime();</code><br /> + * <code>long duration = endTime - startTime;</code><br /> + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. + * </p> + * + * @return the time of a system timer in nanoseconds. + * @since 1.5 + */ + public static long nanoTime() + { + //todo + throw new RuntimeException("Implement it"); + //return VMSystem.nanoTime(); + } + + /** * Copy one array onto another from <code>src[srcStart]</code> ... * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ... * <code>dest[destStart+len-1]</code>. First, the arguments are validated: @@ -319,6 +365,7 @@ * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd> * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd> * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd> + * <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd> * </dl> * * @return the system properties, will never be null @@ -364,7 +411,7 @@ SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPropertyAccess(key); - else if (key.length() == 0) + if (key.length() == 0) throw new IllegalArgumentException("key can't be empty"); return SystemProperties.getProperty(key); } @@ -385,6 +432,10 @@ SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPropertyAccess(key); + // This handles both the null pointer exception and the illegal + // argument exception. + if (key.length() == 0) + throw new IllegalArgumentException("key can't be empty"); return SystemProperties.getProperty(key, def); } @@ -405,6 +456,10 @@ SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPermission(new PropertyPermission(key, "write")); + // This handles both the null pointer exception and the illegal + // argument exception. + if (key.length() == 0) + throw new IllegalArgumentException("key can't be empty"); return SystemProperties.setProperty(key, value); } Modified: trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java =================================================================== --- trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java 2007-01-07 05:41:17 UTC (rev 2993) +++ trunk/core/src/classpath/java/java/security/PrivilegedExceptionAction.java 2007-01-07 05:41:44 UTC (rev 2994) @@ -46,9 +46,9 @@ * * @author Aaron M. Renn (ar...@ur...) * @since 1.1 - * @status updated to 1.4 + * @status updated to 1.5 */ -public interface PrivilegedExceptionAction +public interface PrivilegedExceptionAction<T> { /** * This method performs an operation that requires higher privileges to @@ -61,5 +61,5 @@ * @see AccessController#doPrivileged(PrivilegedExceptionAction, * AccessControlContext) */ - Object run() throws Exception; + T run() throws Exception; } // interface PrivilegedExceptionAction Modified: trunk/core/src/classpath/vm/java/lang/Thread.java =================================================================== --- trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 05:41:17 UTC (rev 2993) +++ trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 05:41:44 UTC (rev 2994) @@ -262,6 +262,56 @@ InheritableThreadLocal.newChildThread(this); // FDy : CLASSPATH patch ? } + /** + * Allocate a new Thread object, as if by + * <code>Thread(group, null, name)</code>, and give it the specified stack + * size, in bytes. The stack size is <b>highly platform independent</b>, + * and the virtual machine is free to round up or down, or ignore it + * completely. A higher value might let you go longer before a + * <code>StackOverflowError</code>, while a lower value might let you go + * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely + * nothing! So be careful, and expect to need to tune this value if your + * virtual machine even supports it. + * + * @param group the group to put the Thread into + * @param target the Runnable object to execute + * @param name the name for the Thread + * @param size the stack size, in bytes; 0 to be ignored + * @throws NullPointerException if name is null + * @throws SecurityException if this thread cannot access <code>group</code> + * @throws IllegalThreadStateException if group is destroyed + * @since 1.4 + */ + public Thread(ThreadGroup group, Runnable target, String name, long size) + { + Thread current = currentThread(); + + if (group != null) { + group.checkAccess(); + } else { + group = current.getThreadGroup(); + } + + if (group == null) { + throw new InternalError("Live thread has invalid group: " + name); + } + + group.addThread(this); + + this.group = group; + this.target = target; + this.name = name; + this.parent = current; + + this.daemon = current.isDaemon(); + + this.vmThread = VmProcessor.current().createThread(this); + this.vmThread.setPriority(current.getPriority()); + this.vmThread.updateName(); + + InheritableThreadLocal.newChildThread(this); // FDy : CLASSPATH patch ? + } + /** * Create a new instance with a given group as containing group, a runnable * as thread runner and a given name. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-07 05:41:20
|
Revision: 2993 http://jnode.svn.sourceforge.net/jnode/?rev=2993&view=rev Author: lsantha Date: 2007-01-06 21:41:17 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/java/java/security/PrivilegedAction.java Modified: trunk/core/src/classpath/java/java/security/PrivilegedAction.java =================================================================== --- trunk/core/src/classpath/java/java/security/PrivilegedAction.java 2007-01-07 05:39:36 UTC (rev 2992) +++ trunk/core/src/classpath/java/java/security/PrivilegedAction.java 2007-01-07 05:41:17 UTC (rev 2993) @@ -47,9 +47,9 @@ * @see AccessController * @see PrivilegedExceptionAction * @since 1.1 - * @status updated to 1.4 + * @status updated to 1.5 */ -public interface PrivilegedAction +public interface PrivilegedAction<T> { /** * This method performs an operation that requires higher privileges to @@ -60,5 +60,5 @@ * @see AccessController#doPrivileged(PrivilegedAction) * @see AccessController#doPrivileged(PrivilegedAction, AccessControlContext) */ - Object run(); + T run(); } // interface PrivilegedAction This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-07 05:39:38
|
Revision: 2992 http://jnode.svn.sourceforge.net/jnode/?rev=2992&view=rev Author: lsantha Date: 2007-01-06 21:39:36 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Added Paths: ----------- trunk/core/src/classpath/tools/gnu/classpath/tools/getopt/package.html Added: trunk/core/src/classpath/tools/gnu/classpath/tools/getopt/package.html =================================================================== --- trunk/core/src/classpath/tools/gnu/classpath/tools/getopt/package.html (rev 0) +++ trunk/core/src/classpath/tools/gnu/classpath/tools/getopt/package.html 2007-01-07 05:39:36 UTC (rev 2992) @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in java.util package. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - gnu.classpath.tools.getopt</title></head> + +<body> +<p>This package contains a GNU-style command line option parser. It +handles short and long options, options with arguments (optionally +joined to the option text), and a "long option only" mode. It also +automatically handles <code>--help</code> output. </p> + +</body> +</html> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-07 05:38:17
|
Revision: 2991 http://jnode.svn.sourceforge.net/jnode/?rev=2991&view=rev Author: lsantha Date: 2007-01-06 21:38:13 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Added Paths: ----------- trunk/core/src/classpath/java/java/util/ArrayDeque.java trunk/core/src/classpath/java/java/util/Deque.java trunk/core/src/classpath/java/java/util/NavigableMap.java trunk/core/src/classpath/java/java/util/NavigableSet.java trunk/core/src/classpath/java/java/util/concurrent/ trunk/core/src/classpath/java/java/util/concurrent/AbstractExecutorService.java trunk/core/src/classpath/java/java/util/concurrent/ArrayBlockingQueue.java trunk/core/src/classpath/java/java/util/concurrent/BlockingDeque.java trunk/core/src/classpath/java/java/util/concurrent/BlockingQueue.java trunk/core/src/classpath/java/java/util/concurrent/BrokenBarrierException.java trunk/core/src/classpath/java/java/util/concurrent/Callable.java trunk/core/src/classpath/java/java/util/concurrent/CancellationException.java trunk/core/src/classpath/java/java/util/concurrent/CompletionService.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentHashMap.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentLinkedQueue.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentMap.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentNavigableMap.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentSkipListMap.java trunk/core/src/classpath/java/java/util/concurrent/ConcurrentSkipListSet.java trunk/core/src/classpath/java/java/util/concurrent/CopyOnWriteArrayList.java trunk/core/src/classpath/java/java/util/concurrent/CopyOnWriteArraySet.java trunk/core/src/classpath/java/java/util/concurrent/CountDownLatch.java trunk/core/src/classpath/java/java/util/concurrent/CyclicBarrier.java trunk/core/src/classpath/java/java/util/concurrent/DelayQueue.java trunk/core/src/classpath/java/java/util/concurrent/Delayed.java trunk/core/src/classpath/java/java/util/concurrent/Exchanger.java trunk/core/src/classpath/java/java/util/concurrent/ExecutionException.java trunk/core/src/classpath/java/java/util/concurrent/Executor.java trunk/core/src/classpath/java/java/util/concurrent/ExecutorCompletionService.java trunk/core/src/classpath/java/java/util/concurrent/ExecutorService.java trunk/core/src/classpath/java/java/util/concurrent/Executors.java trunk/core/src/classpath/java/java/util/concurrent/Future.java trunk/core/src/classpath/java/java/util/concurrent/FutureTask.java trunk/core/src/classpath/java/java/util/concurrent/LinkedBlockingDeque.java trunk/core/src/classpath/java/java/util/concurrent/LinkedBlockingQueue.java trunk/core/src/classpath/java/java/util/concurrent/PriorityBlockingQueue.java trunk/core/src/classpath/java/java/util/concurrent/RejectedExecutionException.java trunk/core/src/classpath/java/java/util/concurrent/RejectedExecutionHandler.java trunk/core/src/classpath/java/java/util/concurrent/RunnableFuture.java trunk/core/src/classpath/java/java/util/concurrent/RunnableScheduledFuture.java trunk/core/src/classpath/java/java/util/concurrent/ScheduledExecutorService.java trunk/core/src/classpath/java/java/util/concurrent/ScheduledFuture.java trunk/core/src/classpath/java/java/util/concurrent/ScheduledThreadPoolExecutor.java trunk/core/src/classpath/java/java/util/concurrent/Semaphore.java trunk/core/src/classpath/java/java/util/concurrent/SynchronousQueue.java trunk/core/src/classpath/java/java/util/concurrent/ThreadFactory.java trunk/core/src/classpath/java/java/util/concurrent/ThreadPoolExecutor.java trunk/core/src/classpath/java/java/util/concurrent/TimeUnit.java trunk/core/src/classpath/java/java/util/concurrent/TimeoutException.java trunk/core/src/classpath/java/java/util/concurrent/atomic/ trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicBoolean.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicInteger.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicIntegerArray.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicLong.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicLongArray.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicMarkableReference.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicReference.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicReferenceArray.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java trunk/core/src/classpath/java/java/util/concurrent/atomic/AtomicStampedReference.java trunk/core/src/classpath/java/java/util/concurrent/atomic/package.html trunk/core/src/classpath/java/java/util/concurrent/locks/ trunk/core/src/classpath/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java trunk/core/src/classpath/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java trunk/core/src/classpath/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java trunk/core/src/classpath/java/java/util/concurrent/locks/Condition.java trunk/core/src/classpath/java/java/util/concurrent/locks/Lock.java trunk/core/src/classpath/java/java/util/concurrent/locks/LockSupport.java trunk/core/src/classpath/java/java/util/concurrent/locks/ReadWriteLock.java trunk/core/src/classpath/java/java/util/concurrent/locks/ReentrantLock.java trunk/core/src/classpath/java/java/util/concurrent/locks/package.html trunk/core/src/classpath/java/java/util/concurrent/package.html trunk/core/src/classpath/java/java/util/spi/ trunk/core/src/classpath/java/java/util/spi/CurrencyNameProvider.java trunk/core/src/classpath/java/java/util/spi/LocaleNameProvider.java trunk/core/src/classpath/java/java/util/spi/LocaleServiceProvider.java trunk/core/src/classpath/java/java/util/spi/TimeZoneNameProvider.java trunk/core/src/classpath/java/java/util/spi/package.html Added: trunk/core/src/classpath/java/java/util/ArrayDeque.java =================================================================== --- trunk/core/src/classpath/java/java/util/ArrayDeque.java (rev 0) +++ trunk/core/src/classpath/java/java/util/ArrayDeque.java 2007-01-07 05:38:13 UTC (rev 2991) @@ -0,0 +1,839 @@ +/* + * Written by Josh Bloch of Google Inc. and released to the public domain, + * as explained at http://creativecommons.org/licenses/publicdomain. + */ + +package java.util; +import java.io.*; + +/** + * Resizable-array implementation of the {@link Deque} interface. Array + * deques have no capacity restrictions; they grow as necessary to support + * usage. They are not thread-safe; in the absence of external + * synchronization, they do not support concurrent access by multiple threads. + * Null elements are prohibited. This class is likely to be faster than + * {@link Stack} when used as a stack, and faster than {@link LinkedList} + * when used as a queue. + * + * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time. + * Exceptions include {@link #remove(Object) remove}, {@link + * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence + * removeLastOccurrence}, {@link #contains contains}, {@link #iterator + * iterator.remove()}, and the bulk operations, all of which run in linear + * time. + * + * <p>The iterators returned by this class's <tt>iterator</tt> method are + * <i>fail-fast</i>: If the deque is modified at any time after the iterator + * is created, in any way except through the iterator's own <tt>remove</tt> + * method, the iterator will generally throw a {@link + * ConcurrentModificationException}. Thus, in the face of concurrent + * modification, the iterator fails quickly and cleanly, rather than risking + * arbitrary, non-deterministic behavior at an undetermined time in the + * future. + * + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed + * as it is, generally speaking, impossible to make any hard guarantees in the + * presence of unsynchronized concurrent modification. Fail-fast iterators + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. + * Therefore, it would be wrong to write a program that depended on this + * exception for its correctness: <i>the fail-fast behavior of iterators + * should be used only to detect bugs.</i> + * + * <p>This class and its iterator implement all of the + * <em>optional</em> methods of the {@link Collection} and {@link + * Iterator} interfaces. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @author Josh Bloch and Doug Lea + * @since 1.6 + * @param <E> the type of elements held in this collection + */ +public class ArrayDeque<E> extends AbstractCollection<E> + implements Deque<E>, Cloneable, Serializable +{ + /** + * The array in which the elements of the deque are stored. + * The capacity of the deque is the length of this array, which is + * always a power of two. The array is never allowed to become + * full, except transiently within an addX method where it is + * resized (see doubleCapacity) immediately upon becoming full, + * thus avoiding head and tail wrapping around to equal each + * other. We also guarantee that all array cells not holding + * deque elements are always null. + */ + private transient E[] elements; + + /** + * The index of the element at the head of the deque (which is the + * element that would be removed by remove() or pop()); or an + * arbitrary number equal to tail if the deque is empty. + */ + private transient int head; + + /** + * The index at which the next element would be added to the tail + * of the deque (via addLast(E), add(E), or push(E)). + */ + private transient int tail; + + /** + * The minimum capacity that we'll use for a newly created deque. + * Must be a power of 2. + */ + private static final int MIN_INITIAL_CAPACITY = 8; + + // ****** Array allocation and resizing utilities ****** + + /** + * Allocate empty array to hold the given number of elements. + * + * @param numElements the number of elements to hold + */ + private void allocateElements(int numElements) { + int initialCapacity = MIN_INITIAL_CAPACITY; + // Find the best power of two to hold elements. + // Tests "<=" because arrays aren't kept full. + if (numElements >= initialCapacity) { + initialCapacity = numElements; + initialCapacity |= (initialCapacity >>> 1); + initialCapacity |= (initialCapacity >>> 2); + initialCapacity |= (initialCapacity >>> 4); + initialCapacity |= (initialCapacity >>> 8); + initialCapacity |= (initialCapacity >>> 16); + initialCapacity++; + + if (initialCapacity < 0) // Too many elements, must back off + initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements + } + elements = (E[]) new Object[initialCapacity]; + } + + /** + * Double the capacity of this deque. Call only when full, i.e., + * when head and tail have wrapped around to become equal. + */ + private void doubleCapacity() { + assert head == tail; + int p = head; + int n = elements.length; + int r = n - p; // number of elements to the right of p + int newCapacity = n << 1; + if (newCapacity < 0) + throw new IllegalStateException("Sorry, deque too big"); + Object[] a = new Object[newCapacity]; + System.arraycopy(elements, p, a, 0, r); + System.arraycopy(elements, 0, a, r, p); + elements = (E[])a; + head = 0; + tail = n; + } + + /** + * Copies the elements from our element array into the specified array, + * in order (from first to last element in the deque). It is assumed + * that the array is large enough to hold all elements in the deque. + * + * @return its argument + */ + private <T> T[] copyElements(T[] a) { + if (head < tail) { + System.arraycopy(elements, head, a, 0, size()); + } else if (head > tail) { + int headPortionLen = elements.length - head; + System.arraycopy(elements, head, a, 0, headPortionLen); + System.arraycopy(elements, 0, a, headPortionLen, tail); + } + return a; + } + + /** + * Constructs an empty array deque with an initial capacity + * sufficient to hold 16 elements. + */ + public ArrayDeque() { + elements = (E[]) new Object[16]; + } + + /** + * Constructs an empty array deque with an initial capacity + * sufficient to hold the specified number of elements. + * + * @param numElements lower bound on initial capacity of the deque + */ + public ArrayDeque(int numElements) { + allocateElements(numElements); + } + + /** + * Constructs a deque containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. (The first element returned by the collection's + * iterator becomes the first element, or <i>front</i> of the + * deque.) + * + * @param c the collection whose elements are to be placed into the deque + * @throws NullPointerException if the specified collection is null + */ + public ArrayDeque(Collection<? extends E> c) { + allocateElements(c.size()); + addAll(c); + } + + // The main insertion and extraction methods are addFirst, + // addLast, pollFirst, pollLast. The other methods are defined in + // terms of these. + + /** + * Inserts the specified element at the front of this deque. + * + * @param e the element to add + * @throws NullPointerException if the specified element is null + */ + public void addFirst(E e) { + if (e == null) + throw new NullPointerException(); + elements[head = (head - 1) & (elements.length - 1)] = e; + if (head == tail) + doubleCapacity(); + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #add}. + * + * @param e the element to add + * @throws NullPointerException if the specified element is null + */ + public void addLast(E e) { + if (e == null) + throw new NullPointerException(); + elements[tail] = e; + if ( (tail = (tail + 1) & (elements.length - 1)) == head) + doubleCapacity(); + } + + /** + * Inserts the specified element at the front of this deque. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Deque#offerFirst}) + * @throws NullPointerException if the specified element is null + */ + public boolean offerFirst(E e) { + addFirst(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Deque#offerLast}) + * @throws NullPointerException if the specified element is null + */ + public boolean offerLast(E e) { + addLast(e); + return true; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeFirst() { + E x = pollFirst(); + if (x == null) + throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeLast() { + E x = pollLast(); + if (x == null) + throw new NoSuchElementException(); + return x; + } + + public E pollFirst() { + int h = head; + E result = elements[h]; // Element is null if deque empty + if (result == null) + return null; + elements[h] = null; // Must null out slot + head = (h + 1) & (elements.length - 1); + return result; + } + + public E pollLast() { + int t = (tail - 1) & (elements.length - 1); + E result = elements[t]; + if (result == null) + return null; + elements[t] = null; + tail = t; + return result; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getFirst() { + E x = elements[head]; + if (x == null) + throw new NoSuchElementException(); + return x; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getLast() { + E x = elements[(tail - 1) & (elements.length - 1)]; + if (x == null) + throw new NoSuchElementException(); + return x; + } + + public E peekFirst() { + return elements[head]; // elements[head] is null if deque empty + } + + public E peekLast() { + return elements[(tail - 1) & (elements.length - 1)]; + } + + /** + * Removes the first occurrence of the specified element in this + * deque (when traversing the deque from head to tail). + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if the deque contained the specified element + */ + public boolean removeFirstOccurrence(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = head; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) { + delete(i); + return true; + } + i = (i + 1) & mask; + } + return false; + } + + /** + * Removes the last occurrence of the specified element in this + * deque (when traversing the deque from head to tail). + * If the deque does not contain the element, it is unchanged. + * More formally, removes the last element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if the deque contained the specified element + */ + public boolean removeLastOccurrence(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = (tail - 1) & mask; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) { + delete(i); + return true; + } + i = (i - 1) & mask; + } + return false; + } + + // *** Queue methods *** + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #addLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + addLast(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #offerLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Queue#offer}) + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + return offerLast(e); + } + + /** + * Retrieves and removes the head of the queue represented by this deque. + * + * This method differs from {@link #poll poll} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException {@inheritDoc} + */ + public E remove() { + return removeFirst(); + } + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), or returns + * <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #pollFirst}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + public E poll() { + return pollFirst(); + } + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque. This method differs from {@link #peek peek} only in + * that it throws an exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException {@inheritDoc} + */ + public E element() { + return getFirst(); + } + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque, or returns <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #peekFirst}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + public E peek() { + return peekFirst(); + } + + // *** Stack methods *** + + /** + * Pushes an element onto the stack represented by this deque. In other + * words, inserts the element at the front of this deque. + * + * <p>This method is equivalent to {@link #addFirst}. + * + * @param e the element to push + * @throws NullPointerException if the specified element is null + */ + public void push(E e) { + addFirst(e); + } + + /** + * Pops an element from the stack represented by this deque. In other + * words, removes and returns the first element of this deque. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the element at the front of this deque (which is the top + * of the stack represented by this deque) + * @throws NoSuchElementException {@inheritDoc} + */ + public E pop() { + return removeFirst(); + } + + private void checkInvariants() { + assert elements[tail] == null; + assert head == tail ? elements[head] == null : + (elements[head] != null && + elements[(tail - 1) & (elements.length - 1)] != null); + assert elements[(head - 1) & (elements.length - 1)] == null; + } + + /** + * Removes the element at the specified position in the elements array, + * adjusting head and tail as necessary. This can result in motion of + * elements backwards or forwards in the array. + * + * <p>This method is called delete rather than remove to emphasize + * that its semantics differ from those of {@link List#remove(int)}. + * + * @return true if elements moved backwards + */ + private boolean delete(int i) { + checkInvariants(); + final E[] elements = this.elements; + final int mask = elements.length - 1; + final int h = head; + final int t = tail; + final int front = (i - h) & mask; + final int back = (t - i) & mask; + + // Invariant: head <= i < tail mod circularity + if (front >= ((t - h) & mask)) + throw new ConcurrentModificationException(); + + // Optimize for least element motion + if (front < back) { + if (h <= i) { + System.arraycopy(elements, h, elements, h + 1, front); + } else { // Wrap around + System.arraycopy(elements, 0, elements, 1, i); + elements[0] = elements[mask]; + System.arraycopy(elements, h, elements, h + 1, mask - h); + } + elements[h] = null; + head = (h + 1) & mask; + return false; + } else { + if (i < t) { // Copy the null tail as well + System.arraycopy(elements, i + 1, elements, i, back); + tail = t - 1; + } else { // Wrap around + System.arraycopy(elements, i + 1, elements, i, mask - i); + elements[mask] = elements[0]; + System.arraycopy(elements, 1, elements, 0, t); + tail = (t - 1) & mask; + } + return true; + } + } + + // *** Collection Methods *** + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size() { + return (tail - head) & (elements.length - 1); + } + + /** + * Returns <tt>true</tt> if this deque contains no elements. + * + * @return <tt>true</tt> if this deque contains no elements + */ + public boolean isEmpty() { + return head == tail; + } + + /** + * Returns an iterator over the elements in this deque. The elements + * will be ordered from first (head) to last (tail). This is the same + * order that elements would be dequeued (via successive calls to + * {@link #remove} or popped (via successive calls to {@link #pop}). + * + * @return an iterator over the elements in this deque + */ + public Iterator<E> iterator() { + return new DeqIterator(); + } + + public Iterator<E> descendingIterator() { + return new DescendingIterator(); + } + + private class DeqIterator implements Iterator<E> { + /** + * Index of element to be returned by subsequent call to next. + */ + private int cursor = head; + + /** + * Tail recorded at construction (also in remove), to stop + * iterator and also to check for comodification. + */ + private int fence = tail; + + /** + * Index of element returned by most recent call to next. + * Reset to -1 if element is deleted by a call to remove. + */ + private int lastRet = -1; + + public boolean hasNext() { + return cursor != fence; + } + + public E next() { + if (cursor == fence) + throw new NoSuchElementException(); + E result = elements[cursor]; + // This check doesn't catch all possible comodifications, + // but does catch the ones that corrupt traversal + if (tail != fence || result == null) + throw new ConcurrentModificationException(); + lastRet = cursor; + cursor = (cursor + 1) & (elements.length - 1); + return result; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + if (delete(lastRet)) { // if left-shifted, undo increment in next() + cursor = (cursor - 1) & (elements.length - 1); + fence = tail; + } + lastRet = -1; + } + } + + private class DescendingIterator implements Iterator<E> { + /* + * This class is nearly a mirror-image of DeqIterator, using + * tail instead of head for initial cursor, and head instead of + * tail for fence. + */ + private int cursor = tail; + private int fence = head; + private int lastRet = -1; + + public boolean hasNext() { + return cursor != fence; + } + + public E next() { + if (cursor == fence) + throw new NoSuchElementException(); + cursor = (cursor - 1) & (elements.length - 1); + E result = elements[cursor]; + if (head != fence || result == null) + throw new ConcurrentModificationException(); + lastRet = cursor; + return result; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + if (!delete(lastRet)) { + cursor = (cursor + 1) & (elements.length - 1); + fence = head; + } + lastRet = -1; + } + } + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. + * + * @param o object to be checked for containment in this deque + * @return <tt>true</tt> if this deque contains the specified element + */ + public boolean contains(Object o) { + if (o == null) + return false; + int mask = elements.length - 1; + int i = head; + E x; + while ( (x = elements[i]) != null) { + if (o.equals(x)) + return true; + i = (i + 1) & mask; + } + return false; + } + + /** + * Removes a single instance of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>o.equals(e)</tt> (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to {@link #removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if this deque contained the specified element + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Removes all of the elements from this deque. + * The deque will be empty after this call returns. + */ + public void clear() { + int h = head; + int t = tail; + if (h != t) { // clear all cells + head = tail = 0; + int i = h; + int mask = elements.length - 1; + do { + elements[i] = null; + i = (i + 1) & mask; + } while (i != t); + } + } + + /** + * Returns an array containing all of the elements in this deque + * in proper sequence (from first to last element). + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this deque. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this deque + */ + public Object[] toArray() { + return copyElements(new Object[size()]); + } + + /** + * Returns an array containing all of the elements in this deque in + * proper sequence (from first to last element); the runtime type of the + * returned array is that of the specified array. If the deque fits in + * the specified array, it is returned therein. Otherwise, a new array + * is allocated with the runtime type of the specified array and the + * size of this deque. + * + * <p>If this deque fits in the specified array with room to spare + * (i.e., the array has more elements than this deque), the element in + * the array immediately following the end of the deque is set to + * <tt>null</tt>. + * + * <p>Like the {@link #toArray()} method, this method acts as bridge between + * array-based and collection-based APIs. Further, this method allows + * precise control over the runtime type of the output array, and may, + * under certain circumstances, be used to save allocation costs. + * + * <p>Suppose <tt>x</tt> is a deque known to contain only strings. + * The following code can be used to dump the deque into a newly + * allocated array of <tt>String</tt>: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that <tt>toArray(new Object[0])</tt> is identical in function to + * <tt>toArray()</tt>. + * + * @param a the array into which the elements of the deque are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this deque + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this deque + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + int size = size(); + if (a.length < size) + a = (T[])java.lang.reflect.Array.newInstance( + a.getClass().getComponentType(), size); + copyElements(a); + if (a.length > size) + a[size] = null; + return a; + } + + // *** Object methods *** + + /** + * Returns a copy of this deque. + * + * @return a copy of this deque + */ + public ArrayDeque<E> clone() { + try { + ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); + // Classpath local: we don't have Arrays.copyOf yet. + // result.elements = Arrays.copyOf(elements, elements.length); + result.elements = elements.clone(); + return result; + + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + /** + * Appease the serialization gods. + */ + private static final long serialVersionUID = 2340985798034038923L; + + /** + * Serialize this deque. + * + * @serialData The current size (<tt>int</tt>) of the deque, + * followed by all of its elements (each an object reference) in + * first-to-last order. + */ + private void writeObject(ObjectOutputStream s) throws IOException { + s.defaultWriteObject(); + + // Write out size + s.writeInt(size()); + + // Write out elements in order. + int mask = elements.length - 1; + for (int i = head; i != tail; i = (i + 1) & mask) + s.writeObject(elements[i]); + } + + /** + * Deserialize this deque. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + + // Read in size and allocate array + int size = s.readInt(); + allocateElements(size); + head = 0; + tail = size; + + // Read in all elements in the proper order. + for (int i = 0; i < size; i++) + elements[i] = (E)s.readObject(); + } +} Added: trunk/core/src/classpath/java/java/util/Deque.java =================================================================== --- trunk/core/src/classpath/java/java/util/Deque.java (rev 0) +++ trunk/core/src/classpath/java/java/util/Deque.java 2007-01-07 05:38:13 UTC (rev 2991) @@ -0,0 +1,547 @@ +/* + * Written by Doug Lea and Josh Bloch with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A linear collection that supports element insertion and removal at + * both ends. The name <i>deque</i> is short for "double ended queue" + * and is usually pronounced "deck". Most <tt>Deque</tt> + * implementations place no fixed limits on the number of elements + * they may contain, but this interface supports capacity-restricted + * deques as well as those with no fixed size limit. + * + * <p>This interface defines methods to access the elements at both + * ends of the deque. Methods are provided to insert, remove, and + * examine the element. Each of these methods exists in two forms: + * one throws an exception if the operation fails, the other returns a + * special value (either <tt>null</tt> or <tt>false</tt>, depending on + * the operation). The latter form of the insert operation is + * designed specifically for use with capacity-restricted + * <tt>Deque</tt> implementations; in most implementations, insert + * operations cannot fail. + * + * <p>The twelve methods described above are summarized in the + * following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td></td> + * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td> + * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td> + * </tr> + * <tr> + * <td></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * <td ALIGN=CENTER><em>Throws exception</em></td> + * <td ALIGN=CENTER><em>Special value</em></td> + * </tr> + * <tr> + * <td><b>Insert</b></td> + * <td>{@link #addFirst addFirst(e)}</td> + * <td>{@link #offerFirst offerFirst(e)}</td> + * <td>{@link #addLast addLast(e)}</td> + * <td>{@link #offerLast offerLast(e)}</td> + * </tr> + * <tr> + * <td><b>Remove</b></td> + * <td>{@link #removeFirst removeFirst()}</td> + * <td>{@link #pollFirst pollFirst()}</td> + * <td>{@link #removeLast removeLast()}</td> + * <td>{@link #pollLast pollLast()}</td> + * </tr> + * <tr> + * <td><b>Examine</b></td> + * <td>{@link #getFirst getFirst()}</td> + * <td>{@link #peekFirst peekFirst()}</td> + * <td>{@link #getLast getLast()}</td> + * <td>{@link #peekLast peekLast()}</td> + * </tr> + * </table> + * + * <p>This interface extends the {@link Queue} interface. When a deque is + * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are + * added at the end of the deque and removed from the beginning. The methods + * inherited from the <tt>Queue</tt> interface are precisely equivalent to + * <tt>Deque</tt> methods as indicated in the following table: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#add add(e)}</td> + * <td>{@link #addLast addLast(e)}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#offer offer(e)}</td> + * <td>{@link #offerLast offerLast(e)}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#remove remove()}</td> + * <td>{@link #removeFirst removeFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#poll poll()}</td> + * <td>{@link #pollFirst pollFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#element element()}</td> + * <td>{@link #getFirst getFirst()}</td> + * </tr> + * <tr> + * <td>{@link java.util.Queue#peek peek()}</td> + * <td>{@link #peek peekFirst()}</td> + * </tr> + * </table> + * + * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This + * interface should be used in preference to the legacy {@link Stack} class. + * When a deque is used as a stack, elements are pushed and popped from the + * beginning of the deque. Stack methods are precisely equivalent to + * <tt>Deque</tt> methods as indicated in the table below: + * + * <p> + * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <tr> + * <td ALIGN=CENTER> <b>Stack Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * </tr> + * <tr> + * <td>{@link #push push(e)}</td> + * <td>{@link #addFirst addFirst(e)}</td> + * </tr> + * <tr> + * <td>{@link #pop pop()}</td> + * <td>{@link #removeFirst removeFirst()}</td> + * </tr> + * <tr> + * <td>{@link #peek peek()}</td> + * <td>{@link #peekFirst peekFirst()}</td> + * </tr> + * </table> + * + * <p>Note that the {@link #peek peek} method works equally well when + * a deque is used as a queue or a stack; in either case, elements are + * drawn from the beginning of the deque. + * + * <p>This interface provides two methods to remove interior + * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and + * {@link #removeLastOccurrence removeLastOccurrence}. + * + * <p>Unlike the {@link List} interface, this interface does not + * provide support for indexed access to elements. + * + * <p>While <tt>Deque</tt> implementations are not strictly required + * to prohibit the insertion of null elements, they are strongly + * encouraged to do so. Users of any <tt>Deque</tt> implementations + * that do allow null elements are strongly encouraged <i>not</i> to + * take advantage of the ability to insert nulls. This is so because + * <tt>null</tt> is used as a special return value by various methods + * to indicated that the deque is empty. + * + * <p><tt>Deque</tt> implementations generally do not define + * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt> + * methods, but instead inherit the identity-based versions from class + * <tt>Object</tt>. + * + * <p>This interface is a member of the <a + * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections + * Framework</a>. + * + * @author Doug Lea + * @author Josh Bloch + * @since 1.6 + * @param <E> the type of elements held in this collection + */ + +public interface Deque<E> extends Queue<E> { + /** + * Inserts the specified element at the front of this deque if it is + * possible to do so immediately without violating capacity restrictions. + * When using a capacity-restricted deque, it is generally preferable to + * use method {@link #offerFirst}. + * + * @param e the element to add + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void addFirst(E e); + + /** + * Inserts the specified element at the end of this deque if it is + * possible to do so immediately without violating capacity restrictions. + * When using a capacity-restricted deque, it is generally preferable to + * use method {@link #offerLast}. + * + * <p>This method is equivalent to {@link #add}. + * + * @param e the element to add + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void addLast(E e); + + /** + * Inserts the specified element at the front of this deque unless it would + * violate capacity restrictions. When using a capacity-restricted deque, + * this method is generally preferable to the {@link #addFirst} method, + * which can fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerFirst(E e); + + /** + * Inserts the specified element at the end of this deque unless it would + * violate capacity restrictions. When using a capacity-restricted deque, + * this method is generally preferable to the {@link #addLast} method, + * which can fail to insert an element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offerLast(E e); + + /** + * Retrieves and removes the first element of this deque. This method + * differs from {@link #pollFirst pollFirst} only in that it throws an + * exception if this deque is empty. + * + * @return the head of this deque + * @throws NoSuchElementException if this deque is empty + */ + E removeFirst(); + + /** + * Retrieves and removes the last element of this deque. This method + * differs from {@link #pollLast pollLast} only in that it throws an + * exception if this deque is empty. + * + * @return the tail of this deque + * @throws NoSuchElementException if this deque is empty + */ + E removeLast(); + + /** + * Retrieves and removes the first element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E pollFirst(); + + /** + * Retrieves and removes the last element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the tail of this deque, or <tt>null</tt> if this deque is empty + */ + E pollLast(); + + /** + * Retrieves, but does not remove, the first element of this deque. + * + * This method differs from {@link #peekFirst peekFirst} only in that it + * throws an exception if this deque is empty. + * + * @return the head of this deque + * @throws NoSuchElementException if this deque is empty + */ + E getFirst(); + + /** + * Retrieves, but does not remove, the last element of this deque. + * This method differs from {@link #peekLast peekLast} only in that it + * throws an exception if this deque is empty. + * + * @return the tail of this deque + * @throws NoSuchElementException if this deque is empty + */ + E getLast(); + + /** + * Retrieves, but does not remove, the first element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the head of this deque, or <tt>null</tt> if this deque is empty + */ + E peekFirst(); + + /** + * Retrieves, but does not remove, the last element of this deque, + * or returns <tt>null</tt> if this deque is empty. + * + * @return the tail of this deque, or <tt>null</tt> if this deque is empty + */ + E peekLast(); + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean removeFirstOccurrence(Object o); + + /** + * Removes the last occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the last element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean removeLastOccurrence(Object o); + + // *** Queue methods *** + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * When using a capacity-restricted deque, it is generally preferable to + * use {@link #offer(Object) offer}. + * + * <p>This method is equivalent to {@link #addLast}. + * + * @param e the element to add + * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean add(E e); + + /** + * Inserts the specified element into the queue represented by this deque + * (in other words, at the tail of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * available. When using a capacity-restricted deque, this method is + * generally preferable to the {@link #add} method, which can fail to + * insert an element only by throwing an exception. + * + * <p>This method is equivalent to {@link #offerLast}. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this deque, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + boolean offer(E e); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque). + * This method differs from {@link #poll poll} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + E remove(); + + /** + * Retrieves and removes the head of the queue represented by this deque + * (in other words, the first element of this deque), or returns + * <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #pollFirst()}. + * + * @return the first element of this deque, or <tt>null</tt> if + * this deque is empty + */ + E poll(); + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque). + * This method differs from {@link #peek peek} only in that it throws an + * exception if this deque is empty. + * + * <p>This method is equivalent to {@link #getFirst()}. + * + * @return the head of the queue represented by this deque + * @throws NoSuchElementException if this deque is empty + */ + E element(); + + /** + * Retrieves, but does not remove, the head of the queue represented by + * this deque (in other words, the first element of this deque), or + * returns <tt>null</tt> if this deque is empty. + * + * <p>This method is equivalent to {@link #peekFirst()}. + * + * @return the head of the queue represented by this deque, or + * <tt>null</tt> if this deque is empty + */ + E peek(); + + + // *** Stack methods *** + + /** + * Pushes an element onto the stack represented by this deque (in other + * words, at the head of this deque) if it is possible to do so + * immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and throwing an + * <tt>IllegalStateException</tt> if no space is currently available. + * + * <p>This method is equivalent to {@link #addFirst}. + * + * @param e the element to push + * @throws IllegalStateException if the element cannot be added at this + * time due to capacity restrictions + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this deque + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this deque + */ + void push(E e); + + /** + * Pops an element from the stack represented by this deque. In other + * words, removes and returns the first element of this deque. + * + * <p>This method is equivalent to {@link #removeFirst()}. + * + * @return the element at the front of this deque (which is the top + * of the stack represented by this deque) + * @throws NoSuchElementException if this deque is empty + */ + E pop(); + + + // *** Collection methods *** + + /** + * Removes the first occurrence of the specified element from this deque. + * If the deque does not contain the element, it is unchanged. + * More formally, removes the first element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt> + * (if such an element exists). + * Returns <tt>true</tt> if this deque contained the specified element + * (or equivalently, if this deque changed as a result of the call). + * + * <p>This method is equivalent to {@link #removeFirstOccurrence}. + * + * @param o element to be removed from this deque, if present + * @return <tt>true</tt> if an element was removed as a result of this call + * @throws ClassCastException if the class of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean remove(Object o); + + /** + * Returns <tt>true</tt> if this deque contains the specified element. + * More formally, returns <tt>true</tt> if and only if this deque contains + * at least one element <tt>e</tt> such that + * <tt>(o==null ? e==null : o.equals(e))</tt>. + * + * @param o element whose presence in this deque is to be tested + * @return <tt>true</tt> if this deque contains the specified element + * @throws ClassCastException if the type of the specified element + * is incompatible with this deque (optional) + * @throws NullPointerException if the specified element is null and this + * deque does not permit null elements (optional) + */ + boolean contains(Object o); + + /** + * Returns the number of elements in this deque. + * + * @return the number of elements in this deque + */ + public int size(); + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * + * @return an iterator over the elements in this deque in proper sequence + */ + Iterator<E> iterator(); + + /** + * Returns an iterator over the elements in this deque in reverse + * sequential order. The elements will be returned in order from + * last (tail) to first (head). + * + * @return an iterator over the elements in this deque in reverse + * sequence + */ + Iterator<E> descendingIterator(); + +} Added: trunk/core/src/classpath/java/java/util/NavigableMap.java =================================================================== --- trunk/core/src/classpath/java/java/util/NavigableMap.java (rev 0) +++ trunk/core/src/classpath/java/java/util/NavigableMap.java 2007-01-07 05:38:13 UTC (rev 2991) @@ -0,0 +1,395 @@ +/* + * Written by Doug Lea and Josh Bloch with assistance from members of JCP + * JSR-166 Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package java.util; + +/** + * A {@link SortedMap} extended with navigation methods returning the + * closest matches for given search targets. Methods + * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry}, + * and {@code higherEntry} return {@code Map.Entry} objects + * associated with keys respectively less than, less than or equal, + * greater than or equal, and greater than a given key, returning + * {@code null} if there is no such key. Similarly, methods + * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and + * {@code higherKey} return only the associated keys. All of these + * methods are designed for locating, not traversing entries. + * + * <p>A {@code NavigableMap} may be accessed and traversed in either + * ascending or descending key order. The {@code descendingMap} + * method returns a view of the map with the senses of all relational + * and directional methods inverted. The performance of ascending + * operations and views is likely to be faster than that of descending + * ones. Methods {@code subMap}, {@code headMap}, + * and {@code tailMap} differ from the like-named {@code + * SortedMap} methods in accepting additional arguments describing + * whether lower and upper bounds are inclusive versus exclusive. + * Submaps of any {@code NavigableMap} must implement the {@code + * NavigableMap} interface. + * + * <p>This interface additionally defines methods {@code firstEntry}, + * {@code pollFirstEntry}, {@code lastEnt... [truncated message content] |
From: <ls...@us...> - 2007-01-07 05:36:40
|
Revision: 2990 http://jnode.svn.sourceforge.net/jnode/?rev=2990&view=rev Author: lsantha Date: 2007-01-06 21:36:39 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Added Paths: ----------- trunk/core/src/classpath/gnu/gnu/classpath/Pair.java Added: trunk/core/src/classpath/gnu/gnu/classpath/Pair.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/classpath/Pair.java (rev 0) +++ trunk/core/src/classpath/gnu/gnu/classpath/Pair.java 2007-01-07 05:36:39 UTC (rev 2990) @@ -0,0 +1,126 @@ +/* Pair.java -- A heterogenous pair of objects. + Copyright (C) 2006 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath; + +/** + * A container for a pair of heterogenous objects. + * + * @author Andrew John Hughes (gnu...@me...) + */ +public class Pair<A,B> +{ + + /** + * The left-hand side of the pair. + */ + private A left; + + /** + * The right-hand side of the pair. + */ + private B right; + + /** + * Constructs a new pair using the given left and + * right values. + * + * @param left the left-hand side of the pair. + * @param right the right-hand side of the pair. + */ + public Pair(A left, B right) + { + this.left = left; + this.right = right; + } + + /** + * Returns the left-hand side of the pair. + * + * @return the left-hand value. + */ + public A getLeft() + { + return left; + } + + /** + * Returns the right-hand side of the pair. + * + * @return the right-hand value. + */ + public B getRight() + { + return right; + } + + /** + * Returns true if the specified object is also a + * pair with equivalent left and right values. + * + * @param obj the object to compare. + * @return true if the two are equal. + */ + public boolean equals(Object obj) + { + if (obj instanceof Pair) + { + Pair<A,B> p = (Pair<A,B>) obj; + A lp = p.getLeft(); + B rp = p.getRight(); + return (lp == null ? left == null : lp.equals(left)) && + (rp == null ? right == null : rp.equals(right)); + } + return false; + } + + /** + * Returns a hashcode for the pair, created by the + * summation of the hashcodes of the left and right + * hand values. + * + * @return a hashcode for the pair. + */ + public int hashCode() + { + return (left == null ? 0 : left.hashCode()) + + (right == null ? 0 : right.hashCode()); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-07 05:35:57
|
Revision: 2989 http://jnode.svn.sourceforge.net/jnode/?rev=2989&view=rev Author: lsantha Date: 2007-01-06 21:35:55 -0800 (Sat, 06 Jan 2007) Log Message: ----------- Classpath patches. Modified Paths: -------------- trunk/core/src/classpath/gnu/gnu/java/awt/font/FontDelegate.java trunk/core/src/classpath/gnu/gnu/java/awt/font/GNUGlyphVector.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AxisHints.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Constants.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/GlyphHints.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Latin.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/LatinAxis.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/LatinMetrics.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Script.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/ScriptMetrics.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Segment.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Width.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/OpenTypeFont.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/Scaler.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/Fixed.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/GlyphLoader.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/Zone.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java Added Paths: ----------- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AutoHinter.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Edge.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/HintScaler.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/LatinBlue.java trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Utils.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/Hinter.java trunk/core/src/classpath/gnu/gnu/java/awt/font/opentype/truetype/Point.java Removed Paths: ------------- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Scaler.java Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/FontDelegate.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/FontDelegate.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/FontDelegate.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -61,6 +61,13 @@ */ public interface FontDelegate { + public static final int FLAG_FITTED = 1 << 0; + public static final int FLAG_NO_HINT_HORIZONTAL = 1 << 1; + public static final int FLAG_NO_HINT_VERTICAL = 1 << 2; + public static final int FLAG_NO_HINT_EDGE_POINTS = 1 << 3; + public static final int FLAG_NO_HINT_STRONG_POINTS = 1 << 4; + public static final int FLAG_NO_HINT_WEAK_POINTS = 1 << 5; + /** * Returns the full name of this font face in the specified * locale, for example <i>“Univers Light”</i>. @@ -221,7 +228,8 @@ float pointSize, AffineTransform transform, boolean antialias, - boolean fractionalMetrics); + boolean fractionalMetrics, + int type); /** Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/GNUGlyphVector.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/GNUGlyphVector.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/GNUGlyphVector.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -164,7 +164,9 @@ renderContext.usesFractionalMetrics(), /* horizontal */ true, advance); - pos[p] = x += advance.x; + // FIXME: We shouldn't round here, but instead hint the metrics + // correctly. + pos[p] = x += Math.round(advance.x); pos[p + 1] = y += advance.y; } valid = true; @@ -284,7 +286,23 @@ return outline; } + public Shape getOutline(float x, float y, int type) + { + validate(); + GeneralPath outline = new GeneralPath(); + int len = glyphs.length; + for (int i = 0; i < len; i++) + { + GeneralPath p = new GeneralPath(getGlyphOutline(i, type)); + outline.append(p, false); + } + AffineTransform t = new AffineTransform(); + t.translate(x, y); + outline.transform(t); + return outline; + } + /** * Determines the shape of the specified glyph. * @@ -309,7 +327,8 @@ path = fontDelegate.getGlyphOutline(glyphs[glyphIndex], fontSize, tx, renderContext.isAntiAliased(), - renderContext.usesFractionalMetrics()); + renderContext.usesFractionalMetrics(), + FontDelegate.FLAG_FITTED); tx = new AffineTransform(); tx.translate(pos[glyphIndex * 2], pos[glyphIndex * 2 + 1]); @@ -317,7 +336,33 @@ return path; } + public Shape getGlyphOutline(int glyphIndex, int type) + { + AffineTransform tx, glyphTx; + GeneralPath path; + validate(); + + if ((transforms != null) + && ((glyphTx = transforms[glyphIndex]) != null)) + { + tx = new AffineTransform(transform); + tx.concatenate(glyphTx); + } + else + tx = transform; + + path = fontDelegate.getGlyphOutline(glyphs[glyphIndex], fontSize, tx, + renderContext.isAntiAliased(), + renderContext.usesFractionalMetrics(), + type); + + tx = new AffineTransform(); + tx.translate(pos[glyphIndex * 2], pos[glyphIndex * 2 + 1]); + path.transform(tx); + return path; + } + /** * Determines the position of the specified glyph, or the * total advance width and height of the vector. Added: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AutoHinter.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AutoHinter.java (rev 0) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AutoHinter.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -0,0 +1,83 @@ +/* AutoHinter.java -- The entry point into the hinter implementation. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.font.autofit; + +import gnu.java.awt.font.opentype.Hinter; +import gnu.java.awt.font.opentype.OpenTypeFont; +import gnu.java.awt.font.opentype.truetype.Fixed; +import gnu.java.awt.font.opentype.truetype.Zone; + +/** + * The public interface to the automatic gridfitter. + */ +public class AutoHinter + implements Hinter +{ + Latin latinScript; + LatinMetrics metrics; + GlyphHints hints; + + HintScaler scaler = new HintScaler(); + public void init(OpenTypeFont font) + { + // TODO: Should support other scripts too. + latinScript = new Latin(); + metrics = new LatinMetrics(font); + latinScript.initMetrics(metrics, font); + scaler.face = font; + } + + public void applyHints(Zone outline) + { + if (hints == null) + hints = new GlyphHints(); + scaler.xScale = Fixed.valueOf16(outline.scaleX * 64); + scaler.yScale = Fixed.valueOf16(outline.scaleY * 64); + latinScript.scaleMetrics(metrics, scaler); + latinScript.applyHints(hints, outline, metrics); + } + + public void setFlags(int flags) + { + if (hints == null) + hints = new GlyphHints(); + hints.flags = flags; + } + +} Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AxisHints.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AxisHints.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/AxisHints.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -1,4 +1,4 @@ -/* AxisHints.java -- FIXME: briefly describe file purpose +/* AxisHints.java -- Hints specific to an axis Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,4 +42,71 @@ { Segment[] segments; + int majorDir; + int numSegments; + int numEdges; + Edge[] edges; + + AxisHints() + { + segments = new Segment[4]; + edges = new Edge[4]; + } + + Segment newSegment() + { + if (numSegments >= segments.length) + { + // Grow array. + int newMax = segments.length; + newMax += (newMax >> 2) + 4; // From FreeType. + Segment[] newSegs = new Segment[newMax]; + System.arraycopy(segments, 0, newSegs, 0, numSegments); + segments = newSegs; + } + Segment seg = new Segment(); + segments[numSegments] = seg; + numSegments++; + return seg; + } + + public Edge newEdge(int pos) + { + if (numEdges >= edges.length) + { + // Grow array. + int newMax = edges.length; + newMax += (newMax >> 2) + 4; // From FreeType. + Edge[] newEdges = new Edge[newMax]; + System.arraycopy(edges, 0, newEdges, 0, numEdges); + edges = newEdges; + } + int edgeIndex = numEdges; + Edge edge = edges[edgeIndex] = new Edge(); + while (edgeIndex > 0 && edges[edgeIndex - 1].fpos > pos) + { + edges[edgeIndex] = edges[edgeIndex - 1]; + edgeIndex--; + } + edges[edgeIndex] = edge; + numEdges++; + edge.fpos = pos; + + return edge; + + } + + int getEdgeIndex(Edge edge2) + { + int idx = -1; + for (int i = 0; i < numEdges; i++) + { + if (edges[i] == edge2) + { + idx = i; + break; + } + } + return idx; + } } Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Constants.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Constants.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Constants.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -58,4 +58,29 @@ * The number of dimensions. */ static final int DIMENSION_MAX = 2; + + /** + * Indicates a vector with no specific direction. + */ + static final int DIR_NONE = 0; + + /** + * Right direction. + */ + static final int DIR_RIGHT = 1; + + /** + * Left direction. + */ + static final int DIR_LEFT = -1; + + /** + * Up direction. + */ + static final int DIR_UP = 2; + + /** + * Down direction. + */ + static final int DIR_DOWN = -2; } Added: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Edge.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Edge.java (rev 0) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Edge.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -0,0 +1,80 @@ +/* Edge.java -- An edge of segments + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.font.autofit; + +class Edge +{ + int fpos; + Segment first; + Segment last; + int opos; + Edge link; + Edge serif; + int flags; + int dir; + Width blueEdge; + int pos; + int scale; + + public String toString() + { + StringBuilder s = new StringBuilder(); + s.append("[Edge] id"); + s.append(hashCode()); + s.append(", fpos: "); + s.append(fpos); + s.append(", opos: "); + s.append(opos); + s.append(", pos: "); + s.append(pos); + s.append(", dir: "); + s.append(dir); + s.append(", serif: "); + s.append(serif != null ? serif.hashCode() : "null"); + s.append(", link: "); + s.append(link != null ? link.hashCode() : "null"); + s.append(", flags: " + flags); + s.append(", blue: " + blueEdge); + s.append(", first: "); + s.append(first == null ? "null" : first.hashCode()); + s.append(", last: "); + s.append(last == null ? "null" : last.hashCode()); + return s.toString(); + } +} Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/GlyphHints.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/GlyphHints.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/GlyphHints.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -38,12 +38,16 @@ package gnu.java.awt.font.autofit; +import gnu.java.awt.font.FontDelegate; +import gnu.java.awt.font.opentype.truetype.Fixed; +import gnu.java.awt.font.opentype.truetype.Point; import gnu.java.awt.font.opentype.truetype.Zone; /** * The data and methods used for the actual hinting process. */ class GlyphHints + implements Constants { int xScale; @@ -53,23 +57,584 @@ AxisHints[] axis; - void rescale(ScriptMetrics metrics) + Point[] points; + int numPoints; + int maxPoints; + + Point[] contours; + int numContours; + int maxContours; + + ScriptMetrics metrics; + + int flags; + + GlyphHints() { - // TODO: Implement. + axis = new AxisHints[Constants.DIMENSION_MAX]; + axis[Constants.DIMENSION_VERT] = new AxisHints(); + axis[Constants.DIMENSION_HORZ] = new AxisHints(); + + xScale = Fixed.ONE; + yScale = Fixed.ONE; } + + void rescale(ScriptMetrics m) + { + metrics = m; + // TODO: Copy scalerFlags. + } void reload(Zone outline) { - // TODO: Implement. + numPoints = 0; + numContours = 0; + axis[0].numSegments = 0; + axis[0].numEdges = 0; + axis[1].numSegments = 0; + axis[1].numEdges = 0; + + // Create/reallocate the contours array. + int newMax = outline.getNumContours(); + if (newMax > maxContours || contours == null) + { + newMax = (newMax + 3) & ~3; // Taken from afhints.c . + Point[] newContours = new Point[newMax]; + if (contours != null) + { + System.arraycopy(contours, 0, newContours, 0, maxContours); + } + contours = newContours; + maxContours = newMax; + } + + // Create/reallocate the points array. + newMax = outline.getSize() + 2; + if (newMax > maxPoints || points == null) + { + newMax = (newMax + 2 + 7) & ~7; // Taken from afhints.c . + Point[] newPoints = new Point[newMax]; + if (points != null) + { + System.arraycopy(points, 0, newPoints, 0, maxPoints); + } + points = newPoints; + maxPoints = newMax; + } + + numPoints = outline.getSize() - 4; // 4 phantom points. + numContours = outline.getNumContours(); + + // Set major direction. We don't handle Type 1 fonts yet. + axis[DIMENSION_HORZ].majorDir = DIR_UP; + axis[DIMENSION_VERT].majorDir = DIR_LEFT; + + // TODO: Freetype seems to scale and translate the glyph at that point. + // I suppose that this is not really needed. + // The scales are scaling from font units to 1/64 device pixels. + xScale = Fixed.valueOf16(outline.scaleX * 64); + yScale = Fixed.valueOf16(outline.scaleY * 64); + + // FIXME: What is that xDelta and yDelta used for? + System.arraycopy(outline.getPoints(), 0, points, 0, numPoints); + + // Setup prev and next and contours array. + // TODO: Probably cache this. + contours = new Point[numContours]; + Point currentContour = points[0]; + for (int i = 0, cIndex = 0; i < numPoints; i++) + { + // Start new contour when the last point has been a contour end. + if (outline.isContourEnd(i)) + { + // Connect the contour end point to the start point. + points[i].setNext(currentContour); + currentContour.setPrev(points[i]); + contours[cIndex] = currentContour; + cIndex++; + currentContour = i < numPoints - 1 ? points[i + 1] : null; + } + else + { + // Connect the current and the previous point. + points[i].setNext(points[i + 1]); + points[i + 1].setPrev(points[i]); + } + } + // Compute directions of in and out vectors of all points as well + // as the weak point flag. + for (int i = 0; i < numPoints; i++) + { + // Compute in and out dir. + Point p = points[i]; + Point prev = p.getPrev(); + int inX = p.getOrigX() - prev.getOrigX(); + int inY = p.getOrigY() - prev.getOrigY(); + p.setInDir(Utils.computeDirection(inX, inY)); + Point next = p.getNext(); + int outX = next.getOrigX() - p.getOrigX(); + int outY = next.getOrigY() - p.getOrigY(); + p.setOutDir(Utils.computeDirection(outX, outY)); + + if (p.isControlPoint()) + { + setWeakPoint(p); + } + else if (p.getOutDir() == p.getInDir()) + { + if (p.getOutDir() != DIR_NONE) + setWeakPoint(p); + else + { + int angleIn = Utils.atan(inY, inX); + int angleOut = Utils.atan(outY, outX); + int delta = Utils.angleDiff(angleIn, angleOut); + if (delta < 2 && delta > -2) + setWeakPoint(p); + } + } + else if (p.getInDir() == - p.getOutDir()) + { + setWeakPoint(p); + } + } + computeInflectionPoints(); } - void computeSegments(int dim) + private void setWeakPoint(Point p) { - // TODO: Implement. + p.setFlags((byte) (p.getFlags() | Point.FLAG_WEAK_INTERPOLATION)); } - void linkSegments(int dim) + /** + * Computes the inflection points for a glyph. + */ + private void computeInflectionPoints() { - // TODO: Implement. + // Do each contour separately. + contours : for (int c = 0; c < contours.length; c++) + { + Point point = contours[c]; + Point first = point; + Point start = point; + Point end = point; + do + { + end = end.getNext(); + if (end == first) + continue contours; + } while (end.getOrigX() == first.getOrigX() + && end.getOrigY() == first.getOrigY()); + + // Extend segment start whenever possible. + Point before = start; + int angleIn; + int angleSeg = Utils.atan(end.getOrigX() - start.getOrigX(), + end.getOrigY() - start.getOrigY()); + do + { + do + { + start = before; + before = before.getPrev(); + if (before == first) + continue contours; + } while (before.getOrigX() == start.getOrigX() + && before.getOrigY() == start.getOrigY()); + angleIn = Utils.atan(start.getOrigX() - before.getOrigX(), + start.getOrigY() - before.getOrigY()); + } while (angleIn == angleSeg); + + first = start; + int diffIn = Utils.angleDiff(angleIn, angleSeg); + // Now, process all segments in the contour. + Point after; + boolean finished = false; + int angleOut, diffOut; + do + { + // First, extend the current segment's end whenever possible. + after = end; + do + { + do + { + end = after; + after = after.getNext(); + if (after == first) + finished = true; + } while (end.getOrigX() == after.getOrigX() + && end.getOrigY() == after.getOrigY()); + angleOut = Utils.atan(after.getOrigX() - end.getOrigX(), + after.getOrigY() - end.getOrigY()); + } while (angleOut == angleSeg); + diffOut = Utils.angleDiff(angleSeg, angleOut); + if ((diffIn ^ diffOut) < 0) + { + // diffIn and diffOut have different signs, we have + // inflection points here. + do + { + start.addFlags(Point.FLAG_INFLECTION); + start = start.getNext(); + } while (start != end); + start.addFlags(Point.FLAG_INFLECTION); + } + start = end; + end = after; + angleSeg = angleOut; + diffIn = diffOut; + } while (! finished); + } } + + boolean doHorizontal() + { + return (flags & FontDelegate.FLAG_NO_HINT_HORIZONTAL) == 0; + } + + boolean doVertical() + { + return (flags & FontDelegate.FLAG_NO_HINT_VERTICAL) == 0; + } + + void alignWeakPoints(int dim) + { + short touchFlag; + Point point; + // PASS 1 : Move segments to edge positions. + if (dim == DIMENSION_HORZ) + { + touchFlag = Point.FLAG_DONE_X; + for (int p = 0; p < numPoints; p++) + { + point = points[p]; + point.setU(point.getX()); + point.setV(point.getScaledX()); + } + } + else + { + touchFlag = Point.FLAG_DONE_Y; + for (int p = 0; p < numPoints; p++) + { + point = points[p]; + point.setU(point.getY()); + point.setV(point.getScaledY()); + } + } + point = points[0]; + for (int c = 0; c < numContours; c++) + { + point = contours[c]; + int idx = getPointIndex(point); + Point endPoint = point.getPrev(); + int endIdx = getPointIndex(endPoint); + int firstIdx = idx; + while (idx <= endIdx + && (point.getFlags() & touchFlag) == 0) + { + idx++; + point = points[idx]; + } + if (idx <= endIdx) + { + int firstTouched = idx; + int curTouched = idx; + idx++; + point = points[idx]; + while (idx <= endIdx) + { + if ((point.getFlags() & touchFlag) != 0) + { + // We found two successive touch points. We interpolate + // all contour points between them. + iupInterp(curTouched + 1, idx - 1, curTouched, idx); + curTouched = idx; + } + idx++; + point = points[idx]; + } + if (curTouched == firstTouched) + { + // This is a special case: Only one point was touched in the + // contour. We thus simply shift the whole contour. + iupShift(firstIdx, endIdx, curTouched); + } + else + { + // Now interpolate after the last touched point to the end + // of the contour. + iupInterp(curTouched + 1, endIdx, curTouched, firstTouched); + // If the first contour point isn't touched, interpolate + // from the contour start to the first touched point. + if (firstTouched > 0) + { + iupInterp(firstIdx, firstTouched - 1, curTouched, + firstTouched); + } + } + } + } + // Now store the values back. + if (dim == DIMENSION_HORZ) + { + for (int p = 0; p < numPoints; p++) + { + point = points[p]; + point.setX(point.getU()); + } + } + else + { + for (int p = 0; p < numPoints; p++) + { + point = points[p]; + point.setY(point.getU()); + } + } + } + + private void iupShift(int p1, int p2, int ref) + { + int delta = points[ref].getU() - points[ref].getV(); + for (int p = p1; p < ref; p++) + { + points[p].setU(points[p].getV() + delta); + } + for (int p = ref + 1; p <= p2; p++) + { + points[p].setU(points[p].getV() + delta); + } + } + + private void iupInterp(int p1, int p2, int ref1, int ref2) + { + int v1 = points[ref1].getV(); + int v2 = points[ref2].getV(); + int d1 = points[ref1].getU() - v1; + int d2 = points[ref2].getU() - v2; + if (p1 > p2) + return; + if (v1 == v2) + { + for (int p = p1; p <= p2; p++) + { + int u = points[p].getV(); + if (u <= v1) + u += d1; + else + u += d2; + points[p].setU(u); + } + } + else if (v1 < v2) + { + for (int p = p1; p <= p2; p++) + { + int u = points[p].getV(); + if (u <= v1) + u += d1; + else if (u >= v2) + u += d2; + else + { + u = points[ref1].getU() + Utils.mulDiv(u - v1, + points[ref2].getU() + - points[ref1].getU(), + v2 - v1); + } + points[p].setU(u); + } + } + else + { + for (int p = p1; p <= p2; p++) + { + int u = points[p].getV(); + if (u <= v2) + u += d2; + else if (u >= v1) + u += d1; + else + { + u = points[ref1].getU() + Utils.mulDiv(u - v1, + points[ref2].getU() + - points[ref1].getU(), + v2 - v1); + } + points[p].setU(u); + } + } + } + + void alignStrongPoints(int dim) + { + AxisHints ax = axis[dim]; + Edge[] edges = ax.edges; + int numEdges = ax.numEdges; + short touchFlag; + if (dim == DIMENSION_HORZ) + touchFlag = Point.FLAG_DONE_X; + else + touchFlag = Point.FLAG_DONE_Y; + + if (numEdges > 0) + { + for (int p = 0; p < numPoints; p++) + { + Point point = points[p]; + if ((point.getFlags() & touchFlag) != 0) + continue; + // If this point is a candidate for weak interpolation, we + // interpolate it after all strong points have been processed. + if ((point.getFlags() & Point.FLAG_WEAK_INTERPOLATION) != 0 + && (point.getFlags() & Point.FLAG_INFLECTION) == 0) + continue; + + int u, ou, fu, delta; + if (dim == DIMENSION_VERT) + { + u = point.getOrigY(); + ou = point.getScaledY(); + } + else + { + u = point.getOrigX(); + ou = point.getScaledX(); + } + fu = u; + // Is the point before the first edge? + Edge edge = edges[0]; + // Inversed vertical dimension. + delta = edge.fpos - u; + if (delta >= 0) + { + u = edge.pos - (edge.opos - ou); + storePoint(point, u, dim, touchFlag); + } + else + { + // Is the point after the last edge? + edge = edges[numEdges - 1]; + delta = u - edge.fpos; + if (delta >= 0) + { + u = edge.pos + (ou - edge.opos); + storePoint(point, u, dim, touchFlag); + } + else + { + // Find enclosing edges. + int min = 0; + int max = numEdges; + int mid, fpos; + boolean found = false; + while (min < max) + { + mid = (max + min) / 2; + edge = edges[mid]; + fpos = edge.fpos; + if (u < fpos) + max = mid; + else if (u > fpos) + min = mid + 1; + else + { + // Directly on the edge. + u = edge.pos; + storePoint(point, u, dim, touchFlag); + found = true; + break; + } + } + if (! found) + { + Edge before = edges[min - 1]; + Edge after = edges[min]; + if (before.scale == 0) + { + before.scale = Fixed.div16(after.pos - before.pos, + after.fpos - before.fpos); + } + u = before.pos + Fixed.mul16(fu - before.fpos, + before.scale); + } + storePoint(point, u, dim, touchFlag); + } + } + } + } + } + + private void storePoint(Point p, int u, int dim, short touchFlag) + { + if (dim == DIMENSION_HORZ) + p.setX(u); + else + p.setY(u); + p.addFlags(touchFlag); + } + + void alignEdgePoints(int dim) + { + AxisHints ax = axis[dim]; + Edge[] edges = ax.edges; + int numEdges = ax.numEdges; + for (int e = 0; e < numEdges; e++) + { + Edge edge = edges[e]; + Segment seg = edge.first; + do + { + Point point = seg.first; + while (true) + { + if (dim == DIMENSION_HORZ) + { + point.setX(edge.pos); + point.addFlags(Point.FLAG_DONE_X); + } + else + { + point.setY(edge.pos); + point.addFlags(Point.FLAG_DONE_Y); + } + if (point == seg.last) + break; + point = point.getNext(); + } + seg = seg.edgeNext; + } while (seg != edge.first); + } + } + + private int getPointIndex(Point p) + { + int idx = -1; + for (int i = 0; i < numPoints; i++) + { + if (p == points[i]) + { + idx = i; + break; + } + } + return idx; + } + + public boolean doAlignEdgePoints() + { + return (flags & FontDelegate.FLAG_NO_HINT_EDGE_POINTS) == 0; + } + + public boolean doAlignStrongPoints() + { + return (flags & FontDelegate.FLAG_NO_HINT_STRONG_POINTS) == 0; + } + + public boolean doAlignWeakPoints() + { + return (flags & FontDelegate.FLAG_NO_HINT_WEAK_POINTS) == 0; + } } Added: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/HintScaler.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/HintScaler.java (rev 0) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/HintScaler.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -0,0 +1,53 @@ +/* Scaler.java -- FIXME: briefly describe file purpose + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.font.autofit; + +import gnu.java.awt.font.opentype.OpenTypeFont; + +class HintScaler +{ + + int xScale; + int xDelta; + int yScale; + int yDelta; + OpenTypeFont face; + int renderMode; + +} Modified: trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Latin.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Latin.java 2007-01-05 20:55:34 UTC (rev 2988) +++ trunk/core/src/classpath/gnu/gnu/java/awt/font/autofit/Latin.java 2007-01-07 05:35:55 UTC (rev 2989) @@ -39,8 +39,11 @@ package gnu.java.awt.font.autofit; import java.awt.geom.AffineTransform; +import java.util.HashSet; import gnu.java.awt.font.opentype.OpenTypeFont; +import gnu.java.awt.font.opentype.truetype.Fixed; +import gnu.java.awt.font.opentype.truetype.Point; import gnu.java.awt.font.opentype.truetype.Zone; /** @@ -50,14 +53,478 @@ implements Script, Constants { - private static final int MAX_WIDTHS = 16; + static final int MAX_WIDTHS = 16; - public void applyHints(GlyphHints hints, ScriptMetrics metrics) + private final static int MAX_TEST_CHARS = 12; + + /** + * The types of the 6 blue zones. + */ + private static final int CAPITAL_TOP = 0; + private static final int CAPITAL_BOTTOM = 1; + private static final int SMALL_F_TOP = 2; + private static final int SMALL_TOP = 3; + private static final int SMALL_BOTTOM = 4; + private static final int SMALL_MINOR = 5; + static final int BLUE_MAX = 6; + + /** + * The test chars for the blue zones. + * + * @see #initBlues(LatinMetrics, OpenTypeFont) + */ + private static final String[] TEST_CHARS = + new String[]{"THEZOCQS", "HEZLOCUS", "fijkdbh", + "xzroesc", "xzroesc", "pqgjy"}; + + public void applyHints(GlyphHints hints, Zone outline, ScriptMetrics metrics) { + hints.reload(outline); + hints.rescale(metrics); + if (hints.doHorizontal()) + { + detectFeatures(hints, DIMENSION_HORZ); + } + if (hints.doVertical()) + { + detectFeatures(hints, DIMENSION_VERT); + computeBlueEdges(hints, (LatinMetrics) metrics); + } + // Grid-fit the outline. + for (int dim = 0; dim < DIMENSION_MAX; dim++) + { + if (dim == DIMENSION_HORZ && hints.doHorizontal() + || dim == DIMENSION_VERT && hints.doVertical()) + { + hintEdges(hints, dim); + if (hints.doAlignEdgePoints()) + hints.alignEdgePoints(dim); + if (hints.doAlignStrongPoints()) + hints.alignStrongPoints(dim); + if (hints.doAlignWeakPoints()) + hints.alignWeakPoints(dim); + + } + } + // FreeType does a save call here. I guess that's not needed as we operate + // on the live glyph data anyway. + } + + private void hintEdges(GlyphHints hints, int dim) + { + AxisHints axis = hints.axis[dim]; + Edge[] edges = axis.edges; + int numEdges = axis.numEdges; + Edge anchor = null; + int hasSerifs = 0; + + // We begin by aligning all stems relative to the blue zone if + // needed -- that's only for horizontal edges. + if (dim == DIMENSION_VERT) + { + for (int e = 0; e < numEdges; e++) + { + Edge edge = edges[e]; + if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0) + continue; + + Width blue = edge.blueEdge; + Edge edge1 = null; + Edge edge2 = edge.link; + if (blue != null) + { + edge1 = edge; + } + else if (edge2 != null && edge2.blueEdge != null) + { + blue = edge2.blueEdge; + edge1 = edge2; + edge2 = edge; + } + if (edge1 == null) + continue; + + edge1.pos = blue.fit; + edge1.flags |= Segment.FLAG_EDGE_DONE; + + if (edge2 != null && edge2.blueEdge == null) + { + alignLinkedEdge(hints, dim, edge1, edge2); + edge2.flags |= Segment.FLAG_EDGE_DONE; + } + if (anchor == null) + anchor = edge; + } + } + + // Now we will align all stem edges, trying to maintain the + // relative order of stems in the glyph. + for (int e = 0; e < numEdges; e++) + { + Edge edge = edges[e]; + if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0) + continue; + Edge edge2 = edge.link; + if (edge2 == null) + { + hasSerifs++; + continue; + } + // Now align the stem. + // This should not happen, but it's better to be safe. + if (edge2.blueEdge != null || axis.getEdgeIndex(edge2) < e) + { + alignLinkedEdge(hints, dim, edge2, edge); + edge.flags |= Segment.FLAG_EDGE_DONE; + continue; + } + + if (anchor == null) + { + int orgLen = edge2.opos - edge.opos; + int curLen = computeStemWidth(hints, dim, orgLen, edge.flags, + edge2.flags); + int uOff, dOff, orgCenter, curPos1, error1, error2; + if (curLen <= 64) // < 1 Pixel. + { + uOff = 32; + dOff = 32; + } + else + { + uOff = 38; + dOff = 26; + } + if (curLen < 96) + { + orgCenter = edge.opos + (orgLen >> 1); + curPos1 = Utils.pixRound(orgCenter); + error1 = orgCenter - (curPos1 - uOff); + if (error1 < 0) + error1 = -error1; + error2 = orgCenter - (curPos1 + dOff); + if (error2 < 0) + error2 = -error2; + if (error1 < error2) + { + curPos1 -= uOff; + } + else + { + curPos1 += dOff; + } + edge.pos = curPos1 - curLen / 2; + edge2.pos = curPos1 + curLen / 2; + } + else + { + edge.pos = Utils.pixRound(edge.opos); + } + anchor = edge; + edge.flags |= Segment.FLAG_EDGE_DONE; + alignLinkedEdge(hints, dim, edge, edge2); + } + else + { + int aDiff = edge.opos - anchor.opos; + int orgPos = anchor.pos + aDiff; + int orgLen = edge2.opos - edge.opos; + int orgCenter = orgPos + (orgLen >> 1); + int curLen = computeStemWidth(hints, dim, orgLen, edge.flags, + edge2.flags); + //System.err.println("stem width: " + curLen); + if (curLen < 96) + { + int uOff, dOff; + int curPos1 = Utils.pixRound(orgCenter); + if (curLen <= 64) + { + uOff = 32; + dOff = 32; + } + else + { + uOff = 38; + dOff = 26; + } + int delta1 = orgCenter - (curPos1 - uOff); + if (delta1 < 0) + delta1 = -delta1; + int delta2 = orgCenter - (curPos1 + dOff); + if (delta2 < 0) + delta2 = -delta2; + if (delta1 < delta2) + { + curPos1 -= uOff; + } + else + { + curPos1 += dOff; + } + edge.pos = curPos1 - curLen / 2; + edge2.pos = curPos1 + curLen / 2; + } + else + { + orgPos = anchor.pos + (edge.opos - anchor.opos); + orgLen = edge2.opos - edge.opos; + orgCenter = orgPos + (orgLen >> 1); + curLen = computeStemWidth(hints, dim, orgLen, edge.flags, + edge2.flags); + int curPos1 = Utils.pixRound(orgPos); + int delta1 = curPos1 + (curLen >> 1) - orgCenter; + if (delta1 < 0) + delta1 = -delta1; + int curPos2 = Utils.pixRound(orgPos + orgLen) - curLen; + int delta2 = curPos2 + (curLen >> 1) - orgCenter; + if (delta2 < 0) + delta2 = -delta2; + edge.pos = (delta1 < delta2) ? curPos1 : curPos2; + edge2.pos = edge.pos + curLen; + } + edge.flags |= Segment.FLAG_EDGE_DONE; + edge2.flags |= Segment.FLAG_EDGE_DONE; + + if (e > 0 && edge.pos < edges[e - 1].pos) + { + edge.pos = edges[e - 1].pos; + } + } + } + // TODO: Implement the lowercase m symmetry thing. + + // Now we hint the remaining edges (serifs and singles) in order + // to complete our processing. + if (hasSerifs > 0 || anchor == null) + { + for (int e = 0; e < numEdges; e++) + { + Edge edge = edges[e]; + if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0) + continue; + if (edge.serif != null) + { + alignSerifEdge(hints, edge.serif, edge); + } + else if (anchor == null) + { + edge.pos = Utils.pixRound(edge.opos); + anchor = edge; + } + else + { + edge.pos = anchor.pos + + Utils.pixRound(edge.opos - anchor.opos); + } + edge.flags |= Segment.FLAG_EDGE_DONE; + + if (e > 0 && edge.pos < edges[e - 1].pos) + { + edge.pos = edges[e - 1].pos; + } + if (e + 1 < numEdges + && (edges[e + 1].flags & Segment.FLAG_EDGE_DONE) != 0 + && edge.pos > edges[e + 1].pos) + { + edge.pos = edges[e + 1].pos; + } + } + } + + // Debug: print all hinted edges. + // System.err.println("hinted edges: " ); + // for (int i = 0; i < numEdges; i++) + // { + // System.err.println("edge#" + i + ": " + edges[i]); + // } + } + + private void alignSerifEdge(GlyphHints hints, Edge base, Edge serif) + { + serif.pos = base.pos + (serif.opos - base.opos); + } + + private int computeStemWidth(GlyphHints hints, int dim, int width, + int baseFlags, int stemFlags) + { + LatinMetrics metrics = (LatinMetrics) hints.metrics; + LatinAxis axis = metrics.axis[dim]; + int dist = width; + int sign = 0; + boolean vertical = dim == DIMENSION_VERT; + if (! doStemAdjust(hints)) + return width; + if (dist < 0) + { + dist = -width; + sign = 1; + } + if ((vertical && ! doVertSnap(hints)) || ! vertical && ! doHorzSnap(hints)) + { + // Smooth hinting process. Very lightly quantize the stem width. + // Leave the widths of serifs alone. + if ((stemFlags & Segment.FLAG_EDGE_SERIF) != 0 && vertical + && dist < 3 * 64) + { + return doneWidth(dist, sign); + } + else if ((baseFlags & Segment.FLAG_EDGE_ROUND) != 0) + { + if (dist < 80) + dist = 64; + } + else if (dist < 56) + { + dist = 56; + } + if (axis.widthCount > 0) + { + int delta; + if (axis.widthCount > 0) + { + delta = dist - axis.widths[0].cur; + if (delta < 0) + { + delta = -delta; + } + if (delta < 40) + { + dist = axis.widths[0].cur; + if (dist < 48) + dist = 48; + return doneWidth(dist, sign); + } + } + if (dist < 3 * 64) // < 3 pixels. + { + delta = dist & 63; + dist &= -64; + if (delta < 10) + dist += delta; + else if (delta < 32) + dist += 10; + else if (delta < 54) + dist += 54; + else + dist += delta; + + } + else + { + dist = (dist + 32) & ~63; + } + } + } + else + { + // Strong hinting process: Snap the stem width to integer pixels. + dist = snapWidth(axis.widths, axis.widthCount, dist); + if (vertical) + { + // In the case of vertical hinting, always round + // the stem heights to integer pixels. + if (dist >= 64) + dist = (dist + 16) & ~63; + else + dist = 64; + } + else + { + if (doMono(hints)) + { + // Monochrome horizontal hinting: Snap widths to integer pixels + // with a different threshold. + if (dist < 64) + dist = 64; + else + dist = (dist + 32) & ~63; + } + else + { + // For anti-aliased hinting, we adopt a more subtle + // approach: We strengthen small stems, round those stems + // whose size is between 1 and 2 pixels to an integer, + // otherwise nothing. + if (dist < 48) + dist = (dist + 64) >> 1; + else if (dist < 128) + dist = (dist + 22) & ~63; + else + // Round otherwise to prevent color fringes in LCD mode. + dist = (dist + 32) & ~63; + } + } + } + return doneWidth(dist, sign); + } + + private boolean doMono(GlyphHints hints) + { + return true; + } + + private int snapWidth(Width[] widths, int count, int width) + { + int best = 64 + 32 + 2; + int reference = width; + for (int n = 0; n < count; n++) + { + int w = widths[n].cur; + int dist = width - w; + if (dist < 0) + dist = -dist; + if (dist < best) + { + best = dist; + reference = w; + } + } + int scaled = Utils.pixRound(reference); + if (width >= reference) + { + if (width < scaled + 48) + width = reference; + } + else + { + if (width > scaled + 48) + width = reference; + } + return width; + } + + private int doneWidth(int w, int s) + { + if (s == 1) + w = -w; + return w; + } + + private boolean doVertSnap(GlyphHints hints) + { // TODO Auto-generated method stub + return true; + } + private boolean doHorzSnap(GlyphHints hints) + { + // TODO Auto-generated method stub + return true; } + private boolean doStemAdjust(GlyphHints hints) + { + // TODO Auto-generated method stub + return true; + } + + private void alignLinkedEdge(GlyphHints hints, int dim, Edge base, Edge stem) + { + int dist = stem.opos - base.opos; + int fitted = computeStemWidth(hints, dim, dist, base.flags, stem.flags); + stem.pos = base.pos + fitted; + } + public void doneMetrics(ScriptMetrics metrics) { // TODO Auto-generated method stub @@ -99,10 +566,119 @@ initBlues(lm, face); } - public void scaleMetrics(ScriptMetrics metrics) + public void scaleMetrics(ScriptMetrics metrics, HintScaler scaler) { - // TODO Auto-generated method stub + LatinMetrics lm = (LatinMetrics) metrics; + lm.scaler.renderMode = scaler.renderMode; + lm.scaler.face = scaler.face; + scaleMetricsDim(lm, scaler, DIMENSION_HORZ); + scaleMetricsDim(lm, scaler, DIMENSION_VERT); + } + private void scaleMetricsDim(LatinMetrics lm, HintScaler scaler, int dim) + { + int scale; + int delta; + if (dim == DIMENSION_HORZ) + { + scale = scaler.xScale; + delta = scaler.xDelta; + } + else + { + scale = scaler.yScale; + delta = scaler.yDelta; + } + LatinAxis axis = lm.axis[dim]; + if (axis.orgScale == scale && axis.orgDelta == delta) + // No change, no need to adjust. + return; + axis.orgScale = scale; + axis.orgDelta = delta; + + // Correct X and Y scale to optimize the alignment of the top small + // letters to the pixel grid. + LatinAxis axis2 = lm.axis[DIMENSION_VERT]; + LatinBlue blue = null; +// for (int nn = 0; nn < axis2.blueCount; nn++) +// { +// if ((axis2.blues[nn].flags & LatinBlue.FLAG_ADJUSTMENT) != 0) +// { +// blue = axis2.blues[nn]; +// break; +// } +// } +// if (blue != null) +// { +// int scaled = Fixed.mul16(blue.shoot.org, scaler.yScale); +// int fitted = Utils.pixRound(scaled); +// if (scaled != fitted) +// { +// if (dim == DIMENSION_HORZ) +// { +// if (fitted < scaled) +// { +// scale -= scale / 50; +// } +// } +// else +// { +// scale = Utils.mulDiv(scale, fitted, scaled); +// } +// } +// } + axis.scale = scale; + axis.delta = delta; + if (dim == DIMENSION_HORZ) + { + lm.scaler.xScale = scale; + lm.scaler.xDelta = delta; + } + else + { + lm.scaler.yScale = scale; + lm.scaler.yDelta = delta; + } + // Scale the standard widths. + for (int nn = 0; nn < axis.widthCount; nn++) + { + Width w = axis.widths[nn]; + w.cur = Fixed.mul16(w.org, scale); + w.fit = w.cur; + } + // Scale blue zones. + if (dim == DIMENSION_VERT) + { + for (int nn = 0; nn < axis.blueCount; nn++) + { + blue = axis.blues[nn]; + blue.ref.cur = Fixed.mul16(blue.ref.org, scale) + delta; + blue.ref.fit = blue.ref.cur; + blue.shoot.cur = Fixed.mul16(blue.ref.org, scale) + delta; + blue.flags &= ~LatinBlue.FLAG_BLUE_ACTIVE; + // A blue zone is only active if it is less than 3/4 pixels tall. + int dist = Fixed.mul16(blue.ref.org - blue.shoot.org, scale); + if (dist <= 48 && dist >= -48) + { + int delta1 = blue.shoot.org - blue.ref.org; + int delta2 = delta1; + if (delta1 < 0) + delta2 = -delta2; + delta2 = Fixed.mul16(delta2, scale); + if (delta2 < 32) + delta2 = 0; + else if (delta2 < 64) + delta2 = 32 + (((delta2 - 32) + 16) & ~31); + else + delta2 = Utils.pixRound(delta2); + if (delta1 < 0) + delta2 = -delta2; + blue.ref.fit = Utils.pixRound(blue.ref.cur); + blue.shoot.fit = blue.ref.fit + delta2; + blue.flags |= LatinBlue.FLAG_BLUE_ACTIVE; + } + } + } } /** @@ -118,12 +694,9 @@ metrics.axis[DIMENSION_HORZ].widthCount = 0; metrics.axis[DIMENSION_VERT].widthCount = 0; int glyphIndex = face.getGlyph(ch); - // TODO: Avoid that AffineTransform constructor and change - // getRawGlyphOutline() to accept null or remove that parameter altogether. - // Consider this when the thing is done and we know what we need that for. - Zone outline = face.getRawGlyphOutline(glyphIndex, new AffineTransform()); + Zone outline = face.getRawGlyphOutline(glyphIndex, IDENTITY); LatinMetrics dummy = new LatinMetrics(); - Scaler scaler = dummy.scaler; + HintScaler scaler = dummy.scaler; dummy.unitsPerEm = metrics.unitsPerEm; scaler.xScale = scaler.yScale = 10000; scaler.xDelta = scaler.yDelta = 0; @@ -135,20 +708,24 @@ LatinAxis axis = metrics.axis[dim]; AxisHints axHints = hints.axis[dim]; int numWidths = 0; - hints.computeSegments(dim); - hints.linkSegments(dim); + computeSegments(hints, dim); + linkSegments(hints, dim); Segment[] segs = axHints.segments; + HashSet<Segment> touched = new HashSet<Segment>(); for (int i = 0; i < segs.length; i++) { Segment seg = segs[i]; Segment link = seg.link; - if (link != null && link.link == seg && link.index > i) + if (link != null && link.link == seg && ! touched.contains(link)) { int dist = Math.abs(seg.pos - link.pos); if (numWidths < MAX_WIDTHS) - axis.widths[numWidths++].org = dist; + axis.widths[numWidths++] = new Width(dist); } + touched.add(seg); } + Utils.sort(numWidths, axis.widths); + axis.widthCount = numWidths; } for (int dim = 0; dim < DIMENSION_MAX; dim++) { @@ -159,6 +736,78 @@ } } + void linkSegments(GlyphHints hints, int dim) + { + AxisHints axis = hints.axis[dim]; + Segment[] segments = axis.segments; + int numSegs = axis.numSegments; + int majorDir = axis.majorDir; + int lenThreshold = constant((LatinMetrics) hints.metrics, 8); + lenThreshold = Math.min(1, lenThreshold); + int lenScore = constant((LatinMetrics) hints.metrics, 3000); + for (int i1 = 0; i1 < numSegs; i1++) + { + Segment seg1 = segments[i1]; + // The fake segments are introduced to hint the metrics. + // Never link them to anything. + if (seg1.first == seg1.last || seg1.dir != majorDir) + continue; + for (int i2 = 0; i2 < numSegs; i2++) + { + Segment seg2 = segments[i2]; + if (seg2 != seg1 && seg1.dir + seg2.dir == 0) + { + int pos1 = seg1.pos; + int pos2 = seg2.pos; + // The vertical coords are swapped compared to how FT handles + // this. + int dist = dim == DIMENSION_VERT ? pos1 - pos2 : pos2 - pos1; + if (dist >= 0) + { + int min = seg1.minPos; + int max = seg1.maxPos; + int len, score; + if (min < seg2.minPos) + min = seg2.minPos; + if (max > seg2.maxPos) + max = seg2.maxPos; + len = max - min; + if (len > lenThreshold) + { + score = dist + lenScore / len; + if (score < seg1.score) + { + seg1.score = score; + seg1.link = seg2; + } + if (score < seg2.score) + { + ... [truncated message content] |
From: <ls...@us...> - 2007-01-05 20:55:44
|
Revision: 2988 http://jnode.svn.sourceforge.net/jnode/?rev=2988&view=rev Author: lsantha Date: 2007-01-05 12:55:34 -0800 (Fri, 05 Jan 2007) Log Message: ----------- Fixed Ctrl-Y. Modified Paths: -------------- trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java Modified: trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java =================================================================== --- trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java 2007-01-04 20:29:43 UTC (rev 2987) +++ trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java 2007-01-05 20:55:34 UTC (rev 2988) @@ -174,7 +174,7 @@ case KeyEvent.VK_RIGHT: {if(fx < mx()) fx ++; break;} case KeyEvent.VK_HOME: {cx = fx = cy = fy = 0; break;} case KeyEvent.VK_END: { if(my() < cym) cy = my(); else {cy = cym; fy = my() - cy;} end(); break;} - case KeyEvent.VK_Y: { if(oy() >= 0 && oy() <= my()) {ls.remove(oy()); if(cy > 0) cy --; else if(fy > 0) fy --;} break;} + case KeyEvent.VK_Y: { if(oy() >= 0 && oy() <= my()) {ls.remove(oy()); if(cy > 0 && oy() == my() + 1) cy --; else if(fy > 0) fy --;} break;} case KeyEvent.VK_S: { saveFile(); break;} case KeyEvent.VK_Q: { console.getManager().unregisterConsole(console); break;} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 20:29:46
|
Revision: 2987 http://jnode.svn.sourceforge.net/jnode/?rev=2987&view=rev Author: lsantha Date: 2007-01-04 12:29:43 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Classpath updates. Modified Paths: -------------- trunk/core/src/classpath/java/java/lang/reflect/Proxy.java Modified: trunk/core/src/classpath/java/java/lang/reflect/Proxy.java =================================================================== --- trunk/core/src/classpath/java/java/lang/reflect/Proxy.java 2007-01-04 20:24:57 UTC (rev 2986) +++ trunk/core/src/classpath/java/java/lang/reflect/Proxy.java 2007-01-04 20:29:43 UTC (rev 2987) @@ -1,48 +1,49 @@ /* Proxy.java -- build a proxy class that implements reflected interfaces Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - This file is part of GNU Classpath. +This file is part of GNU Classpath. - GNU Classpath is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. - GNU Classpath is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. - You should have received a copy of the GNU General Public License - along with GNU Classpath; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. - Linking this library statically or dynamically with other modules is - making a combined work based on this library. Thus, the terms and - conditions of the GNU General Public License cover the whole - combination. +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent - modules, and to copy and distribute the resulting executable under - terms of your choice, provided that you also meet, for each linked - independent module, the terms and conditions of the license of that - module. An independent module is a module which is not derived from - or based on this library. If you modify this library, you may extend - this exception to your version of the library, but you are not - obligated to do so. If you do not wish to do so, delete this - exception statement from your version. */ +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + package java.lang.reflect; import gnu.java.lang.reflect.TypeSignature; import java.io.Serializable; +import java.security.ProtectionDomain; import java.security.AccessController; import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -51,11 +52,12 @@ import java.util.Set; /** - * This class allows you to dynamically create an instance of any (or even - * multiple) interfaces by reflection, and decide at runtime how that instance - * will behave by giving it an appropriate {@link InvocationHandler}. Proxy - * classes serialize specially, so that the proxy object can be reused between - * VMs, without requiring a persistent copy of the generated class code. + * This class allows you to dynamically create an instance of any (or + * even multiple) interfaces by reflection, and decide at runtime + * how that instance will behave by giving it an appropriate + * {@link InvocationHandler}. Proxy classes serialize specially, so + * that the proxy object can be reused between VMs, without requiring + * a persistent copy of the generated class code. * * <h3>Creation</h3> * To create a proxy for some interface Foo: @@ -68,84 +70,87 @@ * .getConstructor(new Class[] { InvocationHandler.class }) * .newInstance(new Object[] { handler }); * </pre> - * * or more simply: - * * <pre> * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), - * new Class[] { Foo.class }, handler); + * new Class[] { Foo.class }, + * handler); * </pre> * * <h3>Dynamic Proxy Classes</h3> * A dynamic proxy class is created at runtime, and has the following * properties: * <ul> - * <li>The class is <code>public</code> and <code>final</code>, and is - * neither <code>abstract</code> nor an inner class.</li> - * <li>The class has no canonical name (there is no formula you can use to - * determine or generate its name), but begins with the sequence "$Proxy". Abuse - * this knowledge at your own peril. (For now, '$' in user identifiers is legal, - * but it may not be that way forever. You weren't using '$' in your + * <li>The class is <code>public</code> and <code>final</code>, + * and is neither <code>abstract</code> nor an inner class.</li> + * <li>The class has no canonical name (there is no formula you can use + * to determine or generate its name), but begins with the + * sequence "$Proxy". Abuse this knowledge at your own peril. + * (For now, '$' in user identifiers is legal, but it may not + * be that way forever. You weren't using '$' in your * identifiers, were you?)</li> - * <li>The class extends Proxy, and explicitly implements all the interfaces - * specified at creation, in order (this is important for determining how method - * invocation is resolved). Note that a proxy class implements - * {@link Serializable}, at least implicitly, since Proxy does, but true serial - * behavior depends on using a serializable invocation handler as well.</li> - * <li>If at least one interface is non-public, the proxy class will be in the - * same package. Otherwise, the package is unspecified. This will work even if - * the package is sealed from user-generated classes, because Proxy classes are - * generated by a trusted source. Meanwhile, the proxy class belongs to the - * classloader you designated.</li> + * <li>The class extends Proxy, and explicitly implements all the + * interfaces specified at creation, in order (this is important + * for determining how method invocation is resolved). Note that + * a proxy class implements {@link Serializable}, at least + * implicitly, since Proxy does, but true serial behavior + * depends on using a serializable invocation handler as well.</li> + * <li>If at least one interface is non-public, the proxy class + * will be in the same package. Otherwise, the package is + * unspecified. This will work even if the package is sealed + * from user-generated classes, because Proxy classes are + * generated by a trusted source. Meanwhile, the proxy class + * belongs to the classloader you designated.</li> * <li>Reflection works as expected: {@link Class#getInterfaces()} and * {@link Class#getMethods()} work as they do on normal classes.</li> - * <li>The method {@link #isProxyClass(Class)} will distinguish between true - * proxy classes and user extensions of this class. It only returns true for - * classes created by {@link #getProxyClass}.</li> + * <li>The method {@link #isProxyClass(Class)} will distinguish between + * true proxy classes and user extensions of this class. It only + * returns true for classes created by {@link #getProxyClass}.</li> * <li>The {@link ProtectionDomain} of a proxy class is the same as for - * bootstrap classes, such as Object or Proxy, since it is created by a trusted - * source. This protection domain will typically be granted - * {@link java.security.AllPermission}. But this is not a security risk, since - * there are adequate permissions on reflection, which is the only way to create - * an instance of the proxy class.</li> - * <li>The proxy class contains a single constructor, which takes as its only - * argument an {@link InvocationHandler}. The method - * {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)} is - * shorthand to do the necessary reflection.</li> + * bootstrap classes, such as Object or Proxy, since it is created by + * a trusted source. This protection domain will typically be granted + * {@link java.security.AllPermission}. But this is not a security + * risk, since there are adequate permissions on reflection, which is + * the only way to create an instance of the proxy class.</li> + * <li>The proxy class contains a single constructor, which takes as + * its only argument an {@link InvocationHandler}. The method + * {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)} + * is shorthand to do the necessary reflection.</li> * </ul> * * <h3>Proxy Instances</h3> - * A proxy instance is an instance of a proxy class. It has the following - * properties, many of which follow from the properties of a proxy class listed - * above: + * A proxy instance is an instance of a proxy class. It has the + * following properties, many of which follow from the properties of a + * proxy class listed above: * <ul> * <li>For a proxy class with Foo listed as one of its interfaces, the - * expression <code>proxy instanceof Foo</code> will return true, and the - * expression <code>(Foo) proxy</code> will succeed without a - * {@link ClassCastException}.</li> - * <li>Each proxy instance has an invocation handler, which can be accessed by - * {@link #getInvocationHandler(Object)}. Any call to an interface method, - * including {@link Object#hashCode()}, {@link Object#equals(Object)}, or - * {@link Object#toString()}, but excluding the public final methods of Object, - * will be encoded and passed to the {@link InvocationHandler#invoke} method of - * this handler.</li> + * expression <code>proxy instanceof Foo</code> will return true, + * and the expression <code>(Foo) proxy</code> will succeed without + * a {@link ClassCastException}.</li> + * <li>Each proxy instance has an invocation handler, which can be + * accessed by {@link #getInvocationHandler(Object)}. Any call + * to an interface method, including {@link Object#hashCode()}, + * {@link Object#equals(Object)}, or {@link Object#toString()}, + * but excluding the public final methods of Object, will be + * encoded and passed to the {@link InvocationHandler#invoke} + * method of this handler.</li> * </ul> * * <h3>Inheritance Issues</h3> - * A proxy class may inherit a method from more than one interface. The order in - * which interfaces are listed matters, because it determines which reflected - * {@link Method} object will be passed to the invocation handler. This means - * that the dynamically generated class cannot determine through which interface - * a method is being invoked. - * <p> - * - * In short, if a method is declared in Object (namely, hashCode, equals, or - * toString), then Object will be used; otherwise, the leftmost interface that - * inherits or declares a method will be used, even if it has a more permissive - * throws clause than what the proxy class is allowed. Thus, in the invocation - * handler, it is not always safe to assume that every class listed in the - * throws clause of the passed Method object can safely be thrown; fortunately, - * the Proxy instance is robust enough to wrap all illegal checked exceptions in + * A proxy class may inherit a method from more than one interface. + * The order in which interfaces are listed matters, because it determines + * which reflected {@link Method} object will be passed to the invocation + * handler. This means that the dynamically generated class cannot + * determine through which interface a method is being invoked.<p> + * + * In short, if a method is declared in Object (namely, hashCode, + * equals, or toString), then Object will be used; otherwise, the + * leftmost interface that inherits or declares a method will be used, + * even if it has a more permissive throws clause than what the proxy + * class is allowed. Thus, in the invocation handler, it is not always + * safe to assume that every class listed in the throws clause of the + * passed Method object can safely be thrown; fortunately, the Proxy + * instance is robust enough to wrap all illegal checked exceptions in * {@link UndeclaredThrowableException}. * * @see InvocationHandler @@ -155,7 +160,8 @@ * @since 1.3 * @status updated to 1.4, except for the use of ProtectionDomain */ -public class Proxy implements Serializable { +public class Proxy implements Serializable +{ /** * Compatible with JDK 1.3+. */ @@ -171,164 +177,166 @@ private static final Map proxyClasses = new HashMap(); /** - * The invocation handler for this proxy instance. For Proxy, this field is - * unused, but it appears here in order to be serialized in all proxy - * classes. + * The invocation handler for this proxy instance. For Proxy, this + * field is unused, but it appears here in order to be serialized in all + * proxy classes. * * <em>NOTE</em>: This implementation is more secure for proxy classes - * than what Sun specifies. Sun does not require h to be immutable, but this - * means you could change h after the fact by reflection. However, by making - * h immutable, we may break non-proxy classes which extend Proxy. - * + * than what Sun specifies. Sun does not require h to be immutable, but + * this means you could change h after the fact by reflection. However, + * by making h immutable, we may break non-proxy classes which extend + * Proxy. * @serial invocation handler associated with this proxy instance */ protected InvocationHandler h; /** - * Constructs a new Proxy from a subclass (usually a proxy class), with the - * specified invocation handler. + * Constructs a new Proxy from a subclass (usually a proxy class), + * with the specified invocation handler. * - * <em>NOTE</em>: This throws a NullPointerException if you attempt to - * create a proxy instance with a null handler using reflection. This - * behavior is not yet specified by Sun; see Sun Bug 4487672. - * - * @param handler - * the invocation handler, may be null if the subclass is not a - * proxy class - * @throws NullPointerException - * if handler is null and this is a proxy instance + * <em>NOTE</em>: This throws a NullPointerException if you attempt + * to create a proxy instance with a null handler using reflection. + * This behavior is not yet specified by Sun; see Sun Bug 4487672. + * + * @param handler the invocation handler, may be null if the subclass + * is not a proxy class + * @throws NullPointerException if handler is null and this is a proxy + * instance */ - protected Proxy(InvocationHandler handler) { + protected Proxy(InvocationHandler handler) + { if (handler == null && isProxyClass(getClass())) throw new NullPointerException("invalid handler"); h = handler; } /** - * Returns the proxy {@link Class} for the given ClassLoader and array of - * interfaces, dynamically generating it if necessary. + * Returns the proxy {@link Class} for the given ClassLoader and array + * of interfaces, dynamically generating it if necessary. * - * <p> - * There are several restrictions on this method, the violation of which - * will result in an IllegalArgumentException or NullPointerException: - * </p> + * <p>There are several restrictions on this method, the violation of + * which will result in an IllegalArgumentException or + * NullPointerException:</p> * * <ul> * <li>All objects in `interfaces' must represent distinct interfaces. * Classes, primitive types, null, and duplicates are forbidden.</li> - * <li>The interfaces must be visible in the specified ClassLoader. In - * other words, for each interface i: - * <code>Class.forName(i.getName(), false, loader) == i</code> must be - * true.</li> - * <li>All non-public interfaces (if any) must reside in the same package, - * or the proxy class would be non-instantiable. If there are no non-public - * interfaces, the package of the proxy class is unspecified.</li> - * <li>All interfaces must be compatible - if two declare a method with the - * same name and parameters, the return type must be the same and the throws - * clause of the proxy class will be the maximal subset of subclasses of the - * throws clauses for each method that is overridden.</li> - * <li>VM constraints limit the number of interfaces a proxy class may - * directly implement (however, the indirect inheritance of - * {@link Serializable} does not count against this limit). Even though most - * VMs can theoretically have 65535 superinterfaces for a class, the actual - * limit is smaller because a class's constant pool is limited to 65535 - * entries, and not all entries can be interfaces.</li> + * <li>The interfaces must be visible in the specified ClassLoader. + * In other words, for each interface i: + * <code>Class.forName(i.getName(), false, loader) == i</code> + * must be true.</li> + * <li>All non-public interfaces (if any) must reside in the same + * package, or the proxy class would be non-instantiable. If + * there are no non-public interfaces, the package of the proxy + * class is unspecified.</li> + * <li>All interfaces must be compatible - if two declare a method + * with the same name and parameters, the return type must be + * the same and the throws clause of the proxy class will be + * the maximal subset of subclasses of the throws clauses for + * each method that is overridden.</li> + * <li>VM constraints limit the number of interfaces a proxy class + * may directly implement (however, the indirect inheritance + * of {@link Serializable} does not count against this limit). + * Even though most VMs can theoretically have 65535 + * superinterfaces for a class, the actual limit is smaller + * because a class's constant pool is limited to 65535 entries, + * and not all entries can be interfaces.</li> * </ul> * - * <p> - * Note that different orders of interfaces produce distinct classes. - * </p> - * - * @param loader - * the class loader to define the proxy class in; null implies - * the bootstrap class loader - * @param interfaces - * the array of interfaces the proxy class implements, may be - * empty, but not null + * <p>Note that different orders of interfaces produce distinct classes.</p> + * + * @param loader the class loader to define the proxy class in; null + * implies the bootstrap class loader + * @param interfaces the array of interfaces the proxy class implements, + * may be empty, but not null * @return the Class object of the proxy class - * @throws IllegalArgumentException - * if the constraints above were violated, except for problems - * with null - * @throws NullPointerException - * if `interfaces' is null or contains a null entry + * @throws IllegalArgumentException if the constraints above were + * violated, except for problems with null + * @throws NullPointerException if `interfaces' is null or contains + * a null entry */ // synchronized so that we aren't trying to build the same class // simultaneously in two threads public static synchronized Class getProxyClass(ClassLoader loader, - Class[] interfaces) { + Class[] interfaces) + { interfaces = (Class[]) interfaces.clone(); ProxyType pt = new ProxyType(loader, interfaces); Class clazz = (Class) proxyClasses.get(pt); - if (clazz == null) { + if (clazz == null) + { if (VMProxy.HAVE_NATIVE_GET_PROXY_CLASS) clazz = VMProxy.getProxyClass(loader, interfaces); - else { - ProxyData data = (VMProxy.HAVE_NATIVE_GET_PROXY_DATA ? VMProxy - .getProxyData(loader, interfaces) : ProxyData - .getProxyData(pt)); + else + { + ProxyData data = (VMProxy.HAVE_NATIVE_GET_PROXY_DATA + ? VMProxy.getProxyData(loader, interfaces) + : ProxyData.getProxyData(pt)); - clazz = (VMProxy.HAVE_NATIVE_GENERATE_PROXY_CLASS ? VMProxy - .generateProxyClass(loader, data) : new ClassFactory( - data).generate(loader)); + clazz = (VMProxy.HAVE_NATIVE_GENERATE_PROXY_CLASS + ? VMProxy.generateProxyClass(loader, data) + : new ClassFactory(data).generate(loader)); } Object check = proxyClasses.put(pt, clazz); // assert check == null && clazz != null; if (check != null || clazz == null) - throw new InternalError(/* "Fatal flaw in getProxyClass" */); + throw new InternalError(/*"Fatal flaw in getProxyClass"*/); } return clazz; } /** * Combines several methods into one. This is equivalent to: - * * <pre> - * Proxy.getProxyClass(loader, interfaces).getConstructor( - * new Class[] { InvocationHandler.class }).newInstance( - * new Object[] { handler }); + * Proxy.getProxyClass(loader, interfaces) + * .getConstructor(new Class[] {InvocationHandler.class}) + * .newInstance(new Object[] {handler}); * </pre> + * except that it will not fail with the normal problems caused + * by reflection. It can still fail for the same reasons documented + * in getProxyClass, or if handler is null. * - * except that it will not fail with the normal problems caused by - * reflection. It can still fail for the same reasons documented in - * getProxyClass, or if handler is null. - * - * @param loader - * the class loader to define the proxy class in; null implies - * the bootstrap class loader - * @param interfaces - * the array of interfaces the proxy class implements, may be - * empty, but not null - * @param handler - * the invocation handler, may not be null + * @param loader the class loader to define the proxy class in; null + * implies the bootstrap class loader + * @param interfaces the array of interfaces the proxy class implements, + * may be empty, but not null + * @param handler the invocation handler, may not be null * @return a proxy instance implementing the specified interfaces - * @throws IllegalArgumentException - * if the constraints for getProxyClass were violated, except - * for problems with null - * @throws NullPointerException - * if `interfaces' is null or contains a null entry, or if - * handler is null + * @throws IllegalArgumentException if the constraints for getProxyClass + * were violated, except for problems with null + * @throws NullPointerException if `interfaces' is null or contains + * a null entry, or if handler is null * @see #getProxyClass(ClassLoader, Class[]) * @see Class#getConstructor(Class[]) * @see Constructor#newInstance(Object[]) */ public static Object newProxyInstance(ClassLoader loader, - Class[] interfaces, InvocationHandler handler) { - try { + Class[] interfaces, + InvocationHandler handler) + { + try + { // getProxyClass() and Proxy() throw the necessary exceptions - return getProxyClass(loader, interfaces).getConstructor( - new Class[] { InvocationHandler.class }).newInstance( - new Object[] { handler }); - } catch (RuntimeException e) { + return getProxyClass(loader, interfaces) + .getConstructor(new Class[] {InvocationHandler.class}) + .newInstance(new Object[] {handler}); + } + catch (RuntimeException e) + { // Let IllegalArgumentException, NullPointerException escape. // assert e instanceof IllegalArgumentException // || e instanceof NullPointerException; throw e; - } catch (InvocationTargetException e) { + } + catch (InvocationTargetException e) + { // Let wrapped NullPointerException escape. // assert e.getTargetException() instanceof NullPointerException throw (NullPointerException) e.getCause(); - } catch (Exception e) { + } + catch (Exception e) + { // Covers InstantiationException, IllegalAccessException, // NoSuchMethodException, none of which should be generated // if the proxy class was generated correctly. @@ -339,24 +347,22 @@ /** * Returns true if and only if the Class object is a dynamically created - * proxy class (created by <code>getProxyClass</code> or by the syntactic - * sugar of <code>newProxyInstance</code>). + * proxy class (created by <code>getProxyClass</code> or by the + * syntactic sugar of <code>newProxyInstance</code>). * - * <p> - * This check is secure (in other words, it is not simply - * <code>clazz.getSuperclass() == Proxy.class</code>), it will not be - * spoofed by non-proxy classes that extend Proxy. + * <p>This check is secure (in other words, it is not simply + * <code>clazz.getSuperclass() == Proxy.class</code>), it will not + * be spoofed by non-proxy classes that extend Proxy. * - * @param clazz - * the class to check, must not be null + * @param clazz the class to check, must not be null * @return true if the class represents a proxy class - * @throws NullPointerException - * if clazz is null + * @throws NullPointerException if clazz is null */ // This is synchronized on the off chance that another thread is // trying to add a class to the map at the same time we read it. - public static synchronized boolean isProxyClass(Class clazz) { - if (!Proxy.class.isAssignableFrom(clazz)) + public static synchronized boolean isProxyClass(Class clazz) + { + if (! Proxy.class.isAssignableFrom(clazz)) return false; // This is a linear search, even though we could do an O(1) search // using new ProxyType(clazz.getClassLoader(), clazz.getInterfaces()). @@ -364,35 +370,33 @@ } /** - * Returns the invocation handler for the given proxy instance. - * <p> + * Returns the invocation handler for the given proxy instance.<p> * - * <em>NOTE</em>: We guarantee a non-null result if successful, but Sun - * allows the creation of a proxy instance with a null handler. See the - * comments for {@link #Proxy(InvocationHandler)}. + * <em>NOTE</em>: We guarantee a non-null result if successful, + * but Sun allows the creation of a proxy instance with a null + * handler. See the comments for {@link #Proxy(InvocationHandler)}. * - * @param proxy - * the proxy instance, must not be null + * @param proxy the proxy instance, must not be null * @return the invocation handler, guaranteed non-null. - * @throws IllegalArgumentException - * if <code>Proxy.isProxyClass(proxy.getClass())</code> - * returns false. - * @throws NullPointerException - * if proxy is null + * @throws IllegalArgumentException if + * <code>Proxy.isProxyClass(proxy.getClass())</code> returns false. + * @throws NullPointerException if proxy is null */ - public static InvocationHandler getInvocationHandler(Object proxy) { - if (!isProxyClass(proxy.getClass())) + public static InvocationHandler getInvocationHandler(Object proxy) + { + if (! isProxyClass(proxy.getClass())) throw new IllegalArgumentException("not a proxy instance"); return ((Proxy) proxy).h; } /** - * Helper class for mapping unique ClassLoader and interface combinations to - * proxy classes. + * Helper class for mapping unique ClassLoader and interface combinations + * to proxy classes. * * @author Eric Blake (eb...@em...) */ - private static final class ProxyType { + private static final class ProxyType + { /** * Store the class loader (may be null) */ @@ -406,13 +410,12 @@ /** * Construct the helper object. * - * @param loader - * the class loader to define the proxy class in; null + * @param loader the class loader to define the proxy class in; null * implies the bootstrap class loader - * @param interfaces - * an array of interfaces + * @param interfaces an array of interfaces */ - ProxyType(ClassLoader loader, Class[] interfaces) { + ProxyType(ClassLoader loader, Class[] interfaces) + { this.loader = loader; this.interfaces = interfaces; } @@ -422,7 +425,8 @@ * * @return a combination of the classloader and interfaces hashcodes. */ - public int hashCode() { + public int hashCode() + { int hash = loader == null ? 0 : loader.hashCode(); for (int i = 0; i < interfaces.length; i++) hash = hash * 31 + interfaces[i].hashCode(); @@ -432,14 +436,13 @@ /** * Calculates equality. * - * @param other - * object to compare to + * @param other object to compare to * @return true if it is a ProxyType with same data */ - public boolean equals(Object other) { + public boolean equals(Object other) + { ProxyType pt = (ProxyType) other; - if (loader != pt.loader - || interfaces.length != pt.interfaces.length) + if (loader != pt.loader || interfaces.length != pt.interfaces.length) return false; for (int i = 0; i < interfaces.length; i++) if (interfaces[i] != pt.interfaces[i]) @@ -449,32 +452,36 @@ } // class ProxyType /** - * Helper class which allows hashing of a method name and signature without - * worrying about return type, declaring class, or throws clause, and which - * reduces the maximally common throws clause between two methods + * Helper class which allows hashing of a method name and signature + * without worrying about return type, declaring class, or throws clause, + * and which reduces the maximally common throws clause between two methods * * @author Eric Blake (eb...@em...) */ - private static final class ProxySignature { + private static final class ProxySignature + { /** * The core signatures which all Proxy instances handle. */ static final HashMap coreMethods = new HashMap(); - static { - try { - ProxySignature sig = new ProxySignature(Object.class.getMethod( - "equals", new Class[] { Object.class })); + static + { + try + { + ProxySignature sig + = new ProxySignature(Object.class + .getMethod("equals", + new Class[] {Object.class})); coreMethods.put(sig, sig); - sig = new ProxySignature(Object.class.getMethod("hashCode", - null)); + sig = new ProxySignature(Object.class.getMethod("hashCode", null)); coreMethods.put(sig, sig); - sig = new ProxySignature(Object.class.getMethod("toString", - null)); + sig = new ProxySignature(Object.class.getMethod("toString", null)); coreMethods.put(sig, sig); - } catch (Exception e) { + } + catch (Exception e) + { // assert false; - throw (Error) new InternalError("Unexpected: " + e) - .initCause(e); + throw (Error) new InternalError("Unexpected: " + e).initCause(e); } } @@ -491,14 +498,15 @@ /** * Construct a signature * - * @param method - * the Method this signature is based on, never null + * @param method the Method this signature is based on, never null */ - ProxySignature(Method method) { + ProxySignature(Method method) + { this.method = method; Class[] exc = method.getExceptionTypes(); int i = exc.length; - while (--i >= 0) { + while (--i >= 0) + { // discard unchecked exceptions if (Error.class.isAssignableFrom(exc[i]) || RuntimeException.class.isAssignableFrom(exc[i])) @@ -508,19 +516,17 @@ } /** - * Given a method, make sure it's return type is identical to this, and - * adjust this signature's throws clause appropriately + * Given a method, make sure it's return type is identical + * to this, and adjust this signature's throws clause appropriately * - * @param other - * the signature to merge in - * @throws IllegalArgumentException - * if the return types conflict + * @param other the signature to merge in + * @throws IllegalArgumentException if the return types conflict */ - void checkCompatibility(ProxySignature other) { + void checkCompatibility(ProxySignature other) + { if (method.getReturnType() != other.method.getReturnType()) - throw new IllegalArgumentException( - "incompatible return types: " + method + ", " - + other.method); + throw new IllegalArgumentException("incompatible return types: " + + method + ", " + other.method); // if you can think of a more efficient way than this O(n^2) search, // implement it! @@ -530,11 +536,13 @@ boolean[] valid2 = new boolean[size2]; Iterator itr = exceptions.iterator(); int pos = size1; - while (--pos >= 0) { + while (--pos >= 0) + { Class c1 = (Class) itr.next(); Iterator itr2 = other.exceptions.iterator(); int pos2 = size2; - while (--pos2 >= 0) { + while (--pos2 >= 0) + { Class c2 = (Class) itr2.next(); if (c2.isAssignableFrom(c1)) valid1[pos] = true; @@ -544,16 +552,18 @@ } pos = size1; itr = exceptions.iterator(); - while (--pos >= 0) { + while (--pos >= 0) + { itr.next(); - if (!valid1[pos]) + if (! valid1[pos]) itr.remove(); } pos = size2; itr = other.exceptions.iterator(); - while (--pos >= 0) { + while (--pos >= 0) + { itr.next(); - if (!valid2[pos]) + if (! valid2[pos]) itr.remove(); } exceptions.addAll(other.exceptions); @@ -564,7 +574,8 @@ * * @return a combination of name and parameter types */ - public int hashCode() { + public int hashCode() + { int hash = method.getName().hashCode(); Class[] types = method.getParameterTypes(); for (int i = 0; i < types.length; i++) @@ -575,15 +586,15 @@ /** * Calculates equality. * - * @param other - * object to compare to + * @param other object to compare to * @return true if it is a ProxySignature with same data */ - public boolean equals(Object other) { + public boolean equals(Object other) + { ProxySignature ps = (ProxySignature) other; Class[] types1 = method.getParameterTypes(); Class[] types2 = ps.method.getParameterTypes(); - if (!method.getName().equals(ps.method.getName()) + if (! method.getName().equals(ps.method.getName()) || types1.length != types2.length) return false; int i = types1.length; @@ -600,10 +611,11 @@ * * @author Eric Blake (eb...@em...) */ - static final class ProxyData { + static final class ProxyData + { /** - * The package this class is in <b>including the trailing dot</b> or an - * empty string for the unnamed (aka default) package. + * The package this class is in <b>including the trailing dot</b> + * or an empty string for the unnamed (aka default) package. */ String pack = ""; @@ -615,8 +627,8 @@ /** * The Method objects this class must pass as the second argument to * invoke (also useful for determining what methods this class has). - * Non-null, non-empty (includes at least Object.hashCode, - * Object.equals, and Object.toString). + * Non-null, non-empty (includes at least Object.hashCode, Object.equals, + * and Object.toString). */ Method[] methods; @@ -624,8 +636,8 @@ * The exceptions that do not need to be wrapped in * UndeclaredThrowableException. exceptions[i] is the same as, or a * subset of subclasses, of methods[i].getExceptionTypes(), depending on - * compatible throws clauses with multiple inheritance. It is - * unspecified if these lists include or exclude subclasses of Error and + * compatible throws clauses with multiple inheritance. It is unspecified + * if these lists include or exclude subclasses of Error and * RuntimeException, but excluding them is harmless and generates a * smaller class. */ @@ -644,16 +656,19 @@ /** * Construct a ProxyData with uninitialized data members. */ - ProxyData() { + ProxyData() + { } /** - * Return the name of a package (including the trailing dot) given the - * name of a class. Returns an empty string if no package. We use this - * in preference to using Class.getPackage() to avoid problems with - * ClassLoaders that don't set the package. + * Return the name of a package (including the trailing dot) + * given the name of a class. + * Returns an empty string if no package. We use this in preference to + * using Class.getPackage() to avoid problems with ClassLoaders + * that don't set the package. */ - private static String getPackage(Class k) { + private static String getPackage(Class k) + { String name = k.getName(); int idx = name.lastIndexOf('.'); return name.substring(0, idx + 1); @@ -661,23 +676,20 @@ /** * Verifies that the arguments are legal, and sets up remaining data - * This should only be called when a class must be generated, as it is - * expensive. + * This should only be called when a class must be generated, as + * it is expensive. * - * @param pt - * the ProxyType to convert to ProxyData - * @return the flattened, verified ProxyData structure for use in class - * generation - * @throws IllegalArgumentException - * if `interfaces' contains non-interfaces or incompatible - * combinations, and verify is true - * @throws NullPointerException - * if interfaces is null or contains null + * @param pt the ProxyType to convert to ProxyData + * @return the flattened, verified ProxyData structure for use in + * class generation + * @throws IllegalArgumentException if `interfaces' contains + * non-interfaces or incompatible combinations, and verify is true + * @throws NullPointerException if interfaces is null or contains null */ - static ProxyData getProxyData(ProxyType pt) { + static ProxyData getProxyData(ProxyType pt) + { Map method_set = (Map) ProxySignature.coreMethods.clone(); - boolean in_package = false; // true if we encounter non-public - // interface + boolean in_package = false; // true if we encounter non-public interface ProxyData data = new ProxyData(); data.interfaces = pt.interfaces; @@ -685,46 +697,52 @@ // if interfaces is too large, we croak later on when the constant // pool overflows int i = data.interfaces.length; - while (--i >= 0) { + while (--i >= 0) + { Class inter = data.interfaces[i]; - if (!inter.isInterface()) - throw new IllegalArgumentException("not an interface: " - + inter); - try { + if (! inter.isInterface()) + throw new IllegalArgumentException("not an interface: " + inter); + try + { if (Class.forName(inter.getName(), false, pt.loader) != inter) throw new IllegalArgumentException("not accessible in " + "classloader: " + inter); - } catch (ClassNotFoundException e) { + } + catch (ClassNotFoundException e) + { throw new IllegalArgumentException("not accessible in " + "classloader: " + inter); } - if (!Modifier.isPublic(inter.getModifiers())) - if (in_package) { + if (! Modifier.isPublic(inter.getModifiers())) + if (in_package) + { String p = getPackage(inter); - if (!data.pack.equals(p)) - throw new IllegalArgumentException( - "non-public interfaces " - + "from different " + "packages"); - } else { + if (! data.pack.equals(p)) + throw new IllegalArgumentException("non-public interfaces " + + "from different " + + "packages"); + } + else + { in_package = true; data.pack = getPackage(inter); } - for (int j = i - 1; j >= 0; j--) + for (int j = i-1; j >= 0; j--) if (data.interfaces[j] == inter) - throw new IllegalArgumentException( - "duplicate interface: " + inter); + throw new IllegalArgumentException("duplicate interface: " + + inter); Method[] methods = inter.getMethods(); int j = methods.length; - while (--j >= 0) { - if (isCoreObjectMethod(methods[j])) { - // In the case of an attempt to redefine a public - // non-final + while (--j >= 0) + { + if (isCoreObjectMethod(methods[j])) + { + // In the case of an attempt to redefine a public non-final // method of Object, we must skip it continue; } ProxySignature sig = new ProxySignature(methods[j]); - ProxySignature old = (ProxySignature) method_set.put(sig, - sig); + ProxySignature old = (ProxySignature) method_set.put(sig, sig); if (old != null) sig.checkCompatibility(old); } @@ -734,7 +752,8 @@ data.methods = new Method[i]; data.exceptions = new Class[i][]; Iterator itr = method_set.values().iterator(); - while (--i >= 0) { + while (--i >= 0) + { ProxySignature sig = (ProxySignature) itr.next(); data.methods[i] = sig.method; data.exceptions[i] = (Class[]) sig.exceptions @@ -745,30 +764,33 @@ /** * Checks whether the method is similar to a public non-final method of - * Object or not (i.e. with the same name and parameter types). Note - * that we can't rely, directly or indirectly (via Collection.contains) - * on Method.equals as it would also check the declaring class, what we - * do not want. We only want to check that the given method have the - * same signature as a core method (same name and parameter types) + * Object or not (i.e. with the same name and parameter types). Note that we + * can't rely, directly or indirectly (via Collection.contains) on + * Method.equals as it would also check the declaring class, what we do not + * want. We only want to check that the given method have the same signature + * as a core method (same name and parameter types) * - * @param method - * the method to check + * @param method the method to check * @return whether the method has the same name and parameter types as * Object.equals, Object.hashCode or Object.toString * @see java.lang.Object#equals(Object) * @see java.lang.Object#hashCode() * @see java.lang.Object#toString() */ - private static boolean isCoreObjectMethod(Method method) { + private static boolean isCoreObjectMethod(Method method) + { String methodName = method.getName(); - if (methodName.equals("equals")) { + if (methodName.equals("equals")) + { return Arrays.equals(method.getParameterTypes(), new Class[] { Object.class }); } - if (methodName.equals("hashCode")) { + if (methodName.equals("hashCode")) + { return method.getParameterTypes().length == 0; } - if (methodName.equals("toString")) { + if (methodName.equals("toString")) + { return method.getParameterTypes().length == 0; } return false; @@ -778,92 +800,59 @@ /** * Does all the work of building a class. By making this a nested class, - * this code is not loaded in memory if the VM has a native implementation - * instead. + * this code is not loaded in memory if the VM has a native + * implementation instead. * * @author Eric Blake (eb...@em...) */ - private static final class ClassFactory { + private static final class ClassFactory + { /** Constants for assisting the compilation */ private static final byte FIELD = 1; - private static final byte METHOD = 2; - private static final byte INTERFACE = 3; - - private static final String CTOR_SIG = "(Ljava/lang/reflect/InvocationHandler;)V"; - + private static final String CTOR_SIG + = "(Ljava/lang/reflect/InvocationHandler;)V"; private static final String INVOKE_SIG = "(Ljava/lang/Object;" + "Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"; /** Bytecodes for insertion in the class definition byte[] */ private static final char ACONST_NULL = 1; - private static final char ICONST_0 = 3; - private static final char BIPUSH = 16; - private static final char SIPUSH = 17; - private static final char ILOAD = 21; - private static final char ILOAD_0 = 26; - private static final char ALOAD_0 = 42; - private static final char ALOAD_1 = 43; - private static final char AALOAD = 50; - private static final char AASTORE = 83; - private static final char DUP = 89; - private static final char DUP_X1 = 90; - private static final char SWAP = 95; - private static final char IRETURN = 172; - private static final char LRETURN = 173; - private static final char FRETURN = 174; - private static final char DRETURN = 175; - private static final char ARETURN = 176; - private static final char RETURN = 177; - private static final char GETSTATIC = 178; - private static final char GETFIELD = 180; - private static final char INVOKEVIRTUAL = 182; - private static final char INVOKESPECIAL = 183; - private static final char INVOKEINTERFACE = 185; - private static final char NEW = 187; - private static final char ANEWARRAY = 189; - private static final char ATHROW = 191; - private static final char CHECKCAST = 192; - private static final char POP = 87; - - // Implementation note: we use StringBuffers to hold the byte data, - // since + // Implementation note: we use StringBuffers to hold the byte data, since // they automatically grow. However, we only use the low 8 bits of // every char in the array, so we are using twice the necessary memory // for the ease StringBuffer provides. /** The constant pool. */ private final StringBuffer pool = new StringBuffer(); - /** The rest of the class data. */ private final StringBuffer stream = new StringBuffer(); @@ -882,15 +871,14 @@ /** * Initializes the buffers with the bytecode contents for a proxy class. * - * @param data - * the remainder of the class data - * @throws IllegalArgumentException - * if anything else goes wrong this late in the game; as far - * as I can tell, this will only happen if the constant pool - * overflows, which is possible even when the user doesn't - * exceed the 65535 interface limit + * @param data the remainder of the class data + * @throws IllegalArgumentException if anything else goes wrong this + * late in the game; as far as I can tell, this will only happen + * if the constant pool overflows, which is possible even when + * the user doesn't exceed the 65535 interface limit */ - ClassFactory(ProxyData data) { + ClassFactory(ProxyData data) + { methods = data.methods; // magic = 0xcafebabe @@ -901,7 +889,7 @@ // constant_pool[], filled in as we go // access_flags - putU2(Modifier.SUPER | Modifier.FINAL | Modifier.PUBLIC); + putU2(/*Modifier.SUPER |*/ Modifier.FINAL | Modifier.PUBLIC); // this_class qualName = (data.pack + "$Proxy" + data.id); putU2(classInfo(TypeSignature.getEncodingOfClass(qualName, false))); @@ -916,8 +904,7 @@ // Recall that Proxy classes serialize specially, so we do not need // to worry about a <clinit> method for this field. Instead, we - // just assign it by reflection after the class is successfully - // loaded. + // just assign it by reflection after the class is successfully loaded. // fields_count - private static Method[] m; putU2(1); // fields[] @@ -972,37 +959,39 @@ /** * Produce the bytecode for a single method. * - * @param i - * the index of the method we are building - * @param e - * the exceptions possible for the method + * @param i the index of the method we are building + * @param e the exceptions possible for the method */ - private void emitMethod(int i, Class[] e) { + private void emitMethod(int i, Class[] e) + { // First, we precalculate the method length and other information. Method m = methods[i]; Class[] paramtypes = m.getParameterTypes(); int wrap_overhead = 0; // max words taken by wrapped primitive int param_count = 1; // 1 for this - int code_length = 16; // aload_0, getfield, aload_0, getstatic, - // const, + int code_length = 16; // aload_0, getfield, aload_0, getstatic, const, // aaload, const/aconst_null, invokeinterface - if (i > 5) { + if (i > 5) + { if (i > Byte.MAX_VALUE) code_length += 2; // sipush else code_length++; // bipush } - if (paramtypes.length > 0) { + if (paramtypes.length > 0) + { code_length += 3; // anewarray if (paramtypes.length > Byte.MAX_VALUE) code_length += 2; // sipush else if (paramtypes.length > 5) code_length++; // bipush - for (int j = 0; j < paramtypes.length; j++) { + for (int j = 0; j < paramtypes.length; j++) + { code_length += 4; // dup, const, load, store Class type = paramtypes[j]; - if (j > 5) { + if (j > 5) + { if (j > Byte.MAX_VALUE) code_length += 2; // sipush else @@ -1011,22 +1000,23 @@ if (param_count >= 4) code_length++; // 2-byte load param_count++; - if (type.isPrimitive()) { + if (type.isPrimitive()) + { code_length += 7; // new, dup, invokespecial - if (type == long.class || type == double.class) { + if (type == long.class || type == double.class) + { wrap_overhead = 3; param_count++; - } else if (wrap_overhead < 2) + } + else if (wrap_overhead < 2) wrap_overhead = 2; } } } int end_pc = code_length; Class ret_type = m.getReturnType(); - if (ret_type == void.class) { - code_length++; // pop + if (ret_type == void.class) code_length++; // return - } else if (ret_type.isPrimitive()) code_length += 7; // cast, invokevirtual, return else @@ -1034,22 +1024,21 @@ int exception_count = 0; boolean throws_throwable = false; for (int j = 0; j < e.length; j++) - if (e[j] == Throwable.class) { + if (e[j] == Throwable.class) + { throws_throwable = true; break; } - if (!throws_throwable) { - exception_count = e.length + 3; // Throwable, Error, - // RuntimeException + if (! throws_throwable) + { + exception_count = e.length + 3; // Throwable, Error, RuntimeException code_length += 9; // new, dup_x1, swap, invokespecial, athrow } int handler_pc = code_length - 1; StringBuffer signature = new StringBuffer("("); for (int j = 0; j < paramtypes.length; j++) - signature.append(TypeSignature - .getEncodingOfClass(paramtypes[j])); - signature.append(")").append( - TypeSignature.getEncodingOfClass(ret_type)); + signature.append(TypeSignature.getEncodingOfClass(paramtypes[j])); + signature.append(")").append(TypeSignature.getEncodingOfClass(ret_type)); // Now we have enough information to emit the method. @@ -1096,56 +1085,58 @@ "Ljava/lang/reflect/InvocationHandler;")); putU1(ALOAD_0); putU1(GETSTATIC); - putU2(refInfo(FIELD, TypeSignature.getEncodingOfClass(qualName, - false), "m", "[Ljava/lang/reflect/Method;")); + putU2(refInfo(FIELD, TypeSignature.getEncodingOfClass(qualName, false), + "m", "[Ljava/lang/reflect/Method;")); putConst(i); putU1(AALOAD); - if (paramtypes.length > 0) { + if (paramtypes.length > 0) + { putConst(paramtypes.length); putU1(ANEWARRAY); putU2(classInfo("java/lang/Object")); param_count = 1; - for (int j = 0; j < paramtypes.length; j++, param_count++) { + for (int j = 0; j < paramtypes.length; j++, param_count++) + { putU1(DUP); putConst(j); - if (paramtypes[j].isPrimitive()) { + if (paramtypes[j].isPrimitive()) + { putU1(NEW); putU2(classInfo(wrapper(paramtypes[j]))); putU1(DUP); } putLoad(param_count, paramtypes[j]); - if (paramtypes[j].isPrimitive()) { + if (paramtypes[j].isPrimitive()) + { ... [truncated message content] |
From: <ls...@us...> - 2007-01-04 20:25:03
|
Revision: 2986 http://jnode.svn.sourceforge.net/jnode/?rev=2986&view=rev Author: lsantha Date: 2007-01-04 12:24:57 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Reduced worker count from 8 to 2. Modified Paths: -------------- trunk/core/src/core/org/jnode/work/WorkPlugin.java Modified: trunk/core/src/core/org/jnode/work/WorkPlugin.java =================================================================== --- trunk/core/src/core/org/jnode/work/WorkPlugin.java 2007-01-04 20:24:19 UTC (rev 2985) +++ trunk/core/src/core/org/jnode/work/WorkPlugin.java 2007-01-04 20:24:57 UTC (rev 2986) @@ -51,6 +51,9 @@ /** Queue processor threads */ private final List<QueueProcessorThread<Work>> threads; + /** Number of workers started initially. */ + private final int workerCount = 2; //8 + /** Counter used for worker thread names */ private int counter = 1; @@ -62,7 +65,7 @@ /** Number of work items ended */ private int workEndCounter; - + /** * @param descriptor */ @@ -75,8 +78,7 @@ * @see org.jnode.plugin.Plugin#startPlugin() */ protected final void startPlugin() throws PluginException { - final int n = 8; - for (int i = 0; i < n; i++) { + for (int i = 0; i < workerCount; i++) { addWorker(); } try { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 20:24:20
|
Revision: 2985 http://jnode.svn.sourceforge.net/jnode/?rev=2985&view=rev Author: lsantha Date: 2007-01-04 12:24:19 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Reduced load-compile thread count from 4 to 2. Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/LoadCompileService.java Modified: trunk/core/src/core/org/jnode/vm/LoadCompileService.java =================================================================== --- trunk/core/src/core/org/jnode/vm/LoadCompileService.java 2007-01-04 20:22:27 UTC (rev 2984) +++ trunk/core/src/core/org/jnode/vm/LoadCompileService.java 2007-01-04 20:24:19 UTC (rev 2985) @@ -40,6 +40,8 @@ private static boolean started = false; + private static final int threadCount = 2; //4 + /** * Default ctor * @@ -101,7 +103,7 @@ initService(); if (!started) { started = true; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < threadCount; i++) { LoadCompileThread thread = new LoadCompileThread(service, "LoadCompile-" + i); thread.start(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 20:22:32
|
Revision: 2984 http://jnode.svn.sourceforge.net/jnode/?rev=2984&view=rev Author: lsantha Date: 2007-01-04 12:22:27 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Added support for signature attribute. Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/classmgr/VmType.java Modified: trunk/core/src/core/org/jnode/vm/classmgr/VmType.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/VmType.java 2007-01-04 20:22:03 UTC (rev 2983) +++ trunk/core/src/core/org/jnode/vm/classmgr/VmType.java 2007-01-04 20:22:27 UTC (rev 2984) @@ -76,6 +76,9 @@ /** The the source file name of this class */ private String sourceFile; + /** The the source file name of this class */ + private String signature; + /** All methods and constructors declared in this class */ private VmMethod[] methodTable; @@ -2323,6 +2326,14 @@ this.sourceFile = sourceFile; } + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + /** * Index of the isolated type state. This refers to an int entry. * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 20:22:06
|
Revision: 2983 http://jnode.svn.sourceforge.net/jnode/?rev=2983&view=rev Author: lsantha Date: 2007-01-04 12:22:03 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Added support for signature attribute. Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java Modified: trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2007-01-04 20:20:19 UTC (rev 2982) +++ trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2007-01-04 20:22:03 UTC (rev 2983) @@ -57,8 +57,10 @@ // VM ClassLoader Code // ------------------------------------------ - private static char[] SourceFile; + private static char[] SourceFileAttrName; + private static char[] SignatureAttrName; + private static char[] CodeAttrName; private static char[] ConstantValueAttrName; @@ -194,7 +196,8 @@ if (ConstantValueAttrName == null) { ConstantValueAttrName = "ConstantValue".toCharArray(); CodeAttrName = "Code".toCharArray(); - SourceFile = "SourceFile".toCharArray(); + SourceFileAttrName = "SourceFile".toCharArray(); + SignatureAttrName = "Signature".toCharArray(); ExceptionsAttrName = "Exceptions".toCharArray(); LineNrTableAttrName = "LineNumberTable".toCharArray(); LocalVariableTableAttrName = "LocalVariableTable".toCharArray(); @@ -412,6 +415,7 @@ VmAnnotation[] rVisAnn = null; VmAnnotation[] rInvisAnn = null; String sourceFile = null; + String signature = null; for (int a = 0; a < acount; a++) { final String attrName = cp.getUTF8(data.getChar()); final int length = data.getInt(); @@ -420,14 +424,17 @@ } else if (VmArray.equals(RuntimeInvisibleAnnotationsAttrName, attrName)) { rInvisAnn = readRuntimeAnnotations(data, cp, false); - } else if (VmArray.equals(SourceFile, attrName)) { + } else if (VmArray.equals(SourceFileAttrName, attrName)) { sourceFile = cp.getUTF8(data.getChar()); + } else if (VmArray.equals(SignatureAttrName, attrName)) { + signature = cp.getUTF8(data.getChar()); } else { skip(data, length); } } cls.setRuntimeAnnotations(rVisAnn); cls.setSourceFile(sourceFile); + cls.setSignature(signature); if (rInvisAnn != null) { cls.addPragmaFlags(getClassPragmaFlags(rInvisAnn, clsName)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 20:20:20
|
Revision: 2982 http://jnode.svn.sourceforge.net/jnode/?rev=2982&view=rev Author: lsantha Date: 2007-01-04 12:20:19 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Various classpath updates. Modified Paths: -------------- trunk/core/src/classpath/vm/java/lang/Class.java Modified: trunk/core/src/classpath/vm/java/lang/Class.java =================================================================== --- trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-04 19:48:10 UTC (rev 2981) +++ trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-04 20:20:19 UTC (rev 2982) @@ -22,6 +22,7 @@ package java.lang; import gnu.java.lang.VMClassHelper; +import gnu.java.lang.reflect.ClassSignatureParser; import java.io.InputStream; import java.io.Serializable; @@ -41,6 +42,8 @@ import java.security.Permissions; import java.security.ProtectionDomain; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Arrays; import org.jnode.security.JNodePermission; import org.jnode.vm.SoftByteCodes; @@ -224,7 +227,12 @@ * @return Class */ public final Class< ? super T> getSuperclass() { - VmType< ? super T> superCls = getLinkedVmClass().getSuperClass(); + VmType<T> vmType = getLinkedVmClass(); + + if(vmType.isPrimitive() || vmType.isInterface()) + return null; + + VmType< ? super T> superCls = vmType.getSuperClass(); if (superCls != null) { return superCls.asClass(); } else { @@ -490,6 +498,50 @@ return null; } + private static final class MethodKey + { + private String name; + private Class[] params; + private Class returnType; + private int hash; + + MethodKey(Method m) + { + name = m.getName(); + params = m.getParameterTypes(); + returnType = m.getReturnType(); + hash = name.hashCode() ^ returnType.hashCode(); + for(int i = 0; i < params.length; i++) + { + hash ^= params[i].hashCode(); + } + } + + public boolean equals(Object o) + { + if (o instanceof MethodKey) + { + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) + { + for (int i = 0; i < params.length; i++) + { + if (m.params[i] != params[i]) + return false; + } + return true; + } + } + return false; + } + + public int hashCode() + { + return hash; + } + } + /** * Gets the method with the given name and argument types declared in this * class or any of its super-classes. @@ -525,8 +577,21 @@ * * @return Method[] */ + public Method[] getMethods() { if (methods == null) { + Method[] a = internalGetMethods(); + ArrayList<Method> list = new ArrayList<Method>(); + for(int i = 0; i < a.length; i++){ + list.add(a[i]); + } + methods = list; + } + return methods.toArray(new Method[methods.size()]); + } + /* + public Method[] getMethods() { + if (methods == null) { final ArrayList<Method> list = new ArrayList<Method>(); Class< ? > cls = this; while (cls != null) { @@ -539,9 +604,42 @@ methods = list; } return (Method[]) methods.toArray(new Method[methods.size()]); - } + }*/ /** + * Like <code>getMethods()</code> but without the security checks. + */ + private Method[] internalGetMethods() + { + HashMap map = new HashMap(); + Method[] methods; + Class[] interfaces = getInterfaces(); + for(int i = 0; i < interfaces.length; i++) + { + methods = interfaces[i].internalGetMethods(); + for(int j = 0; j < methods.length; j++) + { + map.put(new MethodKey(methods[j]), methods[j]); + } + } + Class superClass = getSuperclass(); + if(superClass != null) + { + methods = superClass.internalGetMethods(); + for(int i = 0; i < methods.length; i++) + { + map.put(new MethodKey(methods[i]), methods[i]); + } + } + methods = getDeclaredMethods(true); + for(int i = 0; i < methods.length; i++) + { + map.put(new MethodKey(methods[i]), methods[i]); + } + return (Method[])map.values().toArray(new Method[map.size()]); + } + + /** * Gets the method with the given name and argument types declared in this * class. * @@ -579,25 +677,37 @@ */ public Method[] getDeclaredMethods() { if (declaredMethods == null) { - final VmType<T> vmClass = getLinkedVmClass(); - final int cnt = vmClass.getNoDeclaredMethods(); - int max = 0; - for (int i = 0; i < cnt; i++) { - if (!vmClass.getDeclaredMethod(i).isConstructor()) { - max++; - } + declaredMethods = getDeclaredMethods(false); + } + return declaredMethods; + } + + /** + * Gets all methods declared in this class. + * + * @return Method[] + */ + private Method[] getDeclaredMethods(boolean publicOnly) { + final VmType<T> vmClass = getLinkedVmClass(); + final int cnt = vmClass.getNoDeclaredMethods(); + int max = 0; + for (int i = 0; i < cnt; i++) { + VmMethod method = vmClass.getDeclaredMethod(i); + if (!method.isConstructor() && + (!publicOnly || method.isPublic())) { + max++; } - final Method[] list = new Method[max]; - max = 0; - for (int i = 0; i < cnt; i++) { - VmMethod vmMethod = vmClass.getDeclaredMethod(i); - if (!vmMethod.isConstructor()) { - list[max++] = (Method) vmMethod.asMember(); - } + } + final Method[] list = new Method[max]; + max = 0; + for (int i = 0; i < cnt; i++) { + VmMethod vmMethod = vmClass.getDeclaredMethod(i); + if (!vmMethod.isConstructor() && + (!publicOnly || vmMethod.isPublic())) { + list[max++] = (Method) vmMethod.asMember(); } - declaredMethods = list; } - return declaredMethods; + return list; } /** @@ -952,7 +1062,12 @@ * @see java.lang.reflect.GenericDeclaration#getTypeParameters() */ public TypeVariable< ? >[] getTypeParameters() { - return new TypeVariable[0]; + String sig = vmClass.getSignature(); + if (sig == null) + return new TypeVariable[0]; + + ClassSignatureParser p = new ClassSignatureParser(this, sig); + return p.getTypeParameters(); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-04 19:48:14
|
Revision: 2981 http://jnode.svn.sourceforge.net/jnode/?rev=2981&view=rev Author: lsantha Date: 2007-01-04 11:48:10 -0800 (Thu, 04 Jan 2007) Log Message: ----------- Removed compilation related memory leak. Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/compiler/NativeCodeCompiler.java Modified: trunk/core/src/core/org/jnode/vm/compiler/NativeCodeCompiler.java =================================================================== --- trunk/core/src/core/org/jnode/vm/compiler/NativeCodeCompiler.java 2007-01-03 20:59:06 UTC (rev 2980) +++ trunk/core/src/core/org/jnode/vm/compiler/NativeCodeCompiler.java 2007-01-04 19:48:10 UTC (rev 2981) @@ -274,6 +274,9 @@ bcv.endBasicBlock(); } bcv.endMethod(); + + //remove the compiler data to save memory, will be regenerated if needed + bc.setCompilerData(null); } return cm; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-03 20:59:08
|
Revision: 2980 http://jnode.svn.sourceforge.net/jnode/?rev=2980&view=rev Author: lsantha Date: 2007-01-03 12:59:06 -0800 (Wed, 03 Jan 2007) Log Message: ----------- Added org.jnode.net.help.argument classes. Modified Paths: -------------- trunk/net/descriptors/org.jnode.net.command.xml Modified: trunk/net/descriptors/org.jnode.net.command.xml =================================================================== --- trunk/net/descriptors/org.jnode.net.command.xml 2007-01-03 20:24:27 UTC (rev 2979) +++ trunk/net/descriptors/org.jnode.net.command.xml 2007-01-03 20:59:06 UTC (rev 2980) @@ -18,6 +18,7 @@ <runtime> <library name="jnode-net.jar"> <export name="org.jnode.net.command.*"/> + <export name="org.jnode.net.help.argument.*"/> </library> </runtime> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-03 20:24:28
|
Revision: 2979 http://jnode.svn.sourceforge.net/jnode/?rev=2979&view=rev Author: lsantha Date: 2007-01-03 12:24:27 -0800 (Wed, 03 Jan 2007) Log Message: ----------- Undoing last chenge. Modified Paths: -------------- trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java trunk/net/src/net/org/jnode/net/command/ResolverCommand.java trunk/net/src/net/org/jnode/net/command/RouteCommand.java trunk/net/src/net/org/jnode/net/command/TftpCommand.java Added Paths: ----------- trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java Modified: trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java 2007-01-03 20:23:46 UTC (rev 2978) +++ trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -29,7 +29,7 @@ import org.jnode.driver.net.NetDeviceAPI; import org.jnode.naming.InitialNaming; import org.jnode.net.ethernet.EthernetConstants; -import org.jnode.shell.help.argument.HostArgument; +import org.jnode.net.help.argument.HostArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.config.IPv4ConfigurationService; import org.jnode.shell.Command; Modified: trunk/net/src/net/org/jnode/net/command/ResolverCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/ResolverCommand.java 2007-01-03 20:23:46 UTC (rev 2978) +++ trunk/net/src/net/org/jnode/net/command/ResolverCommand.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -25,7 +25,7 @@ import java.io.PrintStream; import java.util.Collection; -import org.jnode.shell.help.argument.HostArgument; +import org.jnode.net.help.argument.HostArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.util.ResolverImpl; import org.jnode.shell.Command; Modified: trunk/net/src/net/org/jnode/net/command/RouteCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/RouteCommand.java 2007-01-03 20:23:46 UTC (rev 2978) +++ trunk/net/src/net/org/jnode/net/command/RouteCommand.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -27,8 +27,8 @@ import org.jnode.driver.Device; import org.jnode.naming.InitialNaming; import org.jnode.net.ethernet.EthernetConstants; -import org.jnode.shell.help.argument.HostArgument; -import org.jnode.shell.help.argument.NetworkArgument; +import org.jnode.net.help.argument.HostArgument; +import org.jnode.net.help.argument.NetworkArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.config.IPv4ConfigurationService; import org.jnode.net.ipv4.layer.IPv4NetworkLayer; Modified: trunk/net/src/net/org/jnode/net/command/TftpCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/TftpCommand.java 2007-01-03 20:23:46 UTC (rev 2978) +++ trunk/net/src/net/org/jnode/net/command/TftpCommand.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -24,7 +24,7 @@ import java.io.InputStream; import java.io.PrintStream; -import org.jnode.shell.help.argument.HostArgument; +import org.jnode.net.help.argument.HostArgument; import org.jnode.net.ipv4.tftp.TFTPClient; import org.jnode.shell.Command; import org.jnode.shell.CommandLine; Copied: trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java (from rev 2977, trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java) =================================================================== --- trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java (rev 0) +++ trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -0,0 +1,49 @@ +/* + * $Id: HostArgument.java 2224 2006-01-01 12:49:03Z epr $ + * + * JNode.org + * Copyright (C) 2003-2006 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.net.help.argument; + +import org.jnode.net.ipv4.IPv4Address; +import org.jnode.shell.help.Argument; +import org.jnode.shell.help.ParsedArguments; + +/** + * @author qades + */ +public class HostArgument extends Argument { + + public HostArgument(String name, String description, boolean multi) { + super(name, description, multi); + } + + public HostArgument(String name, String description) { + super(name, description); + } + + // here the specific command line completion would be implemented + + public IPv4Address getAddress(ParsedArguments args) { + String value = getValue(args); + if( value == null ) + return null; + return new IPv4Address(value); + } +} Copied: trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java (from rev 2977, trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java) =================================================================== --- trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java (rev 0) +++ trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java 2007-01-03 20:24:27 UTC (rev 2979) @@ -0,0 +1,49 @@ +/* + * $Id: NetworkArgument.java 2224 2006-01-01 12:49:03Z epr $ + * + * JNode.org + * Copyright (C) 2003-2006 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.net.help.argument; + +import org.jnode.net.ipv4.IPv4Address; +import org.jnode.shell.help.Argument; +import org.jnode.shell.help.ParsedArguments; + +/** + * @author qades + */ +public class NetworkArgument extends Argument { + + public NetworkArgument(String name, String description, boolean multi) { + super(name, description, multi); + } + + public NetworkArgument(String name, String description) { + super(name, description); + } + + // here the specific command line completion would be implemented + + public IPv4Address getAddress(ParsedArguments args) { + String value = getValue(args); + if( "default".equals(value) ) + value = "0.0.0.0"; + return new IPv4Address(value); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-03 20:23:54
|
Revision: 2978 http://jnode.svn.sourceforge.net/jnode/?rev=2978&view=rev Author: lsantha Date: 2007-01-03 12:23:46 -0800 (Wed, 03 Jan 2007) Log Message: ----------- Undoing last chenge. Removed Paths: ------------- trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java Deleted: trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java 2007-01-03 20:03:17 UTC (rev 2977) +++ trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java 2007-01-03 20:23:46 UTC (rev 2978) @@ -1,49 +0,0 @@ -/* - * $Id: HostArgument.java 2224 2006-01-01 12:49:03Z epr $ - * - * JNode.org - * Copyright (C) 2003-2006 JNode.org - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; If not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -package org.jnode.shell.help.argument; - -import org.jnode.net.ipv4.IPv4Address; -import org.jnode.shell.help.Argument; -import org.jnode.shell.help.ParsedArguments; - -/** - * @author qades - */ -public class HostArgument extends Argument { - - public HostArgument(String name, String description, boolean multi) { - super(name, description, multi); - } - - public HostArgument(String name, String description) { - super(name, description); - } - - // here the specific command line completion would be implemented - - public IPv4Address getAddress(ParsedArguments args) { - String value = getValue(args); - if( value == null ) - return null; - return new IPv4Address(value); - } -} Deleted: trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java 2007-01-03 20:03:17 UTC (rev 2977) +++ trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java 2007-01-03 20:23:46 UTC (rev 2978) @@ -1,49 +0,0 @@ -/* - * $Id: NetworkArgument.java 2224 2006-01-01 12:49:03Z epr $ - * - * JNode.org - * Copyright (C) 2003-2006 JNode.org - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; If not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -package org.jnode.shell.help.argument; - -import org.jnode.net.ipv4.IPv4Address; -import org.jnode.shell.help.Argument; -import org.jnode.shell.help.ParsedArguments; - -/** - * @author qades - */ -public class NetworkArgument extends Argument { - - public NetworkArgument(String name, String description, boolean multi) { - super(name, description, multi); - } - - public NetworkArgument(String name, String description) { - super(name, description); - } - - // here the specific command line completion would be implemented - - public IPv4Address getAddress(ParsedArguments args) { - String value = getValue(args); - if( "default".equals(value) ) - value = "0.0.0.0"; - return new IPv4Address(value); - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-03 20:03:18
|
Revision: 2977 http://jnode.svn.sourceforge.net/jnode/?rev=2977&view=rev Author: lsantha Date: 2007-01-03 12:03:17 -0800 (Wed, 03 Jan 2007) Log Message: ----------- Moved shell related classes to shell project. Avoid fragmentation. Added Paths: ----------- trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java Copied: trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java (from rev 2975, trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java) =================================================================== --- trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java (rev 0) +++ trunk/shell/src/shell/org/jnode/shell/help/argument/HostArgument.java 2007-01-03 20:03:17 UTC (rev 2977) @@ -0,0 +1,49 @@ +/* + * $Id: HostArgument.java 2224 2006-01-01 12:49:03Z epr $ + * + * JNode.org + * Copyright (C) 2003-2006 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.shell.help.argument; + +import org.jnode.net.ipv4.IPv4Address; +import org.jnode.shell.help.Argument; +import org.jnode.shell.help.ParsedArguments; + +/** + * @author qades + */ +public class HostArgument extends Argument { + + public HostArgument(String name, String description, boolean multi) { + super(name, description, multi); + } + + public HostArgument(String name, String description) { + super(name, description); + } + + // here the specific command line completion would be implemented + + public IPv4Address getAddress(ParsedArguments args) { + String value = getValue(args); + if( value == null ) + return null; + return new IPv4Address(value); + } +} Copied: trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java (from rev 2975, trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java) =================================================================== --- trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java (rev 0) +++ trunk/shell/src/shell/org/jnode/shell/help/argument/NetworkArgument.java 2007-01-03 20:03:17 UTC (rev 2977) @@ -0,0 +1,49 @@ +/* + * $Id: NetworkArgument.java 2224 2006-01-01 12:49:03Z epr $ + * + * JNode.org + * Copyright (C) 2003-2006 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.shell.help.argument; + +import org.jnode.net.ipv4.IPv4Address; +import org.jnode.shell.help.Argument; +import org.jnode.shell.help.ParsedArguments; + +/** + * @author qades + */ +public class NetworkArgument extends Argument { + + public NetworkArgument(String name, String description, boolean multi) { + super(name, description, multi); + } + + public NetworkArgument(String name, String description) { + super(name, description); + } + + // here the specific command line completion would be implemented + + public IPv4Address getAddress(ParsedArguments args) { + String value = getValue(args); + if( "default".equals(value) ) + value = "0.0.0.0"; + return new IPv4Address(value); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-03 19:58:12
|
Revision: 2976 http://jnode.svn.sourceforge.net/jnode/?rev=2976&view=rev Author: lsantha Date: 2007-01-03 11:58:08 -0800 (Wed, 03 Jan 2007) Log Message: ----------- Moved shell related classes to shell project. Avoid fragmentation. Modified Paths: -------------- trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java trunk/net/src/net/org/jnode/net/command/ResolverCommand.java trunk/net/src/net/org/jnode/net/command/RouteCommand.java trunk/net/src/net/org/jnode/net/command/TftpCommand.java Removed Paths: ------------- trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java Modified: trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/command/IfconfigCommand.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -29,7 +29,7 @@ import org.jnode.driver.net.NetDeviceAPI; import org.jnode.naming.InitialNaming; import org.jnode.net.ethernet.EthernetConstants; -import org.jnode.net.help.argument.HostArgument; +import org.jnode.shell.help.argument.HostArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.config.IPv4ConfigurationService; import org.jnode.shell.Command; Modified: trunk/net/src/net/org/jnode/net/command/ResolverCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/ResolverCommand.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/command/ResolverCommand.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -25,7 +25,7 @@ import java.io.PrintStream; import java.util.Collection; -import org.jnode.net.help.argument.HostArgument; +import org.jnode.shell.help.argument.HostArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.util.ResolverImpl; import org.jnode.shell.Command; Modified: trunk/net/src/net/org/jnode/net/command/RouteCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/RouteCommand.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/command/RouteCommand.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -27,8 +27,8 @@ import org.jnode.driver.Device; import org.jnode.naming.InitialNaming; import org.jnode.net.ethernet.EthernetConstants; -import org.jnode.net.help.argument.HostArgument; -import org.jnode.net.help.argument.NetworkArgument; +import org.jnode.shell.help.argument.HostArgument; +import org.jnode.shell.help.argument.NetworkArgument; import org.jnode.net.ipv4.IPv4Address; import org.jnode.net.ipv4.config.IPv4ConfigurationService; import org.jnode.net.ipv4.layer.IPv4NetworkLayer; Modified: trunk/net/src/net/org/jnode/net/command/TftpCommand.java =================================================================== --- trunk/net/src/net/org/jnode/net/command/TftpCommand.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/command/TftpCommand.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -24,7 +24,7 @@ import java.io.InputStream; import java.io.PrintStream; -import org.jnode.net.help.argument.HostArgument; +import org.jnode.shell.help.argument.HostArgument; import org.jnode.net.ipv4.tftp.TFTPClient; import org.jnode.shell.Command; import org.jnode.shell.CommandLine; Deleted: trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java =================================================================== --- trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/help/argument/HostArgument.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -1,49 +0,0 @@ -/* - * $Id: HostArgument.java 2224 2006-01-01 12:49:03Z epr $ - * - * JNode.org - * Copyright (C) 2003-2006 JNode.org - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; If not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -package org.jnode.net.help.argument; - -import org.jnode.net.ipv4.IPv4Address; -import org.jnode.shell.help.Argument; -import org.jnode.shell.help.ParsedArguments; - -/** - * @author qades - */ -public class HostArgument extends Argument { - - public HostArgument(String name, String description, boolean multi) { - super(name, description, multi); - } - - public HostArgument(String name, String description) { - super(name, description); - } - - // here the specific command line completion would be implemented - - public IPv4Address getAddress(ParsedArguments args) { - String value = getValue(args); - if( value == null ) - return null; - return new IPv4Address(value); - } -} Deleted: trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java =================================================================== --- trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java 2007-01-02 19:34:53 UTC (rev 2975) +++ trunk/net/src/net/org/jnode/net/help/argument/NetworkArgument.java 2007-01-03 19:58:08 UTC (rev 2976) @@ -1,49 +0,0 @@ -/* - * $Id: NetworkArgument.java 2224 2006-01-01 12:49:03Z epr $ - * - * JNode.org - * Copyright (C) 2003-2006 JNode.org - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; If not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -package org.jnode.net.help.argument; - -import org.jnode.net.ipv4.IPv4Address; -import org.jnode.shell.help.Argument; -import org.jnode.shell.help.ParsedArguments; - -/** - * @author qades - */ -public class NetworkArgument extends Argument { - - public NetworkArgument(String name, String description, boolean multi) { - super(name, description, multi); - } - - public NetworkArgument(String name, String description) { - super(name, description); - } - - // here the specific command line completion would be implemented - - public IPv4Address getAddress(ParsedArguments args) { - String value = getValue(args); - if( "default".equals(value) ) - value = "0.0.0.0"; - return new IPv4Address(value); - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-02 19:34:58
|
Revision: 2975 http://jnode.svn.sourceforge.net/jnode/?rev=2975&view=rev Author: lsantha Date: 2007-01-02 11:34:53 -0800 (Tue, 02 Jan 2007) Log Message: ----------- Implemented read(byte[], int,int). Bsh begins to work with this. More work is needed in the console for line edittig. Modified Paths: -------------- trunk/core/src/driver/org/jnode/driver/input/KeyboardInputStream.java Modified: trunk/core/src/driver/org/jnode/driver/input/KeyboardInputStream.java =================================================================== --- trunk/core/src/driver/org/jnode/driver/input/KeyboardInputStream.java 2007-01-02 16:16:45 UTC (rev 2974) +++ trunk/core/src/driver/org/jnode/driver/input/KeyboardInputStream.java 2007-01-02 19:34:53 UTC (rev 2975) @@ -39,7 +39,7 @@ /** * Create a new instance - * @param api + * @param api the keyboard API */ public KeyboardInputStream(KeyboardAPI api) { this.api = api; @@ -53,30 +53,86 @@ return 0; } - /** + /* + Doesn't block after the first blocking read. + public int read(byte[] b, int off, int len) throws IOException { + if (off < 0 || len < 0 || b.length - off < len) + throw new IndexOutOfBoundsException(); + + long time = System.currentTimeMillis(); + + int i = 0; + int ch = read(time); + + for(;;) { + b[off + i ++] = (byte) ch; + + if(i < len && queue.size() > 0) + ch = read(time); + else + break; + } + + return i; + } + */ + + public int read(byte[] b, int off, int len) throws IOException { + if (off < 0 || len < 0 || b.length - off < len) + throw new IndexOutOfBoundsException(); + + long time = System.currentTimeMillis(); + + int i = 0; + int ch = read(time); + + for(;;) { + b[off + i ++] = (byte) ch; + + if(i < len && ch != '\n') + ch = read(time); + else + break; + } + + return i; + } + + /** * @see java.io.InputStream#read() */ public int read() throws IOException { - while (true) { - KeyboardEvent event = (KeyboardEvent) queue.get(); - if (!event.isConsumed()) { - event.consume(); - char ch = event.getKeyChar(); - if (ch != 0) { - if (echo) { - System.out.print(ch); - } - return ch; - } - } - } + long time = System.currentTimeMillis(); + return read(time); } - /** + private int read(long time){ + while (true) { + KeyboardEvent event = queue.get(); + int c = event2char(event, time); + if(c > 0) + return c; + } + } + + private int event2char(KeyboardEvent event, long time) { + if (!event.isConsumed() && event.getTime() - time > -10000) { + event.consume(); + char ch = event.getKeyChar(); + if (ch != 0) { + if (echo) { + System.out.print(ch); + } + return ch; + } + } + return -1; + } + + /** * @see org.jnode.driver.input.KeyboardListener#keyPressed(org.jnode.driver.input.KeyboardEvent) */ public void keyPressed(KeyboardEvent event) { - //log.debug("got event(" + event + ")"); queue.add(event); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2007-01-02 16:16:54
|
Revision: 2974 http://jnode.svn.sourceforge.net/jnode/?rev=2974&view=rev Author: lsantha Date: 2007-01-02 08:16:45 -0800 (Tue, 02 Jan 2007) Log Message: ----------- Consume KeyboardEvents. Modified Paths: -------------- trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java Modified: trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java =================================================================== --- trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java 2006-12-30 19:32:30 UTC (rev 2973) +++ trunk/distr/src/apps/org/jnode/apps/editor/TextEditor.java 2007-01-02 16:16:45 UTC (rev 2974) @@ -259,6 +259,7 @@ fx = 0; } } + e.consume(); updateScreen(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2006-12-30 19:32:33
|
Revision: 2973 http://jnode.svn.sourceforge.net/jnode/?rev=2973&view=rev Author: lsantha Date: 2006-12-30 11:32:30 -0800 (Sat, 30 Dec 2006) Log Message: ----------- Removed java.sql dependecy. Modified Paths: -------------- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java =================================================================== --- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java 2006-12-30 19:28:42 UTC (rev 2972) +++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java 2006-12-30 19:32:30 UTC (rev 2973) @@ -55,7 +55,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; -import java.sql.Date; +import java.util.Date; import java.text.DateFormat; import java.text.NumberFormat; import java.util.List; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2006-12-30 19:28:43
|
Revision: 2972 http://jnode.svn.sourceforge.net/jnode/?rev=2972&view=rev Author: lsantha Date: 2006-12-30 11:28:42 -0800 (Sat, 30 Dec 2006) Log Message: ----------- java.sql moved to fragment. Modified Paths: -------------- trunk/core/descriptors/org.classpath.core.xml trunk/core/descriptors/org.classpath.ext.sql.xml Modified: trunk/core/descriptors/org.classpath.core.xml =================================================================== --- trunk/core/descriptors/org.classpath.core.xml 2006-12-30 19:27:41 UTC (rev 2971) +++ trunk/core/descriptors/org.classpath.core.xml 2006-12-30 19:28:42 UTC (rev 2972) @@ -88,8 +88,7 @@ <export name="java.security.acl.*"/> <export name="java.security.cert.*"/> <export name="java.security.interfaces.*"/> - <export name="java.security.spec.*"/> - <export name="java.sql.*"/> + <export name="java.security.spec.*"/> <export name="java.text.*"/> <export name="java.util.*"/> <export name="java.util.jar.*"/> Modified: trunk/core/descriptors/org.classpath.ext.sql.xml =================================================================== --- trunk/core/descriptors/org.classpath.ext.sql.xml 2006-12-30 19:27:41 UTC (rev 2971) +++ trunk/core/descriptors/org.classpath.ext.sql.xml 2006-12-30 19:28:42 UTC (rev 2972) @@ -12,8 +12,8 @@ <runtime> <library name="jnode-core.jar"> + <export name="java.sql.*"/> <export name="javax.sql.*"/> - <export name="javax.transaction.*"/> <export name="javax.transaction.xa.*"/> </library> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2006-12-30 19:27:43
|
Revision: 2971 http://jnode.svn.sourceforge.net/jnode/?rev=2971&view=rev Author: lsantha Date: 2006-12-30 11:27:41 -0800 (Sat, 30 Dec 2006) Log Message: ----------- Removed java.sql dependency. Modified Paths: -------------- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java Removed Paths: ------------- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JDBCSessionContext.java Modified: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java 2006-12-30 18:00:47 UTC (rev 2970) +++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java 2006-12-30 19:27:41 UTC (rev 2971) @@ -38,8 +38,6 @@ package gnu.javax.net.ssl.provider; -import java.io.File; -import java.io.InputStream; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStoreException; @@ -47,9 +45,7 @@ import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; -import java.security.Security; import java.security.UnrecoverableKeyException; -import java.sql.SQLException; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JDBCSessionContext.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JDBCSessionContext.java 2006-12-30 18:00:47 UTC (rev 2970) +++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JDBCSessionContext.java 2006-12-30 19:27:41 UTC (rev 2971) @@ -1,356 +0,0 @@ -/* JDBCSessionContext.java -- database persistent sessions. - Copyright (C) 2006 Free Software Foundation, Inc. - -This file is a part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at -your option) any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 -USA - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.javax.net.ssl.provider; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; - -import java.security.SecureRandom; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.sql.Types; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Enumeration; -import java.util.TreeSet; -import java.util.Vector; - -import javax.net.ssl.SSLSession; - -/** - * The SQL table this class stores sessions in, called <tt>SESSIONS</tt>, - * looks like this: - * - * <blockquote><pre> - * TABLE SESSIONS ( - * ID VARBINARY(32) PRIMARY KEY UNIQUE NOT NULL, - * CREATED TIMESTAMP NOT NULL, - * LAST_ACCESSED TIMESTAMP NOT NULL, - * PROTOCOL VARCHAR(7) NOT NULL, - * SUITE VARCHAR(255) NOT NULL, - * PEER_HOST TEXT NOT NULL, - * PEER_CERT_TYPE VARCHAR(32), - * PEER_CERTS BLOB, - * CERT_TYPE VARCHAR(32), - * CERTS BLOB, - * SECRET VARBINARY(48) NOT NULL - * ) - * </pre></blockquote> - * - * <p>Note that the master secret for sessions is not protected before - * being inserted into the database; it is up to the system to protect - * the stored data from unauthorized access. - */ -class JDBCSessionContext extends SessionContext -{ - - // Fields. - // ------------------------------------------------------------------------- - - protected Connection connection; - protected PreparedStatement selectById; - protected PreparedStatement insert; - protected PreparedStatement selectTimestamp; - protected PreparedStatement updateTimestamp; - protected PreparedStatement deleteSession; - - // Constructor. - // ------------------------------------------------------------------------- - - JDBCSessionContext() throws SQLException - { - String url = Util.getSecurityProperty("jessie.SessionContext.jdbc.url"); - String user = Util.getSecurityProperty("jessie.SessionContext.jdbc.user"); - String passwd = Util.getSecurityProperty("jessie.SessionContext.jdbc.password"); - if (url == null) - { - throw new IllegalArgumentException("no JDBC URL"); - } - if (user == null || passwd == null) - { - connection = DriverManager.getConnection(url); - } - else - { - connection = DriverManager.getConnection(url, user, passwd); - } - selectById = - connection.prepareStatement("SELECT * FROM SESSIONS WHERE ID = ?"); - insert = connection.prepareStatement("INSERT INTO SESSIONS VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - selectTimestamp = - connection.prepareStatement("SELECT CREATED FROM SESSIONS WHERE ID = ?"); - updateTimestamp = - connection.prepareStatement("UPDATE SESSIONS SET LAST_ACCESSED = ? WHERE ID = ?"); - deleteSession = - connection.prepareStatement("DELETE FROM SESSIONS WHERE ID = ?"); - } - - // Instance methods. - // ------------------------------------------------------------------------- - - public synchronized Enumeration getIds() - { - Vector ids = new Vector(); - try - { - Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT ID FROM SESSIONS"); - while (rs.next()) - { - byte[] id = rs.getBytes("ID"); - ids.add(id); - } - } - catch (SQLException sqle) - { - } - return ids.elements(); - } - - public synchronized SSLSession getSession(byte[] sessionId) - { - Session session = (Session) super.getSession(sessionId); - if (session == null) - { - try - { - selectById.setBytes(1, sessionId); - ResultSet rs = selectById.executeQuery(); - if (rs.next()) - { - session = new Session(rs.getTimestamp("CREATED").getTime()); - session.enabledSuites = new ArrayList(SSLSocket.supportedSuites); - session.enabledProtocols = new TreeSet(SSLSocket.supportedProtocols); - session.random = new SecureRandom(); - session.context = this; - session.sessionId = new Session.ID(rs.getBytes("ID")); - session.setLastAccessedTime(rs.getTimestamp("LAST_ACCESSED").getTime()); - long elapsed = System.currentTimeMillis() - session.getLastAccessedTime(); - if ((int) (elapsed / 1000L) > timeout) - { - removeSession(session.sessionId); - return null; - } - session.peerHost = rs.getString("PEER_HOST"); - String protocol = rs.getString("PROTOCOL"); - if (protocol.equals("SSLv3")) - { - session.protocol = ProtocolVersion.SSL_3; - } - else if (protocol.equals("TLSv1")) - { - session.protocol = ProtocolVersion.TLS_1; - } - else if (protocol.equals("TLSv1.1")) - { - session.protocol = ProtocolVersion.TLS_1_1; - } - else - { - return null; - } - session.cipherSuite = CipherSuite.forName(rs.getString("SUITE")); - String type = rs.getString("PEER_CERT_TYPE"); - boolean wasNull = rs.wasNull(); - InputStream certs = null; - if (!wasNull) - { - certs = rs.getBinaryStream("PEER_CERTS"); - wasNull = rs.wasNull(); - } - if (!wasNull) - { - CertificateFactory cf = CertificateFactory.getInstance(type); - session.peerCerts = (Certificate[]) - cf.generateCertificates(certs).toArray(new Certificate[0]); - session.peerVerified = true; - } - type = rs.getString("CERT_TYPE"); - wasNull = rs.wasNull(); - if (!wasNull) - { - certs = rs.getBinaryStream("CERTS"); - wasNull = rs.wasNull(); - } - if (!wasNull) - { - CertificateFactory cf = CertificateFactory.getInstance(type); - session.localCerts = (Certificate[]) - cf.generateCertificates(certs).toArray(new Certificate[0]); - } - session.masterSecret = rs.getBytes("SECRET"); - if (cacheSize == 0 || sessions.size() < cacheSize) - { - sessions.put(session.sessionId, session); - } - } - } - catch (Exception ex) - { - } - } - return session; - } - - synchronized boolean addSession(Session.ID id, Session s) - { - if (containsSessionID(id)) - { - return false; - } - try - { - insert.setBytes(1, id.getId()); - insert.setTimestamp(2, new Timestamp(s.getCreationTime())); - insert.setTimestamp(3, new Timestamp(s.getLastAccessedTime())); - insert.setString(4, s.getProtocol()); - insert.setString(5, s.getCipherSuite()); - insert.setString(6, s.peerHost); - if (s.peerCerts != null && s.peerCerts.length > 0) - { - insert.setString(7, s.peerCerts[0].getType()); - insert.setBytes(8, certs(s.peerCerts)); - } - else - { - insert.setNull(7, Types.VARCHAR); - insert.setNull(8, Types.LONGVARBINARY); - } - if (s.localCerts != null && s.localCerts.length > 0) - { - insert.setString(9, s.localCerts[0].getType()); - insert.setBytes(10, certs(s.localCerts)); - } - else - { - insert.setNull(9, Types.VARCHAR); - insert.setNull(10, Types.LONGVARBINARY); - } - insert.setBytes(11, s.masterSecret); - insert.executeUpdate(); - super.addSession(id, s); - } - catch (SQLException sqle) - { - return false; - } - return true; - } - - synchronized boolean containsSessionID(Session.ID sessionId) - { - try - { - selectTimestamp.setBytes(1, sessionId.getId()); - ResultSet rs = selectTimestamp.executeQuery(); - if (!rs.next()) - { - return false; - } - Timestamp ts = rs.getTimestamp("CREATED"); - if (rs.wasNull()) - { - return false; - } - long elapsed = System.currentTimeMillis() - ts.getTime(); - if ((int) (elapsed / 1000) > timeout) - { - removeSession(sessionId); - return false; - } - return true; - } - catch (SQLException sqle) - { - return false; - } - } - - protected boolean removeSession(Session.ID sessionId) - { - super.removeSession(sessionId); - try - { - deleteSession.setBytes(1, sessionId.getId()); - return deleteSession.executeUpdate() > 0; - } - catch (SQLException sqle) - { - } - return false; - } - - synchronized void notifyAccess(Session session) - { - try - { - updateTimestamp.setTimestamp(1, new Timestamp(session.getLastAccessedTime())); - updateTimestamp.setBytes(2, session.getId()); - updateTimestamp.executeUpdate(); - } - catch (SQLException sqle) - { - } - } - - private byte[] certs(Certificate[] certs) - { - ByteArrayOutputStream out = new ByteArrayOutputStream(2048); - for (int i = 0; i < certs.length; i++) - { - try - { - out.write(certs[i].getEncoded()); - } - catch (Exception x) - { - } - } - return out.toByteArray(); - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2006-12-30 18:00:49
|
Revision: 2970 http://jnode.svn.sourceforge.net/jnode/?rev=2970&view=rev Author: lsantha Date: 2006-12-30 10:00:47 -0800 (Sat, 30 Dec 2006) Log Message: ----------- Added setIO permission. Modified Paths: -------------- trunk/core/descriptors/org.jnode.driver.console.textscreen.xml Modified: trunk/core/descriptors/org.jnode.driver.console.textscreen.xml =================================================================== --- trunk/core/descriptors/org.jnode.driver.console.textscreen.xml 2006-12-30 17:55:27 UTC (rev 2969) +++ trunk/core/descriptors/org.jnode.driver.console.textscreen.xml 2006-12-30 18:00:47 UTC (rev 2970) @@ -18,5 +18,8 @@ <export name="org.jnode.driver.console.textscreen.*"/> </library> </runtime> - + + <extension point="org.jnode.security.permissions"> + <permission class="java.lang.RuntimePermission" name="setIO"/> + </extension> </plugin> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |