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

Last change on this file since 8699 was 8461, checked in by kjdon, 20 years ago

added in Chi's changes for METS documents. mostly the addition of new/improved parseXML methods

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