source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/metadata/METSStructure.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.5 KB
Line 
1package org.greenstone.gsdl3.gs3build.metadata;
2
3import java.io.PrintWriter;
4
5import java.util.List;
6import java.util.ArrayList;
7import java.util.Map;
8import java.util.LinkedHashMap;
9import java.util.Iterator;
10
11import java.sql.SQLException;
12import java.sql.ResultSet;
13
14import org.w3c.dom.Element;
15import org.w3c.dom.NodeList;
16
17import org.greenstone.gsdl3.gs3build.doctypes.DocumentInterface;
18
19import org.greenstone.gsdl3.gs3build.util.XMLTools;
20import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
21import org.greenstone.gsdl3.gs3build.database.*;
22
23public class METSStructure extends AbstractStructure
24{
25 String label;
26 String type;
27 METSDivision divGroup;
28
29 public static final String STRUCTURE_TYPE = "Structure";
30
31 public METSStructure(String id, String label, String type)
32 { super(id);
33
34 this.label = label;
35 this.type = type;
36 this.divGroup = null;
37 }
38
39 /**
40 * Show what sort of <code>AbstractStructure</code> this structure is...
41 *
42 * @return <code>String The identifying string for a <code>METSStructure</code> type.
43 */
44 public String getStructureType()
45 { return STRUCTURE_TYPE;
46 }
47
48 /**
49 * Find all the divisions that match a given list of file group
50 * identifiers...
51 *
52 * @param <code>List</code> the list of identifiers to find
53 * @param <code>List</code> the list into which to place any
54 * matching identifiers.
55 */
56 public void findDivisionsForFiles(List listOfFileIdentifiers, List resultList)
57 { Iterator groups = this.children.values().iterator();
58 while (groups.hasNext())
59 { METSDivision group = (METSDivision) groups.next();
60
61 group.findDivisionsForFiles(listOfFileIdentifiers, resultList);
62 }
63 }
64
65 /**
66 * Add a division further into this structure.
67 *
68 * @param <code>String</code> the identifier label for the division
69 * within which the division is to be added.
70 * @param <code>METSDivision</code> the division to add.
71 */
72 public void addSubDivision(String divisionLabel, METSDivision division)
73 { String topDivision = METSDivision.getTopDivisionName(divisionLabel);
74
75 METSDivision child = (METSDivision) this.children.get(topDivision);
76 if (child == null)
77 { return;
78 }
79
80 child = child.getDivision(divisionLabel);
81
82 if (child != null) {
83 child.addDivision(division);
84 }
85 }
86
87 /**
88 * Get a subdivision of a given identifier...
89 *
90 * @param <code>String</code> the identifier of the division
91 * @return <code>METSDivision</code> the division, which will be
92 * <code>null</code> if it is not found.
93 */
94 public METSDivision getDivision(String divisionLabel)
95 { String topDivision = METSDivision.getTopDivisionName(divisionLabel);
96
97 if (!topDivision.equals("All"))
98 System.out.println("Top division is " + topDivision);
99 METSDivision child = (METSDivision) this.children.get(topDivision);
100 if (child == null)
101 { System.out.println("No child found");
102 Iterator groups = this.children.keySet().iterator();
103 while (groups.hasNext()) {
104 System.out.println(groups.next().toString());
105 }
106 return null;
107 }
108
109
110 child = child.getDivision(divisionLabel);
111
112 return child;
113 }
114
115
116 /*
117 *
118 * parse an XML Element as a METSStructure Section
119 *
120 * @param <code>Element</code> the XML element which represents
121 * the mets:structMap itself
122 */
123
124 public static METSStructure parseXML(Element element)
125 {
126 String structId = element.getAttribute("ID");
127 String structType = element.getAttribute("TYPE");
128 String structLabel = element.getAttribute("LABEL");
129
130 METSStructure thisStruct = new METSStructure (structId, structType, structLabel);
131
132 NodeList divSecs = element.getChildNodes();
133 if (divSecs != null) {
134 for (int c = 0; c < divSecs.getLength(); c++) {
135 if (divSecs.item(c).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE){
136 continue;
137 }
138 Element divElement = (Element) divSecs.item(c);
139 String divName = divElement.getNodeName();
140 if (divName.equals("mets:div")) {
141 METSDivision division = METSDivision.parseXML(divElement);
142 thisStruct.addDivision(division);
143 } else {
144 System.err.println("Error: mets:structMap was expecting mets:div but got "+divName);
145 }
146 }
147 }
148 return thisStruct;
149 }
150
151 /**
152 * Write this structure in XML(METS) format to a <code>PrintWriter</code>
153 */
154 public void write(PrintWriter writer)
155 { Iterator groups = this.children.values().iterator();
156
157 String tag = XMLTools.getOpenTag("mets", "structMap");
158 tag = XMLTools.addAttribute(tag, "ID", this.ID.toString());
159 tag = XMLTools.addAttribute(tag, "TYPE", this.type);
160 tag = XMLTools.addAttribute(tag, "LABEL", this.label);
161
162 writer.println(tag);
163 while (groups.hasNext())
164 { METSDivision group = (METSDivision) groups.next();
165
166 group.write(writer);
167 }
168 writer.println("</mets:structMap>");
169 }
170
171
172 /**
173 * Write this METSStructure to an SQL database....
174 *
175 * @param <code>DocumentInterface</code> the enclosing document.
176 * @param <code>GS3SQLConnection</code> the SQL database connection.
177 */
178 public boolean writeSQL(DocumentInterface document, GS3SQLConnection connection)
179 { int sqlRef = -1;
180 ResultSet results;
181
182 // Prepare query to see if this structure has already been written
183 GS3SQLSelect select = new GS3SQLSelect("structure");
184 select.addField("StructureRef");
185 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("DocID", "=", document.getID().toString());
186 GS3SQLWhereItem item = new GS3SQLWhereItem("StructureID", "=", this.ID.toString());
187 GS3SQLWhere where = new GS3SQLWhere(whereItem);
188 where.add(item);
189 select.setWhere(where);
190
191 // attempt to execute the query & get the current structure's reference
192 try {
193 connection.execute(select.toString());
194 results = connection.getResultSet();
195 if (results != null &&
196 results.first())
197 { sqlRef = results.getInt("structureRef");
198 }
199 else
200 { results = null;
201 }
202
203 if (results != null) {
204 results.close();
205 }
206 }
207 catch (SQLException sqlEx) {
208 System.err.print(sqlEx);
209 return false;
210 }
211
212 // insert a new structure if it wasn't there previously
213 if (results == null) {
214 GS3SQLInsert insert = new GS3SQLInsert("structure");
215 insert.addValue("DocID", document.getID().toString());
216 insert.addValue("StructureID", this.ID.toString());
217 insert.addValue("StructureType", this.type);
218 insert.addValue("Label", this.label);
219
220 if (!connection.execute(insert.toString())) {
221 return false;
222 }
223
224 // get the new structure reference by re-running the original select object
225 connection.execute(select.toString());
226
227 try {
228 results = connection.getResultSet();
229 results.first();
230 sqlRef = results.getInt("StructureRef");
231 }
232 catch (SQLException sql) {
233 System.err.println(sql);
234 return false;
235 }
236 }
237 else {
238 GS3SQLUpdate update = new GS3SQLUpdate("structure");
239 update.setWhere(where);
240
241 update.addValue("StructureType", this.type);
242 update.addValue("Label", this.label);
243
244 connection.execute(update.toString());
245 }
246
247 // write out the child groups (Divisions) now...
248 Iterator groups = this.children.values().iterator();
249
250 while (groups.hasNext())
251 { METSDivision group = (METSDivision) groups.next();
252
253 if (!group.writeSQL(document.getID(), sqlRef, true, connection))
254 { return false;
255 }
256 }
257 return true;
258 }
259
260 /**
261 * Read a METSStructure from a database - on entry, the current item in the
262 * <code>ResultSet</code> holds the row in the database with the structure's
263 * data.
264 *
265 * @param <code>DocumentInterface</code> the document which owns the structure
266 * @param <code>GS3SQLConnection</code> the database connection itself, to load
267 * child objects through, etc.
268 * @param <code>ResultSet</code> pointing to the current row in the database.
269 */
270 public static METSStructure readSQL(DocumentInterface document, GS3SQLConnection connection,
271 ResultSet resultSet)
272 {
273 GS3SQLSelect select = null;
274
275 try {
276 String ID = resultSet.getString("StructureID");
277 String type = resultSet.getString("StructureType");
278 String label = resultSet.getString("Label");
279
280 // create the metadata block object
281 METSStructure structure = new METSStructure(ID, label, type);
282
283 // get its metadata reference to retrieve divisions
284 int structureRef = resultSet.getInt("StructureRef");
285
286 // query the database for matching division for this structure block
287 select = new GS3SQLSelect("divisions");
288 select.addField("*");
289 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ParentRef", "=", Integer.toString(structureRef),
290 GS3SQLField.INTEGER_TYPE);
291 GS3SQLWhere where = new GS3SQLWhere(whereItem);
292 whereItem = new GS3SQLWhereItem("ParentType", "=", METSStructure.STRUCTURE_TYPE);
293 where.add(whereItem);
294 select.setWhere(where);
295
296 connection.execute(select.toString());
297
298 // parse through the divisions
299 ResultSet divisionSet = connection.getResultSet();
300 if (divisionSet != null && divisionSet.first()) {
301 do {
302 METSDivision division = METSDivision.readSQL(connection, divisionSet);
303 if (division != null) {
304 structure.addDivision(division);
305 }
306 }
307 while (divisionSet.next());
308 }
309
310 return structure;
311 }
312 catch (SQLException sqlEx)
313 { System.out.println(sqlEx + " " + select.toString());
314 System.exit(1);
315 }
316 return null;
317 }
318}
319
Note: See TracBrowser for help on using the repository browser.