View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans.
5    *
6    * CosyBeans is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.util;
21  
22  import java.beans.PropertyChangeEvent;
23  import java.beans.PropertyChangeListener;
24  import java.lang.reflect.InvocationTargetException;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import javax.swing.JComponent;
29  
30  import com.cosylab.introspection.BeanIntrospector;
31  
32  
33  /**
34   * This class implements pattern, which protects Java bean properties from undesigred changes. 
35   * For example user setting are protected from data source characteristics override.
36   * 
37   * <p>
38   * Setting properties to bean with this class should have minimum performance overhead if bean is not protected.
39   * </p>
40   * 
41   * <p>
42   * Warning! This class is not synchronized. It expects tht only one thread will access GUI Java Beans
43   * at a time. Otherwise precations must be taken.
44   * </p>
45   * 
46   * @author Igor Kriznar (igor.kriznarATcosylab.com)
47   *
48   */
49  public final class UserSettingsProtection implements PropertyChangeListener {
50  	
51  	static final Map<JComponent,UserSettingsProtection> protections= new HashMap<JComponent,UserSettingsProtection>(10);
52  	private JComponent bean;
53  	private Map<String,Boolean> prot= new HashMap<String,Boolean>(5);
54  	
55  	/**
56  	 * Creates new instance of UserSettingsProtection.
57  	 */
58  	private UserSettingsProtection(JComponent bean) {
59  		this.bean=bean;
60  	}
61  	
62  	/**
63  	 * Sets up or down property protection for provided JavaBean and properties.
64  	 * @param bean Java Bean
65  	 * @param properties the properties to be protected
66  	 * @param protection if <code>true</code> properties are proteccted, othervise protection is removed
67  	 */
68  	public static void setProtection(JComponent bean, String[] properties, boolean protection) {
69  		UserSettingsProtection p= protections.get(bean);
70  		if (protection) {
71  			if (p==null) {
72  				p= new UserSettingsProtection(bean);
73  				protections.put(bean,p);
74  			}
75  			p.setProtection(properties,protection);
76  		} else {
77  			if (p!=null) {
78  				p.setProtection(properties,protection);
79  			}
80  		}
81  	}
82  
83  	public void clearProtections() {
84  		for (String property : prot.keySet()) {
85  			bean.removePropertyChangeListener(property,this);
86  		}
87  		prot.clear();
88  	}
89  
90  	public void setProtection(String[] properties, boolean protection) {
91  		for (int i = 0; i < properties.length; i++) {
92  			prot.put(properties[i],protection);
93  			if (protection) {
94  				bean.addPropertyChangeListener(properties[i],this);
95  			} else {
96  				bean.removePropertyChangeListener(properties[i],this);
97  			}
98  		}
99  	}
100 
101 	/**
102 	 * Sets to a bean a Java Bean property with new value only if property is not protected.
103 	 * @param bean a bean on which property is to be set
104 	 * @param property a property name
105 	 * @param value new property value to be set
106 	 * @return <code>true</code> if value was set, otherwise <code>false</code> (property was protected)
107 	 * @throws NoSuchMethodException
108 	 * @throws InvocationTargetException
109 	 * @throws IllegalAccessException
110 	 */
111 	public static boolean setUnprotected(JComponent bean, String property, Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
112 		if (property==null || value== null) {
113 			return false;
114 		}
115 		UserSettingsProtection p= protections.get(bean);
116 		if (p!=null) {
117 			return p.setUnprotected(property,value);
118 		}
119 		BeanIntrospector.setPropertyValue(bean,property,value);
120 		return true;
121 	}
122 	
123 	/**
124 	 * Sets to a bean a Java Bean property with new value only if property is not protected.
125 	 * @param property a property name
126 	 * @param value new property value to be set
127 	 * @return <code>true</code> if value was set, otherwise <code>false</code> (property was protected)
128 	 * @throws NoSuchMethodException
129 	 * @throws InvocationTargetException
130 	 * @throws IllegalAccessException
131 	 */
132 	public boolean setUnprotected(String property, Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
133 		if (property==null || value== null) {
134 			return false;
135 		}
136 		Boolean b= prot.get(property);
137 		if (b!=null && b.booleanValue()) {
138 			return false;
139 		}
140 		if (b!=null) {
141 			bean.removePropertyChangeListener(property,this);
142 			BeanIntrospector.setPropertyValue(bean,property,value);
143 			bean.addPropertyChangeListener(property,this);
144 		} else {
145 			BeanIntrospector.setPropertyValue(bean,property,value);
146 		}
147 		return true;
148 	}
149 
150 	/* (non-Javadoc)
151 	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
152 	 */
153 	public void propertyChange(PropertyChangeEvent evt) {
154 		String p= evt.getPropertyName();
155 		if (prot.containsKey(p)) prot.put(p,true);
156 	}
157 	
158 }