mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-21 00:00:01 -04:00
Moving files around
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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.
|
||||
* <p/>
|
||||
* Ruhtlessly stolen from
|
||||
* <a href="http://binkley.blogspot.com/2006/08/mapping-java-bean.html>Binkley's Blog</a>
|
||||
*/
|
||||
public final class BeanMap extends AbstractMap<String, Object> implements Serializable, Cloneable {
|
||||
private final Object mBean;
|
||||
private transient Set<PropertyDescriptor> mDescriptors;
|
||||
|
||||
public BeanMap(Object pBean) throws IntrospectionException {
|
||||
if (pBean == null) {
|
||||
throw new IllegalArgumentException("bean == null");
|
||||
}
|
||||
|
||||
mBean = pBean;
|
||||
mDescriptors = initDescriptors(pBean);
|
||||
}
|
||||
|
||||
private static Set<PropertyDescriptor> initDescriptors(Object pBean) throws IntrospectionException {
|
||||
final Set<PropertyDescriptor> descriptors = new HashSet<PropertyDescriptor>();
|
||||
|
||||
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<Entry<String, Object>> 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<String, Object> 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<Entry<String, Object>> {
|
||||
public Iterator<Entry<String, Object>> iterator() {
|
||||
return new BeanIterator(mDescriptors.iterator());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mDescriptors.size();
|
||||
}
|
||||
}
|
||||
|
||||
private class BeanIterator implements Iterator<Entry<String, Object>> {
|
||||
private final Iterator<PropertyDescriptor> mIterator;
|
||||
|
||||
public BeanIterator(final Iterator<PropertyDescriptor> 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<String, Object> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user