All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twelvemonkeys.util.BeanMap Maven / Gradle / Ivy

There is a newer version: 2.3
Show newest version
/*
 * Copyright (c) 2008, Harald Kuhr
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name "TwelveMonkeys" nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.twelvemonkeys.util;

import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.io.Serializable;

/**
 * A {@code Map} adapter for a Java Bean.
 * 

* Ruhtlessly stolen from * initDescriptors(Object pBean) throws IntrospectionException { final Set descriptors = new HashSet(); PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(pBean.getClass()).getPropertyDescriptors(); for (PropertyDescriptor descriptor : propertyDescriptors) { // Skip Object.getClass(), as you probably never want it if ("class".equals(descriptor.getName()) && descriptor.getPropertyType() == Class.class) { continue; } // Only support simple setter/getters. if (!(descriptor instanceof IndexedPropertyDescriptor)) { descriptors.add(descriptor); } } return Collections.unmodifiableSet(descriptors); } public Set> entrySet() { return new BeanSet(); } public Object get(final Object pKey) { return super.get(pKey); } public Object put(final String pKey, final Object pValue) { checkKey(pKey); for (Entry entry : entrySet()) { if (entry.getKey().equals(pKey)) { return entry.setValue(pValue); } } return null; } public Object remove(final Object pKey) { return super.remove(checkKey(pKey)); } public int size() { return mDescriptors.size(); } private String checkKey(final Object pKey) { if (pKey == null) { throw new IllegalArgumentException("key == null"); } // NB - the cast forces CCE if key is the wrong type. final String name = (String) pKey; if (!containsKey(name)) { throw new IllegalArgumentException("Bad key: " + pKey); } return name; } private Object readResolve() throws IntrospectionException { // Initialize the property descriptors mDescriptors = initDescriptors(mBean); return this; } private class BeanSet extends AbstractSet> { public Iterator> iterator() { return new BeanIterator(mDescriptors.iterator()); } public int size() { return mDescriptors.size(); } } private class BeanIterator implements Iterator> { private final Iterator mIterator; public BeanIterator(final Iterator pIterator) { mIterator = pIterator; } public boolean hasNext() { return mIterator.hasNext(); } public BeanEntry next() { return new BeanEntry(mIterator.next()); } public void remove() { mIterator.remove(); } } private class BeanEntry implements Entry { private final PropertyDescriptor mDescriptor; public BeanEntry(final PropertyDescriptor pDescriptor) { this.mDescriptor = pDescriptor; } public String getKey() { return mDescriptor.getName(); } public Object getValue() { return unwrap(new Wrapped() { public Object run() throws IllegalAccessException, InvocationTargetException { final Method method = mDescriptor.getReadMethod(); // A write-only bean. if (method == null) { throw new UnsupportedOperationException("No getter: " + mDescriptor.getName()); } return method.invoke(mBean); } }); } public Object setValue(final Object pValue) { return unwrap(new Wrapped() { public Object run() throws IllegalAccessException, InvocationTargetException { final Method method = mDescriptor.getWriteMethod(); // A read-only bean. if (method == null) { throw new UnsupportedOperationException("No write method for property: " + mDescriptor.getName()); } final Object old = getValue(); method.invoke(mBean, pValue); return old; } }); } public boolean equals(Object pOther) { if (!(pOther instanceof Map.Entry)) { return false; } Map.Entry entry = (Map.Entry) pOther; Object k1 = getKey(); Object k2 = entry.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = entry.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) { return true; } } return false; } public int hashCode() { return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode()); } public String toString() { return getKey() + "=" + getValue(); } } private static interface Wrapped { Object run() throws IllegalAccessException, InvocationTargetException; } private static Object unwrap(final Wrapped wrapped) { try { return wrapped.run(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (final InvocationTargetException e) { // Javadocs for setValue indicate cast is ok. throw (RuntimeException) e.getCause(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy