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

net.obvj.confectory.ConfigurationBuilder Maven / Gradle / Ivy

/*
 * Copyright 2021 obvj.net
 *
 * Licensed 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 net.obvj.confectory;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import net.obvj.confectory.mapper.Mapper;
import net.obvj.confectory.source.DynamicSource;
import net.obvj.confectory.source.Source;
import net.obvj.confectory.source.SourceFactory;

/**
 * A mutable object that supports the creation of immutable {@link Configuration} objects.
 * 

* For example: * *

* *
 * {@code Configuration config = new ConfigurationBuilder()}
 * {@code         .source(new ClasspathFileSource<>("my.properties"))}
 * {@code         .mapper(new PropertiesMapper())}
 * {@code         .namespace("default")}
 * {@code         .precedence(10)}
 * {@code         .lazy()}
 * {@code         .build();}
 * 
* *
* * @param the target configuration type * * @author oswaldo.bapvic.jr (Oswaldo Junior) * @since 0.1.0 * * @see Configuration */ public class ConfigurationBuilder implements ConfigurationMetadataRetriever { private String namespace; private int precedence; private Source source; private Mapper mapper; private boolean optional; private boolean lazy; /** * Creates a new, empty {@code ConfigurationBuilder}. */ public ConfigurationBuilder() { this(null); } /** * Creates a new {@code ConfigurationBuilder} filled with the attributes of an existing * base {@code Configuration}. * * @param sourceConfiguration a preset {@code Configuration} object whose attributes are * to be copied; {@code null} is allowed */ public ConfigurationBuilder(Configuration sourceConfiguration) { if (sourceConfiguration != null) { namespace = sourceConfiguration.getNamespace(); precedence = sourceConfiguration.getPrecedence(); source = sourceConfiguration.getSource(); mapper = sourceConfiguration.getMapper(); optional = sourceConfiguration.isOptional(); lazy = sourceConfiguration.isLazy(); } } /** * Declares a namespace to be assigned to the new {@code Configuration} object. *

* Note: The namespace is optional, but usually recommended to organize * the scope of the target object and to prevent key collisions. * * @param namespace the namespace to set; {@code null} is allowed * @return a reference to this same {@code ConfigurationBuilder} for chained calls */ public ConfigurationBuilder namespace(String namespace) { this.namespace = namespace; return this; } /** * Defines the level of precedence of the new {@code Configuration} compared to similar * objects in the same namespace. *

* In a common configuration container, the object with the highest precedence level may * be selected first in the occurrence of a key collision in the same namespace. *

* Note: This precedence value is optional and the default value is * {@code 0} (zero). * * @param precedence an integer number representing the order of importance given to the * target configuration * @return a reference to this same {@code ConfigurationBuilder} for chained calls */ public ConfigurationBuilder precedence(int precedence) { this.precedence = precedence; return this; } /** * Defines the {@link Source} of the new {@code Configuration}. * * @param source the {@link Source} to be set; not null * @return a reference to this same {@code ConfigurationBuilder} for chained calls */ public ConfigurationBuilder source(Source source) { this.source = source; return this; } /** * Defines a {@link DynamicSource} with the specified path for the new * {@code Configuration}. * * @param path the path to be set; not null * @return a reference to this same {@code ConfigurationBuilder} for chained calls */ public ConfigurationBuilder source(String path) { this.source = SourceFactory.dynamicSource(path); return this; } /** * Defines the {@link Mapper} of the new {@code Configuration}. * * @param mapper the {@link Mapper} to be set; not null * @return a reference to this same {@code ConfigurationBuilder} for chained calls */ public ConfigurationBuilder mapper(Mapper mapper) { this.mapper = mapper; return this; } /** * Marks the new {@code Configuration} as optional. *

* The configuration source will be loaded quietly, i.e., not throwing an exception if the * source is not found or not loaded successfully. * * @return a reference to this same {@code ConfigurationBuilder} for chained calls * @see #required() */ public ConfigurationBuilder optional() { this.optional = true; return this; } /** * Marks the new {@code Configuration} as required (default). * * @return a reference to this same {@code ConfigurationBuilder} for chained calls * @see #optional() */ public ConfigurationBuilder required() { this.optional = false; return this; } /** * Marks the new {@code Configuration} as lazy. *

* The configuration source will not be loaded until needed. * * @return a reference to this same {@code ConfigurationBuilder} for chained calls * @see #eager() * * @since 0.4.0 */ public ConfigurationBuilder lazy() { this.lazy = true; return this; } /** * Marks the new {@code Configuration} as eager. *

* The configuration source will loaded directly during {@code build()} time (default). * * @return a reference to this same {@code ConfigurationBuilder} for chained calls * @see #lazy() * * @since 0.4.0 */ public ConfigurationBuilder eager() { this.lazy = false; return this; } /** * Builds the target {@code Configuration}. * * @return a new {@link Configuration} object * @throws NullPointerException if either the {@code Source} or {@code Mapper} * configuration parameters are missing * @throws ConfigurationSourceException in the event of a failure loading the * configuration source */ public Configuration build() { Objects.requireNonNull(source, "The configuration source must not be null"); Objects.requireNonNull(mapper, "The configuration mapper must not be null"); namespace = StringUtils.defaultString(namespace); return new Configuration<>(this); } @Override public String getNamespace() { return namespace; } @Override public int getPrecedence() { return precedence; } @Override public Source getSource() { return source; } @Override public Mapper getMapper() { return mapper; } @Override public boolean isOptional() { return optional; } @Override public boolean isLazy() { return lazy; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy