source: trunk/gli/src/org/greenstone/gatherer/cdm/Format.java@ 12131

Last change on this file since 12131 was 12088, checked in by kjdon, 18 years ago

some changes that I am not sure what for :-). Also added SearchTypes to the list of commands

  • Property svn:keywords set to Author Date Id Revision
File size: 13.3 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import org.greenstone.gatherer.DebugStream;
30import org.greenstone.gatherer.util.Codec;
31import org.greenstone.gatherer.util.XMLTools;
32import org.w3c.dom.*;
33
34
35/** This class encapsulates all the information about a format command from the collection configuration. This includes both the 'general' formatting commands, and the commands targetted at specific classifiers or classification component types. This class is, unfortunately, the most complex in terms of DOM model support, since we have to maintain a live reference to any classifier this format applies to. We temporarily use the feature name as the format name attribute but since the order of classifiers can change, this of course gets horribly out of date. Before the CollectionDesignManager saves the CollectionConfiguration it calls a method in the FormatManager to force all of the Formats to update their name attributes.
36 * @author John Thompson, Greenstone Digital Library, University of Waikato
37 * @version 2.3
38 */
39public class Format
40 implements DOMProxyListEntry {
41
42 /** The default features (not all of these are in the Greenstone Developer's Guide). */
43 static final public String DEFAULT_FEATURES[] = { "", "AllowExtendedOptions", "Document", "DocumentArrowsBottom", "DocumentArrowsTop", "DocumentButtons", "DocumentContents", "DocumentHeading", "DocumentImages", "DocumentText", "DocumentTitles", "DocumentUseHTML", "RelatedDocuments", "Search", "SearchTypes" };
44 /** The list of known feature parts. */
45 static final public String DEFAULT_PARTS[] = { "", "DateList", "HList", "VList" };
46
47 /** Only "" and "Search" can have parts */
48 static public boolean canHavePart(String name) {
49 return (name.equalsIgnoreCase("") || name.equalsIgnoreCase("Search") || name.equalsIgnoreCase("Document"));
50 }
51
52 static public String generateName(Object feature, String part) {
53 if(feature instanceof Classifier) {
54 return ((Classifier)feature).getPositionString() + part;
55 }
56 else {
57 return feature.toString() + part;
58 }
59 }
60
61 /** Returns true if the parameter is a boolean type, false otherwise. */
62 static public boolean isParamType(String name)
63 {
64 if (name.equalsIgnoreCase("AllowExtendedOptions") || name.equalsIgnoreCase("DocumentArrowsBottom") || name.equalsIgnoreCase("DocumentArrowsTop") || name.equalsIgnoreCase("DocumentContents") || name.equalsIgnoreCase("DocumentImages") || name.equalsIgnoreCase("DocumentTitles") || name.equalsIgnoreCase("DocumentUseHTML")) {
65 return true;
66 }
67 else {
68 return false;
69 }
70 }
71
72 /** If this format is altering a Classifier then this is the classifier in question. */
73 private Classifier classifier = null;
74 /** The element this format is based on. */
75 private Element element = null;
76 /** We keep a copy of the part because its slightly more computationally tricky to calculate. */
77 private String part = null;
78 /** We keep a copy of the feature name */
79 private String feature_name = null;
80 /** Cached result of toString. */
81 private String text = null;
82
83 /** Constructor only to be used during DOMProxyListModel initialization. */
84 public Format() {
85 }
86
87 public Format(Element element) {
88 this.element = element;
89 // Immediately check if we are dealing with a classifier, by retrieving the feature name. If it is a classifier, then restore the live reference immediately before anything changes it.
90 Object object = getFeature();
91
92 // There may be format statements for no-longer-existing classifiers
93 if (object == null) {
94 DebugStream.println("No matching classifier for format statement!");
95 return;
96 }
97
98 if(object instanceof Classifier) {
99 classifier = (Classifier) object;
100 }
101 else {
102 String feature = (String) object;
103 if(feature.toUpperCase().startsWith(Classifier.CLASSIFIER_PREFIX)) {
104 // Extract the integer index
105 int index = Integer.parseInt(feature.substring(Classifier.CLASSIFIER_PREFIX.length()));
106 // Subtract one (as java is 0-2 where G2 is 1-3)
107 index = index - 1;
108 // Retrieve the appropriate classifier
109 classifier = CollectionDesignManager.classifier_manager.getClassifier(index);
110 }
111 }
112 }
113
114 /** Constructor for a flag format command.
115 * @param feature The <Strong>Object</strong> this format affects.
116 * @param part The specific part of the control to format as a <strong>String</strong>.
117 * @param state A <i>boolean</i> indicating this formats state.
118 */
119 public Format(Object feature, String part, boolean state) {
120 element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.FORMAT_ELEMENT);
121 setName(feature, part);
122 setState(state);
123 }
124
125 /** Constructor for a format-string format command.
126 * @param feature The <Strong>Object</strong> this format affects.
127 * @param part The specific part of the control to format as a <strong>String</strong>.
128 * @param value The format <strong>String</strong> which may be a label name, or a piece of HTML formatting.
129 */
130 public Format(Object feature, String part, String value) {
131 element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.FORMAT_ELEMENT);
132 setName(feature, part);
133 setValue(value);
134 }
135
136 public boolean canHavePart() {
137 return canHavePart(getName());
138 }
139
140 public int compareTo(Object object) {
141 if(object == null) { // It seems that occasionally compareTo is called and somehow null ends up in comparison.
142 return -1;
143 }
144 if(object instanceof Format && element != null) {
145 return element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE).compareTo(((Format)object).getName());
146 }
147 return toString().compareTo(object.toString());
148 }
149
150 public DOMProxyListEntry create(Element element) {
151 return new Format(element);
152 }
153
154 public boolean equals(Object object) {
155 return (compareTo(object) == 0);
156 }
157
158 public Element getElement() {
159 return element;
160 }
161
162 /** Method to retrieve the value of feature, which may either be a String or a Classifier.
163 * @return The value of feature as an <strong>Object</strong>.
164 */
165 public Object getFeature() {
166 if(classifier != null) {
167 return classifier;
168 }
169 else if(element != null) {
170 String feature = getFeatureName();
171 // If the feature now refers to a classifier, retrieve it.
172 if(feature.toUpperCase().startsWith(Classifier.CLASSIFIER_PREFIX)) {
173 // Extract the integer index
174 int index = Integer.parseInt(feature.substring(Classifier.CLASSIFIER_PREFIX.length()));
175 // Subtract one (as java is 0-2 where G2 is 1-3)
176 index = index - 1;
177 // Retrieve the appropriate classifier
178 classifier = CollectionDesignManager.classifier_manager.getClassifier(index);
179 return classifier;
180 }
181 else {
182 return feature;
183 }
184 }
185 else {
186 return "Error";
187 }
188 }
189
190 public String getFeatureName() {
191 if (feature_name == null) {
192 String name = element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
193 // Remove part
194 String part = getPart();
195 if(part != null) {
196 feature_name = name.substring(0, name.length() - part.length());
197 }
198 else {
199 feature_name = name;
200 }
201 part = null;
202 name = null;
203 }
204 return feature_name;
205
206 }
207 public String getName() {
208 if(element != null) {
209 return element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
210 }
211 return "Error";
212 }
213
214 /** Method to retrieve the value of part. Of course there may not be one, in which case return ""
215 * @return The value of part as a <Strong>String</strong>.
216 */
217 public String getPart() {
218 if(part == null && element != null) {
219 // To determine a part, we retrieve the Format name, then look for one of our recognized parts
220 String name = element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
221 // DEFAULT_PARTS[0] is an empty string to correctly enable comboboxes.
222 name = name.toLowerCase();
223 for(int i = 1; part == null && i < DEFAULT_PARTS.length; i++) {
224 if(name.endsWith(DEFAULT_PARTS[i].toLowerCase())) {
225 part = DEFAULT_PARTS[i];
226 }
227 }
228 if(part == null) {
229 part = DEFAULT_PARTS[0];
230 }
231 }
232 return part;
233 }
234
235 /** Method to retrieve the value of state.
236 * @return value of state as a <i>boolean</i>.
237 */
238 public boolean getState() {
239 return (element != null && element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR));
240 }
241
242 /** Retrieve the value of value.
243 * @return A <strong>String</strong> which is the value of value.
244 */
245 public String getValue() {
246 String value = "Error";
247 if(element != null) {
248 value = XMLTools.getValue(element);
249 // Decode into text
250 value = Codec.transform(value, Codec.DOM_TO_TEXT);
251 }
252 return value;
253 }
254
255 public boolean isAssigned() {
256 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
257 }
258
259 public boolean isParamType() {
260 return (element != null && element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE).length() > 0);
261 }
262
263 public void setAssigned(boolean assigned) {
264 if(element != null) {
265 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
266 }
267 }
268
269 public void setElement(Element element) {
270 this.element = element;
271 part = null;
272 text = null;
273 // Establish the classifier reference, if necessary
274 getFeature();
275 }
276
277 public void setName(Object feature, String part) {
278 // Can't do anything unless an element exists.
279 if(element != null) {
280 this.part = part; // Easier for later on.
281 if(feature instanceof Classifier) {
282 classifier = (Classifier) feature;
283 feature_name = classifier.getPositionString();
284 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, classifier.getPositionString() + part);
285 }
286 else {
287 feature_name = feature.toString();
288 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, feature.toString() + part);
289 }
290 text = null;
291 }
292 }
293
294 /** Set the value of state.
295 * @param state The new value for state as a <i>boolean</i>.
296 */
297 public void setState(boolean state) {
298 if(element != null) {
299 element.setAttribute(CollectionConfiguration.VALUE_ATTRIBUTE, (state ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
300 text = null;
301 }
302 }
303
304 /** Set the value of value. Hmmm.
305 * @param value The new value from value as a <strong>String</strong>.
306 */
307 public void setValue(String value) {
308 if(element != null) {
309 // Strip off any enclosing speech marks
310 if(value.startsWith(CollectionConfiguration.SPEECH_CHARACTER) && value.startsWith(CollectionConfiguration.SPEECH_CHARACTER)) {
311 value = value.substring(1, value.length() - 1);
312 }
313 // Encode
314 value = Codec.transform(value, Codec.TEXT_TO_DOM);
315 // Store in DOM
316 XMLTools.setValue(element, value);
317 text = null;
318 }
319 }
320
321 /** Method to translate this classes information into a line of text as you would expect in the collection configuration file.
322 * @return A <strong>String</strong> containing the format command.
323 */
324 public String toString() {
325 if(text == null && element != null) {
326 StringBuffer temp = new StringBuffer(CollectionConfiguration.FORMAT_STR);
327 temp.append(" ");
328 temp.append(element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE));
329 temp.append(" ");
330 String value = element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE);
331 if(value.length() > 0) {
332 temp.append(value);
333 }
334 else {
335 value = XMLTools.getValue(element);
336 if(value.equalsIgnoreCase(CollectionConfiguration.TRUE_STR) || value.equalsIgnoreCase(CollectionConfiguration.FALSE_STR)) {
337 temp.append(value);
338 }
339 else {
340 temp.append("\"");
341 // Retrieve the DOM encoded value, decode and then append
342 value = Codec.transform(value, Codec.DOM_TO_TEXT);
343 temp.append(value);
344 temp.append("\"");
345 }
346 }
347 text = temp.toString();
348 temp = null;
349 }
350 return text;
351 }
352
353 public void update() {
354 if(classifier != null) {
355 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, classifier.getPositionString() + getPart());
356 feature_name = classifier.getPositionString();
357 text = null;
358 }
359 }
360}
Note: See TracBrowser for help on using the repository browser.