1 package org.opentrafficsim.base.modelproperties;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6
7 /**
8 * Abstract property.
9 * <p>
10 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
11 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
12 * <p>
13 * $LastChangedDate: 2016-05-28 11:33:31 +0200 (Sat, 28 May 2016) $, @version $Revision: 2051 $, by $Author: averbraeck $,
14 * initial version 18 dec. 2014 <br>
15 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
16 * @param <T> type of the property
17 */
18 public abstract class AbstractProperty<T> implements Property<T>, Serializable
19 {
20 /** */
21 private static final long serialVersionUID = 20150000L;
22
23 /** Key of this property. */
24 private final String key;
25
26 /** Determines sorting order when properties are displayed to the user. */
27 private final int displayPriority;
28
29 /** The shortName of the property. */
30 private String shortName;
31
32 /** The description of the property. */
33 private String description;
34
35 /** The property is read-only. */
36 private Boolean readOnly = null;
37
38 /** Parent of this AbstractProperty. */
39 private CompoundProperty parentProperty = null;
40
41 /**
42 * Construct a new AbstractProperty.
43 * @param key String; unique (within this property tree) name of the new AbstractProperty
44 * @param displayPriority sorting order when properties are displayed to the user
45 * @param shortName String; concise description of the property
46 * @param description String; long description of the property (may use HTML markup)
47 */
48 public AbstractProperty(final String key, final int displayPriority, final String shortName, final String description)
49 {
50 this.key = key;
51 this.displayPriority = displayPriority;
52 this.shortName = shortName;
53 this.description = description;
54 }
55
56 /**
57 * Finalize the readOnly flag.
58 * @param readOnlyValue boolean; the new value for the readonly flag
59 */
60 // XXX Made this method public to allow changes in e.g., tests; it should really be private
61 public final void setReadOnly(final boolean readOnlyValue)
62 {
63 this.readOnly = readOnlyValue;
64 }
65
66 /** {@inheritDoc} */
67 @Override
68 public final int getDisplayPriority()
69 {
70 return this.displayPriority;
71 }
72
73 /** {@inheritDoc} */
74 @Override
75 public abstract String htmlStateDescription();
76
77 /** {@inheritDoc} */
78 @Override
79 public final Iterator<Property<?>> iterator()
80 {
81 return new PropertyIterator(this);
82 }
83
84 /** {@inheritDoc} */
85 @Override
86 public final String getShortName()
87 {
88 return this.shortName;
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public final String getDescription()
94 {
95 return this.description;
96 }
97
98 /** {@inheritDoc} */
99 @Override
100 public final boolean isReadOnly()
101 {
102 return null != this.readOnly && this.readOnly;
103 }
104
105 /**
106 * Retrieve the key of this AbstractProperty.
107 * @return String; the key of this AbstractProperty
108 */
109 @Override
110 public final String getKey()
111 {
112 return this.key;
113 }
114
115 /** {@inheritDoc} */
116 @Override
117 public final Property<?> findByKey(final String propertyKey)
118 {
119 if (this.key.equals(propertyKey))
120 {
121 return this;
122 }
123 if (this instanceof CompoundProperty)
124 {
125 return ((CompoundProperty) this).getPropertyGroup().get(propertyKey);
126 }
127 if (null == getParent())
128 {
129 return null;
130 }
131 return getParent().getPropertyGroup().get(propertyKey);
132 }
133
134 /**
135 * Set the parent of this AbstractProperty.
136 * @param newParent AbstractProperty<?>; the new parent of this AbstractProperty
137 */
138 protected final void setParent(final CompoundProperty newParent)
139 {
140 this.parentProperty = newParent;
141 }
142
143 /** {@inheritDoc} */
144 @Override
145 public final CompoundProperty getParent()
146 {
147 return this.parentProperty;
148 }
149
150 /** {@inheritDoc} */
151 @Override
152 public final String toString()
153 {
154 return this.getShortName();
155 }
156
157 /**
158 * Really simple iterator for properties.
159 * <p>
160 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
161 * <br>
162 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
163 * <p>
164 * $LastChangedDate: 2016-05-28 11:33:31 +0200 (Sat, 28 May 2016) $, @version $Revision: 2051 $, by $Author: averbraeck $,
165 * initial version jan. 2015 <br>
166 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
167 */
168 class PropertyIterator implements Iterator<Property<?>>, Serializable
169 {
170 /** */
171 private static final long serialVersionUID = 20150000L;
172
173 /** Next in line in the main CompoundProperty. */
174 private int currentIndex;
175
176 /** Full list of Properties. */
177 private final ArrayList<Property<?>> list;
178
179 /**
180 * Construct a new PropertyIterator.
181 * @param ap AbstractProperty; root of the tree to iterate over
182 */
183 PropertyIterator(final Property<T> ap)
184 {
185 this.currentIndex = 0;
186 this.list = new ArrayList<Property<?>>();
187 addToList(ap);
188 }
189
190 /**
191 * Recursively add all properties to the list. <br>
192 * Compound properties are included <b>right before</b> their contents.
193 * @param cp AbstractProperty<T>; the property to add (if compound it and all it's children are added)
194 */
195 private void addToList(final Property<?> cp)
196 {
197 this.list.add(cp);
198 if (cp instanceof CompoundProperty)
199 {
200 for (Property<?> ap : ((CompoundProperty) cp).getValue())
201 {
202 addToList(ap);
203 }
204 }
205 }
206
207 /** {@inheritDoc} */
208 @Override
209 public boolean hasNext()
210 {
211 return this.currentIndex < this.list.size();
212 }
213
214 /** {@inheritDoc} */
215 @Override
216 public Property<?> next()
217 {
218 return this.list.get(this.currentIndex++);
219 }
220
221 /** {@inheritDoc} */
222 @Override
223 public void remove()
224 {
225 throw new UnsupportedOperationException();
226 }
227
228 /** {@inheritDoc} */
229 @Override
230 public String toString()
231 {
232 return "PropertyIterator [currentIndex=" + this.currentIndex + ", list=" + this.list + "]";
233 }
234
235 }
236
237 }