0001: /*
0002: * Copyright 2004-2007 Gary Bentley
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License"); you may
0005: * not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: * http://www.apache.org/licenses/LICENSE-2.0
0008: *
0009: * Unless required by applicable law or agreed to in writing, software
0010: * distributed under the License is distributed on an "AS IS" BASIS,
0011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012: * See the License for the specific language governing permissions and
0013: * limitations under the License.
0014: */
0015: package org.josql.internal;
0016:
0017: import java.util.List;
0018: import java.util.ArrayList;
0019: import java.util.Map;
0020: import java.util.HashMap;
0021: import java.util.StringTokenizer;
0022: import java.util.Collection;
0023: import java.util.Iterator;
0024:
0025: import java.lang.reflect.Method;
0026:
0027: public class Utilities {
0028:
0029: private static final String F = "f";
0030: private static final String E = "e";
0031: private static final String A = "a";
0032: private static final String N = "n";
0033:
0034: public static final int GT = 0;
0035: public static final int GTE = 1;
0036: public static final int LT = 2;
0037: public static final int LTE = 3;
0038: public static final int EQ = 4;
0039:
0040: private static Map pCNames = new HashMap();
0041: private static Map primNames = new HashMap();
0042: private static Map primCls = new HashMap();
0043:
0044: static {
0045:
0046: Utilities.pCNames.put("double", "");
0047: Utilities.pCNames.put(Double.class.getName(), "");
0048: Utilities.pCNames.put("int", "");
0049: Utilities.pCNames.put(Integer.class.getName(), "");
0050: Utilities.pCNames.put("float", "");
0051: Utilities.pCNames.put(Float.class.getName(), "");
0052: Utilities.pCNames.put("long", "");
0053: Utilities.pCNames.put(Long.class.getName(), "");
0054: Utilities.pCNames.put("short", "");
0055: Utilities.pCNames.put(Short.class.getName(), "");
0056: Utilities.pCNames.put("byte", "");
0057: Utilities.pCNames.put(Byte.class.getName(), "");
0058: Utilities.pCNames.put(Number.class.getName(), "");
0059:
0060: Utilities.primNames.put(Double.TYPE.getName(), Double.class
0061: .getName());
0062: Utilities.primNames.put(Double.class.getName(), Double.TYPE
0063: .getName());
0064: Utilities.primNames.put(Integer.TYPE.getName(), Integer.class
0065: .getName());
0066: Utilities.primNames.put(Integer.class.getName(), Integer.TYPE
0067: .getName());
0068: Utilities.primNames.put(Float.TYPE.getName(), Float.class
0069: .getName());
0070: Utilities.primNames.put(Float.class.getName(), Float.TYPE
0071: .getName());
0072: Utilities.primNames.put(Long.TYPE.getName(), Long.class
0073: .getName());
0074: Utilities.primNames.put(Long.class.getName(), Long.TYPE
0075: .getName());
0076: Utilities.primNames.put(Short.TYPE.getName(), Short.class
0077: .getName());
0078: Utilities.primNames.put(Short.class.getName(), Short.TYPE
0079: .getName());
0080: Utilities.primNames.put(Byte.TYPE.getName(), Byte.class
0081: .getName());
0082: Utilities.primNames.put(Byte.class.getName(), Byte.TYPE
0083: .getName());
0084: Utilities.primNames.put(Character.TYPE.getName(),
0085: Character.class.getName());
0086: Utilities.primNames.put(Character.class.getName(),
0087: Character.TYPE.getName());
0088: Utilities.primNames.put(Boolean.TYPE.getName(), Boolean.class
0089: .getName());
0090: Utilities.primNames.put(Boolean.class.getName(), Boolean.TYPE
0091: .getName());
0092:
0093: Utilities.primCls.put(Double.TYPE.getName(), Double.TYPE);
0094: Utilities.primCls.put(Double.class.getName(), Double.TYPE);
0095:
0096: Utilities.primCls.put(Integer.TYPE.getName(), Integer.TYPE);
0097: Utilities.primCls.put(Integer.class.getName(), Integer.TYPE);
0098:
0099: Utilities.primCls.put(Float.TYPE.getName(), Float.TYPE);
0100: Utilities.primCls.put(Float.class.getName(), Float.TYPE);
0101:
0102: Utilities.primCls.put(Long.TYPE.getName(), Long.TYPE);
0103: Utilities.primCls.put(Long.class.getName(), Long.TYPE);
0104:
0105: Utilities.primCls.put(Short.TYPE.getName(), Short.TYPE);
0106: Utilities.primCls.put(Short.class.getName(), Short.TYPE);
0107:
0108: Utilities.primCls.put(Byte.TYPE.getName(), Byte.TYPE);
0109: Utilities.primCls.put(Byte.class.getName(), Byte.TYPE);
0110:
0111: Utilities.primCls.put(Character.TYPE.getName(), Character.TYPE);
0112: Utilities.primCls
0113: .put(Character.class.getName(), Character.TYPE);
0114:
0115: Utilities.primCls.put(Boolean.TYPE.getName(), Boolean.TYPE);
0116: Utilities.primCls.put(Boolean.class.getName(), Boolean.TYPE);
0117:
0118: }
0119:
0120: public static Class getObjectClass(Class c) {
0121:
0122: if (c.isPrimitive()) {
0123:
0124: String n = c.getName();
0125:
0126: if (n.equals(Boolean.TYPE.getName())) {
0127:
0128: return Boolean.class;
0129:
0130: }
0131:
0132: if (n.equals(Long.TYPE.getName())) {
0133:
0134: return Long.class;
0135:
0136: }
0137:
0138: if (n.equals(Short.TYPE.getName())) {
0139:
0140: return Short.class;
0141:
0142: }
0143:
0144: if (n.equals(Integer.TYPE.getName())) {
0145:
0146: return Integer.class;
0147:
0148: }
0149:
0150: if (n.equals(Double.TYPE.getName())) {
0151:
0152: return Double.class;
0153:
0154: }
0155:
0156: if (n.equals(Character.TYPE.getName())) {
0157:
0158: return Character.class;
0159:
0160: }
0161:
0162: if (n.equals(Float.TYPE.getName())) {
0163:
0164: return Float.class;
0165:
0166: }
0167:
0168: if (n.equals(Byte.TYPE.getName())) {
0169:
0170: return Byte.class;
0171:
0172: }
0173:
0174: }
0175:
0176: return c;
0177:
0178: }
0179:
0180: public static Class getPrimitiveClass(Class c) {
0181:
0182: return (Class) Utilities.primCls.get(c.getName());
0183:
0184: }
0185:
0186: public static boolean isPrimitiveClass(Class c) {
0187:
0188: return Utilities.primNames.containsKey(c.getName());
0189:
0190: }
0191:
0192: public static boolean getResult(boolean v, boolean n) {
0193:
0194: if (v) {
0195:
0196: if (n) {
0197:
0198: return false;
0199:
0200: }
0201:
0202: return true;
0203:
0204: }
0205:
0206: if (n) {
0207:
0208: return true;
0209:
0210: }
0211:
0212: return false;
0213:
0214: }
0215:
0216: /**
0217: * This method encapsulates our "matching" mechanism. It handles collections correctly
0218: * and will match according to the combination of <b>igoreCase</b>, <b>type</b> and
0219: * <b>not</b>.
0220: *
0221: * Note: this method deliberately throws no exceptions, and it tries hard to ensure that
0222: * ClassCastExceptions and NullPointerExceptions are also NOT thrown, in other words in
0223: * theory it should be possible to compare ANY object against ANY other in safety. However
0224: * if the objects DO NOT implement comparable (and are type compatible, i.e. can <b>r</b>
0225: * be assigned to <b>l</b>) then a string comparison is performed so you may be at the mercy
0226: * of the {@link String#toString()} method of each object. In general this is not a problem
0227: * but beware of potential gotchas such as:
0228: * <code>
0229: * SELECT *
0230: * FROM MyObject
0231: * WHERE 20 >= (SELECT value
0232: * FROM myList)
0233: * </code>
0234: * <pre>
0235: * It's tempting to think here that the query will return the correct result, however this is
0236: * NOT true because the sub-query will return a List of Lists (with "value" as the single
0237: * item in each list of the sub-query results). To make the query above work as expected you
0238: * should use:
0239: * <code>
0240: * SELECT *
0241: * FROM MyObject
0242: * // The value will be returned instead of an enclosing list.
0243: * WHERE 20 >= (SELECT [*] value
0244: * FROM myList)
0245: * </code>
0246: *
0247: * @param l The LHS object.
0248: * @param r The RHS object.
0249: * @param ignoreCase Whether to ignore the case or not, note: setting this to <code>true</code>
0250: * will force a string comparison (the object to compare against will be
0251: * converted to a string via: {@link String#toString()} and then "lowered".
0252: * @param type The type of comparison to make, should be one of:
0253: * {@link Utilities#GT}, {@link Utilities#GTE}, {@link Utilities#LT}
0254: * {@link Utilities#LTE}, {@link Utilities#EQ}.
0255: * @param not Whether the result should be reversed.
0256: * @return <code>true</code> if <b>l</b> matches <b>r</b> given the rules defined by the
0257: * other parms, <code>false</code> otherwise.
0258: */
0259: public static boolean matches(Object l, Object r,
0260: boolean ignoreCase, int type, boolean not) {
0261:
0262: if (l instanceof Collection) {
0263:
0264: if (r instanceof Collection) {
0265:
0266: Collection cl = (Collection) l;
0267: Collection cr = (Collection) r;
0268:
0269: boolean lisra = (cl instanceof List);
0270: boolean risra = (cr instanceof List);
0271:
0272: List rl = null;
0273:
0274: if (risra) {
0275:
0276: rl = (List) cr;
0277:
0278: }
0279:
0280: int rs = cr.size() - 1;
0281:
0282: // Need to now ensure that each item in the left is >, <, >=, <=
0283: // than every item in the right... sigh... ;)
0284: if (lisra) {
0285:
0286: List ll = (List) cl;
0287:
0288: // Can go backwards for slightly faster access.
0289: int s = ll.size() - 1;
0290:
0291: for (int i = s; i > -1; i--) {
0292:
0293: l = Utilities.lowerValue(ll.get(i), ignoreCase);
0294:
0295: if (risra) {
0296:
0297: for (int j = rs; j > -1; j--) {
0298:
0299: r = Utilities.lowerValue(rl.get(j),
0300: ignoreCase);
0301:
0302: if (!Utilities
0303: .compare2(l, r, type, not)) {
0304:
0305: return false;
0306:
0307: }
0308:
0309: }
0310:
0311: } else {
0312:
0313: Iterator it = cr.iterator();
0314:
0315: while (it.hasNext()) {
0316:
0317: r = Utilities.lowerValue(it.next(),
0318: ignoreCase);
0319:
0320: if (!Utilities
0321: .compare2(l, r, type, not)) {
0322:
0323: return false;
0324:
0325: }
0326:
0327: }
0328:
0329: }
0330:
0331: }
0332:
0333: } else {
0334:
0335: Iterator it = cl.iterator();
0336:
0337: while (it.hasNext()) {
0338:
0339: l = Utilities.lowerValue(it.next(), ignoreCase);
0340:
0341: if (risra) {
0342:
0343: for (int j = rs; j > -1; j--) {
0344:
0345: r = Utilities.lowerValue(rl.get(j),
0346: ignoreCase);
0347:
0348: if (!Utilities
0349: .compare2(l, r, type, not)) {
0350:
0351: return false;
0352:
0353: }
0354:
0355: }
0356:
0357: } else {
0358:
0359: Iterator itr = cr.iterator();
0360:
0361: while (itr.hasNext()) {
0362:
0363: r = Utilities.lowerValue(itr.next(),
0364: ignoreCase);
0365:
0366: if (!Utilities
0367: .compare2(l, r, type, not)) {
0368:
0369: return false;
0370:
0371: }
0372:
0373: }
0374:
0375: }
0376:
0377: }
0378:
0379: }
0380:
0381: // If we are here then it means that ALL values in the RHS
0382: // collection match the condition with the LHS values
0383: // so we return true.
0384: return true;
0385:
0386: } else {
0387:
0388: // Here we need to check to ensure that ALL values in the LHS
0389: // collection match the condition for the single RHS value.
0390: Collection cl = (Collection) l;
0391:
0392: r = Utilities.lowerValue(r, ignoreCase);
0393:
0394: if (cl instanceof List) {
0395:
0396: List ll = (List) cl;
0397:
0398: int ls = cl.size() - 1;
0399:
0400: for (int i = ls; i > -1; i--) {
0401:
0402: l = Utilities.lowerValue(ll.get(i), ignoreCase);
0403:
0404: if (!Utilities.compare2(l, r, type, not)) {
0405:
0406: return false;
0407:
0408: }
0409:
0410: }
0411:
0412: } else {
0413:
0414: Iterator cli = cl.iterator();
0415:
0416: while (cli.hasNext()) {
0417:
0418: l = Utilities
0419: .lowerValue(cli.next(), ignoreCase);
0420:
0421: if (!Utilities.compare2(l, r, type, not)) {
0422:
0423: return false;
0424:
0425: }
0426:
0427: }
0428:
0429: }
0430:
0431: // All values in the LHS match the condition for the RHS
0432: // value.
0433: return true;
0434:
0435: }
0436:
0437: } else {
0438:
0439: // See if the RHS is a collection.
0440: if (r instanceof Collection) {
0441:
0442: l = Utilities.lowerValue(l, ignoreCase);
0443:
0444: Collection cr = (Collection) r;
0445:
0446: if (cr instanceof List) {
0447:
0448: List rl = (List) cr;
0449:
0450: int rs = rl.size() - 1;
0451:
0452: for (int i = rs; i > -1; i--) {
0453:
0454: r = Utilities.lowerValue(rl.get(i), ignoreCase);
0455:
0456: if (!Utilities.compare2(l, r, type, not)) {
0457:
0458: return false;
0459:
0460: }
0461:
0462: }
0463:
0464: } else {
0465:
0466: Iterator cri = cr.iterator();
0467:
0468: while (cri.hasNext()) {
0469:
0470: r = Utilities
0471: .lowerValue(cri.next(), ignoreCase);
0472:
0473: if (!Utilities.compare2(l, r, type, not)) {
0474:
0475: return false;
0476:
0477: }
0478:
0479: }
0480:
0481: }
0482:
0483: // All values in the RHS match the condition for the LHS
0484: // value.
0485: return true;
0486:
0487: }
0488:
0489: }
0490:
0491: // Just vanilla objects, so compare.
0492: // Note: we perform the "lower" at this point because (from above)
0493: // we want to ensure that the lower is only ever performed once and
0494: // it's not until now that we can be sure that the objects are not collections.
0495: return Utilities.compare2(Utilities.lowerValue(l, ignoreCase),
0496: Utilities.lowerValue(r, ignoreCase), type, not);
0497:
0498: }
0499:
0500: private static Object lowerValue(Object o, boolean ignoreCase) {
0501:
0502: if (ignoreCase) {
0503:
0504: o = o.toString();
0505:
0506: if (o != null) {
0507:
0508: o = ((String) o).toLowerCase();
0509:
0510: }
0511:
0512: }
0513:
0514: return o;
0515:
0516: }
0517:
0518: private static boolean compare2(Object l, Object r, int type,
0519: boolean not) {
0520:
0521: int c = Utilities.compare(l, r);
0522:
0523: // Use the direct values here for speed.
0524:
0525: // Check for >
0526: if ((type == 0) && (c < 1)) {
0527:
0528: // The LHS value is equal to or less than
0529: // the RHS value, but we expect >, so can safely
0530: // return false.
0531: if (not) {
0532:
0533: return true;
0534:
0535: }
0536:
0537: return false;
0538:
0539: }
0540:
0541: // Check for >= or =
0542: if (((type == 1) || (type == 4)) && (c < 0)) {
0543:
0544: // The RHS value is less than the LHS value
0545: // but we expect >=, so can safely return false.
0546: if (not) {
0547:
0548: return true;
0549:
0550: }
0551:
0552: return false;
0553:
0554: }
0555:
0556: // Check for <
0557: if ((type == 2) && (c > -1)) {
0558:
0559: // The RHS value is greater than or equal to
0560: // the LHS value but we expect <, so can safely return
0561: // false.
0562: if (not) {
0563:
0564: return true;
0565:
0566: }
0567:
0568: return false;
0569:
0570: }
0571:
0572: // Check for <=
0573: if (((type == 3) || (type == 4)) && (c > 0)) {
0574:
0575: // The RHS value is greater than the LHS value
0576: // but we expect <=, so can safely return false.
0577: if (not) {
0578:
0579: return true;
0580:
0581: }
0582:
0583: return false;
0584:
0585: }
0586:
0587: if (not) {
0588:
0589: return false;
0590:
0591: }
0592:
0593: return true;
0594:
0595: }
0596:
0597: public static int compare(Object o1, Object o2) {
0598:
0599: if ((o1 == null) && (o2 == null)) {
0600:
0601: return 0;
0602:
0603: }
0604:
0605: if ((o1 == null) || (o2 == null)) {
0606:
0607: return -1;
0608:
0609: }
0610:
0611: if ((o1 instanceof Number) && (o2 instanceof Number)) {
0612:
0613: return Utilities.getDoubleObject(o1).compareTo(
0614: Utilities.getDoubleObject(o2));
0615:
0616: }
0617:
0618: if ((o1 instanceof Comparable) && (o2 instanceof Comparable)
0619: && (o1.getClass().isAssignableFrom(o2.getClass()))) {
0620:
0621: return ((Comparable) o1).compareTo((Comparable) o2);
0622:
0623: }
0624:
0625: // Force a string comparison.
0626: String s1 = o1.toString();
0627: String s2 = o2.toString();
0628:
0629: return s1.compareTo(s2);
0630:
0631: }
0632:
0633: public static boolean isGTEquals(Object o1, Object o2) {
0634:
0635: return Utilities.matches(o1, o2, false, Utilities.GTE, false);
0636:
0637: }
0638:
0639: public static boolean isLTEquals(Object o1, Object o2) {
0640:
0641: return Utilities.matches(o1, o2, false, Utilities.LTE, false);
0642:
0643: }
0644:
0645: public static boolean isEquals(Object o1, Object o2) {
0646:
0647: return Utilities.compare(o1, o2) == 0;
0648:
0649: }
0650:
0651: public static Double getDoubleObject(Object o) {
0652:
0653: return new Double(Utilities.getDouble(o));
0654:
0655: }
0656:
0657: public static double getDouble(Object o) {
0658:
0659: return ((Number) o).doubleValue();
0660:
0661: }
0662:
0663: public static boolean isNumber(Object o) {
0664:
0665: if (o == null) {
0666:
0667: return false;
0668:
0669: }
0670:
0671: return Utilities.pCNames.containsKey(o.getClass().getName());
0672:
0673: }
0674:
0675: public static boolean isNumber(Class c) {
0676:
0677: return Utilities.pCNames.containsKey(c.getName());
0678:
0679: }
0680:
0681: public static String formatSignature(String name, Class[] ps) {
0682:
0683: StringBuffer buf = new StringBuffer(name);
0684: buf.append("(");
0685:
0686: if (ps != null) {
0687:
0688: for (int i = 0; i < ps.length; i++) {
0689:
0690: buf.append(ps[i].getName());
0691:
0692: if (i < (ps.length - 1)) {
0693:
0694: buf.append(",");
0695:
0696: }
0697:
0698: }
0699:
0700: }
0701:
0702: buf.append(")");
0703:
0704: return buf.toString();
0705:
0706: }
0707:
0708: public static boolean matchLikePattern(List p, Object lhs,
0709: boolean not, boolean ignoreCase) {
0710:
0711: if (lhs instanceof Collection) {
0712:
0713: return Utilities.matchLikePattern(p, (Collection) lhs, not,
0714: ignoreCase);
0715:
0716: }
0717:
0718: boolean v = Utilities.matchLikePattern(p, lhs, ignoreCase);
0719:
0720: if ((!v) && (not)) {
0721:
0722: return true;
0723:
0724: }
0725:
0726: if ((v) && (not)) {
0727:
0728: return false;
0729:
0730: }
0731:
0732: return v;
0733:
0734: }
0735:
0736: public static boolean matchLikePattern(List p, Collection lhs,
0737: boolean not, boolean ignoreCase) {
0738:
0739: if (lhs instanceof List) {
0740:
0741: int s = lhs.size() - 1;
0742:
0743: List l = (List) lhs;
0744:
0745: for (int i = s; i > -1; i--) {
0746:
0747: Object o = l.get(i);
0748:
0749: if (!Utilities.matchLikePattern(p, o, ignoreCase)) {
0750:
0751: if (not) {
0752:
0753: return true;
0754:
0755: }
0756:
0757: return false;
0758:
0759: }
0760:
0761: }
0762:
0763: if (not) {
0764:
0765: return false;
0766:
0767: }
0768:
0769: return true;
0770:
0771: }
0772:
0773: Iterator iter = lhs.iterator();
0774:
0775: while (iter.hasNext()) {
0776:
0777: Object o = iter.next();
0778:
0779: if (!Utilities.matchLikePattern(p, o, ignoreCase)) {
0780:
0781: if (not) {
0782:
0783: return true;
0784:
0785: }
0786:
0787: return false;
0788:
0789: }
0790:
0791: }
0792:
0793: if (not) {
0794:
0795: return false;
0796:
0797: }
0798:
0799: return true;
0800:
0801: }
0802:
0803: public static boolean matchLikePattern(List p, Object o,
0804: boolean ignoreCase) {
0805:
0806: if (o == null) {
0807:
0808: return false;
0809:
0810: }
0811:
0812: String st = o.toString();
0813:
0814: if (ignoreCase) {
0815:
0816: st = st.toLowerCase();
0817:
0818: }
0819:
0820: return Utilities.matchLikePattern(p, st);
0821:
0822: }
0823:
0824: public static boolean matchLikePattern(List p, String value) {
0825:
0826: if (value == null) {
0827:
0828: return false;
0829:
0830: }
0831:
0832: boolean accept = true;
0833:
0834: String c = null;
0835: String pm = null;
0836:
0837: int currPos = 0;
0838: int cmdPos = 0;
0839:
0840: int s = p.size();
0841:
0842: while (cmdPos < s) {
0843:
0844: c = (String) p.get(cmdPos);
0845: pm = (String) p.get(cmdPos + 1);
0846:
0847: if (c.equals(Utilities.F)) {
0848:
0849: // if we are to find 'anything'
0850: // then we are done
0851: if (pm.equals(Utilities.A)) {
0852:
0853: break;
0854:
0855: }
0856:
0857: // otherwise search for the param
0858: // from the curr pos
0859: int nextPos = value.indexOf(pm, currPos);
0860:
0861: if (nextPos >= 0) {
0862:
0863: // found it
0864: currPos = nextPos + pm.length();
0865:
0866: } else {
0867:
0868: accept = false;
0869: break;
0870:
0871: }
0872:
0873: } else {
0874:
0875: if (c.equals(Utilities.E)) {
0876:
0877: // if we are to expect 'nothing'
0878: // then we MUST be at the end of the string
0879: if (pm.equals(Utilities.N)) {
0880:
0881: if (currPos != value.length()) {
0882:
0883: accept = false;
0884:
0885: }
0886:
0887: // since we expect nothing else,
0888: // we must finish here
0889: break;
0890:
0891: } else {
0892:
0893: // otherwise, check if the expected string
0894: // is at our current position
0895: int nextPos = value.indexOf(pm, currPos);
0896:
0897: if (nextPos != currPos) {
0898:
0899: accept = false;
0900: break;
0901:
0902: }
0903:
0904: // if we've made it this far, then we've
0905: // found what we're looking for
0906: currPos += pm.length();
0907:
0908: }
0909:
0910: }
0911:
0912: }
0913:
0914: cmdPos += 2;
0915: }
0916:
0917: return accept;
0918:
0919: }
0920:
0921: public static boolean matchLikePattern(List p, String value,
0922: boolean not) {
0923:
0924: boolean accept = Utilities.matchLikePattern(p, value);
0925:
0926: if (not) {
0927:
0928: return !accept;
0929:
0930: }
0931:
0932: return accept;
0933:
0934: }
0935:
0936: public static List getLikePattern(String value, String wildcard) {
0937:
0938: List p = new ArrayList();
0939:
0940: StringTokenizer t = new StringTokenizer(value, wildcard, true);
0941:
0942: String tok = null;
0943:
0944: while (t.hasMoreTokens()) {
0945:
0946: tok = t.nextToken();
0947:
0948: if (tok.equals(wildcard)) {
0949:
0950: p.add(Utilities.F);
0951:
0952: if (t.hasMoreTokens()) {
0953:
0954: tok = t.nextToken();
0955: p.add(tok);
0956:
0957: } else {
0958:
0959: p.add(Utilities.A);
0960:
0961: }
0962:
0963: } else {
0964:
0965: p.add(Utilities.E);
0966: p.add(tok);
0967:
0968: }
0969:
0970: }
0971:
0972: if ((tok == null) || (!tok.equals(wildcard))) {
0973:
0974: p.add(Utilities.E);
0975: p.add(Utilities.N);
0976:
0977: }
0978:
0979: return p;
0980:
0981: }
0982:
0983: public static String stripQuotes(String s) {
0984:
0985: if (s == null) {
0986:
0987: return s;
0988:
0989: }
0990:
0991: if (((s.charAt(0) == '\'') && (s.charAt(s.length() - 1) == '\''))
0992: || ((s.charAt(0) == '"') && (s.charAt(s.length() - 1) == '"'))) {
0993:
0994: return s.substring(1, s.length() - 1);
0995:
0996: }
0997:
0998: return s;
0999:
1000: }
1001:
1002: public static void getMethods(Class c, String name, int mods,
1003: List ms) {
1004:
1005: if (c == null) {
1006:
1007: return;
1008:
1009: }
1010:
1011: Method[] meths = c.getDeclaredMethods();
1012:
1013: for (int i = 0; i < meths.length; i++) {
1014:
1015: Method m = meths[i];
1016:
1017: if ((m.getName().equals(name))
1018: && ((m.getModifiers() & mods) == mods)) {
1019:
1020: if (!ms.contains(m)) {
1021:
1022: // This is one.
1023: ms.add(m);
1024:
1025: }
1026:
1027: }
1028:
1029: }
1030:
1031: // Now get all the super-classes.
1032: Class sup = c.getSuperclass();
1033:
1034: if (sup != null) {
1035:
1036: Utilities.getMethods(sup, name, mods, ms);
1037:
1038: }
1039:
1040: // Now work up through the super-classes/interfaces.
1041: Class[] ints = c.getInterfaces();
1042:
1043: for (int i = 0; i < ints.length; i++) {
1044:
1045: Class in = ints[i];
1046:
1047: Utilities.getMethods(in, name, mods, ms);
1048:
1049: }
1050:
1051: }
1052:
1053: public static int matchMethodArgs(Class[] args, Class[] compArgs) {
1054:
1055: if ((compArgs == null) && (args == null)) {
1056:
1057: return 2;
1058:
1059: }
1060:
1061: if ((compArgs == null) && (args.length == 0)) {
1062:
1063: return 2;
1064:
1065: }
1066:
1067: if ((compArgs == null) && (args.length > 0)) {
1068:
1069: return 0;
1070:
1071: }
1072:
1073: if (args.length != compArgs.length) {
1074:
1075: return 0;
1076:
1077: }
1078:
1079: // The score here helps in argument resolution, a more specific argument
1080: // match (that is NOT expression in the method args) will score higher and
1081: // thus is a better match.
1082: int score = 0;
1083:
1084: for (int i = 0; i < args.length; i++) {
1085:
1086: Class c = args[i];
1087:
1088: // See if the arg is object, which means "I can accept any type".
1089: if (c.getClass().getName().equals(Object.class.getName())) {
1090:
1091: score += 1;
1092:
1093: continue;
1094:
1095: }
1096:
1097: Class cc = compArgs[i];
1098:
1099: if (cc == null) {
1100:
1101: // Can't match this arg.
1102: continue;
1103:
1104: } else {
1105:
1106: if (c.isAssignableFrom(cc)) {
1107:
1108: score += 2;
1109:
1110: continue;
1111:
1112: }
1113:
1114: }
1115:
1116: if ((Utilities.isNumber(cc)) && (Utilities.isNumber(c))) {
1117:
1118: score += 1;
1119:
1120: // This matches...
1121: continue;
1122:
1123: }
1124:
1125: if ((Utilities.isPrimitiveClass(c))
1126: && (Utilities.isPrimitiveClass(cc))) {
1127:
1128: // It is a primitive class as well, so now see if they are compatible.
1129: if (Utilities.getPrimitiveClass(c).isAssignableFrom(
1130: Utilities.getPrimitiveClass(cc))) {
1131:
1132: score += 1;
1133:
1134: // They are assignable...
1135: continue;
1136:
1137: }
1138:
1139: }
1140:
1141: // See if the type is an object... this "may" mean
1142: // that we can match and it may not, it will be determined at runtime.
1143: if (cc.getName().equals(Object.class.getName())) {
1144:
1145: score += 1;
1146:
1147: continue;
1148:
1149: }
1150:
1151: // If we are here then we can't match this arg type...
1152: // No point checking any further...
1153: return 0;
1154:
1155: }
1156:
1157: // All args can be matched.
1158: return score;
1159:
1160: }
1161:
1162: public static Object[] convertArgs(Object[] args, Class[] argTypes) {
1163:
1164: if (args == null) {
1165:
1166: return args;
1167:
1168: }
1169:
1170: Object[] nargs = new Object[args.length];
1171:
1172: for (int i = 0; i < argTypes.length; i++) {
1173:
1174: if (Utilities.isNumber(argTypes[i])) {
1175:
1176: Class c = Utilities.getObjectClass(argTypes[i]);
1177:
1178: // This arg is a number, need to now convert to the type in the args.
1179: Number arg = (Number) args[i];
1180:
1181: if (Double.class.isAssignableFrom(c)) {
1182:
1183: nargs[i] = arg;
1184:
1185: continue;
1186:
1187: }
1188:
1189: if (Short.class.isAssignableFrom(c)) {
1190:
1191: nargs[i] = new Short(arg.shortValue());
1192:
1193: continue;
1194:
1195: }
1196:
1197: if (Integer.class.isAssignableFrom(c)) {
1198:
1199: nargs[i] = Integer.valueOf(arg.intValue());
1200:
1201: continue;
1202:
1203: }
1204:
1205: if (Long.class.isAssignableFrom(c)) {
1206:
1207: nargs[i] = new Long(arg.longValue());
1208:
1209: continue;
1210:
1211: }
1212:
1213: if (Float.class.isAssignableFrom(c)) {
1214:
1215: nargs[i] = new Float(arg.floatValue());
1216:
1217: continue;
1218:
1219: }
1220:
1221: if (Byte.class.isAssignableFrom(c)) {
1222:
1223: nargs[i] = new Byte(arg.byteValue());
1224:
1225: continue;
1226:
1227: }
1228:
1229: } else {
1230:
1231: nargs[i] = args[i];
1232:
1233: }
1234:
1235: }
1236:
1237: return nargs;
1238:
1239: }
1240:
1241: }
|