All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onebusaway.collections.MappingLibrary Maven / Gradle / Ivy

/**
 * Copyright (C) 2011 Brian Ferris 
 *
 * Licensed 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.onebusaway.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A number of functional-programming-inspired convenience methods for mapping
 * one set of values to another.
 * 
 * @author bdferris
 * @see PropertyPathExpression
 */
public class MappingLibrary {

  /**
   * Iterate over a collection of values, evaluating a
   * {@link PropertyPathExpression} on each value, and constructing a
   * {@link List} from the expression results.
   * 
   * @param values an iterable collection of values to iterate over
   * @param propertyPathExpression a property path expression to evaluate
   *          against each collection value
   * @return a List composed of the property path expression evaluation results
   */
  @SuppressWarnings("unchecked")
  public static  List map(Iterable values,
      String propertyPathExpression) {
    List mappedValues = new ArrayList();
    PropertyPathExpression query = new PropertyPathExpression(
        propertyPathExpression);
    for (T1 value : values)
      mappedValues.add((T2) query.invoke(value));
    return mappedValues;
  }

  /**
   * This method is kept for backwards compatibility, and a more concise version
   * can be found in {@link #map(Iterable, String)}
   */
  public static  List map(Iterable values,
      String propertyPathExpression, Class resultType) {
    return map(values, propertyPathExpression);
  }

  /**
   * Construct a {@link Map} from a set of values where the key for each value
   * is the result from the evaluation of a {@link PropertyPathExpression} on
   * each value. If two values in the iterable collection have the same key,
   * subsequent values will overwrite previous values.
   * 
   * @param values an iterable collection of values to iterate over
   * @param propertyPathExpression a property path expression to evaluate
   *          against each collection value
   * @return a map with values from the specified collection and keys from the
   *         property path expression
   */
  @SuppressWarnings("unchecked")
  public static  Map mapToValue(Iterable values,
      String propertyPathExpression) {

    Map byKey = new HashMap();
    PropertyPathExpression query = new PropertyPathExpression(
        propertyPathExpression);

    for (V value : values) {
      K key = (K) query.invoke(value);
      byKey.put(key, value);
    }

    return byKey;
  }

  /**
   * This method is kept for backwards compatibility, and a more concise version
   * can be found in {@link #mapToValue(Iterable, String)}
   */
  public static  Map mapToValue(Iterable values,
      String property, Class keyType) {
    return mapToValue(values, property);
  }

  /**
   * Construct a {@link Map} from a set of values where the key for each value
   * is the result of the evaluation of a {@link PropertyPathExpression} on each
   * value. Each key maps to a {@link List} of values that all mapped to that
   * same key.
   * 
   * @param values an iterable collection of values to iterate over
   * @param propertyPathExpression a property path expression to evaluate
   *          against each collection value
   * @return a map with values from the specified collection and keys from the
   *         property path expression
   */
  @SuppressWarnings("unchecked")
  public static  Map> mapToValueList(Iterable values,
      String property) {
    return mapToValueCollection(values, property, new ArrayList().getClass());
  }

  /**
   * This method is kept for backwards compatibility, and a more concise version
   * can be found in {@link #mapToValueList(Iterable, String)}
   */
  @SuppressWarnings("unchecked")
  public static  Map> mapToValueList(Iterable values,
      String property, Class keyType) {
    return mapToValueCollection(values, property, new ArrayList().getClass());
  }

  /**
   * Construct a {@link Map} from a set of values where the key for each value
   * is the result of the evaluation of a {@link PropertyPathExpression} on each
   * value. Each key maps to a {@link Set} of values that all mapped to that
   * same key.
   * 
   * @param values an iterable collection of values to iterate over
   * @param propertyPathExpression a property path expression to evaluate
   *          against each collection value
   * @return a map with values from the specified collection and keys from the
   *         property path expression
   */

  @SuppressWarnings("unchecked")
  public static  Map> mapToValueSet(Iterable values,
      String property) {
    return mapToValueCollection(values, property, new HashSet().getClass());
  }

  /**
   * Construct a {@link Map} from a set of values where the key for each value
   * is the result of the evaluation of a {@link PropertyPathExpression} on each
   * value. Each key maps to a collection of values that all mapped to that same
   * key. The collection type must have a no-arg constructor that can be used to
   * create new collection instances as necessary.
   * 
   * @param values an iterable collection of values to iterate over
   * @param propertyPathExpression a property path expression to evaluate
   *          against each collection value
   * @param collectionType the collection type used to contain mutiple values
   *          that map to the same key
   * @return a map with values from the specified collection and keys from the
   *         property path expression
   */
  @SuppressWarnings("unchecked")
  public static , CIMPL extends C> Map mapToValueCollection(
      Iterable values, String property, Class collectionType) {

    Map byKey = new HashMap();
    PropertyPathExpression query = new PropertyPathExpression(property);

    for (V value : values) {

      K key = (K) query.invoke(value);
      C valuesForKey = byKey.get(key);
      if (valuesForKey == null) {

        try {
          valuesForKey = collectionType.newInstance();
        } catch (Exception ex) {
          throw new IllegalStateException(
              "error instantiating collection type: " + collectionType, ex);
        }

        byKey.put(key, valuesForKey);
      }
      valuesForKey.add(value);
    }

    return byKey;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy