/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.client.util; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.emc.storageos.db.client.constraint.URIQueryResultList; import com.emc.storageos.db.client.impl.ColumnField; import com.emc.storageos.db.client.impl.DataObjectType; import com.emc.storageos.db.client.impl.TypeMap; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.exceptions.DatabaseException; /** * A utility class for implementing {@link DataObject} common functions. */ public class DataObjectUtils { /** * This function returns the property value for an object of {@link DataObject} subtype. * * @param clzz the object class that should be a subtype of {@link DataObject} * @param dataObject the instance of clzz * @param property the string name of the property * @return the value of the property */ public static <T extends DataObject> Object getPropertyValue(Class<T> clzz, DataObject dataObject, String property) { try { DataObjectType doType = TypeMap.getDoType(clzz); ColumnField field = doType.getColumnField(property); return field.getPropertyDescriptor().getReadMethod().invoke(dataObject); } catch (Exception ex) { throw DatabaseException.fatals.failedToReadPropertyValue(clzz, property, ex); } } /** * This method invokes a parameterless function. The function is expected to return a value. * This is use when some manipulation of the property is required * * @param clzz the data object class * @param dataObject the data object * @param methodName the name of the method * @return * @throws Exception */ public static <T extends DataObject> Object invokeMethod(Class<T> clzz, DataObject dataObject, String methodName) throws Exception { Method method = String.class.getDeclaredMethod(methodName, new Class[] {}); return (Object) method.invoke(dataObject, new Object[] {}); } /** * Finds an DataObject in a collection by matching it by Id * * @param col the collection * @param obj the object to be found * @return the object in the collection with the same Id and obj. Returns null if no match is found. */ public static <T extends DataObject> T findInCollection(Collection<T> col, T obj) { if (col != null && obj != null) { return findInCollection(col, obj.getId()); } return null; } /** * Returns if the object is found in the collection when the collection contains * and object of the same Id but different instance. * * @param col the collection * @param obj the object being searched for * @return true if an object with the same Id is found; false otherwise. */ public static <T extends DataObject> boolean collectionContains(Collection<T> col, T obj) { return findInCollection(col, obj) != null; } /** * Finds an DataObject in a collection by matching it by Id * * @param col the collection * @param id the object id URI * @return the object in the collection with the ID id. Returns null if no match is found. */ public static <T extends DataObject> T findInCollection(Collection<T> col, URI id) { if (col != null && id != null) { for (T t : col) { if (t.getId().equals(id)) { return t; } } } return null; } /** * Finds an DataObject in a collection by matching it by Id * * @param col the collection * @param id the object id URI as a string * @return the object in the collection with the ID id. Returns null if no match is found. */ public static <T extends DataObject> T findInCollection(Collection<T> col, String id) { if (col != null && id != null) { for (T t : col) { if (t.getId().toString().equals(id)) { return t; } } } return null; } /** * Returns a map of DataObject by Id * * @param col the collection being changed into a map * @return a map of DataObject by Id */ public static <T extends DataObject> Map<URI, T> toMap(Collection<T> col) { Map<URI, T> map = new HashMap<URI, T>(); if (col != null) { for (T t : col) { map.put(t.getId(), t); } } return map; } /** * Finds a DataObject in a collection by matching its property to a value. This method * assumes only one object in the collection can be matched. * * @param col the collection * @param property the property to be checked * @param value the property value to be matched. * @return the object in the collection for which the property value matched the passed in * value. Returns null if no match is found. */ public static <T extends DataObject> T findByProperty(Collection<T> col, String property, Object value) { if (col != null && property != null) { Object val = null; for (T t : col) { val = getPropertyValue(t.getClass(), t, property); if ((val == value) || (val != null && val.equals(value))) { return t; } } } return null; } /** * Utility functions that returns the iterator entries as a list * * @param itr the iterator * @return a list that holds the iterator entries */ public static List<URI> iteratorToList(URIQueryResultList itr) { List<URI> uris = new ArrayList<URI>(); for (URI uri : itr) { uris.add(uri); } return uris; } /** * Utility functions that returns the iterator entries as a list * * @param itr the iterator * @return a list that holds the iterator entries */ public static <T extends DataObject> List<T> iteratorToList(Iterator<T> itr) { List<T> objs = new ArrayList<T>(); while (itr.hasNext()) { objs.add(itr.next()); } return objs; } /** * Utility functions that returns a map of a collection of objects * by a selected property. If the property is null for an object, the * object will not be added to the map. * * @param col the objects collection * @param property the property name * @return a map of object by their property */ public static <T extends DataObject> Map<String, T> mapByProperty(Collection<T> col, String property) { Map<String, T> map = new HashMap<String, T>(); Object prop = null; for (T t : col) { prop = getPropertyValue(t.getClass(), t, property); if (prop != null) { map.put(prop.toString(), t); } } return map; } }