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

at.molindo.notify.model.BeanParams Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010 Molindo GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package at.molindo.notify.model;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

import at.molindo.notify.INotifyService.NotifyRuntimeException;

public class BeanParams implements IParams {

	private final B _bean;

	public static  BeanParams params(B bean) {
		return new BeanParams(bean);
	}

	public BeanParams(B bean) {
		if (bean == null) {
			throw new NullPointerException("bean");
		}
		_bean = bean;

	}

	public B getBean() {
		return _bean;
	}

	@Override
	public  IParams set(Param param, T value) {
		setProperty(param, value);
		return this;
	}

	@Override
	public  T get(Param param) {
		Object o = getProperty(param.getName());
		if (o == null) {
			return null;
		} else if (param.getType().isAssignableFrom(o.getClass())) {
			return param.getType().cast(o);
		} else if (o instanceof String) {
			return param.toObject((String) o);
		} else {
			return param.toObject(param.toString(o));
		}
	}

	@Override
	public boolean isSet(Param param) {
		return getProperty(param.getName()) != null;
	}

	@Override
	public Iterator iterator() {
		return new Iterator() {

			private final Iterator _iter = getDescriptorsIter();
			private ParamValue _next = findNext();

			private ParamValue findNext() {
				while (_iter.hasNext()) {
					PropertyDescriptor pd = _iter.next();
					if (pd.getWriteMethod() == null || pd.getReadMethod() == null) {
						continue;
					}
					Object value = invoke(pd.getReadMethod());
					if (value == null) {
						continue;
					}
					return Param.p(pd.getPropertyType(), pd.getName()).paramValue(value);
				}
				return null;
			}

			@Override
			public boolean hasNext() {
				return _next != null;
			}

			@Override
			public ParamValue next() {
				if (!hasNext()) {
					throw new NoSuchElementException();
				}
				ParamValue next = _next;
				_next = findNext();
				return next;
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	@Override
	public boolean containsAll(Param... params) {
		return IParams.Util.containsAll(this, params);
	}

	@Override
	public IParams setAll(IParams params) {
		IParams.Util.setAll(this, params);
		return this;
	}

	@Override
	public Map newMap() {
		return IParams.Util.newMap(this);
	}

	private PropertyDescriptor getDescriptor(String propertyName) {
		try {
			PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(_bean, propertyName);
			return pd != null && pd.getWriteMethod() != null && pd.getReadMethod() != null ? pd : null;
		} catch (IllegalAccessException e) {
			throw new NotifyRuntimeException("failed to get PropertyDescriptor for property " + propertyName
					+ " from bean " + _bean, e);
		} catch (InvocationTargetException e) {
			throw new NotifyRuntimeException("failed to get PropertyDescriptor for property " + propertyName
					+ " from bean " + _bean, e);
		} catch (NoSuchMethodException e) {
			// ignore
			return null;
		}
	}

	private Iterator getDescriptorsIter() {
		return Arrays.asList(PropertyUtils.getPropertyDescriptors(_bean)).iterator();
	}

	private Object getProperty(String name) {
		try {
			return BeanUtils.getProperty(_bean, name);
		} catch (IllegalAccessException e) {
			throw new NotifyRuntimeException("failed to get property " + name + " from bean " + _bean, e);
		} catch (InvocationTargetException e) {
			throw new NotifyRuntimeException("failed to get property " + name + " from bean " + _bean, e);
		} catch (NoSuchMethodException e) {
			// ignore
			return null;
		}
	}

	private Object invoke(Method m, Object... args) {
		try {
			return m.invoke(_bean, args);
		} catch (IllegalArgumentException e) {
			throw new NotifyRuntimeException("failed to invoke method " + m + " on " + _bean, e);
		} catch (IllegalAccessException e) {
			throw new NotifyRuntimeException("failed to invoke method " + m + " on " + _bean, e);
		} catch (InvocationTargetException e) {
			throw new NotifyRuntimeException("failed to invoke method " + m + " on " + _bean, e);
		}
	}

	private void setProperty(Param param, Object value) {
		PropertyDescriptor pd = getDescriptor(param.getName());
		if (pd == null) {
			// TODO simply ignore?
			return;
		}

		Object converted;
		if (value == null || pd.getPropertyType().isAssignableFrom(value.getClass())) {
			converted = value;
		} else {
			converted = Param.p(pd.getPropertyType(), pd.getName()).toObject(param.toString(value));
		}

		try {
			PropertyUtils.setProperty(_bean, param.getName(), converted);
		} catch (NoSuchMethodException e) {
			throw new NotifyRuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new NotifyRuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new NotifyRuntimeException(e);
		}
	}

}