001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.beanutils2; 018 019/** 020 * <p> 021 * Decorates a {@link DynaBean} to provide {@code Map} behavior. 022 * </p> 023 * 024 * <p> 025 * The motivation for this implementation is to provide access to {@link DynaBean} properties in technologies that are unaware of BeanUtils and 026 * {@link DynaBean}s - such as the expression languages of JSTL and JSF. 027 * </p> 028 * 029 * <p> 030 * This can be achieved either by wrapping the {@link DynaBean} prior to providing it to the technology to process or by providing a {@code Map} accessor method 031 * on the DynaBean implementation: 032 * </p> 033 * 034 * <pre> 035 * <code> 036 * public Map<String, Object> getMap() { 037 * return new DynaBeanPropertyMapDecorator(this); 038 * }</code> 039 * </pre> 040 * 041 * <p> 042 * This, for example, could be used in JSTL in the following way to access a DynaBean's {@code fooProperty}: 043 * </p> 044 * <ul> 045 * <li>{@code ${myDynaBean.<strong>map</strong>.fooProperty}}</li> 046 * </ul> 047 * 048 * <h2>Usage</h2> 049 * 050 * <p> 051 * To decorate a {@link DynaBean} simply instantiate this class with the target {@link DynaBean}: 052 * </p> 053 * 054 * <ul> 055 * <li>{@code Map<String, Object> fooMap = new DynaBeanPropertyMapDecorator(fooDynaBean);}</li> 056 * </ul> 057 * 058 * <p> 059 * The above example creates a <strong><em>read only</em></strong> {@code Map}. To create a {@code Map} which can be modified, construct a 060 * {@code DynaBeanPropertyMapDecorator} with the <strong><em>read only</em></strong> attribute set to {@code false}: 061 * </p> 062 * 063 * <ul> 064 * <li>{@code Map<String, Object> fooMap = 065 * new DynaBeanPropertyMapDecorator(fooDynaBean, false);}</li> 066 * </ul> 067 * 068 * <h2>Limitations</h2> 069 * <p> 070 * In this implementation the {@code entrySet()</code>, <code>keySet()} 071 * and {@code values()} methods create an <strong><em>unmodifiable</em></strong> 072 * {@code Set</code> and it does not support the Map's <code>clear()} and {@code remove()} operations. 073 * </p> 074 * 075 * @since 1.9.0 076 */ 077public class DynaBeanPropertyMapDecorator extends BaseDynaBeanMapDecorator<String> { 078 079 /** 080 * Constructs a read only Map for the specified {@link DynaBean}. 081 * 082 * @param dynaBean The dyna bean being decorated 083 * @throws IllegalArgumentException if the {@link DynaBean} is null. 084 */ 085 public DynaBeanPropertyMapDecorator(final DynaBean dynaBean) { 086 super(dynaBean); 087 } 088 089 /** 090 * Constructs a Map for the specified {@link DynaBean}. 091 * 092 * @param dynaBean The dyna bean being decorated 093 * @param readOnly {@code true} if the Map is read only otherwise {@code false} 094 * @throws IllegalArgumentException if the {@link DynaBean} is null. 095 */ 096 public DynaBeanPropertyMapDecorator(final DynaBean dynaBean, final boolean readOnly) { 097 super(dynaBean, readOnly); 098 } 099 100 @Override 101 protected String convertKey(final String propertyName) { 102 return propertyName; 103 } 104}