001    /*
002     *  Copyright 2001-2010 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.AbstractMap;
019    import java.util.AbstractSet;
020    import java.util.Iterator;
021    import java.util.Set;
022    
023    /**
024     * A standard map of properties.
025     * <p>
026     * This is the standard implementation of a map of properties derived from a meta-bean.
027     * 
028     * @param <B>  the type of the bean
029     * @author Stephen Colebourne
030     */
031    public final class StandardPropertyMap<B extends Bean<B>> extends AbstractMap<String, Property<B, ?>> {
032    
033        /** The bean. */
034        private final B bean;
035    
036        /**
037         * Factory to create a property map avoiding duplicate generics.
038         * 
039         * @param metaBean  the meta-bean
040         */
041        public static <B extends Bean<B>> StandardPropertyMap<B> of(B metaBean) {
042            return new StandardPropertyMap<B>(metaBean);
043        }
044    
045        /**
046         * Creates a property binding the bean to the meta-property.
047         * 
048         * @param bean  the bean that the property is bound to, not null
049         * @param metaProperty  the meta property, not null
050         */
051        private StandardPropertyMap(B metaBean) {
052            Beans.checkNotNull(metaBean, "MetaBean must not be null");
053            this.bean = metaBean;
054        }
055    
056        //-----------------------------------------------------------------------
057        @Override
058        public Set<Entry<String, Property<B, ?>>> entrySet() {
059            return new AbstractSet<Entry<String,Property<B, ?>>>() {
060                @Override
061                public int size() {
062                    return bean.metaBean().metaPropertyMap().size();
063                }
064                @Override
065                public Iterator<Entry<String, Property<B, ?>>> iterator() {
066                    final Iterator<MetaProperty<B, ?>> it = bean.metaBean().metaPropertyMap().values().iterator();
067                    return new Iterator<Entry<String, Property<B,?>>>() {
068                        @Override
069                        public boolean hasNext() {
070                            return it.hasNext();
071                        }
072                        @Override
073                        @SuppressWarnings("unchecked")
074                        public Entry<String, Property<B, ?>> next() {
075                            MetaProperty<B, ?> meta = it.next();
076                            return (Entry) StandardProperty.of(bean, meta);
077                        }
078                        @Override
079                        public void remove() {
080                            throw new UnsupportedOperationException("Unmodifiable");
081                        }
082                    };
083                }
084            };
085        }
086    
087    }