source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/metadata/METSStructure.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: 9.4 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.database.*;
21
22public class METSStructure extends AbstractStructure
23{
24 String label;
25 String type;
26 METSDivision divGroup;
27
28 public static final String STRUCTURE_TYPE = "Structure";
29
30 public METSStructure(String id, String label, String type)
31 {
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 structLabel = element.getAttribute("LABEL");
128 String structType = element.getAttribute("TYPE");
129
130 METSStructure thisStruct = new METSStructure (structId, structLabel, structType);
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 {
156 Iterator groups = this.children.values().iterator();
157
158 String tag = XMLTools.getOpenTag("mets", "structMap");
159 tag = XMLTools.addAttribute(tag, "ID", this.ID.toString());
160 tag = XMLTools.addAttribute(tag, "TYPE", this.type);
161 tag = XMLTools.addAttribute(tag, "LABEL", this.label);
162
163 writer.println(tag);
164 while (groups.hasNext()){
165 METSDivision group = (METSDivision) groups.next();
166
167 group.write(writer);
168 }
169 writer.println("</mets:structMap>");
170 }
171
172
173 /**
174 * Write this METSStructure to an SQL database....
175 *
176 * @param <code>DocumentInterface</code> the enclosing document.
177 * @param <code>GS3SQLConnection</code> the SQL database connection.
178 */
179 public boolean writeSQL(DocumentInterface document, GS3SQLConnection connection)
180 {
181 int sqlRef = -1;
182 ResultSet results;
183
184 // Prepare query to see if this structure has already been written
185 GS3SQLSelect select = new GS3SQLSelect("structure");
186 select.addField("StructureRef");
187 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("DocID", "=", document.getID().toString());
188 GS3SQLWhereItem item = new GS3SQLWhereItem("StructureID", "=", this.ID.toString());
189 GS3SQLWhere where = new GS3SQLWhere(whereItem);
190 where.add(item);
191 select.setWhere(where);
192
193 // attempt to execute the query & get the current structure's reference
194 try {
195 connection.execute(select.toString());
196 results = connection.getResultSet();
197 if (results != null &&
198 results.first()){
199 sqlRef = results.getInt("structureRef");
200 }
201 else {
202 results = null;
203 }
204
205 if (results != null) {
206 results.close();
207 }
208 }
209 catch (SQLException sqlEx) {
210 System.err.print(sqlEx);
211 return false;
212 }
213
214 // insert a new structure if it wasn't there previously
215 if (results == null) {
216 GS3SQLInsert insert = new GS3SQLInsert("structure");
217 insert.addValue("DocID", document.getID().toString());
218 insert.addValue("StructureID", this.ID.toString());
219 insert.addValue("StructureType", this.type);
220 insert.addValue("Label", this.label);
221
222 if (!connection.execute(insert.toString())) {
223 return false;
224 }
225
226 // get the new structure reference by re-running the original select object
227 connection.execute(select.toString());
228
229 try {
230 results = connection.getResultSet();
231 results.first();
232 sqlRef = results.getInt("StructureRef");
233 }
234 catch (SQLException sql) {
235 System.err.println(sql);
236 return false;
237 }
238 }
239 else {
240 GS3SQLUpdate update = new GS3SQLUpdate("structure");
241 update.setWhere(where);
242
243 update.addValue("StructureType", this.type);
244 update.addValue("Label", this.label);
245
246 connection.execute(update.toString());
247 }
248
249 // write out the child groups (Divisions) now...
250 Iterator groups = this.children.values().iterator();
251
252 while (groups.hasNext()){
253 METSDivision group = (METSDivision) groups.next();
254
255 if (!group.writeSQL(document.getID(), sqlRef, true, connection)){
256 return false;
257 }
258 }
259 return true;
260 }
261
262 /**
263 * Read a METSStructure from a database - on entry, the current item in the
264 * <code>ResultSet</code> holds the row in the database with the structure's
265 * data.
266 *
267 * @param <code>DocumentInterface</code> the document which owns the structure
268 * @param <code>GS3SQLConnection</code> the database connection itself, to load
269 * child objects through, etc.
270 * @param <code>ResultSet</code> pointing to the current row in the database.
271 */
272 public static METSStructure readSQL(DocumentInterface document, GS3SQLConnection connection,
273 ResultSet resultSet)
274 {
275 GS3SQLSelect select = null;
276
277 try {
278 String ID = resultSet.getString("StructureID");
279 String type = resultSet.getString("StructureType");
280 String label = resultSet.getString("Label");
281
282 // create the metadata block object
283 METSStructure structure = new METSStructure(ID, label, type);
284
285 // get its metadata reference to retrieve divisions
286 int structureRef = resultSet.getInt("StructureRef");
287
288 // query the database for matching division for this structure block
289 select = new GS3SQLSelect("divisions");
290 select.addField("*");
291 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ParentRef", "=", Integer.toString(structureRef),
292 GS3SQLField.INTEGER_TYPE);
293 GS3SQLWhere where = new GS3SQLWhere(whereItem);
294 whereItem = new GS3SQLWhereItem("ParentType", "=", METSStructure.STRUCTURE_TYPE);
295 where.add(whereItem);
296 select.setWhere(where);
297
298 connection.execute(select.toString());
299
300 // parse through the divisions
301 ResultSet divisionSet = connection.getResultSet();
302 if (divisionSet != null && divisionSet.first()) {
303 do {
304 METSDivision division = METSDivision.readSQL(connection, divisionSet);
305 if (division != null) {
306 structure.addDivision(division);
307 }
308 }
309 while (divisionSet.next());
310 }
311
312 return structure;
313 }
314 catch (SQLException sqlEx)
315 { System.out.println(sqlEx + " " + select.toString());
316 System.exit(1);
317 }
318 return null;
319 }
320}
321
Note: See TracBrowser for help on using the repository browser.