001    package org.fest.util;
002    
003    /*
004     * Created on Sep 17, 2010
005     * 
006     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
012     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
013     * specific language governing permissions and limitations under the License.
014     * 
015     * Copyright @2010-2011 the original author or authors.
016     */
017    
018    import static java.lang.String.format;
019    
020    import java.util.Iterator;
021    
022    /**
023     * Implements {@link ComparisonStrategy} contract with a comparison strategy based on {@link Object#equals(Object)}
024     * method, it is also based on {@link Comparable#compareTo(Object)} when Object are {@link Comparable} method.
025     * 
026     * @author Joel Costigliola
027     */
028    public class StandardComparisonStrategy extends AbstractComparisonStrategy {
029    
030      private static final StandardComparisonStrategy INSTANCE = new StandardComparisonStrategy();
031    
032      /**
033       * Returns the singleton instance of this class.
034       * @return the singleton instance of this class.
035       */
036      public static StandardComparisonStrategy instance() {
037        return INSTANCE;
038      }
039    
040      /**
041       * Creates a new </code>{@link StandardComparisonStrategy}</code>, comparison strategy being based on
042       * {@link Object#equals(Object)}.
043       */
044      private StandardComparisonStrategy() {}
045    
046      /**
047       * Returns true if actual and other are equal based on {@link Object#equals(Object)}, false otherwise.
048       * 
049       * @param actual the object to compare to other
050       * @param other the object to compare to actual
051       * @return true if actual and other are equal based on {@link Object#equals(Object)}, false otherwise.
052       */
053      public boolean areEqual(Object actual, Object other) {
054        return Objects.areEqual(actual, other);
055      }
056    
057      /**
058       * Returns true if given {@link Iterable} contains given value based on {@link Object#equals(Object)}, false
059       * otherwise.<br>
060       * If given {@link Iterable} is null, return false.
061       * 
062       * @param iterable the {@link Iterable} to search value in
063       * @param value the object to look for in given {@link Iterable}
064       * @return true if given {@link Iterable} contains given value based on {@link Object#equals(Object)}, false
065       *         otherwise.
066       */
067      public boolean iterableContains(Iterable<?> iterable, Object value) {
068        if (iterable == null) return false;
069        for (Object next : iterable) {
070          // handle same or null element/value
071          if (next == value) return true;
072          // both objects are not null => if one is then the other is not => compare next element with value
073          if (value == null || next == null) continue;
074          if (next.equals(value)) return true;
075        }
076        return false;
077      }
078    
079      /**
080       * {@inheritDoc}
081       */
082      public void iterableRemoves(Iterable<?> iterable, Object value) {
083        if (iterable == null) return;
084        Iterator<?> iterator = iterable.iterator();
085        while (iterator.hasNext()) {
086          if (iterator.next().equals(value)) {
087            iterator.remove();
088          }
089        }
090      }
091    
092      /**
093       * Returns any duplicate elements from the given collection according to {@link Object#equals(Object)} comparison
094       * strategy.
095       * 
096       * @param iterable the given {@link Iterable} we want to extract duplicate elements.
097       * @return an {@link Iterable} containing the duplicate elements of the given one. If no duplicates are found, an
098       *         empty {@link Iterable} is returned.
099       */
100      // overridden to write javadoc.
101      @Override
102      public Iterable<?> duplicatesFrom(Iterable<?> iterable) {
103        return super.duplicatesFrom(iterable);
104      }
105    
106      public boolean stringStartsWith(String string, String prefix) {
107        return string.startsWith(prefix);
108      }
109    
110      public boolean stringEndsWith(String string, String suffix) {
111        return string.endsWith(suffix);
112      }
113    
114      public boolean stringContains(String string, String sequence) {
115        return string.contains(sequence);
116      }
117    
118      @SuppressWarnings({ "unchecked", "rawtypes" })
119      public boolean isGreaterThan(Object actual, Object other) {
120        if (!Comparable.class.isAssignableFrom(actual.getClass()))
121          throw new IllegalArgumentException(format("argument '%s' should be Comparable but is not", actual));
122        if (!Comparable.class.isAssignableFrom(other.getClass()))
123          throw new IllegalArgumentException(format("argument '%s' should be Comparable but is not", other));
124        Comparable comparableActual = (Comparable) actual;
125        Comparable comparableOther = (Comparable) other;
126        return comparableActual.compareTo(comparableOther) > 0;
127      }
128    
129    }