source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/metadata/SimpleNamespace.java@ 5945

Last change on this file since 5945 was 5945, checked in by cs025, 20 years ago

Extensive additions to metadata

  • Property svn:keywords set to Author Date Id Revision
File size: 9.6 KB
Line 
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 java.sql.SQLException;
11import java.sql.ResultSet;
12
13import org.w3c.dom.Document;
14import org.w3c.dom.Element;
15import org.w3c.dom.NamedNodeMap;
16import org.w3c.dom.Node;
17import org.w3c.dom.NodeList;
18import org.w3c.dom.Text;
19
20import org.greenstone.gsdl3.gs3build.util.MultiMap;
21import org.greenstone.gsdl3.gs3build.util.XMLTools;
22import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
23import org.greenstone.gsdl3.gs3build.database.*;
24
25/**
26 * Implement a simple, unordered, namespace in METS.
27 *
28 * @see: org.greenstone.gsdl3.gs3build.metadata.METSNamespace
29 */
30
31public class SimpleNamespace extends METSNamespace
32{
33 MultiMap metadataMap;
34
35 public SimpleNamespace(String name)
36 { super(name);
37 this.metadataMap = new MultiMap();
38 System.out.println("Namespace " + name);
39 }
40
41 public SimpleNamespace(String name, METSLocation location)
42 { super(name, location);
43 this.metadataMap = new MultiMap();
44 }
45
46 public SimpleNamespace(String name, Element mdWrapTag)
47 { super(name);
48 this.metadataMap = new MultiMap();
49
50 NodeList childNodes = mdWrapTag.getChildNodes();
51 for (int c = 0; c < childNodes.getLength(); c ++)
52 { // a metadata node
53 if (childNodes.item(c).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
54 { // get the name of the metadata from the node
55 String metadataLabel = childNodes.item(c).getNodeName();
56
57 // skip blank labels
58 // TODO: raise an error: metadata item without metadata label set
59 if (metadataLabel == null || metadataLabel.length() == 0)
60 { continue;
61 }
62
63 // build the value
64 String metadataValue = "";
65
66 Element childElement = (Element) childNodes.item(c);
67 for (int i = 0; i < childElement.getChildNodes().getLength(); i ++)
68 { metadataValue = metadataValue + childElement.getChildNodes().item(i).toString();
69 }
70
71 // trim any leading namespace identifiers in "namespace:label" metadata
72 if (metadataLabel.startsWith(this.name + ":"))
73 { metadataLabel = metadataLabel.substring(this.name.length() + 1);
74 }
75
76 this.addMetadata(metadataLabel, metadataValue);
77 }
78 }
79 }
80
81 public boolean validate(String field, String value)
82 { return true;
83 }
84
85 /**
86 * Add a metadata item. Whether the field and value validate for this
87 * schema will also be tested.
88 *
89 * @param <code>String</code> the name of the field to be given the value
90 * @param <code>String</code> the value to be assigned
91 *
92 * @return <code>boolean</code> whether the field value was added. This
93 * would return <code>false</code> if the values did not validate,
94 * for example.
95 */
96 public boolean addMetadata(String label, String value)
97 { if (!this.validate(label, value)) {
98 return false;
99 }
100
101 this.metadataMap.put(label, value);
102 return true;
103 }
104
105 /**
106 * Assign a metadata item. Whether the field and value validate for this
107 * schema will also be tested. Any existing metadata for that field will
108 * be destroyed if the new value validates.
109 *
110 * @param <code>String</code> the name of the field to be given the value
111 * @param <code>String</code> the value to be assigned
112 *
113 * @return <code>boolean</code> whether the field value was added. This
114 * would return <code>false</code> if the values did not validate,
115 * for example.
116 */
117 public boolean setMetadata(String label, String value)
118 { if (!this.validate(label, value))
119 { return false;
120 }
121
122 this.metadataMap.setOnly(label, value);
123 return true;
124 }
125
126 /**
127 * Remove all metadata values for a given field name
128 *
129 * @param <code>String</code> the field to delete
130 *
131 * @return <code>boolean</code> whether the field was actually deleted;
132 * will return <code>true</code> if the field was already empty.
133 */
134 public boolean removeMetadata(String label)
135 { this.metadataMap.remove(label);
136 return true;
137 }
138
139 /**
140 * Remove a particular incidence of a given metadata field for a document.
141 * If an exact match for the given value is not found, nothing changes.
142 * N.B. if a value occurs twice, only the first incidence of it will be
143 * deleted from the list.
144 *
145 * @param <code>String</code> the field to have the value removed
146 * @param <code>String</code> the value to be removed from a given field
147 *
148 * @return <code>boolean</code> <code>true</code> if an actual metadata text
149 * is matched against the given value and is thus deleted.
150 */
151 public boolean removeMetadata(String label, String value)
152 { return this.metadataMap.remove(label, value);
153 }
154
155 /**
156 * Get the metadata items for a particular label
157 *
158 * @param <code>String</code> the label to fetch values for
159 *
160 * @return <code>List</code> the list of corresponding values. May be
161 * <code>null</code>
162 */
163 public List getMetadata(String label)
164 { return this.metadataMap.getAll(label);
165 }
166
167 /**
168 * Write out the metadata to an XML file through a <code>PrintWriter</code>.
169 *
170 * @param <code>PrintWriter</code> the writer to use.
171 */
172 public boolean write(PrintWriter writer)
173 { // if this is a non-file block of metadata, write it out in long hand
174 if (this.location == null)
175 { String tag = XMLTools.getOpenTag("mets", "mdWrap");
176
177 tag = XMLTools.addAttribute(tag, "MDType", this.name);
178 if (this.id != null) {
179 tag = XMLTools.addAttribute(tag, "ID", this.id);
180 }
181 writer.println(tag);
182
183 tag = XMLTools.getOpenTag("mets", "xmlData");
184 writer.println(tag);
185
186 Iterator keys = this.metadataMap.keySet().iterator();
187 while (keys.hasNext())
188 { String thisKey = keys.next().toString();
189 this.writeItem(writer, thisKey);
190 }
191
192 writer.println(XMLTools.getCloseTag("mets", "xmlData"));
193
194 writer.println(XMLTools.getCloseTag("mets", "mdWrap"));
195 }
196 // otherwise, drop the metadata out in a simplified file-reference
197 // form only
198 else
199 { String tag = XMLTools.getOpenTag("mets","mdRef");
200 tag = XMLTools.addAttribute(tag, "LOCTYPE", "URL");
201 tag = XMLTools.addAttribute(tag, "xlink:href", location.getLocation().toString());
202 tag = XMLTools.addAttribute(tag, "MDType", this.name);
203 if (this.id != null) {
204 tag = XMLTools.addAttribute(tag, "ID", this.id);
205 }
206 writer.println(tag);
207
208 writer.println("</mets:mdRef>");
209 }
210 return true;
211 }
212
213 /**
214 * Write out a single element - this may be overloaded to provide for the
215 * appropriate formatting for this metadata.
216 */
217 protected boolean writeItem(PrintWriter writer, String label)
218 { if (this.location == null)
219 { // just place the metadata in a simple wrapper
220 Iterator values = this.metadataMap.getAll(label).iterator();
221
222 while (values.hasNext())
223 { String value = values.next().toString();
224
225 writer.write(XMLTools.getOpenTag(this.name, label));
226
227 writer.write(value);
228
229 writer.println(XMLTools.getCloseTag(this.name, label));
230 }
231 }
232 else
233 { String tag = XMLTools.getOpenTag("mets", "mdRef");
234 tag = XMLTools.addAttribute(tag, "LOCTYPE", this.location.getType());
235 tag = XMLTools.addAttribute(tag, "xlink:href", this.location.getLocation().toString());
236 tag = XMLTools.addAttribute(tag, "MDTYPE", this.getName());
237 tag = XMLTools.makeSingleton(tag);
238 writer.println(tag);
239 }
240 return true;
241 }
242
243 /**
244 * Write out the metadata to an SQL database through a <code>GS3SQLConnection</code>.
245 *
246 * @param <code>GS3SQLConnection</code> the SQL database to use.
247 */
248 public boolean writeSQL(int parentId, GS3SQLConnection connection)
249 { // write the general stuff
250 String sqlId;
251
252 if (!super.writeSQL(parentId, connection)) {
253 return false;
254 }
255
256 try {
257 if (this.id == null) {
258 GS3SQLSelect select = new GS3SQLSelect("namespaces");
259 select.setWhere(new GS3SQLWhere(new GS3SQLWhereItem("MetadataRef", "=", Integer.toString(parentId), GS3SQLField.INTEGER_TYPE)));
260 select.addField("NamespaceRef");
261 connection.execute(select.toString());
262
263 ResultSet results = connection.getResultSet();
264 results.first();
265 sqlId = Integer.toString(results.getInt("NamespaceRef"));
266 }
267 else {
268 sqlId = this.id;
269 }
270
271 // clear all the existing metadata items for this namespace
272 GS3SQLDelete delete = new GS3SQLDelete("mdvalues");
273 GS3SQLWhere where = new GS3SQLWhere(new GS3SQLWhereItem("NamespaceRef", "=", sqlId, GS3SQLField.INTEGER_TYPE));
274 delete.setWhere(where);
275 connection.execute(delete.toString());
276
277 // write out the metadata for this namespace
278 Iterator keys = this.metadataMap.keySet().iterator();
279 while (keys.hasNext())
280 { String thisKey = keys.next().toString();
281
282 Iterator values = this.metadataMap.getAll(thisKey).iterator();
283
284 while (values.hasNext())
285 { String value = values.next().toString();
286
287 GS3SQLInsert insert = new GS3SQLInsert("mdvalues");
288 insert.addValue("NamespaceRef", sqlId, GS3SQLField.INTEGER_TYPE);
289 insert.addValue("label", thisKey);
290 insert.addValue("value", value);
291 connection.execute(insert.toString());
292 }
293 }
294 }
295 catch (SQLException sql) {
296 System.out.println(sql);
297 }
298 return true;
299 }
300
301
302 /**
303 * <p>Indicate whether this metadata is open to being changed or not.</p>
304 * <p>Metadata which is created from a distinct file cannot be changed,
305 * only those which have no associated file can be modified.
306 *
307 * @return <code>boolean</code> whether this namespace can be altered.
308 */
309 public boolean isEditable()
310 { return (this.location == null);
311 }
312}
Note: See TracBrowser for help on using the repository browser.