Source Code Cross Referenced for Options.java in  » Database-ORM » openjpa » org » apache » openjpa » lib » 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 » Database ORM » openjpa » org.apache.openjpa.lib.util 
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.lib.util;
020:
021:        import java.lang.reflect.Constructor;
022:        import java.lang.reflect.Field;
023:        import java.lang.reflect.Member;
024:        import java.lang.reflect.Method;
025:        import java.security.AccessController;
026:        import java.security.PrivilegedActionException;
027:        import java.util.Collection;
028:        import java.util.Iterator;
029:        import java.util.LinkedList;
030:        import java.util.List;
031:        import java.util.Map;
032:        import java.util.Properties;
033:        import java.util.TreeSet;
034:
035:        import org.apache.commons.lang.StringUtils;
036:
037:        import serp.util.Strings;
038:
039:        /**
040:         * A specialization of the {@link Properties} map type with the added
041:         * abilities to read application options from the command line and to
042:         * use bean patterns to set an object's properties via command-line the
043:         * stored mappings.
044:         * A typical use pattern for this class is to construct a new instance
045:         * in the <code>main</code> method, then call {@link #setFromCmdLine} with the
046:         * given args. Next, an instanceof the class being invoked is created, and
047:         * {@link #setInto} is called with that instance as a parameter. With this
048:         * pattern, the user can configure any bean properties of the class, or even
049:         * properties of classes reachable from the class, through the command line.
050:         *
051:         * @author Abe White
052:         * @nojavadoc
053:         */
054:        public class Options extends TypedProperties {
055:
056:            /**
057:             * Immutable empty instance.
058:             */
059:            public static Options EMPTY = new EmptyOptions();
060:
061:            // maps primitive types to the appropriate wrapper class and default value
062:            private static Object[][] _primWrappers = new Object[][] {
063:                    { boolean.class, Boolean.class, Boolean.FALSE },
064:                    { byte.class, Byte.class, new Byte((byte) 0) },
065:                    { char.class, Character.class, new Character((char) 0) },
066:                    { double.class, Double.class, new Double(0D) },
067:                    { float.class, Float.class, new Float(0F) },
068:                    { int.class, Integer.class, new Integer(0) },
069:                    { long.class, Long.class, new Long(0L) },
070:                    { short.class, Short.class, new Short((short) 0) }, };
071:
072:            /**
073:             * Default constructor.
074:             */
075:            public Options() {
076:                super ();
077:            }
078:
079:            /**
080:             * Construct the options instance with the given set of defaults.
081:             *
082:             * @see Properties#Properties(Properties)
083:             */
084:            public Options(Properties defaults) {
085:                super (defaults);
086:            }
087:
088:            /**
089:             * Parses the given argument list into flag/value pairs, which are stored
090:             * as properties. Flags that are present without values are given
091:             * the value "true". If any flag is found for which there is already
092:             * a mapping present, the existing mapping will be overwritten.
093:             * Flags should be of the form:<br />
094:             * <code>java Foo -flag1 value1 -flag2 value2 ... arg1 arg2 ...</code>
095:             *
096:             * @param args the command-line arguments
097:             * @return all arguments in the original array beyond the
098:             * flag/value pair list
099:             * @author Patrick Linskey
100:             */
101:            public String[] setFromCmdLine(String[] args) {
102:                if (args == null || args.length == 0)
103:                    return args;
104:
105:                String key = null;
106:                String value = null;
107:                List remainder = new LinkedList();
108:                for (int i = 0; i < args.length + 1; i++) {
109:                    if (i == args.length || args[i].startsWith("-")) {
110:                        key = trimQuote(key);
111:                        if (key != null) {
112:                            if (!StringUtils.isEmpty(value))
113:                                setProperty(key, trimQuote(value));
114:                            else
115:                                setProperty(key, "true");
116:                        }
117:
118:                        if (i == args.length)
119:                            break;
120:                        else {
121:                            key = args[i].substring(1);
122:                            value = null;
123:                        }
124:                    } else if (key != null) {
125:                        setProperty(key, trimQuote(args[i]));
126:                        key = null;
127:                    } else
128:                        remainder.add(args[i]);
129:                }
130:
131:                return (String[]) remainder
132:                        .toArray(new String[remainder.size()]);
133:            }
134:
135:            /**
136:             * This method uses reflection to set all the properties in the given
137:             * object that are named by the keys in this map. For a given key 'foo',
138:             * the algorithm will look for a 'setFoo' method in the given instance.
139:             * For a given key 'foo.bar', the algorithm will first look for a
140:             * 'getFoo' method in the given instance, then will recurse on the return
141:             * value of that method, now looking for the 'bar' property. This allows
142:             * the setting of nested object properties. If in the above example the
143:             * 'getFoo' method is not present or returns null, the algorithm will
144:             * look for a 'setFoo' method; if found it will constrct a new instance
145:             * of the correct type, set it using the 'setFoo' method, then recurse on
146:             * it as above. Property names can be nested in this way to an arbitrary
147:             * depth. For setter methods that take multiple parameters, the value
148:             * mapped to the key can use the ',' as an argument separator character.
149:             * If not enough values are present for a given method after splitting
150:             * the string on ',', the remaining arguments will receive default
151:             * values. All arguments are converted from string form to the
152:             * correct type if possible(i.e. if the type is primitive,
153:             * java.lang.Clas, or has a constructor that takes a single string
154:             * argument). Examples:
155:             * <ul>
156:             * <li>Map Entry: <code>"age"-&gt;"12"</code><br />
157:             * Resultant method call: <code>obj.setAge(12)</code></li>
158:             * <li>Map Entry: <code>"range"-&gt;"1,20"</code><br />
159:             * Resultant method call: <code>obj.setRange(1, 20)</code></li>
160:             * <li>Map Entry: <code>"range"-&gt;"10"</code><br />
161:             * Resultant method call: <code>obj.setRange(10, 10)</code></li>
162:             * <li>Map Entry: <code>"brother.name"-&gt;"Bob"</code><br />
163:             * Resultant method call: <code>obj.getBrother().setName("Bob")
164:             * <code></li>
165:             * </ul> 
166:             * Any keys present in the map for which there is no
167:             * corresponding property in the given object will be ignored,
168:             * and will be returned in the {@link Map} returned by this method.
169:             *
170:             * @return an {@link Options} of key-value pairs in this object
171:             * for which no setters could be found.
172:             * @throws RuntimeException on parse error
173:             */
174:            public Options setInto(Object obj) {
175:                // set all defaults that have no explicit value
176:                Map.Entry entry = null;
177:                if (defaults != null) {
178:                    for (Iterator itr = defaults.entrySet().iterator(); itr
179:                            .hasNext();) {
180:                        entry = (Map.Entry) itr.next();
181:                        if (!containsKey(entry.getKey()))
182:                            setInto(obj, entry);
183:                    }
184:                }
185:
186:                // set from main map
187:                Options invalidEntries = null;
188:                Map.Entry e;
189:                for (Iterator itr = entrySet().iterator(); itr.hasNext();) {
190:                    e = (Map.Entry) itr.next();
191:                    if (!setInto(obj, e)) {
192:                        if (invalidEntries == null)
193:                            invalidEntries = new Options();
194:                        invalidEntries.put(e.getKey(), e.getValue());
195:                    }
196:                }
197:                return (invalidEntries == null) ? EMPTY : invalidEntries;
198:            }
199:
200:            /**
201:             * Sets the property named by the key of the given entry in the
202:             * given object.
203:             *
204:             * @return <code>true</code> if the set succeeded, or
205:             * <code>false</code> if no method could be found for this property.
206:             */
207:            private boolean setInto(Object obj, Map.Entry entry) {
208:                if (entry.getKey() == null)
209:                    return false;
210:
211:                try {
212:                    // look for matching parameter of object
213:                    Object[] match = new Object[] { obj, null };
214:                    if (!matchOptionToMember(entry.getKey().toString(), match))
215:                        return false;
216:
217:                    Class[] type = getType(match[1]);
218:                    Object[] values = new Object[type.length];
219:                    String[] strValues;
220:                    if (entry.getValue() == null)
221:                        strValues = new String[1];
222:                    else if (values.length == 1)
223:                        strValues = new String[] { entry.getValue().toString() };
224:                    else
225:                        strValues = Strings.split(entry.getValue().toString(),
226:                                ",", 0);
227:
228:                    // convert the string values into parameter values, if not
229:                    // enough string values repeat last one for rest
230:                    for (int i = 0; i < strValues.length; i++)
231:                        values[i] = stringToObject(strValues[i].trim(), type[i]);
232:                    for (int i = strValues.length; i < values.length; i++)
233:                        values[i] = getDefaultValue(type[i]);
234:
235:                    // invoke the setter / set the field
236:                    invoke(match[0], match[1], values);
237:                    return true;
238:                } catch (Throwable t) {
239:                    throw new ParseException(obj + "." + entry.getKey() + " = "
240:                            + entry.getValue(), t);
241:                }
242:            }
243:
244:            /**
245:             * Removes leading and trailing single quotes from the given String, if any.
246:             */
247:            private static String trimQuote(String val) {
248:                if (val != null && val.startsWith("'") && val.endsWith("'"))
249:                    return val.substring(1, val.length() - 1);
250:                return val;
251:            }
252:
253:            /**
254:             * Finds all the options that can be set on the provided class. This does
255:             * not look for path-traversal expressions.
256:             *
257:             * @param type The class for which available options should be listed.
258:             * @return The available option names in <code>type</code>. The
259:             * names will have initial caps. They will be ordered alphabetically.
260:             */
261:            public static Collection findOptionsFor(Class type) {
262:                Collection names = new TreeSet();
263:                // look for a setter method matching the key
264:                Method[] meths = type.getMethods();
265:                Class[] params;
266:                for (int i = 0; i < meths.length; i++) {
267:                    if (meths[i].getName().startsWith("set")) {
268:                        params = meths[i].getParameterTypes();
269:                        if (params.length == 0)
270:                            continue;
271:                        if (params[0].isArray())
272:                            continue;
273:
274:                        names.add(StringUtils.capitalize(meths[i].getName()
275:                                .substring(3)));
276:                    }
277:                }
278:
279:                // check for public fields
280:                Field[] fields = type.getFields();
281:                for (int i = 0; i < fields.length; i++)
282:                    names.add(StringUtils.capitalize(fields[i].getName()));
283:
284:                return names;
285:            }
286:
287:            /**
288:             * Matches a key to an object/setter pair.
289:             *
290:             * @param key the key given at the command line; may be of the form
291:             * 'foo.bar' to signify the 'bar' property of the 'foo' owned object
292:             * @param match an array of length 2, where the first index is set
293:             * to the object to retrieve the setter for
294:             * @return true if a match was made, false otherwise; additionally,
295:             * the first index of the match array will be set to
296:             * the matching object and the second index will be
297:             * set to the setter method or public field for the
298:             * property named by the key
299:             */
300:            private static boolean matchOptionToMember(String key,
301:                    Object[] match) throws Exception {
302:                if (StringUtils.isEmpty(key))
303:                    return false;
304:
305:                // unfortunately we can't use bean properties for setters; any
306:                // setter with more than 1 arg is ignored; calc setter and getter
307:                // name to look for
308:                String[] find = Strings.split(key, ".", 2);
309:                String base = StringUtils.capitalize(find[0]);
310:                String set = "set" + base;
311:                String get = "get" + base;
312:
313:                // look for a setter/getter matching the key; look for methods first
314:                Class type = match[0].getClass();
315:                Method[] meths = type.getMethods();
316:                Method setMeth = null;
317:                Method getMeth = null;
318:                Class[] params;
319:                for (int i = 0; i < meths.length; i++) {
320:                    if (meths[i].getName().equals(set)) {
321:                        params = meths[i].getParameterTypes();
322:                        if (params.length == 0)
323:                            continue;
324:                        if (params[0].isArray())
325:                            continue;
326:
327:                        // use this method if we haven't found any other setter, if
328:                        // it has less parameters than any other setter, or if it uses
329:                        // string parameters
330:                        if (setMeth == null)
331:                            setMeth = meths[i];
332:                        else if (params.length < setMeth.getParameterTypes().length)
333:                            setMeth = meths[i];
334:                        else if (params.length == setMeth.getParameterTypes().length
335:                                && params[0] == String.class)
336:                            setMeth = meths[i];
337:                    } else if (meths[i].getName().equals(get))
338:                        getMeth = meths[i];
339:                }
340:
341:                // if no methods found, check for public field
342:                Member setter = setMeth;
343:                Member getter = getMeth;
344:                if (setter == null) {
345:                    Field[] fields = type.getFields();
346:                    String uncapBase = StringUtils.uncapitalize(find[0]);
347:                    for (int i = 0; i < fields.length; i++) {
348:                        if (fields[i].getName().equals(base)
349:                                || fields[i].getName().equals(uncapBase)) {
350:                            setter = fields[i];
351:                            getter = fields[i];
352:                            break;
353:                        }
354:                    }
355:                }
356:
357:                // if no way to access property, give up
358:                if (setter == null && getter == null)
359:                    return false;
360:
361:                // recurse on inner object with remainder of key?
362:                if (find.length > 1) {
363:                    Object inner = null;
364:                    if (getter != null)
365:                        inner = invoke(match[0], getter, null);
366:
367:                    // if no getter or current inner is null, try to create a new
368:                    // inner instance and set it in object
369:                    if (inner == null && setter != null) {
370:                        Class innerType = getType(setter)[0];
371:                        try {
372:                            inner = AccessController
373:                                    .doPrivileged(J2DoPrivHelper
374:                                            .newInstanceAction(innerType));
375:                        } catch (PrivilegedActionException pae) {
376:                            throw pae.getException();
377:                        }
378:                        invoke(match[0], setter, new Object[] { inner });
379:                    }
380:                    match[0] = inner;
381:                    return matchOptionToMember(find[1], match);
382:                }
383:
384:                // got match; find setter for property
385:                match[1] = setter;
386:                return match[1] != null;
387:            }
388:
389:            /**
390:             * Return the types of the parameters needed to set the given member.
391:             */
392:            private static Class[] getType(Object member) {
393:                if (member instanceof  Method)
394:                    return ((Method) member).getParameterTypes();
395:                return new Class[] { ((Field) member).getType() };
396:            }
397:
398:            /**
399:             * Set the given member to the given value(s).
400:             */
401:            private static Object invoke(Object target, Object member,
402:                    Object[] values) throws Exception {
403:                if (member instanceof  Method)
404:                    return ((Method) member).invoke(target, values);
405:                if (values == null || values.length == 0)
406:                    return ((Field) member).get(target);
407:                ((Field) member).set(target, values[0]);
408:                return null;
409:            }
410:
411:            /**
412:             * Converts the given string into an object of the given type, or its
413:             * wrapper type if it is primitive.
414:             */
415:            private Object stringToObject(String str, Class type)
416:                    throws Exception {
417:                // special case for null and for strings
418:                if (str == null || type == String.class)
419:                    return str;
420:
421:                // special case for creating Class instances
422:                if (type == Class.class)
423:                    return Class.forName(str, false, getClass()
424:                            .getClassLoader());
425:
426:                // special case for numeric types that end in .0; strip the decimal
427:                // places because it can kill int, short, long parsing
428:                if (type.isPrimitive() || Number.class.isAssignableFrom(type))
429:                    if (str.length() > 2 && str.endsWith(".0"))
430:                        str = str.substring(0, str.length() - 2);
431:
432:                // for primitives, recurse on wrapper type
433:                if (type.isPrimitive())
434:                    for (int i = 0; i < _primWrappers.length; i++)
435:                        if (type == _primWrappers[i][0])
436:                            return stringToObject(str,
437:                                    (Class) _primWrappers[i][1]);
438:
439:                // look for a string constructor
440:                Exception err = null;
441:                try {
442:                    Constructor cons = type
443:                            .getConstructor(new Class[] { String.class });
444:                    if (type == Boolean.class && "t".equalsIgnoreCase(str))
445:                        str = "true";
446:                    return cons.newInstance(new Object[] { str });
447:                } catch (Exception e) {
448:                    err = e;
449:                }
450:
451:                // special case: the arg value is a subtype name and a new instance
452:                // of that type should be set as the object
453:                Class subType = null;
454:                try {
455:                    subType = Class.forName(str);
456:                } catch (Exception e) {
457:                    throw err;
458:                }
459:                if (!type.isAssignableFrom(subType))
460:                    throw err;
461:                try {
462:                    return AccessController.doPrivileged(J2DoPrivHelper
463:                            .newInstanceAction(subType));
464:                } catch (PrivilegedActionException pae) {
465:                    throw pae.getException();
466:                }
467:            }
468:
469:            /**
470:             * Returns the default value for the given parameter type.
471:             */
472:            private Object getDefaultValue(Class type) {
473:                for (int i = 0; i < _primWrappers.length; i++)
474:                    if (_primWrappers[i][0] == type)
475:                        return _primWrappers[i][2];
476:
477:                return null;
478:            }
479:
480:            /**
481:             * Specialization of {@link #getBooleanProperty} to allow
482:             * a value to appear under either of two keys; useful for short and
483:             * long versions of command-line flags.
484:             */
485:            public boolean getBooleanProperty(String key, String key2,
486:                    boolean def) {
487:                String val = getProperty(key);
488:                if (val == null)
489:                    val = getProperty(key2);
490:                if (val == null)
491:                    return def;
492:                return "t".equalsIgnoreCase(val)
493:                        || "true".equalsIgnoreCase(val);
494:            }
495:
496:            /**
497:             * Specialization of {@link TypedProperties#getFloatProperty} to allow
498:             * a value to appear under either of two keys; useful for short and
499:             * long versions of command-line flags.
500:             */
501:            public float getFloatProperty(String key, String key2, float def) {
502:                String val = getProperty(key);
503:                if (val == null)
504:                    val = getProperty(key2);
505:                return (val == null) ? def : Float.parseFloat(val);
506:            }
507:
508:            /**
509:             * Specialization of {@link TypedProperties#getDoubleProperty} to allow
510:             * a value to appear under either of two keys; useful for short and
511:             * long versions of command-line flags.
512:             */
513:            public double getDoubleProperty(String key, String key2, double def) {
514:                String val = getProperty(key);
515:                if (val == null)
516:                    val = getProperty(key2);
517:                return (val == null) ? def : Double.parseDouble(val);
518:            }
519:
520:            /**
521:             * Specialization of {@link TypedProperties#getLongProperty} to allow
522:             * a value to appear under either of two keys; useful for short and
523:             * long versions of command-line flags.
524:             */
525:            public long getLongProperty(String key, String key2, long def) {
526:                String val = getProperty(key);
527:                if (val == null)
528:                    val = getProperty(key2);
529:                return (val == null) ? def : Long.parseLong(val);
530:            }
531:
532:            /**
533:             * Specialization of {@link TypedProperties#getIntProperty} to allow
534:             * a value to appear under either of two keys; useful for short and
535:             * long versions of command-line flags.
536:             */
537:            public int getIntProperty(String key, String key2, int def) {
538:                String val = getProperty(key);
539:                if (val == null)
540:                    val = getProperty(key2);
541:                return (val == null) ? def : Integer.parseInt(val);
542:            }
543:
544:            /**
545:             * Specialization of {@link Properties#getProperty} to allow
546:             * a value to appear under either of two keys; useful for short and
547:             * long versions of command-line flags.
548:             */
549:            public String getProperty(String key, String key2, String def) {
550:                String val = getProperty(key);
551:                return (val == null) ? getProperty(key2, def) : val;
552:            }
553:
554:            /**
555:             * Specialization of {@link TypedProperties#removeBooleanProperty} to allow
556:             * a value to appear under either of two keys; useful for short and
557:             * long versions of command-line flags.
558:             */
559:            public boolean removeBooleanProperty(String key, String key2,
560:                    boolean def) {
561:                String val = removeProperty(key);
562:                if (val == null)
563:                    val = removeProperty(key2);
564:                else
565:                    removeProperty(key2);
566:                if (val == null)
567:                    return def;
568:                return "t".equalsIgnoreCase(val)
569:                        || "true".equalsIgnoreCase(val);
570:            }
571:
572:            /**
573:             * Specialization of {@link TypedProperties#removeFloatProperty} to allow
574:             * a value to appear under either of two keys; useful for short and
575:             * long versions of command-line flags.
576:             */
577:            public float removeFloatProperty(String key, String key2, float def) {
578:                String val = removeProperty(key);
579:                if (val == null)
580:                    val = removeProperty(key2);
581:                else
582:                    removeProperty(key2);
583:                return (val == null) ? def : Float.parseFloat(val);
584:            }
585:
586:            /**
587:             * Specialization of {@link TypedProperties#removeDoubleProperty} to allow
588:             * a value to appear under either of two keys; useful for short and
589:             * long versions of command-line flags.
590:             */
591:            public double removeDoubleProperty(String key, String key2,
592:                    double def) {
593:                String val = removeProperty(key);
594:                if (val == null)
595:                    val = removeProperty(key2);
596:                else
597:                    removeProperty(key2);
598:                return (val == null) ? def : Double.parseDouble(val);
599:            }
600:
601:            /**
602:             * Specialization of {@link TypedProperties#removeLongProperty} to allow
603:             * a value to appear under either of two keys; useful for short and
604:             * long versions of command-line flags.
605:             */
606:            public long removeLongProperty(String key, String key2, long def) {
607:                String val = removeProperty(key);
608:                if (val == null)
609:                    val = removeProperty(key2);
610:                else
611:                    removeProperty(key2);
612:                return (val == null) ? def : Long.parseLong(val);
613:            }
614:
615:            /**
616:             * Specialization of {@link TypedProperties#removeIntProperty} to allow
617:             * a value to appear under either of two keys; useful for short and
618:             * long versions of command-line flags.
619:             */
620:            public int removeIntProperty(String key, String key2, int def) {
621:                String val = removeProperty(key);
622:                if (val == null)
623:                    val = removeProperty(key2);
624:                else
625:                    removeProperty(key2);
626:                return (val == null) ? def : Integer.parseInt(val);
627:            }
628:
629:            /**
630:             * Specialization of {@link Properties#removeProperty} to allow
631:             * a value to appear under either of two keys; useful for short and
632:             * long versions of command-line flags.
633:             */
634:            public String removeProperty(String key, String key2, String def) {
635:                String val = removeProperty(key);
636:                return (val == null) ? removeProperty(key2, def) : val;
637:            }
638:
639:            /**
640:             * Immutable empty options.
641:             */
642:            private static class EmptyOptions extends Options {
643:
644:                public Object setProperty(String key, String value) {
645:                    throw new UnsupportedOperationException();
646:                }
647:
648:                public Object put(Object key, Object value) {
649:                    throw new UnsupportedOperationException();
650:                }
651:            }
652:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.