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.impl; 017 018import java.util.AbstractMap; 019import java.util.AbstractSet; 020import java.util.Collections; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.Map; 024import java.util.Set; 025 026import org.joda.beans.Bean; 027import org.joda.beans.MetaProperty; 028import org.joda.beans.Property; 029import org.joda.beans.PropertyMap; 030 031/** 032 * A standard map of properties. 033 * <p> 034 * This is the standard implementation of a map of properties derived from a meta-bean. 035 * 036 * @author Stephen Colebourne 037 */ 038public final class BasicPropertyMap 039 extends AbstractMap<String, Property<?>> implements PropertyMap { 040 041 /** The bean. */ 042 private final Bean bean; 043 044 /** 045 * Factory to create a property map avoiding duplicate generics. 046 * 047 * @param bean the bean 048 * @return the property map, not null 049 */ 050 public static BasicPropertyMap of(Bean bean) { 051 return new BasicPropertyMap(bean); 052 } 053 054 /** 055 * Creates a property map. 056 * 057 * @param bean the bean that the property is bound to, not null 058 */ 059 private BasicPropertyMap(Bean bean) { 060 if (bean == null) { 061 throw new NullPointerException("Bean must not be null"); 062 } 063 this.bean = bean; 064 } 065 066 //----------------------------------------------------------------------- 067 @Override 068 public int size() { 069 return bean.metaBean().metaPropertyCount(); 070 } 071 072 @Override 073 public boolean containsKey(Object obj) { 074 return obj instanceof String ? bean.metaBean().metaPropertyExists(obj.toString()) : false; 075 } 076 077 @Override 078 public Property<?> get(Object obj) { 079 return containsKey(obj) ? bean.metaBean().metaProperty(obj.toString()).createProperty(bean) : null; 080 } 081 082 @Override 083 public Set<String> keySet() { 084 return bean.metaBean().metaPropertyMap().keySet(); 085 } 086 087 @Override 088 public Set<Entry<String, Property<?>>> entrySet() { 089 return new AbstractSet<Entry<String, Property<?>>>() { 090 // TODO: possibly override contains() 091 @Override 092 public int size() { 093 return bean.metaBean().metaPropertyCount(); 094 } 095 @Override 096 public Iterator<Entry<String, Property<?>>> iterator() { 097 final Iterator<MetaProperty<?>> it = bean.metaBean().metaPropertyMap().values().iterator(); 098 return new Iterator<Entry<String, Property<?>>>() { 099 @Override 100 public boolean hasNext() { 101 return it.hasNext(); 102 } 103 @Override 104 public Entry<String, Property<?>> next() { 105 MetaProperty<?> meta = it.next(); 106 return new SimpleImmutableEntry<String, Property<?>>(meta.name(), BasicProperty.of(bean, meta)); 107 } 108 @Override 109 public void remove() { 110 throw new UnsupportedOperationException("Unmodifiable"); 111 } 112 }; 113 } 114 }; 115 } 116 117 //----------------------------------------------------------------------- 118 @Override 119 public Map<String, Object> flatten() { 120 // TODO: dedicated map implementation 121 Map<String, MetaProperty<?>> propertyMap = bean.metaBean().metaPropertyMap(); 122 Map<String, Object> map = new HashMap<String, Object>(propertyMap.size()); 123 for (Entry<String, MetaProperty<?>> entry : propertyMap.entrySet()) { 124 map.put(entry.getKey(), entry.getValue().get(bean)); 125 } 126 return Collections.unmodifiableMap(map); 127 } 128 129}