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

Last change on this file since 8742 was 8742, checked in by kjdon, 19 years ago

changed the import statements for GS3SQLConnection and GS3SQLConnectionFactory to reflect their move to the database package

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