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: AttributeMergePolicy.java
13   * Created: 2008-11-24
14   * Author: tmilos
15   * $Id: AttributeMergePolicy.java 3047 2009-07-23 20:39:18Z fibinger $
16   */
17  
18  package pl.edu.agh.cast.model.attributes;
19  
20  import java.io.Serializable;
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import com.thoughtworks.xstream.annotations.XStreamAlias;
25  
26  /**
27   * This class represents a policy of merging two values of an {@link VisualAttribute} into one. It defines a few basic
28   * policies, however custom ones may be defined by extending this class.
29   *
30   * @author AGH CAST Team
31   */
32  public abstract class AttributeMergePolicy implements Serializable {
33  
34  	private static final long serialVersionUID = 6800412459178310697L;
35  
36  	/**
37  	 * A merge policy that always returns the logical alternative (OR) of given values. It is valid only for two values
38  	 * of type {@link Boolean}
39  	 *
40  	 * @author AGH CAST Team
41  	 */
42  	@XStreamAlias("MERGE_POLICY_LOGICAL_OR")
43  	public static final class MergePolicyLogicalOr extends AttributeMergePolicy {
44  		private static final long serialVersionUID = -6698802554723374885L;
45  
46  		private MergePolicyLogicalOr() {
47  			super();
48  		}
49  
50  		/**
51  		 * {@inheritDoc}
52  		 *
53  		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy
54  		 *      #mergeValues(pl.edu.agh.cast.model.attributes.VisualAttribute, java.lang.Object, java.lang.Object)
55  		 */
56  		@Override
57  		public Object mergeValues(Attribute attribute, Object firstValue, Object secondValue) {
58  			checkIfBoolean(firstValue, secondValue);
59  			return ((Boolean)firstValue) || ((Boolean)secondValue);
60  		}
61  
62  		/**
63  		 * {@inheritDoc}
64  		 *
65  		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy#getId()
66  		 */
67  		@Override
68  		public String getId() {
69  			return "MERGE_POLICY_LOGICAL_OR"; //$NON-NLS-1$
70  		}
71  	}
72  
73  	/**
74  	 * A merge policy that always returns the logical conjunction (AND) of given values. It is valid only for two values
75  	 * of type {@link Boolean}
76  	 *
77  	 * @author AGH CAST Team
78  	 */
79  	@XStreamAlias("MERGE_POLICY_LOGICAL_AND")
80  	public static final class MergePolicyLogicalAnd extends AttributeMergePolicy {
81  		private static final long serialVersionUID = 2306183502914013676L;
82  
83  		private MergePolicyLogicalAnd() {
84  			super();
85  		}
86  
87  		/**
88  		 * {@inheritDoc}
89  		 *
90  		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy
91  		 *      #mergeValues(pl.edu.agh.cast.model.attributes.VisualAttribute, java.lang.Object, java.lang.Object)
92  		 */
93  		@Override
94  		public Object mergeValues(Attribute attribute, Object firstValue, Object secondValue) {
95  			checkIfBoolean(firstValue, secondValue);
96  			return ((Boolean)firstValue) && ((Boolean)secondValue);
97  		}
98  
99  		/**
100 		 * {@inheritDoc}
101 		 *
102 		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy#getId()
103 		 */
104 		@Override
105 		public String getId() {
106 			return "MERGE_POLICY_LOGICAL_AND"; //$NON-NLS-1$
107 		}
108 	}
109 
110 	/**
111 	 * A merge policy that always returns the second value.
112 	 *
113 	 * @author AGH CAST Team
114 	 */
115 	@XStreamAlias("MERGE_POLICY_ALWAYS_SECOND")
116 	public static final class MergePolicyAlwaysSecond extends AttributeMergePolicy {
117 		private static final long serialVersionUID = -6798718594185971003L;
118 
119 		private MergePolicyAlwaysSecond() {
120 			super();
121 		}
122 
123 		/**
124 		 * {@inheritDoc}
125 		 *
126 		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy
127 		 *      #mergeValues(pl.edu.agh.cast.model.attributes.VisualAttribute, java.lang.Object, java.lang.Object)
128 		 */
129 		@Override
130 		public Object mergeValues(Attribute attribute, Object firstValue, Object secondValue) {
131 			return secondValue;
132 		}
133 
134 		/**
135 		 * {@inheritDoc}
136 		 *
137 		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy#getId()
138 		 */
139 		@Override
140 		public String getId() {
141 			return "MERGE_POLICY_ALWAYS_SECOND"; //$NON-NLS-1$
142 		}
143 	}
144 
145 	/**
146 	 * A merge policy that always returns the first value.
147 	 *
148 	 * @author AGH CAST Team
149 	 */
150 	@XStreamAlias("MERGE_POLICY_ALWAYS_FIRST")
151 	public static final class MergePolicyAlwaysFirst extends AttributeMergePolicy {
152 		private static final long serialVersionUID = 3645856921319121245L;
153 
154 		private MergePolicyAlwaysFirst() {
155 			super();
156 		}
157 
158 		/**
159 		 * {@inheritDoc}
160 		 *
161 		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy
162 		 *      #mergeValues(pl.edu.agh.cast.model.attributes.VisualAttribute, java.lang.Object, java.lang.Object)
163 		 */
164 		@Override
165 		public Object mergeValues(Attribute attribute, Object firstValue, Object secondValue) {
166 			return firstValue;
167 		}
168 
169 		/**
170 		 * {@inheritDoc}
171 		 *
172 		 * @see pl.edu.agh.cast.model.attributes.AttributeMergePolicy#getId()
173 		 */
174 		@Override
175 		public String getId() {
176 			return "MERGE_POLICY_ALWAYS_FIRST"; //$NON-NLS-1$
177 		}
178 
179 	};
180 
181 	/**
182 	 * Merge policy registry.
183 	 */
184 	private static Map<String, AttributeMergePolicy> policyRegistry = new HashMap<String, AttributeMergePolicy>();
185 
186 	/**
187 	 * A merge policy that always returns the first value.
188 	 */
189 	public static final AttributeMergePolicy MERGE_POLICY_ALWAYS_FIRST = new MergePolicyAlwaysFirst();
190 
191 	/**
192 	 * A merge policy that always returns the second value.
193 	 */
194 	public static final AttributeMergePolicy MERGE_POLICY_ALWAYS_SECOND = new MergePolicyAlwaysSecond();
195 
196 	/**
197 	 * A merge policy that always returns the logical conjunction (AND) of given values. It is valid only for two values
198 	 * of type {@link Boolean}
199 	 */
200 	public static final AttributeMergePolicy MERGE_POLICY_LOGICAL_AND = new MergePolicyLogicalAnd();
201 
202 	/**
203 	 * A merge policy that always returns the logical alternative (OR) of given values. It is valid only for two values
204 	 * of type {@link Boolean}
205 	 */
206 	public static final AttributeMergePolicy MERGE_POLICY_LOGICAL_OR = new MergePolicyLogicalOr();
207 
208 	protected AttributeMergePolicy() {
209 		if (!policyRegistry.containsKey(getId())) {
210 			policyRegistry.put(toString(), this);
211 		} else if (!policyRegistry.get(getId()).getClass().equals(this.getClass())) {
212 			throw new AttributeMergePolicyNotUniqueException(
213 			        "An instance of AttributeMergePolicy with given ID is already registered: " //$NON-NLS-1$
214 			                + getId());
215 		}
216 	}
217 
218 	/**
219 	 * Verifies if two values are of type {@link Boolean}. Helper method.
220 	 *
221 	 * @param first
222 	 * @param second
223 	 * @return <code>true</code> if types of both values are of type {@link Boolean}
224 	 */
225 	protected boolean checkIfBoolean(Object firstValue, Object secondValue) {
226 		if (!(firstValue instanceof Boolean)) {
227 			throw new IllegalArgumentException("First value is not of type Boolean"); //$NON-NLS-1$
228 		}
229 		if (!(secondValue instanceof Boolean)) {
230 			throw new IllegalArgumentException("Second value is not of type Boolean"); //$NON-NLS-1$
231 		}
232 		return true;
233 	}
234 
235 	/**
236 	 * Returns the unique id of this policy.
237 	 *
238 	 * @return policy id
239 	 */
240 	public abstract String getId();
241 
242 	/**
243 	 * Merges two {@link Attribute} values into one. It is possible that the returned value will be one of the
244 	 * parameters, or a completely new object.
245 	 *
246 	 * @param attribute
247 	 *            {@link Attribute} to merge
248 	 * @param firstValue
249 	 *            first value
250 	 * @param secondValue
251 	 *            second value
252 	 * @return an {@link AttributeValue} that is the result of merging given values according to the policy
253 	 */
254 	public abstract Object mergeValues(Attribute attribute, Object firstValue, Object secondValue);
255 
256 	/**
257 	 * Returns policy based on its id.
258 	 *
259 	 * @param id
260 	 *            policy id
261 	 * @return the policy
262 	 */
263 	public static final AttributeMergePolicy resolve(String id) {
264 		return policyRegistry.get(id);
265 	}
266 
267 	/**
268 	 * {@inheritDoc}
269 	 *
270 	 * @see java.lang.Object#equals(java.lang.Object)
271 	 */
272 	@Override
273 	public boolean equals(Object obj) {
274 		if (obj == this) {
275 			return true;
276 		}
277 		if (!(obj instanceof AttributeMergePolicy)) {
278 			return false;
279 		}
280 		AttributeMergePolicy that = (AttributeMergePolicy)obj;
281 		if (!this.getId().equals(that.getId())) {
282 			return false;
283 		}
284 		return true;
285 	}
286 
287 	/**
288 	 * {@inheritDoc}
289 	 *
290 	 * @see java.lang.Object#toString()
291 	 */
292 	@Override
293 	public String toString() {
294 		return getId();
295 	}
296 
297 	/**
298 	 * {@inheritDoc}
299 	 *
300 	 * @see java.lang.Object#hashCode()
301 	 */
302 	@Override
303 	public int hashCode() {
304 		return getId().hashCode();
305 	}
306 
307 }