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     */
016    package org.joda.beans;
017    
018    import java.util.Map;
019    import java.util.NoSuchElementException;
020    
021    /**
022     * A meta-bean, defining those aspects of a bean which are not specific
023     * to a particular instance, such as the type and set of meta-properties.
024     * 
025     * @author Stephen Colebourne
026     */
027    public interface MetaBean {
028    
029        /**
030         * Creates a bean builder that can be used to create an instance of this bean.
031         * 
032         * @return the bean builder, not null
033         * @throws UnsupportedOperationException if the bean cannot be created
034         */
035        BeanBuilder<? extends Bean> builder();
036    
037        /**
038         * Creates a map of properties for the specified bean.
039         * 
040         * @param bean  the bean to create the map for, not null
041         * @return the created property map, not null
042         */
043        PropertyMap createPropertyMap(Bean bean);
044    
045        //-----------------------------------------------------------------------
046        /**
047         * Gets the bean name, which is normally the fully qualified class name of the bean.
048         * 
049         * @return the name of the bean, not empty
050         */
051        String beanName();
052    
053        /**
054         * Get the type of the bean represented as a {@code Class}.
055         * 
056         * @return the type of the bean, not null
057         */
058        Class<? extends Bean> beanType();
059    
060        //-----------------------------------------------------------------------
061        /**
062         * Counts the number of properties.
063         * 
064         * @return the number of properties
065         */
066        int metaPropertyCount();
067    
068        /**
069         * Checks if a property exists.
070         * 
071         * @param propertyName  the property name to check, null returns false
072         * @return true if the property exists
073         */
074        boolean metaPropertyExists(String propertyName);
075    
076        /**
077         * Gets a meta-property by name.
078         * 
079         * @param <R>  the property type, optional, enabling auto-casting
080         * @param propertyName  the property name to retrieve, null throws NoSuchElementException
081         * @return the meta property, not null
082         * @throws NoSuchElementException if the property name is invalid
083         */
084        <R> MetaProperty<R> metaProperty(String propertyName);
085    
086        /**
087         * Gets an iterator of meta-properties.
088         * <p>
089         * This method returns an {@code Iterable}, which is simpler than a {@code Map}.
090         * As a result, implementations may be able to optimise, and so this method should be
091         * preferred to {@link #metaPropertyMap()} where a choice is possible.
092         * 
093         * @return the unmodifiable map of meta property objects, not null
094         */
095        Iterable<MetaProperty<?>> metaPropertyIterable();
096    
097        /**
098         * Gets the map of meta-properties, keyed by property name.
099         * <p>
100         * Where possible, use {@link #metaPropertyIterable()} instead.
101         * 
102         * @return the unmodifiable map of meta property objects, not null
103         */
104        Map<String, MetaProperty<?>> metaPropertyMap();
105    
106    }