Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id F2797200D88 for ; Wed, 20 Dec 2017 05:29:17 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id F0AC4160C1B; Wed, 20 Dec 2017 04:29:17 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D5FD9160C4C for ; Wed, 20 Dec 2017 05:29:13 +0100 (CET) Received: (qmail 32922 invoked by uid 500); 20 Dec 2017 04:29:13 -0000 Mailing-List: contact commits-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list commits@groovy.apache.org Received: (qmail 32319 invoked by uid 99); 20 Dec 2017 04:29:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Dec 2017 04:29:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 7CD80F2E07; Wed, 20 Dec 2017 04:29:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sunlan@apache.org To: commits@groovy.apache.org Date: Wed, 20 Dec 2017 04:29:22 -0000 Message-Id: <5e94f6cf3fe64cb18c4c3cf7d4be755f@git.apache.org> In-Reply-To: <48be9b2ce20b4b3a90bfd5192834b3a3@git.apache.org> References: <48be9b2ce20b4b3a90bfd5192834b3a3@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [14/47] groovy git commit: Move source files to proper packages archived-at: Wed, 20 Dec 2017 04:29:18 -0000 http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/NumberRange.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/NumberRange.java b/src/main/groovy/lang/NumberRange.java deleted file mode 100644 index 92c6195..0000000 --- a/src/main/groovy/lang/NumberRange.java +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package groovy.lang; - -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.IteratorClosureAdapter; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.AbstractList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareEqual; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareGreaterThan; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareGreaterThanEqual; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareLessThan; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareLessThanEqual; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareNotEqual; -import static org.codehaus.groovy.runtime.ScriptBytecodeAdapter.compareTo; -import static org.codehaus.groovy.runtime.dgmimpl.NumberNumberMinus.minus; -import static org.codehaus.groovy.runtime.dgmimpl.NumberNumberMultiply.multiply; -import static org.codehaus.groovy.runtime.dgmimpl.NumberNumberPlus.plus; - -/** - * Represents an immutable list of Numbers from a value to a value with a particular step size. - * - * In general, it isn't recommended using a NumberRange as a key to a map. The range - * 0..3 is deemed to be equal to 0.0..3.0 but they have different hashCode values, - * so storing a value using one of these ranges couldn't be retrieved using the other. - * - * @since 2.5 - */ -public class NumberRange extends AbstractList implements Range { - - /** - * The first value in the range. - */ - private final Comparable from; - - /** - * The last value in the range. - */ - private final Comparable to; - - /** - * The step size in the range. - */ - private final Number stepSize; - - /** - * The cached size, or -1 if not yet computed - */ - private int size = -1; - - /** - * The cached hashCode (once calculated) - */ - private Integer hashCodeCache = null; - - /** - * true if the range counts backwards from to to from. - */ - private final boolean reverse; - - /** - * true if the range includes the upper bound. - */ - private final boolean inclusive; - - /** - * Creates an inclusive {@link NumberRange} with step size 1. - * Creates a reversed range if from < to. - * - * @param from the first value in the range - * @param to the last value in the range - */ - public - NumberRange(T from, U to) { - this(from, to, null, true); - } - - /** - * Creates a new {@link NumberRange} with step size 1. - * Creates a reversed range if from < to. - * - * @param from start of the range - * @param to end of the range - * @param inclusive whether the range is inclusive - */ - public - NumberRange(T from, U to, boolean inclusive) { - this(from, to, null, inclusive); - } - - /** - * Creates an inclusive {@link NumberRange}. - * Creates a reversed range if from < to. - * - * @param from start of the range - * @param to end of the range - * @param stepSize the gap between discrete elements in the range - */ - public > - NumberRange(T from, U to, V stepSize) { - this(from, to, stepSize, true); - } - - /** - * Creates a {@link NumberRange}. - * Creates a reversed range if from < to. - * - * @param from start of the range - * @param to end of the range - * @param stepSize the gap between discrete elements in the range - * @param inclusive whether the range is inclusive - */ - public - NumberRange(T from, U to, V stepSize, boolean inclusive) { - if (from == null) { - throw new IllegalArgumentException("Must specify a non-null value for the 'from' index in a Range"); - } - if (to == null) { - throw new IllegalArgumentException("Must specify a non-null value for the 'to' index in a Range"); - } - reverse = areReversed(from, to); - Number tempFrom; - Number tempTo; - if (reverse) { - tempFrom = to; - tempTo = from; - } else { - tempFrom = from; - tempTo = to; - } - if (tempFrom instanceof Short) { - tempFrom = tempFrom.intValue(); - } else if (tempFrom instanceof Float) { - tempFrom = tempFrom.doubleValue(); - } - if (tempTo instanceof Short) { - tempTo = tempTo.intValue(); - } else if (tempTo instanceof Float) { - tempTo = tempTo.doubleValue(); - } - - if (tempFrom instanceof Integer && tempTo instanceof Long) { - tempFrom = tempFrom.longValue(); - } else if (tempTo instanceof Integer && tempFrom instanceof Long) { - tempTo = tempTo.longValue(); - } - - this.from = (Comparable) tempFrom; - this.to = (Comparable) tempTo; - this.stepSize = stepSize == null ? 1 : stepSize; - this.inclusive = inclusive; - } - - /** - * For a NumberRange with step size 1, creates a new NumberRange with the same - * from and to as this NumberRange - * but with a step size of stepSize. - * - * @param stepSize the desired step size - * @return a new NumberRange - */ - public NumberRange by(T stepSize) { - if (!Integer.valueOf(1).equals(this.stepSize)) { - throw new IllegalStateException("by only allowed on ranges with original stepSize = 1 but found " + this.stepSize); - } - return new NumberRange(comparableNumber(from), comparableNumber(to), stepSize, inclusive); - } - - @SuppressWarnings("unchecked") - /* package private */ static T comparableNumber(Comparable c) { - return (T) c; - } - - @SuppressWarnings("unchecked") - /* package private */ static T comparableNumber(Number n) { - return (T) n; - } - - private static boolean areReversed(Number from, Number to) { - try { - return compareGreaterThan(from, to); - } catch (ClassCastException cce) { - throw new IllegalArgumentException("Unable to create range due to incompatible types: " + from.getClass().getSimpleName() + ".." + to.getClass().getSimpleName() + " (possible missing brackets around range?)", cce); - } - } - - /** - * An object is deemed equal to this NumberRange if it represents a List of items and - * those items equal the list of discrete items represented by this NumberRange. - * - * @param that the object to be compared for equality with this NumberRange - * @return {@code true} if the specified object is equal to this NumberRange - * @see #fastEquals(NumberRange) - */ - @Override - public boolean equals(Object that) { - return super.equals(that); - } - - /** - * A NumberRange's hashCode is based on hashCode values of the discrete items it represents. - * - * @return the hashCode value - */ - @Override - public int hashCode() { - if (hashCodeCache == null) { - hashCodeCache = super.hashCode(); - } - return hashCodeCache; - } - - /* - * NOTE: as per the class javadoc, this class doesn't obey the normal equals/hashCode contract. - * The following field and method could assist some scenarios which required a similar sort of contract - * (but between equals and the custom canonicalHashCode). Currently commented out since we haven't - * found a real need. We will likely remove this commented out code if no usage is identified soon. - */ - - /* - * The cached canonical hashCode (once calculated) - */ -// private Integer canonicalHashCodeCache = null; - - /* - * A NumberRange's canonicalHashCode is based on hashCode values of the discrete items it represents. - * When two NumberRange's are equal they will have the same canonicalHashCode value. - * Numerical values which Groovy deems equal have the same hashCode during this calculation. - * So currently (0..3).equals(0.0..3.0) yet they have different hashCode values. This breaks - * the normal equals/hashCode contract which is a weakness in Groovy's '==' operator. However - * the contract isn't broken between equals and canonicalHashCode. - * - * @return the hashCode value - */ -// public int canonicalHashCode() { -// if (canonicalHashCodeCache == null) { -// int hashCode = 1; -// for (Comparable e : this) { -// int value; -// if (e == null) { -// value = 0; -// } else { -// BigDecimal next = new BigDecimal(e.toString()); -// if (next.compareTo(BigDecimal.ZERO) == 0) { -// // workaround on pre-Java8 for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6480539 -// value = BigDecimal.ZERO.hashCode(); -// } else { -// value = next.stripTrailingZeros().hashCode(); -// } -// } -// hashCode = 31 * hashCode + value; -// } -// canonicalHashCodeCache = hashCode; -// } -// return canonicalHashCodeCache; -// } - - /** - * Compares a {@link NumberRange} to another {@link NumberRange} using only a strict comparison - * of the NumberRange properties. This won't return true for some ranges which represent the same - * discrete items, use equals instead for that but will be much faster for large lists. - * - * @param that the NumberRange to check equality with - * @return true if the ranges are equal - */ - public boolean fastEquals(NumberRange that) { - return that != null - && reverse == that.reverse - && inclusive == that.inclusive - && compareEqual(from, that.from) - && compareEqual(to, that.to) - && compareEqual(stepSize, that.stepSize); - } - - /* - * NOTE: as per the class javadoc, this class doesn't obey the normal equals/hashCode contract. - * The following field and method could assist some scenarios which required a similar sort of contract - * (but between fastEquals and the custom fastHashCode). Currently commented out since we haven't - * found a real need. We will likely remove this commented out code if no usage is identified soon. - */ - - /* - * The cached fast hashCode (once calculated) - */ -// private Integer fastHashCodeCache = null; - - /* - * A hashCode function that pairs with fastEquals, following the normal equals/hashCode contract. - * - * @return the calculated hash code - */ -// public int fastHashCode() { -// if (fastHashCodeCache == null) { -// int result = 17; -// result = result * 31 + (reverse ? 1 : 0); -// result = result * 31 + (inclusive ? 1 : 0); -// result = result * 31 + new BigDecimal(from.toString()).stripTrailingZeros().hashCode(); -// result = result * 31 + new BigDecimal(to.toString()).stripTrailingZeros().hashCode(); -// result = result * 31 + new BigDecimal(stepSize.toString()).stripTrailingZeros().hashCode(); -// fastHashCodeCache = result; -// } -// return fastHashCodeCache; -// } - - @Override - public Comparable getFrom() { - return from; - } - - @Override - public Comparable getTo() { - return to; - } - - public Comparable getStepSize() { - return (Comparable) stepSize; - } - - @Override - public boolean isReverse() { - return reverse; - } - - @Override - public Comparable get(int index) { - if (index < 0) { - throw new IndexOutOfBoundsException("Index: " + index + " should not be negative"); - } - final Iterator iter = new StepIterator(this, stepSize); - - Comparable value = iter.next(); - for (int i = 0; i < index; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + index + " is too big for range: " + this); - } - value = iter.next(); - } - return value; - } - - /** - * Checks whether a value is between the from and to values of a Range - * - * @param value the value of interest - * @return true if the value is within the bounds - */ - @Override - public boolean containsWithinBounds(Object value) { - final int result = compareTo(from, value); - return result == 0 || result < 0 && compareTo(to, value) >= 0; - } - - /** - * protection against calls from Groovy - */ - @SuppressWarnings("unused") - private void setSize(int size) { - throw new UnsupportedOperationException("size must not be changed"); - } - - @Override - public int size() { - if (size == -1) { - calcSize(from, to, stepSize); - } - return size; - } - - void calcSize(Comparable from, Comparable to, Number stepSize) { - int tempsize = 0; - boolean shortcut = false; - if (isIntegral(stepSize)) { - if ((from instanceof Integer || from instanceof Long) - && (to instanceof Integer || to instanceof Long)) { - // let's fast calculate the size - final BigInteger fromNum = new BigInteger(from.toString()); - final BigInteger toTemp = new BigInteger(to.toString()); - final BigInteger toNum = inclusive ? toTemp : toTemp.subtract(BigInteger.ONE); - final BigInteger sizeNum = new BigDecimal(toNum.subtract(fromNum)).divide(new BigDecimal(stepSize.longValue()), BigDecimal.ROUND_DOWN).toBigInteger().add(BigInteger.ONE); - tempsize = sizeNum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == -1 ? sizeNum.intValue() : Integer.MAX_VALUE; - shortcut = true; - } else if (((from instanceof BigDecimal || from instanceof BigInteger) && to instanceof Number) || - ((to instanceof BigDecimal || to instanceof BigInteger) && from instanceof Number)) { - // let's fast calculate the size - final BigDecimal fromNum = new BigDecimal(from.toString()); - final BigDecimal toTemp = new BigDecimal(to.toString()); - final BigDecimal toNum = inclusive ? toTemp : toTemp.subtract(new BigDecimal("1.0")); - final BigInteger sizeNum = toNum.subtract(fromNum).divide(new BigDecimal(stepSize.longValue()), BigDecimal.ROUND_DOWN).toBigInteger().add(BigInteger.ONE); - tempsize = sizeNum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == -1 ? sizeNum.intValue() : Integer.MAX_VALUE; - shortcut = true; - } - } - if (!shortcut) { - // let's brute-force calculate the size by iterating start to end - final Iterator iter = new StepIterator(this, stepSize); - while (iter.hasNext()) { - tempsize++; - // integer overflow - if (tempsize < 0) { - break; - } - iter.next(); - } - // integer overflow - if (tempsize < 0) { - tempsize = Integer.MAX_VALUE; - } - } - size = tempsize; - } - - private boolean isIntegral(Number stepSize) { - BigDecimal tempStepSize = new BigDecimal(stepSize.toString()); - return tempStepSize.equals(new BigDecimal(tempStepSize.toBigInteger())); - } - - @Override - public List subList(int fromIndex, int toIndex) { - if (fromIndex < 0) { - throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); - } - if (fromIndex > toIndex) { - throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); - } - if (fromIndex == toIndex) { - return new EmptyRange(from); - } - - // Performance detail: - // not using get(fromIndex), get(toIndex) in the following to avoid stepping over elements twice - final Iterator iter = new StepIterator(this, stepSize); - - Comparable value = iter.next(); - int i = 0; - for (; i < fromIndex; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + i + " is too big for range: " + this); - } - value = iter.next(); - } - final Comparable fromValue = value; - for (; i < toIndex - 1; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + i + " is too big for range: " + this); - } - value = iter.next(); - } - final Comparable toValue = value; - - return new NumberRange(comparableNumber(fromValue), comparableNumber(toValue), comparableNumber(stepSize), true); - } - - @Override - public String toString() { - return getToString(to.toString(), from.toString()); - } - - @Override - public String inspect() { - return getToString(InvokerHelper.inspect(to), InvokerHelper.inspect(from)); - } - - private String getToString(String toText, String fromText) { - String sep = inclusive ? ".." : "..<"; - String base = reverse ? "" + toText + sep + fromText : "" + fromText + sep + toText; - return Integer.valueOf(1).equals(stepSize) ? base : base + ".by(" + stepSize + ")"; - } - - /** - * iterates over all values and returns true if one value matches. - * Also see containsWithinBounds. - */ - @Override - public boolean contains(Object value) { - if (value == null) { - return false; - } - final Iterator it = new StepIterator(this, stepSize); - while (it.hasNext()) { - if (compareEqual(value, it.next())) { - return true; - } - } - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public void step(int numSteps, Closure closure) { - if (numSteps == 0 && compareTo(from, to) == 0) { - return; // from == to and step == 0, nothing to do, so return - } - final StepIterator iter = new StepIterator(this, multiply(numSteps, stepSize)); - while (iter.hasNext()) { - closure.call(iter.next()); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Iterator iterator() { - return new StepIterator(this, stepSize); - } - - /** - * convenience class to serve in other methods. - * It's not thread-safe, and lazily produces the next element only on calls of hasNext() or next() - */ - private class StepIterator implements Iterator { - private final NumberRange range; - private final Number step; - private final boolean isAscending; - - private boolean isNextFetched = false; - private Comparable next = null; - - StepIterator(NumberRange range, Number step) { - if (compareEqual(step, 0) && compareNotEqual(range.getFrom(), range.getTo())) { - throw new GroovyRuntimeException("Infinite loop detected due to step size of 0"); - } - - this.range = range; - if (compareLessThan(step, 0)) { - this.step = multiply(step, -1); - isAscending = range.isReverse(); - } else { - this.step = step; - isAscending = !range.isReverse(); - } - } - - @Override - public boolean hasNext() { - fetchNextIfNeeded(); - return (next != null) && (isAscending - ? (range.inclusive ? compareLessThanEqual(next, range.getTo()) : compareLessThan(next, range.getTo())) - : (range.inclusive ? compareGreaterThanEqual(next, range.getFrom()) : compareGreaterThan(next, range.getFrom()))); - } - - @Override - public Comparable next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - - fetchNextIfNeeded(); - isNextFetched = false; - return next; - } - - private void fetchNextIfNeeded() { - if (!isNextFetched) { - isNextFetched = true; - - if (next == null) { - // make the first fetch lazy too - next = isAscending ? range.getFrom() : range.getTo(); - } else { - next = isAscending ? increment(next, step) : decrement(next, step); - } - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - @Override - public List step(int numSteps) { - final IteratorClosureAdapter adapter = new IteratorClosureAdapter(this); - step(numSteps, adapter); - return adapter.asList(); - } - - /** - * Increments by given step - * - * @param value the value to increment - * @param step the amount to increment - * @return the incremented value - */ - @SuppressWarnings("unchecked") - private Comparable increment(Object value, Number step) { - return (Comparable) plus((Number) value, step); - } - - /** - * Decrements by given step - * - * @param value the value to decrement - * @param step the amount to decrement - * @return the decremented value - */ - @SuppressWarnings("unchecked") - private Comparable decrement(Object value, Number step) { - return (Comparable) minus((Number) value, step); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/ObjectRange.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ObjectRange.java b/src/main/groovy/lang/ObjectRange.java deleted file mode 100644 index a7e2b05..0000000 --- a/src/main/groovy/lang/ObjectRange.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.runtime.DefaultGroovyMethods; -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.IteratorClosureAdapter; -import org.codehaus.groovy.runtime.ScriptBytecodeAdapter; -import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.AbstractList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -/** - * Represents an inclusive list of objects from a value to a value using - * comparators. - *

- * Note: This class is similar to {@link IntRange}. If you make any changes to this - * class, you might consider making parallel changes to {@link IntRange}. - */ -public class ObjectRange extends AbstractList implements Range { - /** - * The first value in the range. - */ - private final Comparable from; - - /** - * The last value in the range. - */ - private final Comparable to; - - /** - * The cached size, or -1 if not yet computed - */ - private int size = -1; - - /** - * true if the range counts backwards from to to from. - */ - private final boolean reverse; - - /** - * Creates a new {@link ObjectRange}. Creates a reversed range if - * from < to. - * - * @param from the first value in the range. - * @param to the last value in the range. - */ - public ObjectRange(Comparable from, Comparable to) { - this(from, to, null); - } - - /** - * Creates a new {@link ObjectRange} assumes smaller <= larger, else behavior is undefined. - * Caution: Prefer the other constructor when in doubt. - *

- * Optimized Constructor avoiding initial computation of comparison. - */ - public ObjectRange(Comparable smaller, Comparable larger, boolean reverse) { - this(smaller, larger, (Boolean) reverse); - } - - /** - * Constructs a Range, computing reverse if not provided. When providing reverse, - * 'smaller' must not be larger than 'larger'. - * - * @param smaller start of the range, must no be larger than to when reverse != null - * @param larger end of the range, must be larger than from when reverse != null - * @param reverse direction of the range. If null, causes direction to be computed (can be expensive). - */ - private ObjectRange(Comparable smaller, Comparable larger, Boolean reverse) { - if (smaller == null) { - throw new IllegalArgumentException("Must specify a non-null value for the 'from' index in a Range"); - } - if (larger == null) { - throw new IllegalArgumentException("Must specify a non-null value for the 'to' index in a Range"); - } - if (reverse == null) { - final boolean computedReverse = areReversed(smaller, larger); - // ensure invariant from <= to - if (computedReverse) { - final Comparable temp = larger; - larger = smaller; - smaller = temp; - } - this.reverse = computedReverse; - } else { - this.reverse = reverse; - } - - if (smaller instanceof Short) { - smaller = ((Short) smaller).intValue(); - } else if (smaller instanceof Float) { - smaller = ((Float) smaller).doubleValue(); - } - if (larger instanceof Short) { - larger = ((Short) larger).intValue(); - } else if (larger instanceof Float) { - larger = ((Float) larger).doubleValue(); - } - - if (smaller instanceof Integer && larger instanceof Long) { - smaller = ((Integer) smaller).longValue(); - } else if (larger instanceof Integer && smaller instanceof Long) { - larger = ((Integer) larger).longValue(); - } - - /* - areReversed() already does an implicit type compatibility check - based on DefaultTypeTransformation.compareToWithEqualityCheck() for mixed classes - but it is only invoked if reverse == null. - So Object Range has to perform those type checks for consistency even when not calling - compareToWithEqualityCheck(), and ObjectRange has - to use the normalized value used in a successful comparison in - compareToWithEqualityCheck(). Currently that means Chars and single-char Strings - are evaluated as the char's charValue (an integer) when compared to numbers. - So '7'..'9' should produce ['7', '8', '9'], whereas ['7'..9] and [7..'9'] should produce [55, 56, 57]. - if classes match, or both numerical, no checks possible / necessary - */ - if (smaller.getClass() == larger.getClass() || - (smaller instanceof Number && larger instanceof Number)) { - this.from = smaller; - this.to = larger; - } else { - // Convenience hack: try convert single-char strings to ints - final Comparable tempfrom = normaliseStringType(smaller); - final Comparable tempto = normaliseStringType(larger); - // if after normalizing both are numbers, assume intended range was numbers - if (tempfrom instanceof Number && tempto instanceof Number) { - this.from = tempfrom; - this.to = tempto; - } else { - // if convenience hack did not make classes match, - // throw exception when starting with known class, and thus "from" cannot be advanced over "to". - // Note if start is an unusual Object, it could have a next() method - // that yields a Number or String to close the range - final Comparable start = this.reverse ? larger : smaller; - if (start instanceof String || start instanceof Number) { - // starting with number will never reach a non-number, same for string - throw new IllegalArgumentException("Incompatible Argument classes for ObjectRange " + smaller.getClass() + ", " + larger.getClass()); - } - // Since normalizing did not help, use original values at user's risk - this.from = smaller; - this.to = larger; - } - } - checkBoundaryCompatibility(); - } - - /** - * throws IllegalArgumentException if to and from are incompatible, meaning they e.g. (likely) produce infinite sequences. - * Called at construction time, subclasses may override cautiously (using only members to and from). - */ - protected void checkBoundaryCompatibility() { - if (from instanceof String && to instanceof String) { - // this test depends deeply on the String.next implementation - // 009.next is 00:, not 010 - final String start = from.toString(); - final String end = to.toString(); - if (start.length() != end.length()) { - throw new IllegalArgumentException("Incompatible Strings for Range: different length"); - } - final int length = start.length(); - int i; - for (i = 0; i < length; i++) { - if (start.charAt(i) != end.charAt(i)) { - break; - } - } - // strings must be equal except for the last character - if (i < length - 1) { - throw new IllegalArgumentException("Incompatible Strings for Range: String#next() will not reach the expected value"); - } - } - } - - private static boolean areReversed(Comparable from, Comparable to) { - try { - return ScriptBytecodeAdapter.compareGreaterThan(from, to); - } catch (IllegalArgumentException iae) { - throw new IllegalArgumentException("Unable to create range due to incompatible types: " + from.getClass().getSimpleName() + ".." + to.getClass().getSimpleName() + " (possible missing brackets around range?)", iae); - } - } - - public boolean equals(Object that) { - return (that instanceof ObjectRange) ? equals((ObjectRange) that) : super.equals(that); - } - - /** - * Compares an {@link ObjectRange} to another {@link ObjectRange}. - * - * @param that the object to check equality with - * @return true if the ranges are equal - */ - public boolean equals(ObjectRange that) { - return that != null - && reverse == that.reverse - && DefaultTypeTransformation.compareEqual(from, that.from) - && DefaultTypeTransformation.compareEqual(to, that.to); - } - - @Override - public Comparable getFrom() { - return from; - } - - @Override - public Comparable getTo() { - return to; - } - - @Override - public boolean isReverse() { - return reverse; - } - - @Override - public Comparable get(int index) { - if (index < 0) { - throw new IndexOutOfBoundsException("Index: " + index + " should not be negative"); - } - final StepIterator iter = new StepIterator(this, 1); - - Comparable value = iter.next(); - for (int i = 0; i < index; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + index + " is too big for range: " + this); - } - value = iter.next(); - } - return value; - } - - /** - * Checks whether a value is between the from and to values of a Range - * - * @param value the value of interest - * @return true if the value is within the bounds - */ - @Override - public boolean containsWithinBounds(Object value) { - if (value instanceof Comparable) { - final int result = compareTo(from, (Comparable) value); - return result == 0 || result < 0 && compareTo(to, (Comparable) value) >= 0; - } - return contains(value); - } - - protected int compareTo(Comparable first, Comparable second) { - return DefaultGroovyMethods.numberAwareCompareTo(first, second); - } - - /** - * protection against calls from Groovy - */ - @SuppressWarnings("unused") - private void setSize(int size) { - throw new UnsupportedOperationException("size must not be changed"); - } - - @Override - public int size() { - if (size == -1) { - int tempsize = 0; - if ((from instanceof Integer || from instanceof Long) - && (to instanceof Integer || to instanceof Long)) { - // let's fast calculate the size - final BigInteger fromNum = new BigInteger(from.toString()); - final BigInteger toNum = new BigInteger(to.toString()); - final BigInteger sizeNum = toNum.subtract(fromNum).add(new BigInteger("1")); - tempsize = sizeNum.intValue(); - if (!BigInteger.valueOf(tempsize).equals(sizeNum)) { - tempsize = Integer.MAX_VALUE; - } - } else if (from instanceof Character && to instanceof Character) { - // let's fast calculate the size - final char fromNum = (Character) from; - final char toNum = (Character) to; - tempsize = toNum - fromNum + 1; - } else if (((from instanceof BigDecimal || from instanceof BigInteger) && to instanceof Number) || - ((to instanceof BigDecimal || to instanceof BigInteger) && from instanceof Number)) { - // let's fast calculate the size - final BigDecimal fromNum = new BigDecimal(from.toString()); - final BigDecimal toNum = new BigDecimal(to.toString()); - final BigInteger sizeNum = toNum.subtract(fromNum).add(new BigDecimal(1.0)).toBigInteger(); - tempsize = sizeNum.intValue(); - if (!BigInteger.valueOf(tempsize).equals(sizeNum)) { - tempsize = Integer.MAX_VALUE; - } - } else { - // let's brute-force calculate the size by iterating start to end - final Iterator iter = new StepIterator(this, 1); - while (iter.hasNext()) { - tempsize++; - // integer overflow - if (tempsize < 0) { - break; - } - iter.next(); - } - } - // integer overflow - if (tempsize < 0) { - tempsize = Integer.MAX_VALUE; - } - size = tempsize; - } - return size; - } - - @Override - public List subList(int fromIndex, int toIndex) { - if (fromIndex < 0) { - throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); - } - if (fromIndex > toIndex) { - throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); - } - if (fromIndex == toIndex) { - return new EmptyRange(from); - } - - // Performance detail: - // not using get(fromIndex), get(toIndex) in the following to avoid stepping over elements twice - final Iterator iter = new StepIterator(this, 1); - - Comparable toValue = iter.next(); - int i = 0; - for (; i < fromIndex; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + i + " is too big for range: " + this); - } - toValue = iter.next(); - } - final Comparable fromValue = toValue; - for (; i < toIndex - 1; i++) { - if (!iter.hasNext()) { - throw new IndexOutOfBoundsException("Index: " + i + " is too big for range: " + this); - } - toValue = iter.next(); - } - - return new ObjectRange(fromValue, toValue, reverse); - } - - public String toString() { - return reverse ? "" + to + ".." + from : "" + from + ".." + to; - } - - @Override - public String inspect() { - final String toText = InvokerHelper.inspect(to); - final String fromText = InvokerHelper.inspect(from); - return reverse ? "" + toText + ".." + fromText : "" + fromText + ".." + toText; - } - - /** - * Iterates over all values and returns true if one value matches. - * - * @see #containsWithinBounds(Object) - */ - @Override - public boolean contains(Object value) { - final Iterator iter = new StepIterator(this, 1); - if (value == null) { - return false; - } - while (iter.hasNext()) { - if (DefaultTypeTransformation.compareEqual(value, iter.next())) return true; - } - return false; - } - - @Override - public void step(int step, Closure closure) { - if (step == 0 && compareTo(from, to) == 0) { - return; // from == to and step == 0, nothing to do, so return - } - final Iterator iter = new StepIterator(this, step); - while (iter.hasNext()) { - closure.call(iter.next()); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Iterator iterator() { - // non thread-safe iterator - return new StepIterator(this, 1); - } - - /** - * Non-thread-safe iterator which lazily produces the next element only on calls of hasNext() or next() - */ - private static final class StepIterator implements Iterator { - // actual step, can be +1 when desired step is -1 and direction is from high to low - private final int step; - private final ObjectRange range; - private int index = -1; - private Comparable value; - private boolean nextFetched = true; - - private StepIterator(ObjectRange range, final int desiredStep) { - if (desiredStep == 0 && range.compareTo(range.getFrom(), range.getTo()) != 0) { - throw new GroovyRuntimeException("Infinite loop detected due to step size of 0"); - } - this.range = range; - if (range.isReverse()) { - step = -desiredStep; - } else { - step = desiredStep; - } - if (step > 0) { - value = range.getFrom(); - } else { - value = range.getTo(); - } - } - - @Override - public void remove() { - range.remove(index); - } - - @Override - public Comparable next() { - // not thread safe - if (!hasNext()) { - throw new NoSuchElementException(); - } - nextFetched = false; - index++; - return value; - } - - @Override - public boolean hasNext() { - // not thread safe - if (!nextFetched) { - value = peek(); - nextFetched = true; - } - return value != null; - } - - private Comparable peek() { - if (step > 0) { - Comparable peekValue = value; - for (int i = 0; i < step; i++) { - peekValue = (Comparable) range.increment(peekValue); - // handle back to beginning due to modulo incrementing - if (range.compareTo(peekValue, range.from) <= 0) return null; - } - if (range.compareTo(peekValue, range.to) <= 0) { - return peekValue; - } - } else { - final int positiveStep = -step; - Comparable peekValue = value; - for (int i = 0; i < positiveStep; i++) { - peekValue = (Comparable) range.decrement(peekValue); - // handle back to beginning due to modulo decrementing - if (range.compareTo(peekValue, range.to) >= 0) return null; - } - if (range.compareTo(peekValue, range.from) >= 0) { - return peekValue; - } - } - return null; - } - } - - @Override - public List step(int step) { - final IteratorClosureAdapter adapter = new IteratorClosureAdapter(this); - step(step, adapter); - return adapter.asList(); - } - - /** - * Increments by one - * - * @param value the value to increment - * @return the incremented value - */ - protected Object increment(Object value) { - return InvokerHelper.invokeMethod(value, "next", null); - } - - /** - * Decrements by one - * - * @param value the value to decrement - * @return the decremented value - */ - protected Object decrement(Object value) { - return InvokerHelper.invokeMethod(value, "previous", null); - } - - /** - * if operand is a Character or a String with one character, return that character's int value. - */ - private static Comparable normaliseStringType(final Comparable operand) { - if (operand instanceof Character) { - return (int) (Character) operand; - } - if (operand instanceof String) { - final String string = (String) operand; - - if (string.length() == 1) { - return (int) string.charAt(0); - } - return string; - } - return operand; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/ParameterArray.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ParameterArray.java b/src/main/groovy/lang/ParameterArray.java deleted file mode 100644 index d3a4163..0000000 --- a/src/main/groovy/lang/ParameterArray.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - * Distinguish a parameter array from Object[]. - * - * @author Pilho Kim - */ -public class ParameterArray { - - private final Object parameters; - - public ParameterArray(Object data) { - parameters = packArray(data); - } - - private static Object packArray(Object object) { - if (object instanceof Object[]) - return (Object[]) object; - else - return object; - } - - public Object get() { - return parameters; - } - - public String toString() { - if (parameters == null) - return ""; - return parameters.toString(); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/PropertyAccessInterceptor.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/PropertyAccessInterceptor.java b/src/main/groovy/lang/PropertyAccessInterceptor.java deleted file mode 100644 index 6d2906e..0000000 --- a/src/main/groovy/lang/PropertyAccessInterceptor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - *

An interface that adds the ability to intercept - * property getters/setters - * - * @author Graeme Rocher - * @since Oct 24, 2005 - */ -public interface PropertyAccessInterceptor extends Interceptor { - - /** - * Intercepts a getXXX call and returns a result. The result is replaced by the - * real value if doGet() return false - * - * @param object The target object - * @param property The property to get - * @return A value supplied by the interceptor - */ - Object beforeGet(Object object, String property); - - /** - * Intercepts a setXXX call - * - * @param object The target object - * @param property The property to set - * @param newValue The new value - */ - void beforeSet(Object object, String property, Object newValue); - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/PropertyValue.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/PropertyValue.java b/src/main/groovy/lang/PropertyValue.java deleted file mode 100644 index ac77b54..0000000 --- a/src/main/groovy/lang/PropertyValue.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -public class PropertyValue { - // the owner of the property - private final Object bean; - - // the description of the property - private final MetaProperty mp; - - public PropertyValue(Object bean, MetaProperty mp) { - this.bean = bean; - this.mp = mp; - } - - public String getName() { - return mp.getName(); - } - - public Class getType() { - return mp.getType(); - } - - public Object getValue() { - return mp.getProperty(bean); - } - - public void setValue(Object value) { - mp.setProperty(bean, value); - } -} - http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/ProxyMetaClass.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ProxyMetaClass.java b/src/main/groovy/lang/ProxyMetaClass.java deleted file mode 100644 index 8c41f7d..0000000 --- a/src/main/groovy/lang/ProxyMetaClass.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - * As subclass of MetaClass, ProxyMetaClass manages calls from Groovy Objects to POJOs. - * It enriches MetaClass with the feature of making method invocations interceptable by - * an Interceptor. To this end, it acts as a decorator (decorator pattern) allowing - * to add or withdraw this feature at runtime. - * See groovy/lang/InterceptorTest.groovy for details. - *

- * WARNING: This implementation of ProxyMetaClass is NOT thread-safe and hence should only be used for - * as a per-instance MetaClass running in a single thread. Do not place this MetaClass in the MetaClassRegistry - * as it will result in unpredictable behaviour - * - * @author Dierk Koenig - * @author Graeme Rocher - * @see groovy.lang.MetaClassRegistry - */ -public class ProxyMetaClass extends MetaClassImpl implements AdaptingMetaClass { - - protected MetaClass adaptee = null; - protected Interceptor interceptor = null; - - - /** - * convenience factory method for the most usual case. - */ - public static ProxyMetaClass getInstance(Class theClass) { - MetaClassRegistry metaRegistry = GroovySystem.getMetaClassRegistry(); - MetaClass meta = metaRegistry.getMetaClass(theClass); - return new ProxyMetaClass(metaRegistry, theClass, meta); - } - - /** - * @param adaptee the MetaClass to decorate with interceptability - */ - public ProxyMetaClass(MetaClassRegistry registry, Class theClass, MetaClass adaptee) { - super(registry, theClass); - this.adaptee = adaptee; - if (null == adaptee) throw new IllegalArgumentException("adaptee must not be null"); - super.initialize(); - } - - public synchronized void initialize() { - this.adaptee.initialize(); - } - - /** - * Use the ProxyMetaClass for the given Closure. - * Cares for balanced register/unregister. - * - * @param closure piece of code to be executed with registered ProxyMetaClass - */ - public Object use(Closure closure) { - // grab existing meta (usually adaptee but we may have nested use calls) - MetaClass origMetaClass = registry.getMetaClass(theClass); - registry.setMetaClass(theClass, this); - try { - return closure.call(); - } finally { - registry.setMetaClass(theClass, origMetaClass); - } - } - - /** - * Use the ProxyMetaClass for the given Closure. - * Cares for balanced setting/unsetting ProxyMetaClass. - * - * @param closure piece of code to be executed with ProxyMetaClass - */ - public Object use(GroovyObject object, Closure closure) { - // grab existing meta (usually adaptee but we may have nested use calls) - MetaClass origMetaClass = object.getMetaClass(); - object.setMetaClass(this); - try { - return closure.call(); - } finally { - object.setMetaClass(origMetaClass); - } - } - - /** - * @return the interceptor in use or null if no interceptor is used - */ - public Interceptor getInterceptor() { - return interceptor; - } - - /** - * @param interceptor may be null to reset any interception - */ - public void setInterceptor(Interceptor interceptor) { - this.interceptor = interceptor; - } - - /** - * Call invokeMethod on adaptee with logic like in MetaClass unless we have an Interceptor. - * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods. - * The method call is suppressed if Interceptor.doInvoke() returns false. - * See Interceptor for details. - */ - public Object invokeMethod(final Object object, final String methodName, final Object[] arguments) { - return doCall(object, methodName, arguments, interceptor, new Callable() { - public Object call() { - return adaptee.invokeMethod(object, methodName, arguments); - } - }); - } - - /** - * Call invokeMethod on adaptee with logic like in MetaClass unless we have an Interceptor. - * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods. - * The method call is suppressed if Interceptor.doInvoke() returns false. - * See Interceptor for details. - */ - @Override - public Object invokeMethod(final Class sender, final Object object, final String methodName, final Object[] arguments, final boolean isCallToSuper, final boolean fromInsideClass) { - return doCall(object, methodName, arguments, interceptor, new Callable() { - public Object call() { - return adaptee.invokeMethod(sender, object, methodName, arguments, isCallToSuper, fromInsideClass); - } - }); - } - - /** - * Call invokeStaticMethod on adaptee with logic like in MetaClass unless we have an Interceptor. - * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods. - * The method call is suppressed if Interceptor.doInvoke() returns false. - * See Interceptor for details. - */ - public Object invokeStaticMethod(final Object object, final String methodName, final Object[] arguments) { - return doCall(object, methodName, arguments, interceptor, new Callable() { - public Object call() { - return adaptee.invokeStaticMethod(object, methodName, arguments); - } - }); - } - - /** - * Call invokeConstructor on adaptee with logic like in MetaClass unless we have an Interceptor. - * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods. - * The method call is suppressed if Interceptor.doInvoke() returns false. - * See Interceptor for details. - */ - public Object invokeConstructor(final Object[] arguments) { - return doCall(theClass, "ctor", arguments, interceptor, new Callable() { - public Object call() { - return adaptee.invokeConstructor(arguments); - } - }); - } - - /** - * Interceptors the call to getProperty if a PropertyAccessInterceptor is - * available - * - * @param object the object to invoke the getter on - * @param property the property name - * @return the value of the property - */ - public Object getProperty(Class aClass, Object object, String property, boolean b, boolean b1) { - if (null == interceptor) { - return super.getProperty(aClass, object, property, b, b1); - } - if (interceptor instanceof PropertyAccessInterceptor) { - PropertyAccessInterceptor pae = (PropertyAccessInterceptor) interceptor; - - Object result = pae.beforeGet(object, property); - if (interceptor.doInvoke()) { - result = super.getProperty(aClass, object, property, b, b1); - } - return result; - } - return super.getProperty(aClass, object, property, b, b1); - } - - /** - * Interceptors the call to a property setter if a PropertyAccessInterceptor - * is available - * - * @param object The object to invoke the setter on - * @param property The property name to set - * @param newValue The new value of the property - */ - public void setProperty(Class aClass, Object object, String property, Object newValue, boolean b, boolean b1) { - if (null == interceptor) { - super.setProperty(aClass, object, property, newValue, b, b1); - } - if (interceptor instanceof PropertyAccessInterceptor) { - PropertyAccessInterceptor pae = (PropertyAccessInterceptor) interceptor; - - pae.beforeSet(object, property, newValue); - if (interceptor.doInvoke()) { - super.setProperty(aClass, object, property, newValue, b, b1); - } - } else { - super.setProperty(aClass, object, property, newValue, b, b1); - } - } - - public MetaClass getAdaptee() { - return this.adaptee; - } - - public void setAdaptee(MetaClass metaClass) { - this.adaptee = metaClass; - } - - // since Java has no Closures... - private interface Callable { - Object call(); - } - - private Object doCall(Object object, String methodName, Object[] arguments, Interceptor interceptor, Callable howToInvoke) { - if (null == interceptor) { - return howToInvoke.call(); - } - Object result = interceptor.beforeInvoke(object, methodName, arguments); - if (interceptor.doInvoke()) { - result = howToInvoke.call(); - } - result = interceptor.afterInvoke(object, methodName, arguments, result); - return result; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/Range.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Range.java b/src/main/groovy/lang/Range.java deleted file mode 100644 index 99f30de..0000000 --- a/src/main/groovy/lang/Range.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import java.util.List; - -/** - * A Range represents the list of discrete items between some starting (or from) - * value and working up towards some ending (or to) value. - * For a reverse range, the list is obtained by starting at the to value and - * working down towards the from value. - * - * The concept of working up and working down is dependent on the range implementation. - * In the general case, working up involves successive calls to the first item's next() - * method while working down involves calling the previous() method. Optimized - * numerical ranges may apply numeric addition or subtraction of some numerical step size. - * - * Particular range implementations may also support the notion of inclusivity - * and exclusivity with respect to the ending value in the range. - * E.g. 1..3 == [1, 2, 3]; but 1..<3 == [1, 2]. - * - * In general, the second boundary may not be contained in the range, - * and a..b may produce a different set of elements than (b..a).reversed(). - * E.g. 1..2.5 == [1, 2]; but 2.5..1 == [2.5, 1.5]. - * - * Implementations can be memory efficient by storing just the from and to boundary - * values rather than eagerly creating all discrete items in the conceptual list. The actual discrete items - * can be lazily calculated on an as needed basis (e.g. when calling methods from the java.util.List - * interface or the additional step methods in the Range interface). - * - * In addition to the methods related to a Range's "discrete items" abstraction, there is a method, - * containsWithinBounds which, for numerical ranges, allows checking within the continuous - * interval between the Range's boundary values. - */ -public interface Range extends List { - /** - * The lower value in the range. - * - * @return the lower value in the range. - */ - T getFrom(); - - /** - * The upper value in the range. - * - * @return the upper value in the range - */ - T getTo(); - - /** - * Indicates whether this is a reverse range which iterates backwards - * starting from the to value and ending on the from value - * - * @return true if this is a reverse range - */ - boolean isReverse(); - - /** - * Indicates whether an object is greater than or equal to the from - * value for the range and less than or equal to the to value. - *

- * This may be true even for values not contained in the range. - * - * Example: from = 1.5, to = 3, next() increments by 1 - * containsWithinBounds(2) == true - * contains(2) == false - * - * @param o the object to check against the boundaries of the range - * @return true if the object is between the from and to values - */ - boolean containsWithinBounds(Object o); - - /** - * Steps through the range, calling a closure for each item. - * - * @param step the amount by which to step. If negative, steps through the range backwards. - * @param closure the {@link Closure} to call - */ - void step(int step, Closure closure); - - /** - * Forms a list by stepping through the range by the indicated interval. - * - * @param step the amount by which to step. If negative, steps through the range backwards. - * @return the list formed by stepping through the range by the indicated interval. - */ - List step(int step); - - /** - * @return the verbose {@link String} representation of this {@link Range} as would be typed into a console to create the {@link Range} instance - */ - String inspect(); -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/ReadOnlyPropertyException.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ReadOnlyPropertyException.java b/src/main/groovy/lang/ReadOnlyPropertyException.java deleted file mode 100644 index 342a182..0000000 --- a/src/main/groovy/lang/ReadOnlyPropertyException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - - -/** - * This exception is thrown if an attempt is made to set a read only property - * - * @author James Strachan - */ -public class ReadOnlyPropertyException extends MissingPropertyException { - - public ReadOnlyPropertyException(final String property, final Class type) { - super("Cannot set readonly property: " + property + " for class: " + type.getName(), property, type); - } - - public ReadOnlyPropertyException(final String property, final String classname) { - super("Cannot set readonly property: " + property + " for class: " + classname); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/Reference.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Reference.java b/src/main/groovy/lang/Reference.java deleted file mode 100644 index c4bf21d..0000000 --- a/src/main/groovy/lang/Reference.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.runtime.InvokerHelper; - -import java.io.Serializable; - -/** - * Represents a reference to a value - * - * @author James Strachan - */ -public class Reference extends GroovyObjectSupport implements Serializable { - - private static final long serialVersionUID = 4963704631487573488L; - private T value; - - public Reference() { - } - - public Reference(T value) { - this.value = value; - } - - public Object getProperty(String property) { - Object value = get(); - if (value != null) { - return InvokerHelper.getProperty(value, property); - } - return super.getProperty(property); - } - - public void setProperty(String property, Object newValue) { - Object value = get(); - if (value != null) { - InvokerHelper.setProperty(value, property, newValue); - } - else { - super.setProperty(property, newValue); - } - } - - public Object invokeMethod(String name, Object args) { - Object value = get(); - if (value != null) { - try { - return InvokerHelper.invokeMethod(value, name, args); - } - catch (Exception e) { - return super.invokeMethod(name, args); - } - } - else { - return super.invokeMethod(name, args); - } - } - - public T get() { - return value; - } - - public void set(T value) { - this.value = value; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/Script.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Script.java b/src/main/groovy/lang/Script.java deleted file mode 100644 index 196c74c..0000000 --- a/src/main/groovy/lang/Script.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.runtime.DefaultGroovyMethods; -import org.codehaus.groovy.runtime.InvokerHelper; - -import java.io.File; -import java.io.IOException; - -/** - * This object represents a Groovy script - * - * @author James Strachan - * @author Guillaume Laforge - */ -public abstract class Script extends GroovyObjectSupport { - private Binding binding; - - protected Script() { - this(new Binding()); - } - - protected Script(Binding binding) { - this.binding = binding; - } - - public Binding getBinding() { - return binding; - } - - public void setBinding(Binding binding) { - this.binding = binding; - } - - public Object getProperty(String property) { - try { - return binding.getVariable(property); - } catch (MissingPropertyException e) { - return super.getProperty(property); - } - } - - public void setProperty(String property, Object newValue) { - if ("binding".equals(property)) - setBinding((Binding) newValue); - else if("metaClass".equals(property)) - setMetaClass((MetaClass)newValue); - else - binding.setVariable(property, newValue); - } - - /** - * Invoke a method (or closure in the binding) defined. - * - * @param name method to call - * @param args arguments to pass to the method - * @return value - */ - public Object invokeMethod(String name, Object args) { - try { - return super.invokeMethod(name, args); - } - // if the method was not found in the current scope (the script's methods) - // let's try to see if there's a method closure with the same name in the binding - catch (MissingMethodException mme) { - try { - if (name.equals(mme.getMethod())) { - Object boundClosure = getProperty(name); - if (boundClosure != null && boundClosure instanceof Closure) { - return ((Closure) boundClosure).call((Object[])args); - } else { - throw mme; - } - } else { - throw mme; - } - } catch (MissingPropertyException mpe) { - throw mme; - } - } - } - - /** - * The main instance method of a script which has variables in scope - * as defined by the current {@link Binding} instance. - */ - public abstract Object run(); - - // println helper methods - - /** - * Prints a newline to the current 'out' variable which should be a PrintWriter - * or at least have a println() method defined on it. - * If there is no 'out' property then print to standard out. - */ - public void println() { - Object object; - - try { - object = getProperty("out"); - } catch (MissingPropertyException e) { - System.out.println(); - return; - } - - InvokerHelper.invokeMethod(object, "println", ArgumentListExpression.EMPTY_ARRAY); - } - - /** - * Prints the value to the current 'out' variable which should be a PrintWriter - * or at least have a print() method defined on it. - * If there is no 'out' property then print to standard out. - */ - public void print(Object value) { - Object object; - - try { - object = getProperty("out"); - } catch (MissingPropertyException e) { - DefaultGroovyMethods.print(System.out,value); - return; - } - - InvokerHelper.invokeMethod(object, "print", new Object[]{value}); - } - - /** - * Prints the value and a newline to the current 'out' variable which should be a PrintWriter - * or at least have a println() method defined on it. - * If there is no 'out' property then print to standard out. - */ - public void println(Object value) { - Object object; - - try { - object = getProperty("out"); - } catch (MissingPropertyException e) { - DefaultGroovyMethods.println(System.out,value); - return; - } - - InvokerHelper.invokeMethod(object, "println", new Object[]{value}); - } - - /** - * Prints a formatted string using the specified format string and argument. - * - * @param format the format to follow - * @param value the value to be formatted - */ - public void printf(String format, Object value) { - Object object; - - try { - object = getProperty("out"); - } catch (MissingPropertyException e) { - DefaultGroovyMethods.printf(System.out, format, value); - return; - } - - InvokerHelper.invokeMethod(object, "printf", new Object[] { format, value }); - } - - /** - * Prints a formatted string using the specified format string and arguments. - * - * @param format the format to follow - * @param values an array of values to be formatted - */ - public void printf(String format, Object[] values) { - Object object; - - try { - object = getProperty("out"); - } catch (MissingPropertyException e) { - DefaultGroovyMethods.printf(System.out, format, values); - return; - } - - InvokerHelper.invokeMethod(object, "printf", new Object[] { format, values }); - } - - /** - * A helper method to allow the dynamic evaluation of groovy expressions using this - * scripts binding as the variable scope - * - * @param expression is the Groovy script expression to evaluate - */ - public Object evaluate(String expression) throws CompilationFailedException { - GroovyShell shell = new GroovyShell(getClass().getClassLoader(), binding); - return shell.evaluate(expression); - } - - /** - * A helper method to allow the dynamic evaluation of groovy expressions using this - * scripts binding as the variable scope - * - * @param file is the Groovy script to evaluate - */ - public Object evaluate(File file) throws CompilationFailedException, IOException { - GroovyShell shell = new GroovyShell(getClass().getClassLoader(), binding); - return shell.evaluate(file); - } - - /** - * A helper method to allow scripts to be run taking command line arguments - */ - public void run(File file, String[] arguments) throws CompilationFailedException, IOException { - GroovyShell shell = new GroovyShell(getClass().getClassLoader(), binding); - shell.run(file, arguments); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/Sequence.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Sequence.java b/src/main/groovy/lang/Sequence.java deleted file mode 100644 index 2b4316c..0000000 --- a/src/main/groovy/lang/Sequence.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -/** - * Represents a sequence of objects which represents zero or many instances of - * of objects of a given type. The type can be omitted in which case any type of - * object can be added. - * - * @author James Strachan - */ -public class Sequence extends ArrayList implements GroovyObject { - - private MetaClass metaClass = InvokerHelper.getMetaClass(getClass()); - private final Class type; - private int hashCode; - - public Sequence() { - this(null); - } - - public Sequence(Class type) { - this.type = type; - } - - public Sequence(Class type, List content) { - super(content.size()); - this.type = type; - addAll(content); - } - - /** - * Sets the contents of this sequence to that - * of the given collection. - */ - public void set(Collection collection) { - checkCollectionType(collection); - clear(); - addAll(collection); - } - - public boolean equals(Object that) { - if (that instanceof Sequence) { - return equals((Sequence) that); - } - return false; - } - - public boolean equals(Sequence that) { - if (size() == that.size()) { - for (int i = 0; i < size(); i++) { - if (!DefaultTypeTransformation.compareEqual(this.get(i), that.get(i))) { - return false; - } - } - return true; - } - return false; - } - - public int hashCode() { - if (hashCode == 0) { - for (int i = 0; i < size(); i++) { - Object value = get(i); - int hash = (value != null) ? value.hashCode() : 0xbabe; - hashCode ^= hash; - } - if (hashCode == 0) { - hashCode = 0xbabe; - } - } - return hashCode; - } - - public int minimumSize() { - return 0; - } - - /** - * @return the type of the elements in the sequence or null if there is no - * type constraint on this sequence - */ - public Class type() { - return type; - } - - public void add(int index, Object element) { - checkType(element); - hashCode = 0; - super.add(index, element); - } - - public boolean add(Object element) { - checkType(element); - hashCode = 0; - return super.add(element); - } - - public boolean addAll(Collection c) { - checkCollectionType(c); - hashCode = 0; - return super.addAll(c); - } - - public boolean addAll(int index, Collection c) { - checkCollectionType(c); - hashCode = 0; - return super.addAll(index, c); - } - - public void clear() { - hashCode = 0; - super.clear(); - } - - public Object remove(int index) { - hashCode = 0; - return super.remove(index); - } - - protected void removeRange(int fromIndex, int toIndex) { - hashCode = 0; - super.removeRange(fromIndex, toIndex); - } - - public Object set(int index, Object element) { - hashCode = 0; - return super.set(index, element); - } - - // GroovyObject interface - //------------------------------------------------------------------------- - public Object invokeMethod(String name, Object args) { - try { - return getMetaClass().invokeMethod(this, name, args); - } - catch (MissingMethodException e) { - // lets apply the method to each item in the collection - List answer = new ArrayList(size()); - for (Iterator iter = iterator(); iter.hasNext(); ) { - Object element = iter.next(); - Object value = InvokerHelper.invokeMethod(element, name, args); - answer.add(value); - } - return answer; - } - } - - public Object getProperty(String property) { - return getMetaClass().getProperty(this, property); - } - - public void setProperty(String property, Object newValue) { - getMetaClass().setProperty(this, property, newValue); - } - - public MetaClass getMetaClass() { - return metaClass; - } - - public void setMetaClass(MetaClass metaClass) { - this.metaClass = metaClass; - } - - // Implementation methods - //------------------------------------------------------------------------- - - /** - * Checks that each member of the given collection are of the correct - * type - */ - protected void checkCollectionType(Collection c) { - if (type != null) { - for (Iterator iter = c.iterator(); iter.hasNext(); ) { - Object element = iter.next(); - checkType(element); - } - } - } - - - /** - * Checks that the given object instance is of the correct type - * otherwise a runtime exception is thrown - */ - protected void checkType(Object object) { - if (object == null) { - throw new NullPointerException("Sequences cannot contain null, use a List instead"); - } - if (type != null) { - if (!type.isInstance(object)) { - throw new IllegalArgumentException( - "Invalid type of argument for sequence of type: " - + type.getName() - + " cannot add object: " - + object); - } - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/lang/Singleton.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Singleton.java b/src/main/groovy/lang/Singleton.java deleted file mode 100644 index c1aabf6..0000000 --- a/src/main/groovy/lang/Singleton.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.transform.GroovyASTTransformationClass; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Class annotation to make a singleton class. The singleton is obtained through normal property access using the singleton property (defaults to "instance"). - * - * Such classes can be initialized during normal static initialization of the class or lazily (on first access). - * To make the singleton lazy use {@code @Singleton(lazy=true)}. - * Lazy singletons are implemented with double-checked locking and a volatile backing field. - * By default, no explicit constructors are allowed. To create one or more explicit constructors - * use {@code @Singleton(strict=false)}. - * This could be used to: - *

    - *
  • provide your own custom initialization logic in your own no-arg constructor - you - * will be responsible for the entire code (the {@code @Singleton} annotation becomes merely documentation)
  • - *
  • provide one or more constructors with arguments for a quasi-singleton - these constructors will be used - * to create instances that are independent of the singleton instance returned by the singleton property
  • - *
- * - * @author Alex Tkachman - * @author Paul King - */ -@java.lang.annotation.Documented -@Retention(RetentionPolicy.SOURCE) -@Target({ElementType.TYPE}) -@GroovyASTTransformationClass("org.codehaus.groovy.transform.SingletonASTTransformation") -public @interface Singleton { - /** - * @return if this singleton should be lazy - */ - boolean lazy() default false; - - /** - * @return if this singleton should have strict semantics - */ - boolean strict() default true; - - /** - * @return the singleton property name - */ - String property() default "instance"; -}