/* * RHQ Management Platform * Copyright (C) 2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.util; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.rhq.core.domain.criteria.Criteria; /** * @author Lukas Krejci * @since 4.9 */ public class CriteriaUtil { private CriteriaUtil() { } public static List<Field> getFields(Criteria criteria, Criteria.Type type) { String prefix = type.name().toLowerCase(); List<Field> results = new ArrayList<Field>(); Class<?> currentLevelClass = criteria.getClass(); List<String> globalFields = type.getGlobalFields(); boolean isCriteriaClass = false; do { isCriteriaClass = currentLevelClass.equals(Criteria.class); for (Field field : currentLevelClass.getDeclaredFields()) { if (isCriteriaClass) { if (globalFields.contains(field.getName())) results.add(field); } else if (field.getName().startsWith(prefix)) { results.add(field); } } currentLevelClass = currentLevelClass.getSuperclass(); } while (!isCriteriaClass); return results; } /** * This method is <b>VERY EXPENSIVE</b>. Do not use it "casually" but rather only in very concrete and exceptional * cases like severe error reporting. * * @return a human readable representation of the criteria object */ public static String toString(Criteria criteria) { StringBuilder bld = new StringBuilder(); bld.append(criteria.getClass().getSimpleName()).append("["); for(Criteria.Type type : Criteria.Type.values()) { switch (type) { case FETCH: bld.append("fetche"); break; default: bld.append(type.name().toLowerCase()); } bld.append("s: ["); List<Field> fields = getFields(criteria, type); Collections.sort(fields, new Comparator<Field>() { @Override public int compare(Field o1, Field o2) { return o1.getName().compareTo(o2.getName()); } }); boolean hasValues = false; for (Field f : fields) { boolean hasValue = false; try { f.setAccessible(true); Object value = f.get(criteria); //don't show fetch fields that are not applied if (type == Criteria.Type.FETCH && value instanceof Boolean && !(Boolean)value) { value = null; } if (value != null) { bld.append(f.getName()).append("="); appendToString(value, bld); hasValue = true; hasValues = true; } } catch (IllegalAccessException e) { bld.append("<value-inaccessible>"); hasValue = true; hasValues = true; } if (hasValue) { bld.append(", "); } } if (hasValues) { bld.replace(bld.length() - 2, bld.length(), ""); } bld.append("], "); } bld.replace(bld.length() - 2, bld.length(), "").append("]"); return bld.toString(); } private static void appendToString(Object object, StringBuilder bld) { if (object == null) { bld.append("null"); } else if (object.getClass().isArray()) { Class<?> componentType = object.getClass().getComponentType(); String str; if (componentType == boolean.class) { str = Arrays.toString((boolean[]) object); } else if (componentType == byte.class) { str = Arrays.toString((byte[]) object); } else if (componentType == char.class) { str = Arrays.toString((char[]) object); } else if (componentType == double.class) { str = Arrays.toString((double[]) object); } else if (componentType == float.class) { str = Arrays.toString((float[]) object); } else if (componentType == int.class) { str = Arrays.toString((int[]) object); } else if (componentType == long.class) { str = Arrays.toString((long[]) object); } else if (componentType == short.class) { str = Arrays.toString((short[]) object); } else { str = Arrays.deepToString((Object[]) object); } bld.append(str); } else if (object instanceof CharSequence) { bld.append("\"").append(object).append("\""); } else { bld.append(object.toString()); } } }