source: trunk/greenstone3-extensions/gs3build/src/org/greenstone/gsdl3/gs3build/metadata/OrderedNamespace.java@ 12188

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

Initial revision

  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
RevLine 
[12188]1package org.greenstone.gsdl3.gs3build.metadata;
2
3import java.io.PrintWriter;
4import java.util.Iterator;
5import java.util.List;
6import java.util.Map;
7import java.util.ArrayList;
8import java.util.HashMap;
9
10import org.greenstone.gsdl3.gs3build.util.MultiMap;
11import org.greenstone.gsdl3.gs3build.util.XMLTools;
12
13/**
14 * Implement a generic, ordered namespace in METS.
15 *
16 * @see: org.greenstone.gsdl3.gs3build.metadata.METSNamespace
17 */
18
19public class OrderedNamespace extends METSNamespace
20{
21 List metadataList;
22
23 public OrderedNamespace(String name)
24 {
25 super(name);
26 this.metadataList = new ArrayList();
27 }
28
29 public OrderedNamespace(String name, METSLocation location)
30 {
31 super(name, location);
32 this.metadataList = new ArrayList();
33 }
34
35 public boolean validate(String field, String value)
36 {
37 return true;
38 }
39
40 /**
41 * Add a metadata item. Whether the field and value validate for this
42 * schema will also be tested.
43 *
44 * @param <code>String</code> the name of the field to be given the value
45 * @param <code>String</code> the value to be assigned
46 *
47 * @return <code>boolean</code> whether the field value was added. This
48 * would return <code>false</code> if the values did not validate,
49 * for example.
50 */
51 public boolean addMetadata(String label, String value)
52 {
53 if (!this.validate(label, value)) {
54 return false;
55 }
56
57 this.metadataList.add(new NamespaceItem(label, value));
58 return true;
59 }
60
61 /**
62 * Assign a metadata item. Whether the field and value validate for this
63 * schema will also be tested. Any existing metadata for that field will
64 * be destroyed if the new value validates.
65 *
66 * @param <code>String</code> the name of the field to be given the value
67 * @param <code>String</code> the value to be assigned
68 *
69 * @return <code>boolean</code> whether the field value was added. This
70 * would return <code>false</code> if the values did not validate,
71 * for example.
72 */
73 public boolean setMetadata(String label, String value)
74 {
75 if (!this.validate(label, value)){
76 return false;
77 }
78
79 // TODO: this.metadataMap.setOnly(label, value);
80 int itemNo = this.findItem(label);
81 if (itemNo >= 0){
82 this.metadataList.set(itemNo, new NamespaceItem(label, value));
83 return true;
84 }
85 return false;
86 }
87
88 /**
89 * Remove all metadata values for a given field name
90 *
91 * @param <code>String</code> the field to delete
92 *
93 * @return <code>boolean</code> whether the field was actually deleted;
94 * will return <code>true</code> if the field was already empty.
95 */
96 public boolean removeMetadata(String label)
97 {
98 int itemNo;
99
100 itemNo = this.findItem(label);
101 while (itemNo >= 0){
102 this.metadataList.remove(itemNo);
103 itemNo = this.findItem(label);
104 }
105 return true;
106 }
107
108 /**
109 * Remove a particular incidence of a given metadata field for a document.
110 * If an exact match for the given value is not found, nothing changes.
111 * N.B. if a value occurs twice, only the first incidence of it will be
112 * deleted from the list.
113 *
114 * @param <code>String</code> the field to have the value removed
115 * @param <code>String</code> the value to be removed from a given field
116 *
117 * @return <code>boolean</code> <code>true</code> if an actual metadata text
118 * is matched against the given value and is thus deleted.
119 */
120 public boolean removeMetadata(String label, String value)
121 {
122 int itemNo;
123
124 itemNo = this.findItem(label);
125 if (itemNo >= 0) {
126 this.metadataList.remove(itemNo);
127 return true;
128 }
129 return false;
130 }
131
132 /**
133 * Get the metadata items for a particular label
134 *
135 * @param <code>String</code> the label to fetch values for - must be devoid
136 * of namespace prologue (i.e. "title" rather than
137 * e.g. "dc:title").
138 *
139 * @return <code>List</code> the list of corresponding values. May be
140 * <code>null</code> if no values are found for the metadata
141 */
142 public List getMetadata(String label)
143 {
144 List resultList = new ArrayList();
145
146 for (int i = 0; i < this.metadataList.size(); i ++) {
147 NamespaceItem item = (NamespaceItem) this.metadataList.get(i);
148
149 if (item.getLabel().equals(label)){
150 resultList.add(item.getValue());
151 }
152 }
153 if (resultList.size() > 0){
154 return resultList;
155 }
156 return null;
157 }
158
159 private int findItem(String label)
160 {
161 for (int i = 0; i < this.metadataList.size(); i ++) {
162 if (((NamespaceItem) this.metadataList.get(i)).getLabel().equals(label)){
163 return i;
164 }
165 }
166 return -1;
167 }
168
169 private int findItem(String label, String value)
170 {
171 for (int i = 0; i < this.metadataList.size(); i ++){
172 NamespaceItem item = (NamespaceItem) this.metadataList.get(i);
173 if (item.getLabel().equals(label) && item.getValue().equals(value)){
174 return i;
175 }
176 }
177 return -1;
178 }
179
180 public Iterator getMetadataNames()
181 {
182 return this.metadataList.iterator();
183 }
184
185
186 /**
187 * Write out the metadata to an XML file through a <code>PrintWriter</code>.
188 *
189 * @param <code>PrintWriter</code> the writer to use.
190 */
191 public boolean write(PrintWriter writer)
192 {
193 // if this is a non-file block of metadata, write it out in long hand
194 if (this.location == null){
195 String tag = XMLTools.getOpenTag("mets", "mdWrap");
196 tag = XMLTools.addAttribute(tag, "MDTYPE", "OTHER");
197 tag = XMLTools.addAttribute(tag, "OTHERMDTYPE", this.name);
198 if (this.id != null) {
199 this.id = "gsdl"+this.id;
200 tag = XMLTools.addAttribute(tag, "ID", this.id);
201 }
202 writer.print(" "); //indentation
203 writer.println(tag);
204
205 Iterator items = this.metadataList.iterator();
206
207 while (items.hasNext()){
208 NamespaceItem item = (NamespaceItem) items.next();
209 this.writeItem(writer, item);
210 }
211 writer.print(" "); //indentation
212 writer.println("</mets:mdWrap>");
213 }
214 // otherwise, drop the metadata out in a simplified file-reference
215 // form only
216 else
217 {
218 String tag = XMLTools.getOpenTag("mets", "mdRef");
219 tag = XMLTools.addAttribute(tag, "LOCTYPE", this.location.getType());
220 tag = XMLTools.addAttribute(tag, "xlink:href", this.location.getLocation().toString());
221 tag = XMLTools.addAttribute(tag, "MDTYPE", this.name);
222 //tag = XMLTools.addAttribute (tag, "MDTYPE", "OTHER");
223 //tag = XMLTools.addAttribute(tag, "OTHERMDTYPE", this.name);
224 if (this.id != null) {
225 tag = XMLTools.addAttribute(tag, "ID", this.id);
226 }
227 tag = XMLTools.makeSingleton(tag);
228 }
229 return true;
230 }
231
232 /**
233 * Write out a single element - this may be overloaded to provide for the
234 * appropriate formatting for this metadata.
235 */
236 protected boolean writeItem(PrintWriter writer, NamespaceItem item)
237 {
238 // Do some default sillinesses
239 //writer.write(" ");
240 writer.write(XMLTools.getOpenTag(this.name, item.getLabel()));
241
242 writer.write(item.getValue());
243
244 writer.write(XMLTools.getCloseTag(this.name, item.getLabel()));
245 return true;
246 }
247
248 /**
249 * <p>Indicate whether this metadata is open to being changed or not.</p>
250 * <p>Metadata which is created from a distinct file cannot be changed,
251 * only those which have no associated file can be modified.
252 *
253 * @return <code>boolean</code> whether this namespace can be altered.
254 */
255 public boolean isEditable()
256 {
257 return (this.location == null);
258 }
259}
Note: See TracBrowser for help on using the repository browser.