001/*
002 *  Copyright 2001-2013 Stephen Colebourne
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.joda.beans;
017
018import java.util.Map;
019
020/**
021 * A builder for a bean, providing a safe way to create it.
022 * <p>
023 * This interface allows a bean to be created even if it is immutable.
024 * 
025 * @param <T>  the type of the bean
026 * @author Stephen Colebourne
027 */
028public interface BeanBuilder<T extends Bean> {
029
030    /**
031     * Sets the value of a single property into the builder.
032     * <p>
033     * This will normally behave as per a {@code Map}, however it may not
034     * and as a general rule callers should only set each property once.
035     * 
036     * @param propertyName  the property name, not null
037     * @param value  the property value, may be null
038     * @return {@code this}, for chaining, not null
039     * @throws RuntimeException optionally thrown if the property name is invalid
040     */
041    BeanBuilder<T> set(String propertyName, Object value);
042
043    /**
044     * Sets the value of a single property into the builder.
045     * <p>
046     * This will normally behave as per a {@code Map}, however it may not
047     * and as a general rule callers should only set each property once.
048     * 
049     * @param property  the property, not null
050     * @param value  the property value, may be null
051     * @return {@code this}, for chaining, not null
052     * @throws RuntimeException optionally thrown if the property name is invalid
053     */
054    BeanBuilder<T> set(MetaProperty<?> property, Object value);
055
056    /**
057     * Sets the value of a single property into the builder.
058     * <p>
059     * This converts the string to the correct type for the property.
060     * Conversion uses Joda-Convert.
061     * <p>
062     * This will normally behave as per a {@code Map}, however it may not
063     * and as a general rule callers should only set each property once.
064     * 
065     * @param propertyName  the property name, not null
066     * @param value  the property value, may be null
067     * @return {@code this}, for chaining, not null
068     * @throws RuntimeException optionally thrown if the property name is invalid
069     */
070    BeanBuilder<T> setString(String propertyName, String value);
071
072    /**
073     * Sets the value of a single property into the builder.
074     * <p>
075     * This converts the string to the correct type for the property.
076     * Conversion uses Joda-Convert.
077     * <p>
078     * This will normally behave as per a {@code Map}, however it may not
079     * and as a general rule callers should only set each property once.
080     * 
081     * @param property  the property name, not null
082     * @param value  the property value, may be null
083     * @return {@code this}, for chaining, not null
084     * @throws RuntimeException optionally thrown if the property name is invalid
085     */
086    BeanBuilder<T> setString(MetaProperty<?> property, String value);
087
088    /**
089     * Sets the value of a map of properties into the builder.
090     * <p>
091     * Each map entry is used as the input to {@link #set(String, Object)}.
092     * <p>
093     * This will normally behave as per a {@code Map}, however it may not
094     * and as a general rule callers should only set each property once.
095     * 
096     * @param propertyValueMap  the property name to value map, not null
097     * @return {@code this}, for chaining, not null
098     * @throws RuntimeException optionally thrown if a property name is invalid
099     */
100    BeanBuilder<T> setAll(Map<String, ? extends Object> propertyValueMap);
101
102    /**
103     * Builds the bean from the state of the builder.
104     * <p>
105     * Once this method has been called, the builder is in an invalid state.
106     * The effect of further method calls is undetermined.
107     * 
108     * @return the created bean, not null
109     */
110    T build();
111
112}