Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.lib.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.time.Duration;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeSet;
/**
* A specialization of the {@link Properties} map type with the added
* abilities to read application options from the command line and to
* use bean patterns to set an object's properties via command-line the
* stored mappings.
* A typical use pattern for this class is to construct a new instance
* in the main method, then call {@link #setFromCmdLine} with the
* given args. Next, an instanceof the class being invoked is created, and
* {@link #setInto} is called with that instance as a parameter. With this
* pattern, the user can configure any bean properties of the class, or even
* properties of classes reachable from the class, through the command line.
*
* @author Abe White
*/
public class Options extends TypedProperties {
private static final long serialVersionUID = 1L;
/**
* Immutable empty instance.
*/
public static Options EMPTY = new EmptyOptions();
// maps primitive types to the appropriate wrapper class and default value
private static Object[][] _primWrappers = new Object[][]{
{ boolean.class, Boolean.class, Boolean.FALSE },
{ byte.class, Byte.class, (byte) 0},
{ char.class, Character.class, (char) 0},
{ double.class, Double.class, 0D},
{ float.class, Float.class, 0F},
{ int.class, Integer.class, 0},
{ long.class, Long.class, 0L},
{ short.class, Short.class, (short) 0}, };
private static Localizer _loc = Localizer.forPackage(Options.class);
/**
* Default constructor.
*/
public Options() {
super();
}
/**
* Construct the options instance with the given set of defaults.
*
* @see Properties#Properties(Properties)
*/
public Options(Properties defaults) {
super(defaults);
}
/**
* Parses the given argument list into flag/value pairs, which are stored
* as properties. Flags that are present without values are given
* the value "true". If any flag is found for which there is already
* a mapping present, the existing mapping will be overwritten.
* Flags should be of the form:
* java Foo -flag1 value1 -flag2 value2 ... arg1 arg2 ...
*
* @param args the command-line arguments
* @return all arguments in the original array beyond the
* flag/value pair list
* @author Patrick Linskey
*/
public String[] setFromCmdLine(String[] args) {
if (args == null || args.length == 0)
return args;
String key = null;
String value = null;
List remainder = new LinkedList<>();
for (int i = 0; i < args.length + 1; i++) {
if (i == args.length || args[i].startsWith("-")) {
key = trimQuote(key);
if (key != null) {
if (!StringUtil.isEmpty(value))
setProperty(key, trimQuote(value));
else
setProperty(key, "true");
}
if (i == args.length)
break;
else {
key = args[i].substring(1);
value = null;
}
} else if (key != null) {
setProperty(key, trimQuote(args[i]));
key = null;
} else
remainder.add(args[i]);
}
return remainder.toArray(new String[remainder.size()]);
}
/**
* This method uses reflection to set all the properties in the given
* object that are named by the keys in this map. For a given key 'foo',
* the algorithm will look for a 'setFoo' method in the given instance.
* For a given key 'foo.bar', the algorithm will first look for a
* 'getFoo' method in the given instance, then will recurse on the return
* value of that method, now looking for the 'bar' property. This allows
* the setting of nested object properties. If in the above example the
* 'getFoo' method is not present or returns null, the algorithm will
* look for a 'setFoo' method; if found it will constrct a new instance
* of the correct type, set it using the 'setFoo' method, then recurse on
* it as above. Property names can be nested in this way to an arbitrary
* depth. For setter methods that take multiple parameters, the value
* mapped to the key can use the ',' as an argument separator character.
* If not enough values are present for a given method after splitting
* the string on ',', the remaining arguments will receive default
* values. All arguments are converted from string form to the
* correct type if possible(i.e. if the type is primitive,
* java.lang.Clas, or has a constructor that takes a single string
* argument). Examples:
*
* Any keys present in the map for which there is no
* corresponding property in the given object will be ignored,
* and will be returned in the {@link Map} returned by this method.
*
* @return an {@link Options} of key-value pairs in this object
* for which no setters could be found.
* @throws RuntimeException on parse error
*/
public Options setInto(Object obj) {
// set all defaults that have no explicit value
Map.Entry entry = null;
if (defaults != null) {
for (Map.Entry