Source code: org/metacosm/util/NonNumericProperty.java
1 /*
2 Metacosm, an object-oriented network game framework
3 Copyright (C) 1999-2001 Metacosm Development Team
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package org.metacosm.util;
21
22 import java.util.List;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Iterator;
26
27 /**
28 * A Non-numeric Property contains a non-numeric value (ie an non-null object).
29 * We couldn't find useful examples for using intersections, unions or exclusions of
30 * sets to define the field. So we'll only use one set (or none). The set should contain
31 * one or more values (i.e. a field is a non-null and non-empty set of distinct non-null
32 * Objects).
33 */
34 final public class NonNumericProperty extends Property {
35 /**
36 * @throws IllegalArgumentException if name or value are null.
37 */
38 public NonNumericProperty( String name, Object value) throws IllegalArgumentException {
39 super( name);
40 if ( value == null) {
41 throw new IllegalArgumentException();
42 }
43 this.initialValue = value;
44 this.value = value;
45 this.field = null;
46 absModifier = null;
47 absList = Collections.synchronizedList(new ArrayList());
48 randomValues = Collections.synchronizedList(new ArrayList());
49 }
50
51 /**
52 * @throws IllegalArgumentException if name, value or field are null, or value not in field
53 */
54 public NonNumericProperty( String name, Object value, Field field) throws IllegalArgumentException {
55 super( name);
56 if ( value == null || field == null || !field.isInField( value)) {
57 throw new IllegalArgumentException();
58 }
59 this.initialValue = value;
60 this.value = value;
61 this.field = field;
62 absModifier = null;
63 absList = Collections.synchronizedList(new ArrayList());
64 randomValues = Collections.synchronizedList(new ArrayList());
65 }
66
67 /**
68 * @throws IllegalArgumentException if a field exists and the value is outside
69 */
70 public void setValue(Object value) throws IllegalArgumentException {
71 if ( field == null || field.isInField( value)) {
72 this.value = value;
73 } else {
74 throw new IllegalArgumentException();
75 }
76 }
77
78 /**
79 * @throws IllegalArgumentException if value is null
80 */
81 public void addToField( Object value) throws IllegalArgumentException {
82 if (value != null) {
83 field = Field.add( field, value);
84 } else {
85 throw new IllegalArgumentException();
86 }
87 }
88
89 /**
90 * @throws IllegalArgumentException if value is null, or value is the current value
91 */
92 public void removeFromField( Object value) throws IllegalArgumentException {
93 if (value != null || this.value == value) {
94 field = Field.remove( field, value);
95 } else {
96 throw new IllegalArgumentException();
97 }
98 }
99
100 public Object getValue() {
101 return value;
102 }
103
104 /**
105 * Applies an absolute modifier to the property.
106 * @param absMod the absolute modifier to be applied
107 * @throws IllegalArgumentException if absMod is null or new value is out of the field
108 */
109 public void applyModifier(AbsoluteModifier absMod) throws IllegalArgumentException {
110 if (absMod != null) {
111 Object randomValue = null;
112 if (absMod instanceof RandomAbsoluteModifier) {
113 randomValue = absMod.getValue();
114 randomValues.add( randomValue);
115 } else {
116 absList.add(absMod);
117 }
118 if (absModifier == null || (absMod.getPriority() > absModifier.getPriority())) {
119 absModifier = absMod;
120 if (randomValue == null) {
121 value = absModifier.getValue();
122 } else {
123 value = randomValue;
124 }
125 if ( field != null && !field.isInField( this.value)) {
126 throw new IllegalArgumentException();
127 }
128 }
129 }
130 }
131
132 /**
133 * Removes an absolute modifier previously applied to the property.
134 * Does nothing if the modifier has not been previously applied or is null.
135 * @param absMod the absolute modifier to be removed
136 */
137 public void removeModifier(AbsoluteModifier absMod) {
138 if (absMod == null) {
139 return;
140 }
141 if (absMod instanceof RandomAbsoluteModifier) {
142 int cptRAM = 0;
143 // Search which value should be removed from randomList
144 boolean found = false;
145 Iterator i = absList.iterator();
146 for (; !found && i.hasNext();) {
147 AbsoluteModifier current = ((AbsoluteModifier)i.next());
148 if ( current == absModifier) {
149 found = true;
150 } else if (current instanceof RandomAbsoluteModifier) {
151 ++cptRAM;
152 }
153 }
154 if (found) {
155 // Value found
156 i.remove();
157 randomValues.remove( cptRAM);
158 }
159 } else if (!absList.remove(absMod)) {
160 return;
161 }
162 if ( absMod == absModifier) {
163 long maxPriority = Integer.MIN_VALUE;
164 absModifier = null;
165 for (Iterator i = absList.iterator(); i.hasNext(); ) {
166 AbsoluteModifier current = ((AbsoluteModifier)i.next());
167 int priority = current.getPriority();
168 if (priority > maxPriority) {
169 maxPriority = priority;
170 absModifier = current;
171 }
172 }
173 if (absModifier == null) {
174 value = initialValue;
175 } else {
176 value = absModifier.getValue();
177 }
178 }
179 }
180
181 /**
182 * Unsupported method
183 * @throws UnsupportedOperationException
184 */
185 public void applyModifier(RelativeModifier relMod) {
186 throw new UnsupportedOperationException();
187 }
188
189 /**
190 * Unsupported method
191 * @throws UnsupportedOperationException
192 */
193 public void removeModifier(RelativeModifier relMod) {
194 throw new UnsupportedOperationException();
195 }
196
197 public void save(java.io.OutputStream os) throws java.io.IOException {
198 /*
199 new java.io.ObjectOutputStream( os).writeObject( this);
200 */
201 }
202
203 public void load(java.io.InputStream is) throws java.io.IOException {
204 /*
205 java.io.ObjectInputStream ois = new java.io.ObjectInputStream( is);
206 try {
207 NonNumericProperty nnp = (NonNumericProperty) ois.readObject();
208 this.value = nnp.value;
209 this.field = nnp.field;
210 } catch ( ClassNotFoundException e) {
211 throw new UnsupportedOperationException();
212 }
213 */
214 }
215
216 public String toString() {
217 return value.toString();
218 }
219
220 /**
221 * @return a new NonNumericProperty with the same name, value and field
222 */
223 public Object clone() {
224 if (field == null) {
225 return new NonNumericProperty( name, value);
226 } else {
227 return new NonNumericProperty( name, value, (Field)field.clone());
228 }
229 }
230
231 private Object value;
232 private Object initialValue;
233
234 /**
235 * AbsoluteModifiers list
236 */
237 private List absList;
238 /**
239 * RandomAbsoluteModifier values list
240 */
241 private List randomValues;
242 /**
243 * The first max priority AbsoluteModifier
244 */
245 private AbsoluteModifier absModifier;
246
247 private Field field;
248 }