Source Code Cross Referenced for BeanUtils.java in  » Testing » PolePosition-0.20 » com » versant » core » util » 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 » Testing » PolePosition 0.20 » com.versant.core.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 1998 - 2005 Versant Corporation
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         * Versant Corporation - initial API and implementation
010:         */
011:        package com.versant.core.util;
012:
013:        import com.versant.core.util.classhelper.ClassHelper;
014:
015:        import java.util.*;
016:        import java.lang.reflect.Method;
017:        import java.lang.reflect.InvocationTargetException;
018:        import java.lang.reflect.Field;
019:        import java.lang.reflect.Modifier;
020:        import java.io.PrintStream;
021:        import java.io.IOException;
022:
023:        import com.versant.core.common.BindingSupportImpl;
024:        import com.versant.core.common.Debug;
025:
026:        /**
027:         * Static utility methods for working with java beans.
028:         */
029:        public class BeanUtils {
030:
031:            private BeanUtils() {
032:            }
033:
034:            private static final HashMap PRIMITIVE_NAME_MAP = new HashMap(17);
035:
036:            static {
037:                PRIMITIVE_NAME_MAP.put(Long.TYPE.getName(), Long.TYPE);
038:                PRIMITIVE_NAME_MAP.put(Integer.TYPE.getName(), Integer.TYPE);
039:                PRIMITIVE_NAME_MAP.put(Short.TYPE.getName(), Short.TYPE);
040:                PRIMITIVE_NAME_MAP.put(Byte.TYPE.getName(), Byte.TYPE);
041:                PRIMITIVE_NAME_MAP.put(Boolean.TYPE.getName(), Boolean.TYPE);
042:                PRIMITIVE_NAME_MAP
043:                        .put(Character.TYPE.getName(), Character.TYPE);
044:                PRIMITIVE_NAME_MAP.put(Float.TYPE.getName(), Float.TYPE);
045:                PRIMITIVE_NAME_MAP.put(Double.TYPE.getName(), Double.TYPE);
046:
047:                PRIMITIVE_NAME_MAP
048:                        .put(Long.TYPE.getName() + "[]", Long[].class);
049:                PRIMITIVE_NAME_MAP.put(Integer.TYPE.getName() + "[]",
050:                        Integer[].class);
051:                PRIMITIVE_NAME_MAP.put(Short.TYPE.getName() + "[]",
052:                        Short[].class);
053:                PRIMITIVE_NAME_MAP
054:                        .put(Byte.TYPE.getName() + "[]", Byte[].class);
055:                PRIMITIVE_NAME_MAP.put(Boolean.TYPE.getName() + "[]",
056:                        Boolean[].class);
057:                PRIMITIVE_NAME_MAP.put(Character.TYPE.getName() + "[]",
058:                        Character[].class);
059:                PRIMITIVE_NAME_MAP.put(Float.TYPE.getName() + "[]",
060:                        Float[].class);
061:                PRIMITIVE_NAME_MAP.put(Double.TYPE.getName() + "[]",
062:                        Double[].class);
063:
064:            }
065:
066:            private static final Class[] STRING_ARGS = new Class[] { String.class };
067:            private static final Class[] INT_ARGS = new Class[] { Integer.TYPE };
068:            private static final Class[] BOOLEAN_ARGS = new Class[] { Boolean.TYPE };
069:
070:            private static final String DEFAULT_PROP_FILE = "versant.properties";
071:
072:            /**
073:             * Find and set all properties or public fields on bean from key/value
074:             * pairs in props. Only int, String and boolean properties and fields may
075:             * be set. This is a NOP if props or bean is null.
076:             *
077:             * @exception IllegalArgumentException if any are invalid
078:             */
079:            public static void setProperties(Object bean, Map props)
080:                    throws IllegalArgumentException {
081:                if (props == null || bean == null)
082:                    return;
083:                Class cls = bean.getClass();
084:                Object[] args = new Object[1];
085:                for (Iterator i = props.entrySet().iterator(); i.hasNext();) {
086:                    Map.Entry e = (Map.Entry) i.next();
087:                    String prop = (String) e.getKey();
088:                    String value = (String) e.getValue();
089:                    Field f = findField(prop, cls, value, args);
090:                    if (f != null) {
091:                        try {
092:                            f.set(bean, args);
093:                        } catch (Throwable x) {
094:                            if (x instanceof  InvocationTargetException) {
095:                                x = ((InvocationTargetException) x)
096:                                        .getTargetException();
097:                            }
098:                            throw BindingSupportImpl.getInstance()
099:                                    .illegalArgument(
100:                                            x.getClass() + ": "
101:                                                    + x.getMessage());
102:                        }
103:                    }
104:                    Method m = findSetMethod(prop, cls, value, args);
105:                    try {
106:                        m.invoke(bean, args);
107:                    } catch (IllegalArgumentException x) {
108:                        throw x;
109:                    } catch (Throwable x) {
110:                        if (x instanceof  InvocationTargetException) {
111:                            x = ((InvocationTargetException) x)
112:                                    .getTargetException();
113:                        }
114:                        throw BindingSupportImpl.getInstance().illegalArgument(
115:                                x.getClass() + ": " + x.getMessage());
116:                    }
117:                }
118:            }
119:
120:            /**
121:             * Set a property on bean. Only int, String and boolean properties may be
122:             * set.
123:             * @exception IllegalArgumentException if invalid
124:             */
125:            public static void setProperty(Object bean, String prop,
126:                    String value) throws IllegalArgumentException {
127:                Class cls = bean.getClass();
128:                Object[] args = new Object[1];
129:                Method m = findSetMethod(prop, cls, value, args);
130:                try {
131:                    m.invoke(bean, args);
132:                } catch (IllegalArgumentException x) {
133:                    throw x;
134:                } catch (Throwable x) {
135:                    if (x instanceof  InvocationTargetException) {
136:                        x = ((InvocationTargetException) x)
137:                                .getTargetException();
138:                    }
139:                    throw BindingSupportImpl.getInstance().illegalArgument(
140:                            x.getClass() + ": " + x.getMessage());
141:                }
142:            }
143:
144:            private static Field findField(String prop, Class cls,
145:                    String value, Object[] args) {
146:                try {
147:                    Field f = cls.getField(prop);
148:                    Class t = f.getType();
149:                    if (t == Integer.TYPE || t == Integer.class) {
150:                        args[0] = toInteger(value, prop);
151:                    } else if (t == Boolean.TYPE || t == Boolean.class) {
152:                        args[0] = toBoolean(value, prop);
153:                    } else if (t == String.class) {
154:                        args[0] = value;
155:                    } else {
156:                        throw BindingSupportImpl.getInstance().internal(
157:                                "Unsupported field type: " + f);
158:                    }
159:                    return f;
160:                } catch (NoSuchFieldException e) {
161:                    return null;
162:                }
163:            }
164:
165:            private static Method findSetMethod(String prop, Class cls,
166:                    String value, Object[] args) {
167:                String name = "set" + Character.toUpperCase(prop.charAt(0))
168:                        + prop.substring(1);
169:                Method m;
170:                try {
171:                    try {
172:                        m = cls.getMethod(name, STRING_ARGS);
173:                        args[0] = value;
174:                    } catch (NoSuchMethodException x) {
175:                        try {
176:                            m = cls.getMethod(name, INT_ARGS);
177:                            args[0] = toInteger(value, prop);
178:                        } catch (NoSuchMethodException xx) {
179:                            m = cls.getMethod(name, BOOLEAN_ARGS);
180:                            args[0] = toBoolean(value, prop);
181:                        }
182:                    }
183:                } catch (NoSuchMethodException x) {
184:                    String pos = getClosestProperty(prop, cls);
185:                    String all = getAllPropsFormatted(cls);
186:                    throw BindingSupportImpl
187:                            .getInstance()
188:                            .illegalArgument(
189:                                    "An invalid property '"
190:                                            + prop
191:                                            + "' was set on "
192:                                            + cls.getName()
193:                                            + ". "
194:                                            + (pos != null ? ("The property closely matches '"
195:                                                    + pos + "'. ")
196:                                                    : "")
197:                                            + (all != null ? ("All possible properties are: " + all)
198:                                                    : ""));
199:                }
200:                return m;
201:            }
202:
203:            private static Boolean toBoolean(String value, String prop) {
204:                if (value.equals("true")) {
205:                    return Boolean.TRUE;
206:                } else if (value.equals("false")) {
207:                    return Boolean.FALSE;
208:                } else {
209:                    throw BindingSupportImpl.getInstance().illegalArgument(
210:                            "Expected true or false value for '" + prop
211:                                    + "' got '" + value + "'");
212:                }
213:            }
214:
215:            private static Integer toInteger(String value, String prop) {
216:                try {
217:                    return new Integer(value);
218:                } catch (NumberFormatException xx) {
219:                    throw BindingSupportImpl.getInstance().illegalArgument(
220:                            "Expected int value for '" + prop + "' got '"
221:                                    + value + "'");
222:                }
223:            }
224:
225:            /**
226:             * Process a list of command line arguments in [-propertyname value]+
227:             * format setting each on the bean.
228:             * @param args Command line arguments as passed to a main method
229:             * @param expected Names of allowed properties
230:             * @exception IllegalArgumentException if args are invalid
231:             */
232:            public static void setCommandLineArgs(Object bean, String[] args,
233:                    String[] expected) throws IllegalArgumentException {
234:
235:                int n = args.length;
236:                Object[] v = new Object[1];
237:                for (int i = 0; i < n; i++) {
238:                    String s = args[i];
239:                    if (!s.startsWith("-")) {
240:                        throw BindingSupportImpl.getInstance().illegalArgument(
241:                                "Invalid argument: " + s);
242:                    }
243:                    String prop = s.substring(1);
244:                    int j;
245:                    for (j = expected.length - 1; j >= 0; j--) {
246:                        if (expected[j].equals(prop))
247:                            break;
248:                    }
249:                    if (j < 0) {
250:                        throw BindingSupportImpl.getInstance().illegalArgument(
251:                                "Invalid argument: " + prop);
252:                    }
253:                    if (++i == n) {
254:                        throw BindingSupportImpl.getInstance().illegalArgument(
255:                                "Expected value for " + prop);
256:                    }
257:                    String value = args[i];
258:                    Method m = findSetMethod(prop, bean.getClass(), value, v);
259:                    try {
260:                        m.invoke(bean, v);
261:                    } catch (IllegalArgumentException x) {
262:                        throw x;
263:                    } catch (Throwable x) {
264:                        if (x instanceof  InvocationTargetException) {
265:                            x = ((InvocationTargetException) x)
266:                                    .getTargetException();
267:                        }
268:                        throw BindingSupportImpl.getInstance().illegalArgument(
269:                                "Invalid value for " + prop + ": "
270:                                        + x.getClass().getName() + ": "
271:                                        + x.getMessage());
272:                    }
273:                }
274:            }
275:
276:            /**
277:             * Add any properties from a semicolon delimited String ps to props.
278:             */
279:            public static void parseProperties(String ps, Properties props) {
280:                StringTokenizer t = new StringTokenizer(ps, "=", false);
281:                for (;;) {
282:                    String key;
283:                    try {
284:                        key = t.nextToken("=");
285:                        if (key.startsWith(";"))
286:                            key = key.substring(1);
287:                    } catch (NoSuchElementException e) {
288:                        break;
289:                    }
290:                    try {
291:                        String value = t.nextToken(";").substring(1);
292:                        props.put(key, value);
293:                    } catch (NoSuchElementException e) {
294:                        throw BindingSupportImpl.getInstance().runtime(
295:                                "Expected semicolon delimited property=value pairs: '"
296:                                        + ps + "'");
297:                    }
298:                }
299:            }
300:
301:            /**
302:             * Parse semicolon delimited properties from props and set them on bean.
303:             * This can handle String, int and boolean properties.
304:             * @exception IllegalArgumentException on errors
305:             */
306:            public static void parseProperties(String props, Object bean) {
307:                if (props == null || props.length() == 0)
308:                    return;
309:                Class cls = bean.getClass();
310:                Object[] args = new Object[1];
311:                int last = 0;
312:                for (;;) {
313:                    int i = props.indexOf('=', last);
314:                    if (i < 0) {
315:                        throw BindingSupportImpl.getInstance().illegalArgument(
316:                                "Expected property name at position " + last
317:                                        + ": " + props);
318:                    }
319:                    String key = props.substring(last, i);
320:                    int j = props.indexOf(';', ++i);
321:                    String value;
322:                    if (j < 0)
323:                        value = props.substring(i);
324:                    else
325:                        value = props.substring(i, j);
326:                    Method m = findSetMethod(key, cls, value, args);
327:                    try {
328:                        m.invoke(bean, args);
329:                    } catch (Exception e) {
330:                        Throwable t;
331:                        if (e instanceof  InvocationTargetException) {
332:                            t = ((InvocationTargetException) e)
333:                                    .getTargetException();
334:                        } else {
335:                            t = e;
336:                        }
337:                        throw BindingSupportImpl.getInstance().runtime(
338:                                "Error setting property '" + key + "' to '"
339:                                        + value + "'", t);
340:                    }
341:                    if (j < 0)
342:                        break;
343:                    last = j + 1;
344:                }
345:            }
346:
347:            /**
348:             * Convert a primitive name (int, byte etc.) to a class or null if the
349:             * name is not a primitive.
350:             */
351:            public static Class toClass(String primitiveName) {
352:                return (Class) PRIMITIVE_NAME_MAP.get(primitiveName);
353:            }
354:
355:            /**
356:             * Load the class with name using loaded. The name may be a primitive
357:             * (int, byte etc) or a single dimensional array (e.g. int[]).
358:             */
359:            public static Class loadClass(String name, boolean initialize,
360:                    ClassLoader loader) throws ClassNotFoundException {
361:                Class ans = toClass(name);
362:                if (ans == null) {
363:                    int i = name.indexOf("[]");
364:                    if (i >= 0) {
365:                        name = "[L" + name.substring(0, i);
366:                    }
367:                    ans = ClassHelper.get().classForName(name, initialize,
368:                            loader);
369:                }
370:                return ans;
371:            }
372:
373:            /**
374:             * Create a new instance of cname using loader. It must be an instance of
375:             * mustBe.
376:             */
377:            public static Object newInstance(String cname, ClassLoader loader,
378:                    Class mustBe) {
379:                try {
380:                    Class cls = ClassHelper.get().classForName(cname, true,
381:                            loader);
382:                    if (!mustBe.isAssignableFrom(cls)) {
383:                        throw BindingSupportImpl.getInstance().runtime(
384:                                cname + " is not a " + mustBe.getName());
385:                    }
386:                    return cls.newInstance();
387:                } catch (Exception e) {
388:                    if (BindingSupportImpl.getInstance().isOwnException(e)) {
389:                        throw (RuntimeException) e;
390:                    }
391:                    throw BindingSupportImpl.getInstance().runtime(
392:                            "Unable to create instance of " + cname + ": "
393:                                    + e.getMessage(), e);
394:                }
395:            }
396:
397:            /**
398:             * Get the value of a property of bean.
399:             */
400:            public static Object getPropertyValue(Object bean, String property)
401:                    throws Exception {
402:                Class cls = bean.getClass();
403:                property = Character.toUpperCase(property.charAt(0))
404:                        + property.substring(1);
405:                Method m;
406:                try {
407:                    m = cls.getMethod("get" + property, null);
408:                } catch (NoSuchMethodException e) {
409:                    m = cls.getMethod("is" + property, null);
410:                }
411:                return m.invoke(bean, null);
412:            }
413:
414:            /**
415:             * Fill o by introspecting all of its public non-static, non-final fields
416:             * that are int, Integer, boolean, Boolean or String and looking for
417:             * properties named prefix + fieldname to populate them.
418:             */
419:            public static void fillFields(Object o, String prefix, Map props,
420:                    Set fieldsToIgnore) {
421:                Field[] a = o.getClass().getFields();
422:                for (int i = 0; i < a.length; i++) {
423:                    Field f = a[i];
424:                    int m = f.getModifiers();
425:                    if (Modifier.isFinal(m) || Modifier.isStatic(m)
426:                            || !isSupportedFieldType(f.getType())) {
427:                        continue;
428:                    }
429:                    String name = f.getName();
430:                    if (fieldsToIgnore != null && fieldsToIgnore.contains(name)) {
431:                        continue;
432:                    }
433:                    String prop = prefix + name;
434:                    String value = (String) props.get(prop);
435:                    if (value == null) {
436:                        continue;
437:                    }
438:                    setFieldValue(f, o, value, prop);
439:                }
440:            }
441:
442:            public static boolean isSupportedFieldType(Class t) {
443:                return t == Integer.TYPE || t == Integer.class
444:                        || t == Boolean.TYPE || t == Boolean.class
445:                        || t == String.class;
446:            }
447:
448:            /**
449:             * Set field f on o converting value to the correct type for the field.
450:             * Fields of int, Integer, boolean, Boolean and String are suppported.
451:             */
452:            private static void setFieldValue(Field f, Object o, String value,
453:                    String name) {
454:                Class t = f.getType();
455:                Object arg;
456:                if (t == Integer.TYPE || t == Integer.class) {
457:                    arg = toInteger(value, name);
458:                } else if (t == Boolean.TYPE || t == Boolean.class) {
459:                    arg = toBoolean(value, name);
460:                } else if (t == String.class) {
461:                    arg = value;
462:                } else {
463:                    throw BindingSupportImpl.getInstance().illegalArgument(
464:                            "Unsupported field type: " + f);
465:                }
466:                try {
467:                    f.set(o, arg);
468:                } catch (Throwable x) {
469:                    if (x instanceof  InvocationTargetException) {
470:                        x = ((InvocationTargetException) x)
471:                                .getTargetException();
472:                    }
473:                    throw BindingSupportImpl.getInstance().illegalArgument(
474:                            x.getClass() + ": " + x.getMessage());
475:                }
476:            }
477:
478:            /**
479:             * The result of a call to processCmdline.
480:             */
481:            public static class CmdLineResult {
482:                public HashSet fieldsFilled = new HashSet();
483:                public Properties properties;
484:            }
485:
486:            /**
487:             * <p>Process command line arguments. Arguments starting with a dash are
488:             * expected to match the names of public fields in o (like
489:             * {@link #fillFields}) with non-boolean fields requiring an argument.
490:             * If a boolean field does not have an argument then it is set to true.</p>
491:             *
492:             * <p>If hasProps is true then there is an implicit -p arguement to
493:             * specify the resource name or filename of a properties file to load and
494:             * return. The default name is versant.properties. The argument is first
495:             * treated as a file and if this fails then as a resource. System
496:             * properties starting with "versant." or "javax.jdo.option." are added
497:             * after the properties are loaded. Finally command line arguments of the
498:             * form key=value are added i.e. they override any previous value.</p>
499:             *
500:             * <p>Errors are printed to System.err followed by usage information and
501:             * an IllegalArgumentException is thrown.</p>
502:             *
503:             * <p>If one of the args is /? or -help or --help then the usage is printed
504:             * and an IllegalArgumentException is thrown.</p>
505:             *
506:             * @return The fieldsFilled set contains the names of all fields that were
507:             * set from the command line. If hasProps is true then the properties field
508:             * on the result holds all properties with overrides already applied
509:             * otherwise it is null.
510:             */
511:            public static CmdLineResult processCmdLine(String[] args,
512:                    ClassLoader loader, Object o, String[] requiredFields,
513:                    String toolName, String toolDescription, boolean hasProps) {
514:                try {
515:                    CmdLineResult res = new CmdLineResult();
516:                    Properties overrides = hasProps ? new Properties() : null;
517:                    String propFileName = DEFAULT_PROP_FILE;
518:                    for (int i = 0; i < args.length;) {
519:                        String arg = args[i++];
520:                        if (arg.equals("-p")) {
521:                            if (i >= args.length) {
522:                                throw BindingSupportImpl
523:                                        .getInstance()
524:                                        .illegalArgument(
525:                                                "Expected file or resource name for -p");
526:                            }
527:                            propFileName = args[i++];
528:                        } else if (arg.equals("/?") || arg.equals("-help")
529:                                || arg.equals("--help")) {
530:                            throw BindingSupportImpl.getInstance()
531:                                    .illegalArgument("");
532:                        } else if (arg.startsWith("-")) {
533:                            String key = arg.substring(1);
534:                            if (key.length() == 0) {
535:                                throw BindingSupportImpl
536:                                        .getInstance()
537:                                        .illegalArgument(
538:                                                "Expected name of argument after '-'");
539:                            }
540:                            try {
541:                                Field f = o.getClass().getField(key);
542:                                Class t = f.getType();
543:                                int m = f.getModifiers();
544:                                if (Modifier.isFinal(m) || Modifier.isStatic(m)
545:                                        || !isSupportedFieldType(t)) {
546:                                    throw new NoSuchFieldException();
547:                                }
548:                                String value = i < args.length ? args[i] : null;
549:                                if (value.startsWith("-")) {
550:                                    value = null;
551:                                }
552:                                if (value == null) {
553:                                    if (t == Boolean.class || t == Boolean.TYPE) {
554:                                        value = "true";
555:                                    } else {
556:                                        throw BindingSupportImpl.getInstance()
557:                                                .illegalArgument(
558:                                                        "Expected value for "
559:                                                                + arg);
560:                                    }
561:                                } else {
562:                                    ++i;
563:                                }
564:                                setFieldValue(f, o, value, arg);
565:                                res.fieldsFilled.add(f.getName());
566:                            } catch (NoSuchFieldException e) {
567:                                throw BindingSupportImpl.getInstance()
568:                                        .illegalArgument(
569:                                                "Unknown option: " + arg);
570:                            }
571:                        } else {
572:                            int pos = hasProps ? arg.indexOf('=') : -1;
573:                            if (pos <= 0) {
574:                                throw BindingSupportImpl.getInstance()
575:                                        .illegalArgument(
576:                                                "Invalid argument: " + arg);
577:                            }
578:                            String key = arg.substring(0, i);
579:                            String value = arg.substring(i + 1);
580:                            overrides.put(key, value);
581:                        }
582:                    }
583:                    if (hasProps) {
584:                        Properties p;
585:                        try {
586:                            p = PropertiesLoader.loadProperties(propFileName);
587:                            if (p == null) {
588:                                p = PropertiesLoader.loadProperties(loader,
589:                                        propFileName);
590:                                if (p == null) {
591:                                    throw BindingSupportImpl.getInstance()
592:                                            .illegalArgument(
593:                                                    "File or resource not found: '"
594:                                                            + propFileName
595:                                                            + "'");
596:                                }
597:                            }
598:                        } catch (IOException e) {
599:                            throw BindingSupportImpl.getInstance()
600:                                    .illegalArgument(
601:                                            "Error loading " + propFileName);
602:                        }
603:                        Properties sp = System.getProperties();
604:                        for (Iterator i = sp.keySet().iterator(); i.hasNext();) {
605:                            String key = (String) i.next();
606:                            if (key.startsWith("versant.")
607:                                    || key.startsWith("javax.jdo.option.")) {
608:                                String value = sp.getProperty(key);
609:                                System.err.println("Using system property: "
610:                                        + key + "=" + value);
611:                                p.put(key, value);
612:                            }
613:                        }
614:                        for (Iterator i = overrides.keySet().iterator(); i
615:                                .hasNext();) {
616:                            String key = (String) i.next();
617:                            String value = overrides.getProperty(key);
618:                            System.err.println("Command line override: " + key
619:                                    + "=" + value);
620:                            p.put(key, value);
621:                        }
622:                        res.properties = p;
623:                    }
624:                    return res;
625:                } catch (IllegalArgumentException e) {
626:                    System.err.println(e.getMessage());
627:                    System.err.println();
628:                    printUsage(o, requiredFields, toolName, toolDescription,
629:                            hasProps, System.err);
630:                    throw e;
631:                }
632:            }
633:
634:            /**
635:             * <p>Print command line usage information by introspecting o to find all
636:             * of its public non-static, non-final fields that are int, Integer,
637:             * boolean, Boolean or String. For each field a public static final
638:             * String field named HELP_fieldname is used to provided a description
639:             * of the field if present. The values of the fields in o are assumed
640:             * to be the defaults.</p>
641:             *
642:             * <p>If hasProps is true the information on how to specify key=value
643:             * properties is also printed.</p>
644:             */
645:            public static void printUsage(Object o, String[] requiredFields,
646:                    String toolName, String toolDescription, boolean hasProps,
647:                    PrintStream out) {
648:                Field[] all = o.getClass().getFields();
649:
650:                // find all of the help text
651:                HashMap helpMap = new HashMap();
652:                for (int i = 0; i < all.length; i++) {
653:                    Field f = all[i];
654:                    int m = f.getModifiers();
655:                    if (!(Modifier.isFinal(m) && Modifier.isStatic(m))
656:                            || f.getType() != String.class) {
657:                        continue;
658:                    }
659:                    String name = f.getName();
660:                    if (name.startsWith("HELP_")) {
661:                        try {
662:                            helpMap.put(name.substring(5), f.get(null));
663:                        } catch (IllegalAccessException e) {
664:                            throw BindingSupportImpl.getInstance().internal(
665:                                    e.toString(), e);
666:                        }
667:                    }
668:                }
669:
670:                // map all the options to their default values
671:                HashMap defaults = new HashMap();
672:                ArrayList options = new ArrayList();
673:                HashMap fields = new HashMap();
674:                int longestOp = 0;
675:                if (hasProps) {
676:                    String s = "-p " + DEFAULT_PROP_FILE;
677:                    longestOp = s.length();
678:                }
679:                for (int i = 0; i < all.length; i++) {
680:                    Field f = all[i];
681:                    int m = f.getModifiers();
682:                    if (Modifier.isFinal(m) || Modifier.isStatic(m)
683:                            || !isSupportedFieldType(f.getType())) {
684:                        continue;
685:                    }
686:                    String op = f.getName();
687:                    options.add(op);
688:                    fields.put(op, f);
689:                    String def;
690:                    try {
691:                        Object v = f.get(o);
692:                        def = v == null ? null : v.toString();
693:                    } catch (IllegalAccessException e) {
694:                        throw BindingSupportImpl.getInstance().internal(
695:                                e.toString(), e);
696:                    }
697:                    String s = "-" + op;
698:                    if (def != null) {
699:                        defaults.put(op, def);
700:                        s = s + " " + def;
701:                    }
702:                    if (s.length() > longestOp) {
703:                        longestOp = s.length();
704:                    }
705:                }
706:
707:                // now print everything
708:                out.println("Versant Open Access " + Debug.VERSION + " "
709:                        + toolName);
710:                out.println("Usage: " + toolName
711:                        + (hasProps ? " -p <property file or resource>" : "")
712:                        + " [OPTION] ... "
713:                        + (hasProps ? " [property=value] ..." : ""));
714:                out.println(toolDescription);
715:                out.println();
716:                HashSet requiredSet = new HashSet();
717:                int rfc = requiredFields == null ? 0 : requiredFields.length;
718:                if (rfc > 0) {
719:                    requiredSet.addAll(Arrays.asList(requiredFields));
720:                    out.println("Required arguements:");
721:                    for (int i = 0; i < requiredFields.length; i++) {
722:                        printOption(requiredFields[i], fields, null, helpMap,
723:                                longestOp, out);
724:                    }
725:                }
726:                int n = options.size();
727:                if (n - rfc > 0 || hasProps) {
728:                    out.println("Optional arguements with default values:");
729:                    if (hasProps) {
730:                        printOption(
731:                                "p",
732:                                DEFAULT_PROP_FILE,
733:                                "Name of file or resource to load properties from",
734:                                longestOp, out);
735:                    }
736:                    for (int i = 0; i < n; i++) {
737:                        String op = (String) options.get(i);
738:                        if (!requiredSet.contains(op)) {
739:                            printOption(op, fields, defaults, helpMap,
740:                                    longestOp, out);
741:                        }
742:                    }
743:                    out.println();
744:                }
745:                if (hasProps) {
746:                    out
747:                            .println("Use property=value pairs to override properties "
748:                                    + "including properties set from System properties.");
749:                    out.println();
750:                }
751:            }
752:
753:            private static void printOption(String op, HashMap fields,
754:                    HashMap defaults, HashMap helpMap, int longestOp,
755:                    PrintStream out) {
756:                Field f = (Field) fields.get(op);
757:                String def = defaults == null ? null : (String) defaults
758:                        .get(op);
759:                String help = (String) helpMap.get(op);
760:                if (help == null) {
761:                    Class t = f.getType();
762:                    if (t == Integer.class || t == Integer.TYPE) {
763:                        help = "int";
764:                    } else if (t == Boolean.class || t == Boolean.TYPE) {
765:                        help = "true|false";
766:                    } else if (t == String.class) {
767:                        help = "string";
768:                    } else {
769:                        help = "...";
770:                    }
771:                }
772:                printOption(op, def, help, longestOp, out);
773:            }
774:
775:            private static void printOption(String op, String def, String help,
776:                    int longestOp, PrintStream out) {
777:                StringBuffer b = new StringBuffer();
778:                b.append('-');
779:                b.append(op);
780:                if (def != null) {
781:                    b.append(' ');
782:                    b.append(def);
783:                }
784:                for (int j = longestOp - b.length() + 2; j > 0; j--) {
785:                    b.append(' ');
786:                }
787:                b.append(help);
788:                out.println(b.toString());
789:            }
790:
791:            /**
792:             * Get the closest property that can be set to this s, or return null, if
793:             * they are too diffrent.
794:             */
795:            private static String getClosestProperty(String s, Class cls) {
796:                Method[] methods = cls.getMethods();
797:                int j = 0;
798:                for (int i = 0; i < methods.length; i++) {
799:                    String methodName = methods[i].getName();
800:                    if (methodName.startsWith("set") && methodName.length() > 3) {
801:                        Class params[] = methods[i].getParameterTypes();
802:                        if (params.length != 0 && !params[0].isArray()) {
803:                            j++;
804:                        }
805:                    }
806:
807:                }
808:                if (j == 0) {
809:                    return null;
810:                }
811:                String[] targets = new String[j];
812:                j = 0;
813:                for (int i = 0; i < methods.length; i++) {
814:                    String methodName = methods[i].getName();
815:                    if (methodName.startsWith("set") && methodName.length() > 3) {
816:                        Class params[] = methods[i].getParameterTypes();
817:                        if (params.length != 0 && !params[0].isArray()) {
818:                            targets[j] = Character.toLowerCase(methodName
819:                                    .charAt(3))
820:                                    + (methodName.length() > 4 ? methodName
821:                                            .substring(4) : "");
822:                            j++;
823:                        }
824:                    }
825:                }
826:
827:                return getClosest(s, targets, 0.25f);
828:            }
829:
830:            /**
831:             * Does this class contain this property
832:             */
833:            private static boolean containsProperties(Class cls, String prop) {
834:                return getAllProperties(cls).contains(prop);
835:            }
836:
837:            /**
838:             * Get all the valid properties for this class.
839:             */
840:            public static Set getAllProperties(Class cls) {
841:                Method[] methods = cls.getMethods();
842:                Set set = new HashSet();
843:                for (int i = 0; i < methods.length; i++) {
844:                    String methodName = methods[i].getName();
845:                    if (methodName.startsWith("set") && methodName.length() > 3) {
846:                        String prop = Character.toLowerCase(methodName
847:                                .charAt(3))
848:                                + (methodName.length() > 4 ? methodName
849:                                        .substring(4) : "");
850:                        set.add(prop);
851:                    }
852:
853:                }
854:
855:                Field fields[] = cls.getFields();
856:                for (int i = 0; i < fields.length; i++) {
857:                    String fieldName = fields[i].getName();
858:                    String prop = Character.toLowerCase(fieldName.charAt(0))
859:                            + (fieldName.length() > 1 ? fieldName.substring(1)
860:                                    : "");
861:
862:                    set.add(prop);
863:                }
864:                return set;
865:
866:            }
867:
868:            /**
869:             * format the properties.
870:             */
871:            private static String getAllPropsFormatted(Class cls) {
872:                Set set = getAllProperties(cls);
873:                if (set.isEmpty()) {
874:                    return null;
875:                } else {
876:                    ArrayList list = new ArrayList(set);
877:                    Collections.sort(list);
878:                    StringBuffer buff = new StringBuffer();
879:                    for (Iterator iter = list.iterator(); iter.hasNext();) {
880:                        String name = (String) iter.next();
881:
882:                        buff.append(name);
883:                        buff.append(';');
884:                    }
885:                    return buff.toString();
886:                }
887:            }
888:
889:            /**
890:             * This method uses a Levenshtein Distance algorithm to find the closest
891:             * match.
892:             */
893:            private static String getClosest(String s, String[] targets,
894:                    float diffs) {
895:                if (s == null || targets == null) {
896:                    return null;
897:                }
898:
899:                HashMap map = new HashMap();
900:                for (int i = 0; i < targets.length; i++) {
901:                    map.put(targets[i], targets[i].toUpperCase());
902:                }
903:                s = s.toUpperCase();
904:                int n = s.length(); // length of s
905:
906:                float srcLenght = (float) n;
907:
908:                float currentWeight = 1;
909:                String currentString = null;
910:                Set set = map.keySet();
911:                for (Iterator iter = set.iterator(); iter.hasNext();) {
912:                    String origianal = (String) iter.next();
913:                    String t = (String) map.get(origianal);
914:
915:                    int m = t.length(); // length of t
916:
917:                    int p[] = new int[n + 1]; //'previous' cost array, horizontally
918:                    int d[] = new int[n + 1]; // cost array, horizontally
919:                    int _d[]; //placeholder to assist in swapping p and d
920:
921:                    // indexes into strings s and t
922:                    int i; // iterates through s
923:                    int j; // iterates through t
924:
925:                    char t_j; // jth character of t
926:
927:                    int cost; // cost
928:
929:                    for (i = 0; i <= n; i++) {
930:                        p[i] = i;
931:                    }
932:
933:                    for (j = 1; j <= m; j++) {
934:                        t_j = t.charAt(j - 1);
935:                        d[0] = j;
936:
937:                        for (i = 1; i <= n; i++) {
938:                            cost = s.charAt(i - 1) == t_j ? 0 : 1;
939:                            // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
940:                            d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1),
941:                                    p[i - 1] + cost);
942:                        }
943:
944:                        // copy current distance counts to 'previous row' distance counts
945:                        _d = p;
946:                        p = d;
947:                        d = _d;
948:                    }
949:
950:                    // our last action in the above loop was to switch d and p, so p now
951:                    // actually has the most recent cost counts
952:                    float diff = ((float) p[n]) / srcLenght;
953:
954:                    if (currentWeight > diff) {
955:                        currentWeight = diff;
956:                        currentString = origianal;
957:                    }
958:                }
959:
960:                if (currentWeight <= diffs) {
961:                    return currentString;
962:                } else {
963:                    return null;
964:                }
965:            }
966:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.