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

com.orientechnologies.common.collection.OMultiValue Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010-2012 Luca Garulli (l.garulli--at--orientechnologies.com)
 *
 * 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 com.orientechnologies.common.collection;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;

import com.orientechnologies.common.log.OLogManager;

/**
 * Handles Multi-value types such as Arrays, Collections and Maps
 * 
 * @author Luca Garulli (l.garulli--at--orientechnologies.com)
 */
@SuppressWarnings("unchecked")
public class OMultiValue {

  /**
   * Checks if a class is a multi-value type.
   * 
   * @param iType
   *          Class to check
   * @return true if it's an array, a collection or a map, otherwise false
   */
  public static boolean isMultiValue(final Class iType) {
    return (iType.isArray() || Collection.class.isAssignableFrom(iType) || Map.class.isAssignableFrom(iType));
  }

  /**
   * Checks if the object is a multi-value type.
   * 
   * @param iObject
   *          Object to check
   * @return true if it's an array, a collection or a map, otherwise false
   */
  public static boolean isMultiValue(final Object iObject) {
    return iObject == null ? false : isMultiValue(iObject.getClass());
  }

  /**
   * Returns the size of the multi-value object
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   * @return the size of the multi value object
   */
  public static int getSize(final Object iObject) {
    if (iObject == null)
      return 0;

    if (!isMultiValue(iObject))
      return 0;

    if (iObject instanceof Collection)
      return ((Collection) iObject).size();
    if (iObject instanceof Map)
      return ((Map) iObject).size();
    if (iObject.getClass().isArray())
      return Array.getLength(iObject);
    return 0;
  }

  /**
   * Returns the first item of the Multi-value object (array, collection or map)
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   * @return The first item if any
   */
  public static Object getFirstValue(final Object iObject) {
    if (iObject == null)
      return null;

    if (!isMultiValue(iObject))
      return null;

    try {
      if (iObject instanceof Collection)
        return ((Collection) iObject).iterator().next();
      else if (iObject instanceof Map)
        return ((Map) iObject).values().iterator().next();
      else if (iObject.getClass().isArray())
        return Array.get(iObject, 0);
    } catch (Exception e) {
      // IGNORE IT
      OLogManager.instance().debug(iObject, "Error on reading the first item of the Multi-value field '%s'", iObject);
    }

    return null;
  }

  /**
   * Returns the iIndex item of the Multi-value object (array, collection or map)
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   * @param iIndex
   *          integer as the position requested
   * @return The first item if any
   */
  public static Object getValue(final Object iObject, final int iIndex) {
    if (iObject == null)
      return null;

    if (!isMultiValue(iObject))
      return null;

    if (iIndex > getSize(iObject))
      return null;

    try {
      if (iObject instanceof List)
        return ((List) iObject).get(iIndex);
      else if (iObject instanceof Set) {
        int i = 0;
        for (Object o : ((Set) iObject)) {
          if (i++ == iIndex) {
            return o;
          }
        }
      } else if (iObject instanceof Map) {
        int i = 0;
        for (Object o : ((Map) iObject).values()) {
          if (i++ == iIndex) {
            return o;
          }
        }
      } else if (iObject.getClass().isArray())
        return Array.get(iObject, 0);
    } catch (Exception e) {
      // IGNORE IT
      OLogManager.instance().debug(iObject, "Error on reading the first item of the Multi-value field '%s'", iObject);
    }
    return null;
  }

  /**
   * Returns an Iterable object to browse the multi-value instance (array, collection or map)
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   */
  public static Iterable getMultiValueIterable(final Object iObject) {
    if (iObject == null)
      return null;
    
    if( iObject instanceof Iterable)
      return (Iterable) iObject;

    if (!isMultiValue(iObject))
      return null;

    if (iObject instanceof Collection)
      return ((Collection) iObject);
    if (iObject instanceof Map)
      return ((Map) iObject).values();
    if (iObject.getClass().isArray())
      return new OIterableObjectArray(iObject);
    return null;
  }

  /**
   * Returns an Iterator object to browse the multi-value instance (array, collection or map)
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   */

  public static Iterator getMultiValueIterator(final Object iObject) {
    if (iObject == null)
      return null;

    if (!isMultiValue(iObject))
      return null;

    if (iObject instanceof Collection)
      return ((Collection) iObject).iterator();
    if (iObject instanceof Map)
      return ((Map) iObject).values().iterator();
    if (iObject.getClass().isArray())
      return new OIterableObjectArray(iObject).iterator();
    return null;
  }

  /**
   * Returns a stringified version of the multi-value object.
   * 
   * @param iObject
   *          Multi-value object (array, collection or map)
   * @return a stringified version of the multi-value object.
   */
  public static String toString(final Object iObject) {
    final StringBuilder sb = new StringBuilder();

    if (iObject instanceof Collection) {
      final Collection coll = (Collection) iObject;

      sb.append('[');
      for (final Iterator it = coll.iterator(); it.hasNext();) {
        try {
          Object e = it.next();
          sb.append(e == iObject ? "(this Collection)" : e);
          if (it.hasNext())
            sb.append(", ");
        } catch (NoSuchElementException ex) {
          // IGNORE THIS
        }
      }
      return sb.append(']').toString();
    } else if (iObject instanceof Map) {
      final Map map = (Map) iObject;

      Entry e;

      sb.append('{');
      for (final Iterator> it = map.entrySet().iterator(); it.hasNext();) {
        try {
          e = it.next();

          sb.append(e.getKey());
          sb.append(":");
          sb.append(e.getValue() == iObject ? "(this Map)" : e.getValue());
          if (it.hasNext())
            sb.append(", ");
        } catch (NoSuchElementException ex) {
          // IGNORE THIS
        }
      }
      return sb.append('}').toString();
    }

    return iObject.toString();
  }
}