View Javadoc

1   /*
2    * Copyright 2004-2005, 2007 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.morph.context.contexts;
17  
18  import net.sf.morph.Defaults;
19  import net.sf.morph.context.Context;
20  import net.sf.morph.context.ContextException;
21  import net.sf.morph.context.DelegatingContext;
22  import net.sf.morph.context.HierarchicalContext;
23  import net.sf.morph.reflect.BeanReflector;
24  import net.sf.morph.util.ClassUtils;
25  
26  /**
27   * A context that delegates property storage to some delegate and uses
28   * {@link net.sf.morph.reflect.BeanReflector}s to manipulate the information in the
29   * delegate. By default this class uses the
30   * {@link net.sf.morph.reflect.reflectors.SimpleDelegatingReflector}, so
31   * contexts can be created out of any type for which the reflector can expose a
32   * BeanReflector.
33   *
34   * @author Matt Sgarlata
35   * @since Nov 21, 2004
36   * @see net.sf.morph.context.support.SimpleReflectorContext
37   * @see net.sf.morph.context.HierarchicalContext
38   */
39  public class ReflectorHierarchicalContext extends BaseHierarchicalContext implements HierarchicalContext, DelegatingContext {
40  	
41  	private BeanReflector beanReflector;
42  
43  	private Object delegate;
44  	
45  	/**
46  	 * Creates a new, empty context.
47  	 */
48  	public ReflectorHierarchicalContext() {
49  		super();
50  	}
51  	
52  	public ReflectorHierarchicalContext(Object delegate) {
53  		this();
54  		setDelegate(delegate);
55  	}
56  	
57  	/**
58  	 * Creates a new, empty context with the specified parent.  Before this
59  	 * context is used, the 
60  	 */
61  	public ReflectorHierarchicalContext(Context parentContext) {
62  		super(parentContext);
63  	}
64  	
65  	public ReflectorHierarchicalContext(Object delegate, Context parentContext) {
66  		super(parentContext);
67  		this.delegate = delegate;
68  	}
69  	
70  	protected void checkConfiguration() {
71  		if (getBeanReflector() == null) {
72  			throw new ContextException("The " + getClass().getName()
73  				+ " requires a beanReflector be set using the setReflector method");
74  		}
75  		if (getDelegate() == null) {
76  			throw new ContextException(
77  				"The "
78  					+ getClass().getName()
79  					+ " requires an object that can have its properties delegate.  Use the setReflected method");
80  		}
81  		if (!ClassUtils.inheritanceContains(getBeanReflector().getReflectableClasses(), getDelegate().getClass())) {
82  			throw new ContextException("The beanReflector of class "
83  				+ getBeanReflector().getClass().getName()
84  				+ " cannot reflect objects of class "
85  				+ getDelegate().getClass().getName());
86  		}
87  	}
88  
89  	protected String[] getPropertyNamesHierarchicalImpl() throws Exception {
90  		checkConfiguration();
91  		return getBeanReflector().getPropertyNames(getDelegate());
92  	}
93  
94  	protected Object getHierarchicalImpl(String propertyName) throws Exception {
95  		checkConfiguration();
96  		return getBeanReflector().isReadable(getDelegate(), propertyName)
97  				? getBeanReflector().get(getDelegate(), propertyName) : null;
98  	}
99  
100 	protected void setHierarchicalImpl(String propertyName, Object propertyValue)
101 		throws Exception {
102 		checkConfiguration();
103 		getBeanReflector().set(getDelegate(), propertyName, propertyValue);
104 	}
105 
106 	public BeanReflector getBeanReflector() {
107 		if (beanReflector == null) {
108 			beanReflector = Defaults.createBeanReflector();
109 		}
110 		return beanReflector;
111 	}
112 
113 	public void setBeanReflector(BeanReflector beanReflector) {
114 		this.beanReflector = beanReflector;
115 	}
116 
117 	public Object getDelegate() {
118 		return delegate;
119 	}
120 
121 	public void setDelegate(Object reflected) {
122 		this.delegate = reflected;
123 	}
124 
125 // sgarlatam 12/11/2004: turns out this is more annoying than helpful	
126 //	public String toString() {
127 //		return "[delegate=" + ObjectUtils.getObjectDescription(delegate) + ",parent=" + ObjectUtils.getObjectDescription(getParentContext()) + "]";
128 //	}
129 }