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

There is a newer version: 2.10.1
Show 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.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;

/**
 * 

* 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. *

* * @version $Id: Parameters.java 1679780 2015-05-16 17:44:36Z oheger $ * @since 2.0 */ public final class Parameters { /** 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(DefaultParametersManager manager) { defaultParametersManager = (manager != null) ? manager : new DefaultParametersManager(); } /** * Returns the {@code DefaultParametersManager} associated with this object. * * @return the {@code DefaultParametersManager} */ public DefaultParametersManager getDefaultParametersManager() { return defaultParametersManager; } /** * 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(Class paramsClass, 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(Class paramsClass, DefaultParametersHandler handler, Class startClass) { getDefaultParametersManager().registerDefaultsHandler(paramsClass, handler, startClass); } /** * 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 file-based * configuration properties. * * @return the new parameters object */ public FileBasedBuilderParameters fileBased() { return createParametersProxy(new FileBasedBuilderParametersImpl(), FileBasedBuilderParameters.class); } /** * 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 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 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 XML configurations. * * @return the new parameters object */ public XMLBuilderParameters xml() { return createParametersProxy(new XMLBuilderParametersImpl(), XMLBuilderParameters.class, FileBasedBuilderParameters.class, HierarchicalBuilderParameters.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); } /** * 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 database * configurations. * * @return the new parameters object */ public DatabaseBuilderParameters database() { return createParametersProxy(new DatabaseBuilderParametersImpl(), DatabaseBuilderParameters.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(Object target, Class ifcClass, Class... superIfcs) { Class[] ifcClasses = new Class[1 + superIfcs.length]; ifcClasses[0] = ifcClass; System.arraycopy(superIfcs, 0, ifcClasses, 1, superIfcs.length); Object obj = Proxy.newProxyInstance(Parameters.class.getClassLoader(), ifcClasses, new ParametersIfcInvocationHandler(target)); getDefaultParametersManager().initializeParameters( (BuilderParameters) obj); return ifcClass.cast(obj); } /** * 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 class ParametersIfcInvocationHandler implements InvocationHandler { /** 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(Object targetObj) { target = targetObj; } /** * {@inheritDoc} This implementation delegates method invocations to the * target object and handles the return value correctly. */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); return isFluentResult(method) ? proxy : result; } /** * 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(Method method) { Class declaringClass = method.getDeclaringClass(); return declaringClass.isInterface() && !declaringClass.equals(BuilderParameters.class); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy