View Javadoc

1   /*
2    * This file is a part of CAST project.
3    * (c) Copyright 2007, AGH University of Science & Technology
4    * https://caribou.iisg.agh.edu.pl/trac/cast
5    *
6    * Licensed under the Eclipse Public License, Version 1.0 (the "License").
7    * You may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * http://www.eclipse.org/legal/epl-v10.html
10   */
11  /*
12   * File: Attribute.java
13   * Created: 2007-00-00
14   * Author: awos, tmilos
15   * $Id: Attribute.java 2817 2009-05-05 13:17:57Z tmilos $
16   */
17  
18  package pl.edu.agh.cast.model.attributes;
19  
20  import java.beans.PropertyChangeListener;
21  import java.io.Serializable;
22  
23  import pl.edu.agh.cast.data.model.property.IPropertyChangeProvider;
24  import pl.edu.agh.cast.data.model.property.PropertyChangeProviderHelper;
25  import pl.edu.agh.cast.model.ModelUtil;
26  import pl.edu.agh.cast.util.Messages;
27  
28  import com.thoughtworks.xstream.annotations.XStreamAlias;
29  import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
30  import com.thoughtworks.xstream.annotations.XStreamOmitField;
31  
32  /**
33   * Stores information about a single attribute registered in an attribute manager.
34   *
35   * Two {@link Attribute}s are considered equal if their names are equal.
36   *
37   * @author AGH CAST Team
38   */
39  @XStreamAlias("attribute")
40  public class Attribute implements Serializable, Comparable<Attribute>, IPropertyChangeProvider {
41  
42  	private static final long serialVersionUID = -1988514436802189113L;
43  
44  	/**
45  	 * ID of the <em>ShowAsLabel</em> property.
46  	 */
47  	public static final String PROPERTY_SHOW_AS_LABEL = "Attribute.ShowAsLabel"; //$NON-NLS-1$
48  
49  	/**
50  	 * Default {@link AttributeMergePolicy} for this attribute.
51  	 */
52  	@XStreamAlias("mergePolicy")
53  	@XStreamAsAttribute
54  	private AttributeMergePolicy defaultMergePolicy;
55  
56  	/**
57  	 * Attribute name.
58  	 */
59  	@XStreamAsAttribute
60  	private String name;
61  
62  	/**
63  	 * The name of the type (in some domain model) which defines this attribute. It might be null, if the attribute is
64  	 * created, but it doesn't matter since such attributes are not localizable.
65  	 */
66  	@XStreamAsAttribute
67  	private String ownerTypeName;
68  
69  	/**
70  	 * The ID of the model extension in which this attribute is defined. It might be null if the attribute is created by
71  	 * user or it is some predefined attribute. In the first case, the attribute is not localizable, in the second, the
72  	 * localized message is taken from the Core plug-in.
73  	 */
74  	@XStreamAsAttribute
75  	private String modelExtensionId;
76  
77  	/**
78  	 * Whether attribute name should be localized.
79  	 */
80  	@XStreamAsAttribute
81  	private boolean nameIsLocalizable;
82  
83  	@XStreamAsAttribute
84  	private ValueType type;
85  
86  	@XStreamAsAttribute
87  	private Object defaultValue;
88  
89  	@XStreamAsAttribute
90  	private boolean permanent;
91  
92  	@XStreamAsAttribute
93  	private boolean editable;
94  
95  	@XStreamAsAttribute
96  	private boolean showAsLabel;
97  
98  	private static ModelUtil modelUtil = new ModelUtil();
99  
100 	/**
101 	 * Constructor.
102 	 *
103 	 * @param name
104 	 *            name of the attribute
105 	 * @param nameIsLocalizable
106 	 *            whether the name is localizable
107 	 * @param type
108 	 *            value type
109 	 * @param defaultValue
110 	 *            default attribute value
111 	 * @param permanent
112 	 *            whether the attribute is permanent
113 	 * @param editable
114 	 *            whether the attribute can be edited
115 	 * @param showAsLabel
116 	 *            whether the attribute should be displayed in label
117 	 * @param ownerTypeName
118 	 *            the name of the type (in some domain model) which defines this attribute - it might be null, if the
119 	 *            attribute is created, but it doesn't matter since such attributes are not localizable
120 	 * @param modelExtensionId
121 	 *            the ID of the model extension in which this attribute is defined. It might be null if the attribute is
122 	 *            created by user or it is some predefined attribute. In the first case, the attribute is not
123 	 *            localizable, in the second, the localized message is taken from the Core plug-in.
124 	 */
125 	public Attribute(String name, boolean nameIsLocalizable, ValueType type, Object defaultValue, boolean permanent,
126 	        boolean editable, boolean showAsLabel, String ownerTypeName, String modelExtensionId) {
127 		this.name = name;
128 		this.nameIsLocalizable = nameIsLocalizable;
129 		this.type = type;
130 		this.defaultValue = defaultValue;
131 		this.permanent = permanent;
132 		this.editable = editable;
133 		this.showAsLabel = showAsLabel;
134 		this.ownerTypeName = ownerTypeName;
135 		this.modelExtensionId = modelExtensionId;
136 		pcpHelper = new PropertyChangeProviderHelper(this);
137 	}
138 
139 	public ValueType getType() {
140 		return type;
141 	}
142 
143 	public boolean isPermanent() {
144 		return permanent;
145 	}
146 
147 	public boolean isNameLocalizable() {
148 		return nameIsLocalizable;
149 	}
150 
151 	public boolean isEditable() {
152 		return editable;
153 	}
154 
155 	public boolean isShowAsLabel() {
156 		return showAsLabel;
157 	}
158 
159 	public String getName() {
160 		return name;
161 	}
162 
163 	public Object getDefaultValue() {
164 		return defaultValue;
165 	}
166 
167 	/**
168 	 * The human readable name of the attribute. If the attribute is localizable (i.e. is a predefined attribute or is
169 	 * defined in some domain model) the localized representation of the name is returned. Otherwise the raw name is
170 	 * returned.
171 	 *
172 	 * @return The human readable name of the attribute.
173 	 */
174 	public String getDisplayName() {
175 		/*
176 		 * The lookup strategy is as follows: - if the modelExtensionId is defined, then the model extension is looked
177 		 * up for the localized message - if the modelExtensionId is not defined, then the localized name is looked up
178 		 * in the Core plug-in - if the localized name is not found, the raw name is returned
179 		 */
180 		if (nameIsLocalizable) {
181 			try {
182 				if (modelExtensionId != null) {
183 					return modelUtil.getAttributeName(modelExtensionId, ownerTypeName, name);
184 				} else {
185 					return Messages.getByKey(name);
186 				}
187 			} catch (java.lang.IllegalArgumentException e) {
188 				// its OK - the raw name will be returned
189 			}
190 
191 		}
192 		return name;
193 	}
194 
195 	/**
196 	 * Checks if given value is valid for this attribute.
197 	 *
198 	 * @param value
199 	 *            value to check
200 	 * @return validation result
201 	 */
202 	public boolean validateValue(Object value) {
203 		return type.getValidator().isValidClass(value);
204 	}
205 
206 	/**
207 	 * Two {@link Attribute}s are considered equal if their names are equal.
208 	 *
209 	 * {@inheritDoc}
210 	 *
211 	 * @see java.lang.Object#equals(java.lang.Object)
212 	 */
213 	@Override
214 	public boolean equals(Object obj) {
215 		if (obj == this) {
216 			return true;
217 		}
218 		if (!(obj instanceof Attribute)) {
219 			return false;
220 		}
221 		Attribute that = (Attribute)obj;
222 		return this.name.equalsIgnoreCase(that.name);
223 	}
224 
225 	/**
226 	 * {@inheritDoc}
227 	 *
228 	 * @see java.lang.Object#hashCode()
229 	 */
230 	@Override
231 	public int hashCode() {
232 		return name.toLowerCase().hashCode();
233 	}
234 
235 	/**
236 	 * {@inheritDoc}
237 	 *
238 	 * @see java.lang.Comparable#compareTo(java.lang.Object)
239 	 */
240 	public int compareTo(Attribute o) {
241 		return this.name.compareToIgnoreCase(o.name);
242 	}
243 
244 	/**
245 	 * {@inheritDoc}
246 	 *
247 	 * @see java.lang.Object#toString()
248 	 */
249 	@Override
250 	public String toString() {
251 		return name;
252 	}
253 
254 	/**
255 	 * Sets new value of showAsLabel flag. Fires a {@link #PROPERTY_SHOW_AS_LABEL} event.
256 	 *
257 	 * @param showAsLabel
258 	 *            new showAsLabel value
259 	 */
260 	public void setShowAsLabel(boolean showAsLabel) {
261 		Boolean oldValue = Boolean.valueOf(this.showAsLabel);
262 		this.showAsLabel = showAsLabel;
263 		firePropertyChange(PROPERTY_SHOW_AS_LABEL, oldValue, Boolean.valueOf(showAsLabel));
264 	}
265 
266 	/**
267 	 * Returns a copy of this {@link Attribute} instance.
268 	 *
269 	 * @return copy of this instance
270 	 */
271 	public Attribute copy() {
272 		return new Attribute(name, nameIsLocalizable, type, defaultValue, permanent, editable, showAsLabel,
273 		        ownerTypeName, modelExtensionId);
274 	}
275 
276 	/**
277 	 * Property change support.
278 	 */
279 	@XStreamOmitField
280 	private transient PropertyChangeProviderHelper pcpHelper;
281 
282 	protected Object readResolve() {
283 		pcpHelper = new PropertyChangeProviderHelper(this);
284 		return this;
285 	}
286 
287 	/**
288 	 * {@inheritDoc}
289 	 *
290 	 * @see pl.edu.agh.cast.data.model.property.IPropertyChangeProvider#addPropertyChangeListener(java.beans.PropertyChangeListener)
291 	 */
292 	public void addPropertyChangeListener(PropertyChangeListener l) {
293 		pcpHelper.addPropertyChangeListener(l);
294 	}
295 
296 	/**
297 	 * {@inheritDoc}
298 	 *
299 	 * @see pl.edu.agh.cast.data.model.property.IPropertyChangeProvider
300 	 *      #removePropertyChangeListener(java.beans.PropertyChangeListener)
301 	 */
302 	public void removePropertyChangeListener(PropertyChangeListener l) {
303 		pcpHelper.removePropertyChangeListener(l);
304 	}
305 
306 	protected void firePropertyChange(String property, Object oldValue, Object newValue) {
307 		pcpHelper.firePropertyChange(property, oldValue, newValue);
308 	}
309 
310 	public AttributeMergePolicy getDefaultMergePolicy() {
311 		return defaultMergePolicy;
312 	}
313 
314 	public void setDefaultMergePolicy(AttributeMergePolicy defaultMergePolicy) {
315 		this.defaultMergePolicy = defaultMergePolicy;
316 	}
317 
318 }