1 package org.opentrafficsim.simulationengine.properties;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5
6 /**
7 * Abstract property.
8 * <p>
9 * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
11 * <p>
12 * $LastChangedDate: 2016-04-05 21:30:47 +0200 (Tue, 05 Apr 2016) $, @version $Revision: 1889 $, by $Author: pknoppers $,
13 * initial version 18 dec. 2014 <br>
14 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
15 * @param <T> type of the property
16 */
17 public abstract class AbstractProperty<T> implements Iterable<AbstractProperty<T>>
18 {
19 /** Determines sorting order when properties are displayed to the user. */
20 private final int displayPriority;
21
22 /**
23 * @param displayPriority sorting order when properties are displayed to the user.
24 */
25 public AbstractProperty(final int displayPriority)
26 {
27 super();
28 this.displayPriority = displayPriority;
29 }
30
31 /**
32 * Retrieve the current value of the property.
33 * @return T; the current value of the property
34 */
35 public abstract T getValue();
36
37 /**
38 * Return a short description of the property.
39 * @return String; a short description of the property
40 */
41 public abstract String getShortName();
42
43 /**
44 * Return a description of the property (may use HTML markup).
45 * @return String; the description of the property
46 */
47 public abstract String getDescription();
48
49 /**
50 * Change the value of the property.
51 * @param newValue T; the new value for the property
52 * @throws PropertyException when this Property is read-only, or newValue is not valid
53 */
54 public abstract void setValue(T newValue) throws PropertyException;
55
56 /**
57 * Return true if the property can not be altered.
58 * @return boolean; true if this property can not be altered, false if this property can be altered
59 */
60 public abstract boolean isReadOnly();
61
62 /**
63 * Display priority determines the order in which properties should be displayed. Properties with lower values should be
64 * displayed above or before those with higher values.
65 * @return int; the display priority of this AbstractProperty
66 */
67 public final int getDisplayPriority()
68 {
69 return this.displayPriority;
70 }
71
72 /**
73 * Generate a description of the state of this property in HTML (excluding the <html> at the start and the
74 * </html> at the end. The result can be embedded in a html-table.
75 * @return String; the description of this property and the current state in HTML
76 */
77 public abstract String htmlStateDescription();
78
79 /**
80 * Construct a deep copy of this property (duplicates everything except immutable fields).
81 * @return AbstractProperty<T>; a deep copy of this AbstractProperty
82 */
83 public abstract AbstractProperty<T> deepCopy();
84
85 /** {@inheritDoc} */
86 @Override
87 public final Iterator<AbstractProperty<T>> iterator()
88 {
89 return new PropertyIterator(this);
90 }
91
92 /** {@inheritDoc} */
93 public final String toString()
94 {
95 return this.getShortName();
96 }
97
98 /**
99 * Really simple iterator for properties.
100 * <p>
101 * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
102 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
103 * <p>
104 * $LastChangedDate: 2016-04-05 21:30:47 +0200 (Tue, 05 Apr 2016) $, @version $Revision: 1889 $, by $Author: pknoppers $,
105 * initial version jan. 2015 <br>
106 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
107 */
108 class PropertyIterator implements Iterator<AbstractProperty<T>>
109 {
110 /** Next in line in the main CompoundProperty. */
111 private int currentIndex;
112
113 /** Full list of AbstractProperties. */
114 private final ArrayList<AbstractProperty<T>> list;
115
116 /**
117 * Construct a new PropertyIterator.
118 * @param ap AbstractProperty; root of the tree to iterate over
119 */
120 PropertyIterator(final AbstractProperty<T> ap)
121 {
122 this.currentIndex = 0;
123 this.list = new ArrayList<AbstractProperty<T>>();
124 addToList(ap);
125 }
126
127 /**
128 * Recursively add all properties to the list. <br>
129 * Compound properties are included <b>before</b> their contents.
130 * @param cp AbstractProperty<T>; the property to add (if compound it and all it's children are added)
131 */
132 @SuppressWarnings("unchecked")
133 private void addToList(final AbstractProperty<T> cp)
134 {
135 this.list.add(cp);
136 if (cp instanceof CompoundProperty)
137 {
138 for (AbstractProperty<?> ap : ((CompoundProperty) cp).getValue())
139 {
140 addToList((AbstractProperty<T>) ap);
141 }
142 }
143 }
144
145 /** {@inheritDoc} */
146 @Override
147 public boolean hasNext()
148 {
149 return this.currentIndex < this.list.size();
150 }
151
152 /** {@inheritDoc} */
153 @Override
154 public AbstractProperty<T> next()
155 {
156 return this.list.get(this.currentIndex++);
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public void remove()
162 {
163 throw new UnsupportedOperationException();
164 }
165
166 }
167
168 }