All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.configuration2.builder.fluent.Parameters Maven / Gradle / Ivy

Go to download

Tools to assist in the reading of configuration/preferences files in various formats

The newest version!
/*
 * 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.commons.configuration2.builder.fluent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.commons.configuration2.builder.BasicBuilderParameters;
import org.apache.commons.configuration2.builder.BuilderParameters;
import org.apache.commons.configuration2.builder.DatabaseBuilderParametersImpl;
import org.apache.commons.configuration2.builder.DefaultParametersHandler;
import org.apache.commons.configuration2.builder.DefaultParametersManager;
import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
import org.apache.commons.configuration2.builder.HierarchicalBuilderParametersImpl;
import org.apache.commons.configuration2.builder.INIBuilderParametersImpl;
import org.apache.commons.configuration2.builder.JndiBuilderParametersImpl;
import org.apache.commons.configuration2.builder.PropertiesBuilderParametersImpl;
import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
import org.apache.commons.configuration2.builder.combined.CombinedBuilderParametersImpl;
import org.apache.commons.configuration2.builder.combined.MultiFileBuilderParametersImpl;

//@formatter:off
/**
 * A convenience class for creating parameter objects for initializing configuration builder objects.
 * 

* For setting initialization properties of new configuration objects, a number of specialized parameter classes exists. * These classes use inheritance to organize the properties they support in a logic way. For instance, parameters for * file-based configurations also support the basic properties common to all configuration implementations, parameters * for XML configurations also include file-based and basic properties, etc. *

*

* When constructing a configuration builder, an easy-to-use fluent API is desired to define specific properties for the * configuration to be created. However, the inheritance structure of the parameter classes makes it surprisingly * difficult to provide such an API. This class comes to rescue by defining a set of methods for the creation of * interface-based parameter objects offering a truly fluent API. The methods provided can be called directly when * setting up a configuration builder as shown in the following example code fragment: *

*
 * Parameters params = new Parameters();
 * configurationBuilder.configure(params.fileBased()
 *   .setThrowExceptionOnMissing(true)
 *   .setEncoding("UTF-8")
 *   .setListDelimiter('#')
 *   .setFileName("test.xml"));
 * 
*

* Using this class it is not only possible to create new parameters objects but also to initialize the newly created * objects with default values. This is via the associated {@link DefaultParametersManager} object. Such an object can * be passed to the constructor, or a new (uninitialized) instance is created. There are convenience methods for * interacting with the associated {@code DefaultParametersManager}, namely to register or remove * {@link DefaultParametersHandler} objects. On all newly created parameters objects the handlers registered at the * associated {@code DefaultParametersHandler} are automatically applied. *

*

* Implementation note: This class is thread-safe. *

* * @since 2.0 */ //@formatter:off public final class Parameters { /** * A specialized {@code InvocationHandler} implementation which maps the methods of a parameters interface to an * implementation of the corresponding property interfaces. The parameters interface is a union of multiple property * interfaces. The wrapped object implements all of these, but not the union interface. Therefore, a reflection-based * approach is required. A special handling is required for the method of the {@code BuilderParameters} interface * because here no fluent return value is used. */ private static final class ParametersIfcInvocationHandler implements InvocationHandler { /** * Checks whether the specified method belongs to an interface which requires fluent result values. * * @param method the method to be checked * @return a flag whether the method's result should be handled as a fluent result value */ private static boolean isFluentResult(final Method method) { final Class declaringClass = method.getDeclaringClass(); return declaringClass.isInterface() && !declaringClass.equals(BuilderParameters.class); } /** The target object of reflection calls. */ private final Object target; /** * Creates a new instance of {@code ParametersIfcInvocationHandler} and sets the wrapped parameters object. * * @param targetObj the target object for reflection calls */ public ParametersIfcInvocationHandler(final Object targetObj) { target = targetObj; } /** * {@inheritDoc} This implementation delegates method invocations to the target object and handles the return value * correctly. */ @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { final Object result = method.invoke(target, args); return isFluentResult(method) ? proxy : result; } } /** The manager for default handlers. */ private final DefaultParametersManager defaultParametersManager; /** * Creates a new instance of {@code Parameters}. A new, uninitialized {@link DefaultParametersManager} is created. */ public Parameters() { this(null); } /** * Creates a new instance of {@code Parameters} and initializes it with the given {@code DefaultParametersManager}. * Because {@code DefaultParametersManager} is thread-safe, it makes sense to share a single instance between multiple * {@code Parameters} objects; that way the same initialization is performed on newly created parameters objects. * * @param manager the {@code DefaultParametersHandler} (may be null, then a new default instance is created) */ public Parameters(final DefaultParametersManager manager) { defaultParametersManager = manager != null ? manager : new DefaultParametersManager(); } /** * Creates a new instance of a parameters object for basic configuration properties. * * @return the new parameters object */ public BasicBuilderParameters basic() { return new BasicBuilderParameters(); } /** * Creates a new instance of a parameters object for combined configuration builder properties. * * @return the new parameters object */ public CombinedBuilderParameters combined() { return createParametersProxy(new CombinedBuilderParametersImpl(), CombinedBuilderParameters.class); } /** * Creates a proxy object for a given parameters interface based on the given implementation object. The newly created * object is initialized with default values if there are matching {@link DefaultParametersHandler} objects. * * @param the type of the parameters interface * @param target the implementing target object * @param ifcClass the interface class * @param superIfcs an array with additional interface classes to be implemented * @return the proxy object */ private T createParametersProxy(final Object target, final Class ifcClass, final Class... superIfcs) { final Class[] ifcClasses = new Class[1 + superIfcs.length]; ifcClasses[0] = ifcClass; System.arraycopy(superIfcs, 0, ifcClasses, 1, superIfcs.length); final Object obj = Proxy.newProxyInstance(Parameters.class.getClassLoader(), ifcClasses, new ParametersIfcInvocationHandler(target)); getDefaultParametersManager().initializeParameters((BuilderParameters) obj); return ifcClass.cast(obj); } /** * Creates a new instance of a parameters object for database configurations. * * @return the new parameters object */ public DatabaseBuilderParameters database() { return createParametersProxy(new DatabaseBuilderParametersImpl(), DatabaseBuilderParameters.class); } /** * Creates a new instance of a parameters object for file-based configuration properties. * * @return the new parameters object */ public FileBasedBuilderParameters fileBased() { return createParametersProxy(new FileBasedBuilderParametersImpl(), FileBasedBuilderParameters.class); } /** * Gets the {@code DefaultParametersManager} associated with this object. * * @return the {@code DefaultParametersManager} */ public DefaultParametersManager getDefaultParametersManager() { return defaultParametersManager; } /** * Creates a new instance of a parameters object for hierarchical configurations. * * @return the new parameters object */ public HierarchicalBuilderParameters hierarchical() { return createParametersProxy(new HierarchicalBuilderParametersImpl(), HierarchicalBuilderParameters.class, FileBasedBuilderParameters.class); } /** * Creates a new instance of a parameters object for INI configurations. * * @return the new parameters object */ public INIBuilderParameters ini() { return createParametersProxy(new INIBuilderParametersImpl(), INIBuilderParameters.class, FileBasedBuilderParameters.class, HierarchicalBuilderParameters.class); } /** * Creates a new instance of a parameters object for JNDI configurations. * * @return the new parameters object */ public JndiBuilderParameters jndi() { return createParametersProxy(new JndiBuilderParametersImpl(), JndiBuilderParameters.class); } /** * Creates a new instance of a parameters object for a builder for multiple file-based configurations. * * @return the new parameters object */ public MultiFileBuilderParameters multiFile() { return createParametersProxy(new MultiFileBuilderParametersImpl(), MultiFileBuilderParameters.class); } /** * Creates a new instance of a parameters object for properties configurations. * * @return the new parameters object */ public PropertiesBuilderParameters properties() { return createParametersProxy(new PropertiesBuilderParametersImpl(), PropertiesBuilderParameters.class, FileBasedBuilderParameters.class); } /** * Registers the specified {@code DefaultParametersHandler} object for the given parameters class. This is a convenience * method which just delegates to the associated {@code DefaultParametersManager}. * * @param the type of the parameters supported by this handler * @param paramsClass the parameters class supported by this handler (must not be null) * @param handler the {@code DefaultParametersHandler} to be registered (must not be null) * @throws IllegalArgumentException if a required parameter is missing * @see DefaultParametersManager */ public void registerDefaultsHandler(final Class paramsClass, final DefaultParametersHandler handler) { getDefaultParametersManager().registerDefaultsHandler(paramsClass, handler); } /** * Registers the specified {@code DefaultParametersHandler} object for the given parameters class and start class in the * inheritance hierarchy. This is a convenience method which just delegates to the associated * {@code DefaultParametersManager}. * * @param the type of the parameters supported by this handler * @param paramsClass the parameters class supported by this handler (must not be null) * @param handler the {@code DefaultParametersHandler} to be registered (must not be null) * @param startClass an optional start class in the hierarchy of parameter objects for which this handler should be * applied * @throws IllegalArgumentException if a required parameter is missing */ public void registerDefaultsHandler(final Class paramsClass, final DefaultParametersHandler handler, final Class startClass) { getDefaultParametersManager().registerDefaultsHandler(paramsClass, handler, startClass); } /** * Creates a new instance of a parameters object for XML configurations. * * @return the new parameters object */ public XMLBuilderParameters xml() { return createParametersProxy(new XMLBuilderParametersImpl(), XMLBuilderParameters.class, FileBasedBuilderParameters.class, HierarchicalBuilderParameters.class); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy