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

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

capitalised a few remaining field names that were lower case

  • 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.