You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by an...@apache.org on 2012/03/13 04:53:37 UTC
svn commit: r1299970 -
/myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java
Author: andys
Date: Tue Mar 13 03:53:36 2012
New Revision: 1299970
URL: http://svn.apache.org/viewvc?rev=1299970&view=rev
Log:
Checkpoint: introduce new immutable Range API to replace lame (mutable) internal Range class. (For real this time. Sorry about the commit spam.)
Added:
myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java
Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java?rev=1299970&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/Range.java Tue Mar 13 03:53:36 2012
@@ -0,0 +1,228 @@
+/*
+ * 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 org.apache.myfaces.trinidad.util;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * Represents a range of comparable values with a specific start and end.
+ *
+ * Range instances are constructed using the of() factory method.
+ *
+ * Range instances are immutable.
+ */
+public final class Range<C extends Comparable>
+{
+ /**
+ * Returns a new range consisting of the specified start and end points.
+ *
+ * If start > end, an empty range is returned.
+ *
+ * @throws IllegalArgumentException if start or end is null
+ */
+ public static <C extends Comparable> Range<C> of(C start, C end)
+ {
+ _checkNull("start", start);
+ _checkNull("end", end);
+
+ if (start.compareTo(end) > 0)
+ {
+ return emptyRange();
+ }
+
+ return new Range<C>(start, end);
+ }
+
+ /**
+ * Returns an empty range.
+ */
+ public static <C extends Comparable> Range<C> emptyRange()
+ {
+ return (Range<C>)_EMPTY_RANGE;
+ }
+
+ /**
+ * Returns the start of the range.
+ */
+ public C getStart()
+ {
+ return _start;
+ }
+
+ /**
+ * Returns the end of the range.
+ */
+ public C getEnd()
+ {
+ return _end;
+ }
+
+ /**
+ * Tests whether this range is empty.
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ // Both start and end are null in the empty range (and
+ // non-null in all other ranges).
+ if (_start == null)
+ {
+ assert(_end == null);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Tests whether the specified value is contained within this range.
+ * @param value the value to test
+ * @return true if the value is within this range, false otherwise.
+ */
+ public boolean contains(C value)
+ {
+ if (isEmpty())
+ {
+ return false;
+ }
+
+ return (_start.compareTo(value) <= 0) && (_end.compareTo(value) >= 0);
+ }
+
+ /**
+ * Computes the intersection of the this range with another range
+ * and returns the result in a new Range.
+ *
+ * If there is no intersection between the two ranges, the empty
+ * range (EMPTY_RANGE) is returned.
+ *
+ * @param otherRange the (non-null) range to intersect/update
+ */
+ public Range<C> intersect(Range<C> otherRange)
+ {
+ _checkNull("otherRange", otherRange);
+
+ if (isEmpty() || (otherRange.isEmpty()))
+ {
+ return emptyRange();
+ }
+
+ C start = _max(this.getStart(), otherRange.getStart());
+ C end = _min(this.getEnd(), otherRange.getEnd());
+
+ // start > end means there was no intersection
+ if (start.compareTo(end) > 0)
+ {
+ return emptyRange();
+ }
+
+ return new Range<C>(start, end);
+ }
+
+ private static <C extends Comparable> C _min(C c1, C c2)
+ {
+ return (c1.compareTo(c2) > 0 ? c2 : c1);
+ }
+
+ private static <C extends Comparable> C _max(C c1, C c2)
+ {
+ return (c1.compareTo(c2) < 0 ? c2 : c1);
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getName() + "[" + _start + " - " + _end + "]";
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o instanceof Range))
+ {
+ return false;
+ }
+
+ Range<C> otherRange = (Range<C>)o;
+
+ // Short-circuit to simplify subsequent equals comparisons.
+ if (isEmpty() || otherRange.isEmpty())
+ {
+ // Note: this assumes that empty ranges will be properly
+ // resolved to the _EMPTY_RANGE instance during deserialization.
+ // Which is something to keep in mind if we ever implement
+ // Serializable.
+ return (this == o);
+ }
+
+ return (getStart().equals(otherRange.getStart()) &&
+ getEnd().equals(otherRange.getEnd()));
+
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 17;
+
+ if (!isEmpty())
+ {
+ assert(_start != null);
+ assert(_end != null);
+
+ result = 31 * result + _start.hashCode();
+ result = 31 * result + _end.hashCode();
+ }
+
+ return result;
+ }
+
+ // Throws an IllegalArgumentException if the specified param value is null
+ private static <C extends Comparable> void _checkNull(String paramName, Object paramValue)
+ throws IllegalArgumentException
+ {
+ if (paramValue == null)
+ {
+ String message = _LOG.getMessage("ILLEGAL_NULL_VALUE", paramName);
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+ private Range(C start, C end)
+ {
+ _start = start;
+ _end = end;
+ }
+
+ private final C _start;
+ private final C _end;
+
+ // Note: if we decide to make Range implement Serializable, be sure
+ // that we properly handle deserialization to this singleton instance.
+ private static final Range<? extends Comparable> _EMPTY_RANGE =
+ new Range<Comparable>(null, null);
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(Range.class);
+}