View Javadoc
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-2016 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 the readonly property value to set
59       */
60      protected final void setReadOnly(final boolean readOnlyValue)
61      {
62          this.readOnly = readOnlyValue;
63      }
64  
65      /** {@inheritDoc} */
66      @Override
67      public final int getDisplayPriority()
68      {
69          return this.displayPriority;
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      public abstract String htmlStateDescription();
75  
76      /** {@inheritDoc} */
77      @Override
78      public final Iterator<Property<?>> iterator()
79      {
80          return new PropertyIterator(this);
81      }
82  
83      /** {@inheritDoc} */
84      @Override
85      public final String getShortName()
86      {
87          return this.shortName;
88      }
89  
90      /** {@inheritDoc} */
91      @Override
92      public final String getDescription()
93      {
94          return this.description;
95      }
96  
97      /** {@inheritDoc} */
98      @Override
99      public final boolean isReadOnly()
100     {
101         return null != this.readOnly && this.readOnly;
102     }
103 
104     /**
105      * Retrieve the key of this AbstractProperty.
106      * @return String; the key of this AbstractProperty
107      */
108     public final String getKey()
109     {
110         return this.key;
111     }
112 
113     /** {@inheritDoc} */
114     @Override
115     public final Property<?> findByKey(final String propertyKey)
116     {
117         if (this.key.equals(propertyKey))
118         {
119             return this;
120         }
121         if (this instanceof CompoundProperty)
122         {
123             return ((CompoundProperty) this).getPropertyGroup().get(propertyKey);
124         }
125         if (null == getParent())
126         {
127             return null;
128         }
129         return getParent().getPropertyGroup().get(propertyKey);
130     }
131 
132     /**
133      * Set the parent of this AbstractProperty.
134      * @param newParent AbstractProperty&lt;?&gt;; the new parent of this AbstractProperty
135      */
136     protected final void setParent(final CompoundProperty newParent)
137     {
138         this.parentProperty = newParent;
139     }
140 
141     /** {@inheritDoc} */
142     @Override
143     public final CompoundProperty getParent()
144     {
145         return this.parentProperty;
146     }
147 
148     /** {@inheritDoc} */
149     @Override
150     public final String toString()
151     {
152         return this.getShortName();
153     }
154 
155     /**
156      * Really simple iterator for properties.
157      * <p>
158      * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
159      * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
160      * <p>
161      * $LastChangedDate: 2016-05-28 11:33:31 +0200 (Sat, 28 May 2016) $, @version $Revision: 2051 $, by $Author: averbraeck $,
162      * initial version jan. 2015 <br>
163      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
164      */
165     class PropertyIterator implements Iterator<Property<?>>, Serializable
166     {
167         /** */
168         private static final long serialVersionUID = 20150000L;
169 
170         /** Next in line in the main CompoundProperty. */
171         private int currentIndex;
172 
173         /** Full list of AbstractProperties. */
174         private final ArrayList<Property<?>> list;
175 
176         /**
177          * Construct a new PropertyIterator.
178          * @param ap AbstractProperty; root of the tree to iterate over
179          */
180         PropertyIterator(final Property<T> ap)
181         {
182             this.currentIndex = 0;
183             this.list = new ArrayList<Property<?>>();
184             addToList(ap);
185         }
186 
187         /**
188          * Recursively add all properties to the list. <br>
189          * Compound properties are included <b>before</b> their contents.
190          * @param cp AbstractProperty&lt;T&gt;; the property to add (if compound it and all it's children are added)
191          */
192         private void addToList(final Property<?> cp)
193         {
194             this.list.add(cp);
195             if (cp instanceof CompoundProperty)
196             {
197                 for (Property<?> ap : ((CompoundProperty) cp).getValue())
198                 {
199                     addToList(ap);
200                 }
201             }
202         }
203 
204         /** {@inheritDoc} */
205         @Override
206         public boolean hasNext()
207         {
208             return this.currentIndex < this.list.size();
209         }
210 
211         /** {@inheritDoc} */
212         @Override
213         public Property<?> next()
214         {
215             return this.list.get(this.currentIndex++);
216         }
217 
218         /** {@inheritDoc} */
219         @Override
220         public void remove()
221         {
222             throw new UnsupportedOperationException();
223         }
224 
225         /** {@inheritDoc} */
226         @Override
227         public String toString()
228         {
229             return "PropertyIterator [currentIndex=" + this.currentIndex + ", list=" + this.list + "]";
230         }
231 
232     }
233 
234 }