📄 utilities.java
字号:
/* * Copyright 2004-2005 Gary Bentley * * 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.josql.internal;import java.util.List;import java.util.ArrayList;import java.util.Map;import java.util.HashMap;import java.util.StringTokenizer;import java.util.Collection;import java.util.Iterator;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Constructor;public class Utilities{ private static final String F = "f"; private static final String E = "e"; private static final String A = "a"; private static final String N = "n"; public static final int GT = 0; public static final int GTE = 1; public static final int LT = 2; public static final int LTE = 3; public static final int EQ = 4; private static Map pCNames = new HashMap (); private static Map primNames = new HashMap (); private static Map primCls = new HashMap (); static { Utilities.pCNames.put ("double", ""); Utilities.pCNames.put (Double.class.getName (), ""); Utilities.pCNames.put ("int", ""); Utilities.pCNames.put (Integer.class.getName (), ""); Utilities.pCNames.put ("float", ""); Utilities.pCNames.put (Float.class.getName (), ""); Utilities.pCNames.put ("long", ""); Utilities.pCNames.put (Long.class.getName (), ""); Utilities.pCNames.put ("short", ""); Utilities.pCNames.put (Short.class.getName (), ""); Utilities.pCNames.put ("byte", ""); Utilities.pCNames.put (Byte.class.getName (), ""); Utilities.pCNames.put (Number.class.getName (), ""); Utilities.primNames.put (Double.TYPE.getName (), Double.class.getName ()); Utilities.primNames.put (Double.class.getName (), Double.TYPE.getName ()); Utilities.primNames.put (Integer.TYPE.getName (), Integer.class.getName ()); Utilities.primNames.put (Integer.class.getName (), Integer.TYPE.getName ()); Utilities.primNames.put (Float.TYPE.getName (), Float.class.getName ()); Utilities.primNames.put (Float.class.getName (), Float.TYPE.getName ()); Utilities.primNames.put (Long.TYPE.getName (), Long.class.getName ()); Utilities.primNames.put (Long.class.getName (), Long.TYPE.getName ()); Utilities.primNames.put (Short.TYPE.getName (), Short.class.getName ()); Utilities.primNames.put (Short.class.getName (), Short.TYPE.getName ()); Utilities.primNames.put (Byte.TYPE.getName (), Byte.class.getName ()); Utilities.primNames.put (Byte.class.getName (), Byte.TYPE.getName ()); Utilities.primNames.put (Character.TYPE.getName (), Character.class.getName ()); Utilities.primNames.put (Character.class.getName (), Character.TYPE.getName ()); Utilities.primNames.put (Boolean.TYPE.getName (), Boolean.class.getName ()); Utilities.primNames.put (Boolean.class.getName (), Boolean.TYPE.getName ()); Utilities.primCls.put (Double.TYPE.getName (), Double.TYPE); Utilities.primCls.put (Double.class.getName (), Double.TYPE); Utilities.primCls.put (Integer.TYPE.getName (), Integer.TYPE); Utilities.primCls.put (Integer.class.getName (), Integer.TYPE); Utilities.primCls.put (Float.TYPE.getName (), Float.TYPE); Utilities.primCls.put (Float.class.getName (), Float.TYPE); Utilities.primCls.put (Long.TYPE.getName (), Long.TYPE); Utilities.primCls.put (Long.class.getName (), Long.TYPE); Utilities.primCls.put (Short.TYPE.getName (), Short.TYPE); Utilities.primCls.put (Short.class.getName (), Short.TYPE); Utilities.primCls.put (Byte.TYPE.getName (), Byte.TYPE); Utilities.primCls.put (Byte.class.getName (), Byte.TYPE); Utilities.primCls.put (Character.TYPE.getName (), Character.TYPE); Utilities.primCls.put (Character.class.getName (), Character.TYPE); Utilities.primCls.put (Boolean.TYPE.getName (), Boolean.TYPE); Utilities.primCls.put (Boolean.class.getName (), Boolean.TYPE); } public static Class getObjectClass (Class c) { if (c.isPrimitive ()) { String n = c.getName (); if (n.equals (Boolean.TYPE.getName ())) { return Boolean.class; } if (n.equals (Long.TYPE.getName ())) { return Long.class; } if (n.equals (Short.TYPE.getName ())) { return Short.class; } if (n.equals (Integer.TYPE.getName ())) { return Integer.class; } if (n.equals (Double.TYPE.getName ())) { return Double.class; } if (n.equals (Character.TYPE.getName ())) { return Character.class; } if (n.equals (Float.TYPE.getName ())) { return Float.class; } if (n.equals (Byte.TYPE.getName ())) { return Byte.class; } } return c; } public static Class getPrimitiveClass (Class c) { return (Class) Utilities.primCls.get (c.getName ()); } public static boolean isPrimitiveClass (Class c) { return Utilities.primNames.containsKey (c.getName ()); } public static boolean getResult (boolean v, boolean n) { if (v) { if (n) { return false; } return true; } if (n) { return true; } return false; } /** * This method encapsulates our "matching" mechanism. It handles collections correctly * and will match according to the combination of <b>igoreCase</b>, <b>type</b> and * <b>not</b>. * * Note: this method deliberately throws no exceptions, and it tries hard to ensure that * ClassCastExceptions and NullPointerExceptions are also NOT thrown, in other words in * theory it should be possible to compare ANY object against ANY other in safety. However * if the objects DO NOT implement comparable (and are type compatible, i.e. can <b>r</b> * be assigned to <b>l</b>) then a string comparison is performed so you may be at the mercy * of the {@link String#toString()} method of each object. In general this is not a problem * but beware of potential gotchas such as: * <code> * SELECT * * FROM MyObject * WHERE 20 >= (SELECT value * FROM myList) * </code> * <pre> * It's tempting to think here that the query will return the correct result, however this is * NOT true because the sub-query will return a List of Lists (with "value" as the single * item in each list of the sub-query results). To make the query above work as expected you * should use: * <code> * SELECT * * FROM MyObject * // The value will be returned instead of an enclosing list. * WHERE 20 >= (SELECT [*] value * FROM myList) * </code> * * @param l The LHS object. * @param r The RHS object. * @param ignoreCase Whether to ignore the case or not, note: setting this to <code>true</code> * will force a string comparison (the object to compare against will be * converted to a string via: {@link String#toString()} and then "lowered". * @param type The type of comparison to make, should be one of: * {@link Utilities#GT}, {@link Utilities#GTE}, {@link Utilities#LT} * {@link Utilities#LTE}, {@link Utilities#EQ}. * @param not Whether the result should be reversed. * @return <code>true</code> if <b>l</b> matches <b>r</b> given the rules defined by the * other parms, <code>false</code> otherwise. */ public static boolean matches (Object l, Object r, boolean ignoreCase, int type, boolean not) { if (l instanceof Collection) { if (r instanceof Collection) { Collection cl = (Collection) l; Collection cr = (Collection) r; boolean lisra = (cl instanceof List); boolean risra = (cr instanceof List); List rl = null; if (risra) { rl = (List) cr; } int rs = cr.size () - 1; // Need to now ensure that each item in the left is >, <, >=, <= // than every item in the right... sigh... ;) if (lisra) { List ll = (List) cl; // Can go backwards for slightly faster access. int s = ll.size () - 1; for (int i = s; i > -1; i--) { l = Utilities.lowerValue (ll.get (i), ignoreCase); if (risra) { for (int j = rs; j > -1; j--) { r = Utilities.lowerValue (rl.get (j), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } else { Iterator it = cr.iterator (); while (it.hasNext ()) { r = Utilities.lowerValue (it.next (), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } } } else { Iterator it = cl.iterator (); while (it.hasNext ()) { l = Utilities.lowerValue (it.next (), ignoreCase); if (risra) { for (int j = rs; j > -1; j--) { r = Utilities.lowerValue (rl.get (j), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } else { Iterator itr = cr.iterator (); while (itr.hasNext ()) { r = Utilities.lowerValue (itr.next (), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } } } // If we are here then it means that ALL values in the RHS // collection match the condition with the LHS values // so we return true. return true; } else { // Here we need to check to ensure that ALL values in the LHS // collection match the condition for the single RHS value. Collection cl = (Collection) l; r = Utilities.lowerValue (r, ignoreCase); if (cl instanceof List) { List ll = (List) cl; int ls = cl.size () - 1; for (int i = ls; i > -1; i--) { l = Utilities.lowerValue (ll.get (i), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } else { Iterator cli = cl.iterator (); while (cli.hasNext ()) { l = Utilities.lowerValue (cli.next (), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } // All values in the LHS match the condition for the RHS // value. return true; } } else { // See if the RHS is a collection. if (r instanceof Collection) { l = Utilities.lowerValue (l, ignoreCase); Collection cr = (Collection) r; if (cr instanceof List) { List rl = (List) cr; int rs = rl.size () - 1; for (int i = rs; i > -1; i--) { r = Utilities.lowerValue (rl.get (i), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } else { Iterator cri = cr.iterator (); while (cri.hasNext ()) { r = Utilities.lowerValue (cri.next (), ignoreCase); if (!Utilities.compare2 (l, r, type, not)) { return false; } } } // All values in the RHS match the condition for the LHS // value. return true; } } // Just vanilla objects, so compare. // Note: we perform the "lower" at this point because (from above) // we want to ensure that the lower is only ever performed once and // it's not until now that we can be sure that the objects are not collections. return Utilities.compare2 (Utilities.lowerValue (l, ignoreCase), Utilities.lowerValue (r, ignoreCase), type, not); } private static Object lowerValue (Object o, boolean ignoreCase) { if (ignoreCase) { o = o.toString (); if (o != null) { o = ((String) o).toLowerCase (); } } return o; } private static boolean compare2 (Object l, Object r, int type, boolean not) { int c = Utilities.compare (l, r); // Use the direct values here for speed. // Check for > if ((type == 0) && (c < 1) ) { // The LHS value is equal to or less than // the RHS value, but we expect >, so can safely // return false. if (not) { return true; } return false; } // Check for >= or = if (((type == 1) || (type == 4) ) && (c < 0) ) { // The RHS value is less than the LHS value // but we expect >=, so can safely return false. if (not) { return true; } return false; } // Check for < if ((type == 2) && (c > -1) ) { // The RHS value is greater than or equal to // the LHS value but we expect <, so can safely return // false. if (not) { return true; } return false; } // Check for <= if (((type == 3) || (type == 4) ) && (c > 0) ) { // The RHS value is greater than the LHS value // but we expect <=, so can safely return false. if (not) { return true; } return false; } if (not) { return false; } return true; } public static int compare (Object o1, Object o2) { if ((o1 == null) && (o2 == null) ) { return 0; } if ((o1 == null) || (o2 == null) ) { return -1; } if ((o1 instanceof Number) && (o2 instanceof Number) ) { return Utilities.getDoubleObject (o1).compareTo (Utilities.getDoubleObject (o2)); } if ((o1 instanceof Comparable) && (o2 instanceof Comparable) && (o1.getClass ().isAssignableFrom (o2.getClass ())) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -