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.impl.map;
017    
018    import java.util.HashMap;
019    import java.util.NoSuchElementException;
020    import java.util.Set;
021    
022    import org.joda.beans.DynamicBean;
023    import org.joda.beans.MetaBean;
024    import org.joda.beans.MetaProperty;
025    import org.joda.beans.Property;
026    import org.joda.beans.impl.BasicProperty;
027    
028    /**
029     * Implementation of a fully dynamic {@code Bean} based on an exposed {@code Map}.
030     * <p>
031     * Properties are dynamic, and can be added and removed at will from the map.
032     * 
033     * @author Stephen Colebourne
034     */
035    public class MapBean extends HashMap<String, Object> implements DynamicBean {
036    
037        /** Serialization version. */
038        private static final long serialVersionUID = 1L;
039    
040        @Override
041        public MetaBean metaBean() {
042            return new MapMetaBean(this);
043        }
044    
045        @Override
046        public Property<Object> property(String name) {
047            return BasicProperty.of(this, metaProperty(name));
048        }
049    
050        MetaProperty<Object> metaProperty(String name) {
051            Object obj = get(name);
052            if (obj == null) {
053                throw new NoSuchElementException("Property not found: " + name);
054            }
055            return MapBeanMetaProperty.of(MapBean.this, name);
056        }
057    
058        @Override
059        public Set<String> propertyNames() {
060            return keySet();
061        }
062    
063        @Override
064        public void propertyDefine(String propertyName, Class<?> propertyType) {
065            // no need to define
066        }
067    
068        @Override
069        public void propertyRemove(String propertyName) {
070            remove(propertyName);
071        }
072    
073        //-----------------------------------------------------------------------
074        /**
075         * Returns a string that summarises the bean.
076         * <p>
077         * The string contains the class name and properties.
078         * 
079         * @return a summary string, not null
080         */
081        @Override
082        public String toString() {
083            return getClass().getSimpleName() + super.toString();
084        }
085    
086    }