001 package jigcell.compare.data;
002
003 import java.beans.DefaultPersistenceDelegate;
004 import java.beans.Encoder;
005 import java.beans.Statement;
006 import java.util.StringTokenizer;
007 import jigcell.compare.IDataElement;
008 import jigcell.compare.IEditableDataGenerator;
009 import jigcell.compare.IProgrammableDataGenerator;
010 import jigcell.compare.impl.Compare;
011
012 /**
013 * Implementation of DataGenerator that supports editing the generator fields. The default element type of an EditableDataGenerator is a
014 * SparseTreeDataElement.
015 *
016 * <p>
017 * This code is licensed under the DARPA BioCOMP Open Source License. See LICENSE for more details.
018 * </p>
019 *
020 * @author Nicholas Allen
021 */
022
023 public class EditableDataGenerator extends DataGenerator implements IEditableDataGenerator {
024
025 /**
026 * Cached version of the associated element
027 */
028
029 private transient IDataElement element;
030
031 /**
032 * Persist the generator using the setElement method with a flat string rather than trying to expand the element.
033 */
034
035 protected static class EditableDataGeneratorDelegate extends DefaultPersistenceDelegate {
036 protected void initialize (Class clazz, Object o1, Object o2, Encoder encoder) {
037 super.initialize (clazz, o1, o2, encoder);
038 if (!(o1 instanceof IProgrammableDataGenerator))
039 encoder.writeStatement (new Statement (o1, "setElement", new Object [] {((EditableDataGenerator) o1).getElement ().toString ()}));
040 }
041 }
042
043 static {
044 Compare.addTransient (EditableDataGenerator.class, "element");
045 Compare.addDelegate (EditableDataGenerator.class, new EditableDataGeneratorDelegate ());
046 }
047
048 /**
049 * Creates a new data generator that supports editing.
050 */
051
052 public EditableDataGenerator () {
053 this (new SparseTreeDataElement ());
054 }
055
056 /**
057 * Creates a new data generator that supports editing.
058 *
059 * @param element Element to link to
060 */
061
062 public EditableDataGenerator (IDataElement element) {
063 super ();
064 this.element = element;
065 setName ("New");
066 setWriteDescriptionOption ("Write to Generator");
067 }
068
069 /**
070 * {@inheritDoc}
071 */
072
073 public synchronized void clear () {
074 element = null;
075 }
076
077 /**
078 * {@inheritDoc}
079 */
080
081 public IDataElement getElement () {
082 return element;
083 }
084
085 /**
086 * {@inheritDoc}
087 */
088
089 public boolean getPredictedCompatibility (Class clazz) {
090 return String.class.isAssignableFrom (clazz) || IDataElement.class.isAssignableFrom (clazz);
091 }
092
093 /**
094 * {@inheritDoc}
095 */
096
097 public boolean getPredictedCompatibility (Object instance) {
098 return instance instanceof String || instance instanceof IDataElement;
099 }
100
101 /**
102 * {@inheritDoc}
103 */
104
105 public boolean isCached () {
106 return true;
107 }
108
109 /**
110 * Whether this generator has a set value.
111 */
112
113 public boolean isSet () {
114 return element != null;
115 }
116
117 /**
118 * {@inheritDoc}
119 */
120
121 public synchronized boolean setAttribute (String key, String value) {
122 String oldValue = (String) getOption (key);
123 if (value == oldValue || value != null && value.equals (oldValue))
124 return false;
125 setOptionType (key, Option.SAFE);
126 setOption (key, value);
127 return true;
128 }
129
130 /**
131 * {@inheritDoc}
132 */
133
134 public void setComment (String displayableComment) {
135 setAttribute (ATTRIBUTE_COMMENT, displayableComment);
136 }
137
138 /**
139 * {@inheritDoc}
140 */
141
142 public synchronized void setElement (IDataElement element) {
143 this.element = element == null ? SparseTreeDataElement.createElement ("null") : element;
144 }
145
146 /**
147 * Creates a new associated data element and initializes it with the given text.
148 *
149 * @param text Textual representation of an element
150 */
151
152 public synchronized void setElement (String text) {
153 element = SparseTreeDataElement.createElement (text);
154 }
155
156 /**
157 * {@inheritDoc}
158 */
159
160 public synchronized boolean setOption (String key, Object value) {
161 return super.setOption (key, value);
162 }
163
164 /**
165 * {@inheritDoc}
166 */
167
168 public void setState (String state) {
169 for (StringTokenizer tokenizer = new StringTokenizer (state, SEPARATORS); tokenizer.hasMoreElements (); ) {
170 String key = tokenizer.nextToken ();
171 if (!tokenizer.hasMoreElements ())
172 throw new IllegalArgumentException ("Unable to fully parse expression");
173 setAttribute (key, tokenizer.nextToken ());
174 }
175 }
176
177 /**
178 * {@inheritDoc}
179 */
180
181 public void write (Object data) throws Exception {
182 if (data instanceof IDataElement)
183 setElement ((IDataElement) data);
184 else
185 setElement ((String) data);
186 }
187 }