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

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

Various changes to the METS structures and identifier factories to
move towards updateable structures and to add section support.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.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.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 /**
167 * Write out the metadata to an XML file through a <code>PrintWriter</code>.
168 *
169 * @param <code>PrintWriter</code> the writer to use.
170 */
171 public boolean write(PrintWriter writer)
172 { // if this is a non-file block of metadata, write it out in long hand
173 if (this.location == null)
174 { String tag = XMLTools.getOpenTag("mets", "mdWrap");
175
176 tag = XMLTools.addAttribute(tag, "MDType", this.name);
177 if (this.id != null) {
178 tag = XMLTools.addAttribute(tag, "ID", this.id);
179 }
180 writer.println(tag);
181
182 tag = XMLTools.getOpenTag("mets", "xmlData");
183 writer.println(tag);
184
185 Iterator keys = this.metadataMap.keySet().iterator();
186 while (keys.hasNext())
187 { String thisKey = keys.next().toString();
188 this.writeItem(writer, thisKey);
189 }
190
191 writer.println(XMLTools.getCloseTag("mets", "xmlData"));
192
193 writer.println(XMLTools.getCloseTag("mets", "mdWrap"));
194 }
195 // otherwise, drop the metadata out in a simplified file-reference
196 // form only
197 else
198 { String tag = XMLTools.getOpenTag("mets","mdRef");
199 tag = XMLTools.addAttribute(tag, "LOCTYPE", "URL");
200 tag = XMLTools.addAttribute(tag, "xlink:href", location.getLocation().toString());
201 tag = XMLTools.addAttribute(tag, "MDType", this.name);
202 if (this.id != null) {
203 tag = XMLTools.addAttribute(tag, "ID", this.id);
204 }
205 writer.println(tag);
206
207 writer.println("</mets:mdRef>");
208 }
209 return true;
210 }
211
212 /**
213 * Write out a single element - this may be overloaded to provide for the
214 * appropriate formatting for this metadata.
215 */
216 protected boolean writeItem(PrintWriter writer, String label)
217 { if (this.location == null)
218 { // just place the metadata in a simple wrapper
219 Iterator values = this.metadataMap.getAll(label).iterator();
220
221 while (values.hasNext())
222 { String value = values.next().toString();
223
224 writer.write(XMLTools.getOpenTag(this.name, label));
225
226 writer.write(value);
227
228 writer.println(XMLTools.getCloseTag(this.name, label));
229 }
230 }
231 else
232 { String tag = XMLTools.getOpenTag("mets", "mdRef");
233 tag = XMLTools.addAttribute(tag, "LOCTYPE", this.location.getType());
234 tag = XMLTools.addAttribute(tag, "xlink:href", this.location.getLocation().toString());
235 tag = XMLTools.addAttribute(tag, "MDTYPE", this.getName());
236 tag = XMLTools.makeSingleton(tag);
237 writer.println(tag);
238 }
239 return true;
240 }
241
242 /**
243 * Write out the metadata to an SQL database through a <code>GS3SQLConnection</code>.
244 *
245 * @param <code>GS3SQLConnection</code> the SQL database to use.
246 */
247 public boolean writeSQL(int parentId, GS3SQLConnection connection)
248 { // write the general stuff
249 String sqlId;
250
251 if (!super.writeSQL(parentId, connection)) {
252 return false;
253 }
254
255 try {
256 if (this.id == null) {
257 GS3SQLSelect select = new GS3SQLSelect("namespaces");
258 select.setWhere(new GS3SQLWhere(new GS3SQLWhereItem("MetadataRef", "=", Integer.toString(parentId), GS3SQLField.INTEGER_TYPE)));
259 select.addField("NamespaceRef");
260 connection.execute(select.toString());
261
262 ResultSet results = connection.getResultSet();
263 results.first();
264 sqlId = Integer.toString(results.getInt("NamespaceRef"));
265 }
266 else {
267 sqlId = this.id;
268 }
269
270 // clear all the existing metadata items for this namespace
271 GS3SQLDelete delete = new GS3SQLDelete("mdvalues");
272 GS3SQLWhere where = new GS3SQLWhere(new GS3SQLWhereItem("NamespaceRef", "=", sqlId, GS3SQLField.INTEGER_TYPE));
273 delete.setWhere(where);
274 connection.execute(delete.toString());
275
276 // write out the metadata for this namespace
277 Iterator keys = this.metadataMap.keySet().iterator();
278 while (keys.hasNext())
279 { String thisKey = keys.next().toString();
280
281 Iterator values = this.metadataMap.getAll(thisKey).iterator();
282
283 while (values.hasNext())
284 { String value = values.next().toString();
285
286 GS3SQLInsert insert = new GS3SQLInsert("mdvalues");
287 insert.addValue("NamespaceRef", sqlId, GS3SQLField.INTEGER_TYPE);
288 insert.addValue("label", thisKey);
289 insert.addValue("value", value);
290 connection.execute(insert.toString());
291 }
292 }
293 }
294 catch (SQLException sql) {
295 System.out.println(sql);
296 }
297 return true;
298 }
299
300
301 /**
302 * <p>Indicate whether this metadata is open to being changed or not.</p>
303 * <p>Metadata which is created from a distinct file cannot be changed,
304 * only those which have no associated file can be modified.
305 *
306 * @return <code>boolean</code> whether this namespace can be altered.
307 */
308 public boolean isEditable()
309 { return (this.location == null);
310 }
311}
Note: See TracBrowser for help on using the repository browser.