Source Code Cross Referenced for Filters.java in  » Database-ORM » openjpa » org » apache » openjpa » kernel » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » openjpa » org.apache.openjpa.kernel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        package org.apache.openjpa.kernel;
020:
021:        import java.lang.reflect.Method;
022:        import java.math.BigDecimal;
023:        import java.math.BigInteger;
024:        import java.security.AccessController;
025:        import java.security.PrivilegedActionException;
026:        import java.util.ArrayList;
027:        import java.util.Calendar;
028:        import java.util.Collection;
029:        import java.util.Date;
030:        import java.util.List;
031:
032:        import org.apache.openjpa.enhance.Reflection;
033:        import org.apache.openjpa.kernel.exps.AggregateListener;
034:        import org.apache.openjpa.kernel.exps.FilterListener;
035:        import org.apache.openjpa.lib.util.J2DoPrivHelper;
036:        import org.apache.openjpa.lib.util.Localizer;
037:        import org.apache.openjpa.meta.ClassMetaData;
038:        import org.apache.openjpa.meta.JavaTypes;
039:        import org.apache.openjpa.util.InternalException;
040:        import org.apache.openjpa.util.UserException;
041:        import serp.util.Numbers;
042:        import serp.util.Strings;
043:
044:        /**
045:         * Helper methods for dealing with query filters.
046:         *
047:         * @author Abe White
048:         * @nojavadoc
049:         */
050:        public class Filters {
051:
052:            private static final BigDecimal ZERO_BIGDECIMAL = new BigDecimal(0D);
053:            private static final BigInteger ZERO_BIGINTEGER = new BigInteger(
054:                    "0");
055:
056:            private static final int OP_ADD = 0;
057:            private static final int OP_SUBTRACT = 1;
058:            private static final int OP_MULTIPLY = 2;
059:            private static final int OP_DIVIDE = 3;
060:            private static final int OP_MOD = 4;
061:
062:            private static final Localizer _loc = Localizer
063:                    .forPackage(Filters.class);
064:
065:            /**
066:             * Return the correct wrapper type for the given class.
067:             */
068:            public static Class wrap(Class c) {
069:                if (!c.isPrimitive())
070:                    return c;
071:                if (c == int.class)
072:                    return Integer.class;
073:                if (c == float.class)
074:                    return Float.class;
075:                if (c == double.class)
076:                    return Double.class;
077:                if (c == long.class)
078:                    return Long.class;
079:                if (c == boolean.class)
080:                    return Boolean.class;
081:                if (c == short.class)
082:                    return Short.class;
083:                if (c == byte.class)
084:                    return Byte.class;
085:                if (c == char.class)
086:                    return Character.class;
087:                return c;
088:            }
089:
090:            /**
091:             * Return the correct primitive type for the given class, if it is a
092:             * wrapper.
093:             */
094:            public static Class unwrap(Class c) {
095:                if (c.isPrimitive() || c == String.class)
096:                    return c;
097:                if (c == Integer.class)
098:                    return int.class;
099:                if (c == Float.class)
100:                    return float.class;
101:                if (c == Double.class)
102:                    return double.class;
103:                if (c == Long.class)
104:                    return long.class;
105:                if (c == Boolean.class)
106:                    return boolean.class;
107:                if (c == Short.class)
108:                    return short.class;
109:                if (c == Byte.class)
110:                    return byte.class;
111:                if (c == Character.class)
112:                    return char.class;
113:                return c;
114:            }
115:
116:            /**
117:             * Given two types, return type they should both be converted
118:             * to before performing any operations between them.
119:             */
120:            public static Class promote(Class c1, Class c2) {
121:                if (c1 == c2)
122:                    return unwrap(c1);
123:                Class w1 = wrap(c1);
124:                Class w2 = wrap(c2);
125:                if (w1 == w2)
126:                    return unwrap(c1);
127:
128:                // not numbers?
129:                boolean w1Number = Number.class.isAssignableFrom(w1);
130:                boolean w2Number = Number.class.isAssignableFrom(w2);
131:                if (!w1Number || !w2Number) {
132:                    // the only non-numeric promotion we do is string to char,
133:                    // or from char/string to number
134:                    if (!w1Number) {
135:                        if (w2Number
136:                                && (w1 == Character.class || w1 == String.class))
137:                            return (w2 == Byte.class || w2 == Short.class) ? Integer.class
138:                                    : unwrap(c2);
139:                        if (!w2Number && w1 == Character.class
140:                                && w2 == String.class)
141:                            return String.class;
142:                        if (w2Number)
143:                            return unwrap(c2);
144:                    }
145:                    if (!w2Number) {
146:                        if (w1Number
147:                                && (w2 == Character.class || w2 == String.class))
148:                            return (w1 == Byte.class || w1 == Short.class) ? Integer.class
149:                                    : unwrap(c1);
150:                        if (!w1Number && w2 == Character.class
151:                                && w1 == String.class)
152:                            return String.class;
153:                        if (w1Number)
154:                            return unwrap(c1);
155:                    }
156:
157:                    // if neither are numbers, use least-derived of the two.  if neither
158:                    // is assignable from the other but one is a standard type, assume
159:                    // the other can be converted to that standard type
160:                    if (!w1Number && !w2Number) {
161:                        if (w1 == Object.class)
162:                            return unwrap(c2);
163:                        if (w2 == Object.class)
164:                            return unwrap(c1);
165:                        if (w1.isAssignableFrom(w2))
166:                            return unwrap(c1);
167:                        if (w2.isAssignableFrom(w1))
168:                            return unwrap(c2);
169:                        if (isNonstandardType(w1))
170:                            return (isNonstandardType(w2)) ? Object.class
171:                                    : unwrap(c2);
172:                        if (isNonstandardType(w2))
173:                            return (isNonstandardType(w1)) ? Object.class
174:                                    : unwrap(c1);
175:                    }
176:                    return Object.class;
177:                }
178:
179:                if (w1 == BigDecimal.class || w2 == BigDecimal.class)
180:                    return BigDecimal.class;
181:                if (w1 == BigInteger.class) {
182:                    if (w2 == Float.class || w2 == Double.class)
183:                        return BigDecimal.class;
184:                    return BigInteger.class;
185:                }
186:                if (w2 == BigInteger.class) {
187:                    if (w1 == Float.class || w1 == Double.class)
188:                        return BigDecimal.class;
189:                    return BigInteger.class;
190:                }
191:                if (w1 == Double.class || w2 == Double.class)
192:                    return double.class;
193:                if (w1 == Float.class || w2 == Float.class)
194:                    return float.class;
195:                if (w1 == Long.class || w2 == Long.class)
196:                    return long.class;
197:                return int.class;
198:            }
199:
200:            /**
201:             * Return whether the given type is not a standard persistent type.
202:             */
203:            private static boolean isNonstandardType(Class c) {
204:                switch (JavaTypes.getTypeCode(c)) {
205:                case JavaTypes.ARRAY:
206:                case JavaTypes.COLLECTION:
207:                case JavaTypes.MAP:
208:                case JavaTypes.PC:
209:                case JavaTypes.PC_UNTYPED:
210:                case JavaTypes.OID:
211:                case JavaTypes.OBJECT:
212:                    return true;
213:                default:
214:                    return false;
215:                }
216:            }
217:
218:            /**
219:             * Return whether an instance of the first class can be converted to
220:             * an instance of the second.
221:             */
222:            public static boolean canConvert(Class c1, Class c2, boolean strict) {
223:                c1 = wrap(c1);
224:                c2 = wrap(c2);
225:                if (c2.isAssignableFrom(c1))
226:                    return true;
227:
228:                boolean c1Number = Number.class.isAssignableFrom(c1);
229:                boolean c2Number = Number.class.isAssignableFrom(c2);
230:                if (c1Number && c2Number)
231:                    return true;
232:                if ((c1Number && (c2 == Character.class || (!strict && c2 == String.class)))
233:                        || (c2Number && (c1 == Character.class || (!strict && c1 == String.class))))
234:                    return true;
235:                if (c1 == String.class && c2 == Character.class)
236:                    return true;
237:                if (c2 == String.class)
238:                    return !strict;
239:                return false;
240:            }
241:
242:            /**
243:             * Convert the given value to the given type.
244:             */
245:            public static Object convert(Object o, Class type) {
246:                if (o == null)
247:                    return null;
248:                if (o.getClass() == type)
249:                    return o;
250:
251:                type = wrap(type);
252:                if (type.isAssignableFrom(o.getClass()))
253:                    return o;
254:
255:                // the only non-numeric conversions we do are to string, or from
256:                // string/char to number, or calendar/date
257:                boolean num = o instanceof  Number;
258:                if (!num) {
259:                    if (type == String.class)
260:                        return o.toString();
261:                    else if (type == Character.class) {
262:                        String str = o.toString();
263:                        if (str != null && str.length() == 1)
264:                            return new Character(str.charAt(0));
265:                    } else if (Calendar.class.isAssignableFrom(type)
266:                            && o instanceof  Date) {
267:                        Calendar cal = Calendar.getInstance();
268:                        cal.setTime((Date) o);
269:                        return cal;
270:                    } else if (Date.class.isAssignableFrom(type)
271:                            && o instanceof  Calendar) {
272:                        return ((Calendar) o).getTime();
273:                    } else if (Number.class.isAssignableFrom(type)) {
274:                        Integer i = null;
275:                        if (o instanceof  Character)
276:                            i = Numbers.valueOf(((Character) o).charValue());
277:                        else if (o instanceof  String
278:                                && ((String) o).length() == 1)
279:                            i = Numbers.valueOf(((String) o).charAt(0));
280:
281:                        if (i != null) {
282:                            if (type == Integer.class)
283:                                return i;
284:                            num = true;
285:                        }
286:                    }
287:                }
288:                if (!num)
289:                    throw new ClassCastException(_loc.get("cant-convert", o,
290:                            o.getClass(), type).getMessage());
291:
292:                if (type == Integer.class) {
293:                    return Numbers.valueOf(((Number) o).intValue());
294:                } else if (type == Float.class) {
295:                    return new Float(((Number) o).floatValue());
296:                } else if (type == Double.class) {
297:                    return new Double(((Number) o).doubleValue());
298:                } else if (type == Long.class) {
299:                    return Numbers.valueOf(((Number) o).longValue());
300:                } else if (type == BigDecimal.class) {
301:                    // the BigDecimal constructor doesn't handle the
302:                    // "NaN" string version of Double.NaN and Float.NaN, nor
303:                    // does it handle infinity; we need to instead use the Double
304:                    // and Float versions, despite wanting to cast it to BigDecimal
305:                    double dval = ((Number) o).doubleValue();
306:                    if (Double.isNaN(dval) || Double.isInfinite(dval))
307:                        return new Double(dval);
308:
309:                    float fval = ((Number) o).floatValue();
310:                    if (Float.isNaN(fval) || Float.isInfinite(fval))
311:                        return new Float(fval);
312:
313:                    return new BigDecimal(o.toString());
314:                } else if (type == BigInteger.class) {
315:                    return new BigInteger(o.toString());
316:                } else if (type == Short.class) {
317:                    return new Short(((Number) o).shortValue());
318:                } else if (type == Byte.class) {
319:                    return new Byte(((Number) o).byteValue());
320:                } else {
321:                    return Numbers.valueOf(((Number) o).intValue());
322:                }
323:            }
324:
325:            /**
326:             * Add the given values.
327:             */
328:            public static Object add(Object o1, Class c1, Object o2, Class c2) {
329:                return op(o1, c1, o2, c2, OP_ADD);
330:            }
331:
332:            /**
333:             * Subtract the given values.
334:             */
335:            public static Object subtract(Object o1, Class c1, Object o2,
336:                    Class c2) {
337:                return op(o1, c1, o2, c2, OP_SUBTRACT);
338:            }
339:
340:            /**
341:             * Multiply the given values.
342:             */
343:            public static Object multiply(Object o1, Class c1, Object o2,
344:                    Class c2) {
345:                return op(o1, c1, o2, c2, OP_MULTIPLY);
346:            }
347:
348:            /**
349:             * Divide the given values.
350:             */
351:            public static Object divide(Object o1, Class c1, Object o2, Class c2) {
352:                return op(o1, c1, o2, c2, OP_DIVIDE);
353:            }
354:
355:            /**
356:             * Mod the given values.
357:             */
358:            public static Object mod(Object o1, Class c1, Object o2, Class c2) {
359:                return op(o1, c1, o2, c2, OP_MOD);
360:            }
361:
362:            /**
363:             * Perform the given operation on two numbers.
364:             */
365:            private static Object op(Object o1, Class c1, Object o2, Class c2,
366:                    int op) {
367:                Class promote = promote(c1, c2);
368:                if (promote == int.class) {
369:                    int n1 = (o1 == null) ? 0 : ((Number) o1).intValue();
370:                    int n2 = (o2 == null) ? 0 : ((Number) o2).intValue();
371:                    return op(n1, n2, op);
372:                }
373:                if (promote == float.class) {
374:                    float n1 = (o1 == null) ? 0F : ((Number) o1).floatValue();
375:                    float n2 = (o2 == null) ? 0F : ((Number) o2).floatValue();
376:                    return op(n1, n2, op);
377:                }
378:                if (promote == double.class) {
379:                    double n1 = (o1 == null) ? 0D : ((Number) o1).doubleValue();
380:                    double n2 = (o2 == null) ? 0D : ((Number) o2).doubleValue();
381:                    return op(n1, n2, op);
382:                }
383:                if (promote == long.class) {
384:                    long n1 = (o1 == null) ? 0L : ((Number) o1).longValue();
385:                    long n2 = (o2 == null) ? 0L : ((Number) o2).longValue();
386:                    return op(n1, n2, op);
387:                }
388:                if (promote == BigDecimal.class) {
389:                    BigDecimal n1 = (o1 == null) ? ZERO_BIGDECIMAL
390:                            : (BigDecimal) convert(o1, promote);
391:                    BigDecimal n2 = (o2 == null) ? ZERO_BIGDECIMAL
392:                            : (BigDecimal) convert(o2, promote);
393:                    return op(n1, n2, op);
394:                }
395:                if (promote == BigInteger.class) {
396:                    BigInteger n1 = (o1 == null) ? ZERO_BIGINTEGER
397:                            : (BigInteger) convert(o1, promote);
398:                    BigInteger n2 = (o2 == null) ? ZERO_BIGINTEGER
399:                            : (BigInteger) convert(o2, promote);
400:                    return op(n1, n2, op);
401:                }
402:                // default to int
403:                int n1 = (o1 == null) ? 0 : ((Number) o1).intValue();
404:                int n2 = (o2 == null) ? 0 : ((Number) o2).intValue();
405:                return op(n1, n2, op);
406:            }
407:
408:            /**
409:             * Return the result of a mathematical operation.
410:             */
411:            private static Object op(int n1, int n2, int op) {
412:                int tot;
413:                switch (op) {
414:                case OP_ADD:
415:                    tot = n1 + n2;
416:                    break;
417:                case OP_SUBTRACT:
418:                    tot = n1 - n2;
419:                    break;
420:                case OP_MULTIPLY:
421:                    tot = n1 * n2;
422:                    break;
423:                case OP_DIVIDE:
424:                    tot = n1 / n2;
425:                    break;
426:                case OP_MOD:
427:                    tot = n1 % n2;
428:                    break;
429:                default:
430:                    throw new InternalException();
431:                }
432:                return Numbers.valueOf(tot);
433:            }
434:
435:            /**
436:             * Return the result of a mathematical operation.
437:             */
438:            private static Object op(float n1, float n2, int op) {
439:                float tot;
440:                switch (op) {
441:                case OP_ADD:
442:                    tot = n1 + n2;
443:                    break;
444:                case OP_SUBTRACT:
445:                    tot = n1 - n2;
446:                    break;
447:                case OP_MULTIPLY:
448:                    tot = n1 * n2;
449:                    break;
450:                case OP_DIVIDE:
451:                    tot = n1 / n2;
452:                    break;
453:                case OP_MOD:
454:                    tot = n1 % n2;
455:                    break;
456:                default:
457:                    throw new InternalException();
458:                }
459:                return new Float(tot);
460:            }
461:
462:            /**
463:             * Return the result of a mathematical operation.
464:             */
465:            private static Object op(double n1, double n2, int op) {
466:                double tot;
467:                switch (op) {
468:                case OP_ADD:
469:                    tot = n1 + n2;
470:                    break;
471:                case OP_SUBTRACT:
472:                    tot = n1 - n2;
473:                    break;
474:                case OP_MULTIPLY:
475:                    tot = n1 * n2;
476:                    break;
477:                case OP_DIVIDE:
478:                    tot = n1 / n2;
479:                    break;
480:                case OP_MOD:
481:                    tot = n1 % n2;
482:                    break;
483:                default:
484:                    throw new InternalException();
485:                }
486:                return new Double(tot);
487:            }
488:
489:            /**
490:             * Return the result of a mathematical operation.
491:             */
492:            private static Object op(long n1, long n2, int op) {
493:                long tot;
494:                switch (op) {
495:                case OP_ADD:
496:                    tot = n1 + n2;
497:                    break;
498:                case OP_SUBTRACT:
499:                    tot = n1 - n2;
500:                    break;
501:                case OP_MULTIPLY:
502:                    tot = n1 * n2;
503:                    break;
504:                case OP_DIVIDE:
505:                    tot = n1 / n2;
506:                    break;
507:                case OP_MOD:
508:                    tot = n1 % n2;
509:                    break;
510:                default:
511:                    throw new InternalException();
512:                }
513:                return Numbers.valueOf(tot);
514:            }
515:
516:            /**
517:             * Return the result of a mathematical operation.
518:             */
519:            private static Object op(BigDecimal n1, BigDecimal n2, int op) {
520:                switch (op) {
521:                case OP_ADD:
522:                    return n1.add(n2);
523:                case OP_SUBTRACT:
524:                    return n1.subtract(n2);
525:                case OP_MULTIPLY:
526:                    return n1.multiply(n2);
527:                case OP_DIVIDE:
528:                    int scale = Math.max(n1.scale(), n2.scale());
529:                    return n1.divide(n2, scale, BigDecimal.ROUND_HALF_UP);
530:                case OP_MOD:
531:                    throw new UserException(_loc.get("mod-bigdecimal"));
532:                default:
533:                    throw new InternalException();
534:                }
535:            }
536:
537:            /**
538:             * Return the result of a mathematical operation.
539:             */
540:            private static Object op(BigInteger n1, BigInteger n2, int op) {
541:                switch (op) {
542:                case OP_ADD:
543:                    return n1.add(n2);
544:                case OP_SUBTRACT:
545:                    return n1.subtract(n2);
546:                case OP_MULTIPLY:
547:                    return n1.multiply(n2);
548:                case OP_DIVIDE:
549:                    return n1.divide(n2);
550:                default:
551:                    throw new InternalException();
552:                }
553:            }
554:
555:            /**
556:             * Parses the given declarations into a list of type, name, type, name...
557:             * Returns null if no declarations. Assumes declaration is not an empty
558:             * string and is already trimmed (valid assumptions given the checks made
559:             * in our setters).
560:             *
561:             * @param decType the type of declaration being parsed, for use in
562:             * error messages
563:             */
564:            public static List parseDeclaration(String dec, char split,
565:                    String decType) {
566:                if (dec == null)
567:                    return null;
568:
569:                // watch for common mixups between commas and semis
570:                char bad = (char) 0;
571:                if (split == ',')
572:                    bad = ';';
573:                else if (split == ';')
574:                    bad = ',';
575:
576:                char sentinal = ' ';
577:                char cur;
578:                int start = 0;
579:                boolean skipSpace = false;
580:                List results = new ArrayList(6);
581:                for (int i = 0; i < dec.length(); i++) {
582:                    cur = dec.charAt(i);
583:                    if (cur == bad)
584:                        throw new UserException(_loc.get("bad-dec", dec,
585:                                decType));
586:                    if (cur == ' ' && skipSpace) {
587:                        start++;
588:                        continue;
589:                    }
590:
591:                    skipSpace = false;
592:                    if (cur != sentinal)
593:                        continue;
594:
595:                    // if looking for spaces, look for split char, or vice versa
596:                    sentinal = (sentinal == ' ') ? split : ' ';
597:                    results.add(dec.substring(start, i).trim());
598:                    start = i + 1;
599:                    skipSpace = true;
600:                }
601:
602:                // add last token, if any
603:                if (start < dec.length())
604:                    results.add(dec.substring(start));
605:
606:                // if not an even number of elements, something is wrong
607:                if (results.isEmpty() || results.size() % 2 != 0)
608:                    throw new UserException(_loc.get("bad-dec", dec, decType));
609:
610:                return results;
611:            }
612:
613:            /**
614:             * Split the given expression list into distinct expressions. Assumes the
615:             * given string is not null or of zero length and is already trimmed
616:             * (valid assumptions given the checks in our setters and before
617:             * this method call).
618:             */
619:            public static List splitExpressions(String str, char split,
620:                    int expected) {
621:                if (str == null)
622:                    return null;
623:
624:                List exps = null;
625:                int parenDepth = 0;
626:                int begin = 0, pos = 0;
627:                boolean escape = false;
628:                boolean string = false;
629:                boolean nonspace = false;
630:                char quote = 0;
631:                for (char c; pos < str.length(); pos++) {
632:                    c = str.charAt(pos);
633:                    if (c == '\\') {
634:                        escape = !escape;
635:                        continue;
636:                    }
637:                    if (escape) {
638:                        escape = false;
639:                        continue;
640:                    }
641:
642:                    switch (c) {
643:                    case '\'':
644:                    case '"':
645:                        if (string && quote == c)
646:                            string = false;
647:                        else if (!string) {
648:                            quote = c;
649:                            string = true;
650:                        }
651:                        nonspace = true;
652:                        break;
653:                    case '(':
654:                        if (!string)
655:                            parenDepth++;
656:                        nonspace = true;
657:                        break;
658:                    case ')':
659:                        if (!string)
660:                            parenDepth--;
661:                        nonspace = true;
662:                        break;
663:                    case ' ':
664:                    case '\t':
665:                    case '\n':
666:                    case '\r':
667:                        if (c == split && !string && parenDepth == 0
668:                                && nonspace) {
669:                            if (exps == null)
670:                                exps = new ArrayList(expected);
671:                            exps.add(str.substring(begin, pos).trim());
672:                            begin = pos + 1;
673:                            nonspace = false;
674:                        }
675:                        break;
676:                    default:
677:                        if (c == split && !string && parenDepth == 0) {
678:                            if (exps == null)
679:                                exps = new ArrayList(expected);
680:                            exps.add(str.substring(begin, pos).trim());
681:                            begin = pos + 1;
682:                        }
683:                        nonspace = true;
684:                    }
685:                    escape = false;
686:                }
687:
688:                if (exps == null) {
689:                    // Collections.singletonList wasn't added until 1.3
690:                    exps = new ArrayList(1);
691:                    exps.add(str);
692:                    return exps;
693:                }
694:
695:                // add last exp and return array
696:                String last = str.substring(begin).trim();
697:                if (last.length() > 0)
698:                    exps.add(last);
699:                return exps;
700:            }
701:
702:            /**
703:             * Add the given access path metadatas to the full path list, making sure
704:             * to maintain only base metadatas in the list. The given list may be null.
705:             */
706:            public static List addAccessPathMetaDatas(List metas,
707:                    ClassMetaData[] path) {
708:                if (path == null || path.length == 0)
709:                    return metas;
710:
711:                // create set of base class metadatas in access path
712:                if (metas == null)
713:                    metas = new ArrayList();
714:                int last = metas.size();
715:
716:                // for every element in the path of this executor, compare it
717:                // to already-gathered elements to see if it should replace
718:                // a subclass in the list or should be added as a new base;
719:                // at least it's n^2 of a small n...
720:                ClassMetaData meta;
721:                boolean add;
722:                for (int i = 0; i < path.length; i++) {
723:                    add = true;
724:                    for (int j = 0; add && j < last; j++) {
725:                        meta = (ClassMetaData) metas.get(j);
726:
727:                        if (meta.getDescribedType().isAssignableFrom(
728:                                path[i].getDescribedType())) {
729:                            // list already contains base class
730:                            add = false;
731:                        } else if (path[i].getDescribedType().isAssignableFrom(
732:                                meta.getDescribedType())) {
733:                            // this element replaces its subclass
734:                            add = false;
735:                            metas.set(j, path[i]);
736:                        }
737:                    }
738:
739:                    // if no base class of current path element already in
740:                    // list and path element didn't replace a subclass in the
741:                    // list, then add it now as a new base
742:                    if (add)
743:                        metas.add(path[i]);
744:                }
745:                return metas;
746:            }
747:
748:            /**
749:             * Convert the user-given hint value to an aggregate listener.
750:             * The hint can be an aggregate listener instance or class name.
751:             */
752:            public static AggregateListener hintToAggregateListener(
753:                    Object hint, ClassLoader loader) {
754:                if (hint == null)
755:                    return null;
756:                if (hint instanceof  AggregateListener)
757:                    return (AggregateListener) hint;
758:
759:                Exception cause = null;
760:                if (hint instanceof  String) {
761:                    try {
762:                        return (AggregateListener) AccessController
763:                                .doPrivileged(J2DoPrivHelper
764:                                        .newInstanceAction(Class.forName(
765:                                                (String) hint, true, loader)));
766:                    } catch (Exception e) {
767:                        if (e instanceof  PrivilegedActionException)
768:                            e = ((PrivilegedActionException) e).getException();
769:                        cause = e;
770:                    }
771:                }
772:                throw new UserException(_loc.get("bad-agg-listener-hint", hint,
773:                        hint.getClass())).setCause(cause);
774:            }
775:
776:            /**
777:             * Convert the user-given hint value to an array of aggregate listeners.
778:             * The hint can be an aggregate listener, aggregate listener array,
779:             * collection, or comma-separated class names.
780:             */
781:            public static AggregateListener[] hintToAggregateListeners(
782:                    Object hint, ClassLoader loader) {
783:                if (hint == null)
784:                    return null;
785:                if (hint instanceof  AggregateListener[])
786:                    return (AggregateListener[]) hint;
787:                if (hint instanceof  AggregateListener)
788:                    return new AggregateListener[] { (AggregateListener) hint };
789:                if (hint instanceof  Collection) {
790:                    Collection c = (Collection) hint;
791:                    return (AggregateListener[]) c
792:                            .toArray(new AggregateListener[c.size()]);
793:                }
794:
795:                Exception cause = null;
796:                if (hint instanceof  String) {
797:                    String[] clss = Strings.split((String) hint, ",", 0);
798:                    AggregateListener[] aggs = new AggregateListener[clss.length];
799:                    try {
800:                        for (int i = 0; i < clss.length; i++)
801:                            aggs[i] = (AggregateListener) AccessController
802:                                    .doPrivileged(J2DoPrivHelper
803:                                            .newInstanceAction(Class.forName(
804:                                                    clss[i], true, loader)));
805:                        return aggs;
806:                    } catch (Exception e) {
807:                        if (e instanceof  PrivilegedActionException)
808:                            e = ((PrivilegedActionException) e).getException();
809:                        cause = e;
810:                    }
811:                }
812:                throw new UserException(_loc.get("bad-agg-listener-hint", hint,
813:                        hint.getClass())).setCause(cause);
814:            }
815:
816:            /**
817:             * Convert the user-given hint value to a filter listener.
818:             * The hint can be a filter listener instance or class name.
819:             */
820:            public static FilterListener hintToFilterListener(Object hint,
821:                    ClassLoader loader) {
822:                if (hint == null)
823:                    return null;
824:                if (hint instanceof  FilterListener)
825:                    return (FilterListener) hint;
826:
827:                Exception cause = null;
828:                if (hint instanceof  String) {
829:                    try {
830:                        return (FilterListener) AccessController
831:                                .doPrivileged(J2DoPrivHelper
832:                                        .newInstanceAction(Class.forName(
833:                                                (String) hint, true, loader)));
834:                    } catch (Exception e) {
835:                        if (e instanceof  PrivilegedActionException)
836:                            e = ((PrivilegedActionException) e).getException();
837:                        cause = e;
838:                    }
839:                }
840:                throw new UserException(_loc.get("bad-filter-listener-hint",
841:                        hint, hint.getClass())).setCause(cause);
842:            }
843:
844:            /**
845:             * Convert the user-given hint value to an array of filter listeners.
846:             * The hint can be a filter listener, filter listener array,
847:             * collection, or comma-separated class names.
848:             */
849:            public static FilterListener[] hintToFilterListeners(Object hint,
850:                    ClassLoader loader) {
851:                if (hint == null)
852:                    return null;
853:                if (hint instanceof  FilterListener[])
854:                    return (FilterListener[]) hint;
855:                if (hint instanceof  FilterListener)
856:                    return new FilterListener[] { (FilterListener) hint };
857:                if (hint instanceof  Collection) {
858:                    Collection c = (Collection) hint;
859:                    return (FilterListener[]) c.toArray(new FilterListener[c
860:                            .size()]);
861:                }
862:
863:                Exception cause = null;
864:                if (hint instanceof  String) {
865:                    String[] clss = Strings.split((String) hint, ",", 0);
866:                    FilterListener[] filts = new FilterListener[clss.length];
867:                    try {
868:                        for (int i = 0; i < clss.length; i++)
869:                            filts[i] = (FilterListener) AccessController
870:                                    .doPrivileged(J2DoPrivHelper
871:                                            .newInstanceAction(Class.forName(
872:                                                    clss[i], true, loader)));
873:                        return filts;
874:                    } catch (Exception e) {
875:                        if (e instanceof  PrivilegedActionException)
876:                            e = ((PrivilegedActionException) e).getException();
877:                        cause = e;
878:                    }
879:                }
880:                throw new UserException(_loc.get("bad-filter-listener-hint",
881:                        hint, hint.getClass())).setCause(cause);
882:            }
883:
884:            /**
885:             * Return the value of the property named by the hint key.
886:             */
887:            public static Object hintToGetter(Object target, String hintKey) {
888:                if (target == null || hintKey == null)
889:                    return null;
890:
891:                Method getter = Reflection.findGetter(target.getClass(),
892:                        hintKey, true);
893:                return Reflection.get(target, getter);
894:            }
895:
896:            /**
897:             * Set the value of the property named by the hint key.
898:             */
899:            public static void hintToSetter(Object target, String hintKey,
900:                    Object value) {
901:                if (target == null || hintKey == null)
902:                    return;
903:
904:                Method setter = Reflection.findSetter(target.getClass(),
905:                        hintKey, true);
906:                if (value instanceof  String) {
907:                    if ("null".equals(value))
908:                        value = null;
909:                    else {
910:                        try {
911:                            value = Strings.parse((String) value, setter
912:                                    .getParameterTypes()[0]);
913:                        } catch (Exception e) {
914:                            throw new UserException(_loc.get(
915:                                    "bad-setter-hint-arg", hintKey, value,
916:                                    setter.getParameterTypes()[0])).setCause(e);
917:                        }
918:                    }
919:                }
920:                Reflection.set(target, setter, value);
921:            }
922:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.