1 package nl.tudelft.simulation.introspection.fields;
2
3 import java.lang.reflect.Field;
4
5 import nl.tudelft.simulation.introspection.AbstractProperty;
6 import nl.tudelft.simulation.introspection.Property;
7
8 /**
9 * The field implementation of the Property interface. See for details.
10 * <p>
11 * Copyright (c) 2002-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
12 * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
13 * project is distributed under a three-clause BSD-style license, which can be found at
14 * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
15 * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
16 * </p>
17 * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
18 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
19 * @author Niels Lang.
20 * @since 1.5
21 */
22 public class FieldProperty extends AbstractProperty implements Property
23 {
24 /** the owner of the fieldProperty */
25 private Object owner = null;
26
27 /** the descriptor of the field. */
28 private Field descriptor = null;
29
30 /** is the property editable. */
31 private boolean editable = false;
32
33 /**
34 * constructs a new FieldProperty.
35 * @param owner Object; its owner
36 * @param descriptor Field; the descriptor
37 * @param editable boolean; is the property editable
38 */
39 public FieldProperty(final Object owner, final Field descriptor, final boolean editable)
40 {
41 // Check whether descriptor is valid for owner should be conducted here
42 this.owner = owner;
43 this.descriptor = descriptor;
44 this.descriptor.setAccessible(true);
45 this.editable = editable;
46 }
47
48 /**
49 * constructs a new FieldProperty.
50 * @param owner Object; its owner
51 * @param descriptor Field; the descriptor
52 */
53 public FieldProperty(final Object owner, final Field descriptor)
54 {
55 this(owner, descriptor, true);
56 }
57
58 /** {@inheritDoc} */
59 @Override
60 public String getName()
61 {
62 return this.descriptor.getName();
63 }
64
65 /** {@inheritDoc} */
66 @Override
67 public Class<?> getType()
68 {
69 return this.descriptor.getType();
70 }
71
72 /** {@inheritDoc} */
73 @Override
74 public void setRegularValue(final Object value)
75 {
76 Class<?> type = this.descriptor.getType();
77 if (!type.isInstance(value) || !this.editable)
78 {
79 throw new IllegalArgumentException("Cannot assign " + value + " to " + this.owner + ", " + this.descriptor);
80 }
81 synchronized (this.owner)
82 {
83 try
84 {
85 this.descriptor.set(this.owner, value);
86 }
87 catch (Exception exception)
88 {
89 throw new IllegalArgumentException(this + " - setRegularValue", exception);
90 }
91 }
92 }
93
94 /** {@inheritDoc} */
95 @Override
96 public Object getValue()
97 {
98 try
99 {
100 return this.descriptor.get(this.owner);
101 }
102 catch (Exception exception)
103 {
104 throw new IllegalArgumentException(this + " - getValue", exception);
105 }
106 }
107
108 /** {@inheritDoc} */
109 @Override
110 public Object getInstance()
111 {
112 return this.owner;
113 }
114
115 /** {@inheritDoc} */
116 @Override
117 public boolean isEditable()
118 {
119 return this.editable;
120 }
121 }