source: branches/ant-install-branch/gsdl3/src/java/org/greenstone/gsdl3/gs3build/metadata/METSFileGroup.java@ 9858

Last change on this file since 9858 was 9858, checked in by kjdon, 19 years ago

OK, changed my mind about making SQLConnection kill off the previous statement.
To make it more transparent what is happening, you now have to create a Statement (connection.createStatement()), then use the Statement to execute the query. This means that the thing doing the query owns the Statement, and can kill it off when finished with it, and nothing else can kill it off unexpectedly. The previous way this was all implemented meant that there was a large memory leak, and some functionality actually relied on this. A newer version of the mysql connector/J has fixed the bug where the statement wasn't closed on garbage collection, but it still seems better to close it explicitly.
Hopefully I have got it all back to working as well as it was bfore, and haven't introduced any bugs :-)

  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1package org.greenstone.gsdl3.gs3build.metadata;
2
3import java.util.List;
4import java.util.ArrayList;
5import java.util.Iterator;
6
7import java.net.URL;
8
9import java.sql.SQLException;
10import java.sql.Statement;
11import java.sql.ResultSet;
12
13import org.w3c.dom.Element;
14import org.w3c.dom.NodeList;
15
16
17import java.io.PrintWriter;
18
19import org.greenstone.gsdl3.gs3build.util.XMLTools;
20import org.greenstone.gsdl3.gs3build.database.*;
21
22import org.greenstone.gsdl3.gs3build.doctypes.DocumentInterface;
23
24/**
25 * Child groups are indicated by colons. E.g. Chapter1:Section1 would indicate
26 * the group "Section1" inside the "Chapter1" group...
27 */
28
29public class METSFileGroup
30{
31 List children;
32 List childGroups;
33 String id;
34
35 public static final String SECTION_PARENT = "Section";
36 public static final String GROUP_PARENT = "Group";
37
38 public METSFileGroup(String id)
39 {
40 this.children = new ArrayList();
41 this.childGroups = new ArrayList();
42 this.id = id;
43 }
44
45 /**
46 * Get the modified datestamp that applies for this file group. An empty group
47 * will return <code>0</code>.
48 *
49 * @return <code>long</code> the date modified as milliseconds from the 1st January 1970
50 */
51 public long getModifiedDatestamp()
52 {
53 long reply = 0; // empty groups reply '0'
54
55 Iterator childIter = children.iterator();
56 while (childIter.hasNext()){
57 METSFile file = (METSFile) childIter.next();
58 long fileStamp = file.getModifiedDatestamp();
59 if (fileStamp > reply) {
60 reply = fileStamp;
61 }
62 }
63
64 childIter = childGroups.iterator();
65 while (childIter.hasNext()){
66 METSFileGroup fileGroup = (METSFileGroup) childIter.next();
67 long fileStamp = fileGroup.getModifiedDatestamp();
68 if (fileStamp > reply) {
69 reply = fileStamp;
70 }
71 }
72
73 return reply;
74 }
75
76 /**
77 * Find all the occurrences of a given file, and place them
78 * in a <code>List</code>.
79 */
80 public void findGroups(URL findFile, List resultList)
81 {
82 // find in this particular group
83 Iterator childIter = children.iterator();
84 while (childIter.hasNext()){
85 METSFile file = (METSFile) childIter.next();
86 if (file.equals(findFile))
87 { resultList.add(this.id);
88 }
89 }
90
91 // iterate over the child groups
92 childIter = childGroups.iterator();
93 while (childIter.hasNext()){
94 METSFileGroup fileGroup = (METSFileGroup) childIter.next();
95
96 fileGroup.findGroups(findFile, resultList);
97 }
98 }
99
100 /**
101 * Get a sub group of this METSFileGroup.
102 *
103 * @param <code>String</code> the name of the subgroup
104 * @return <code>METSFileGroup</code> the child group, which will
105 * be <code>null</code> if the group is not known.
106 */
107 public METSFileGroup getSubgroup(String id)
108 {
109 String childId;
110
111 int dotAt = id.indexOf(':');
112 if (dotAt == -1){
113 childId = null;
114 }
115 else{
116 childId = id.substring(dotAt+1);
117 id = id.substring(0, dotAt);
118 }
119
120 // iterate over the child groups
121 Iterator childIter = childGroups.iterator();
122 while (childIter.hasNext()){
123 METSFileGroup group = (METSFileGroup) childIter.next();
124
125 if (group.id.equals(id)) {
126 if (childId == null) {
127 return group;
128 }
129 else {
130 return group.getSubgroup(childId);
131 }
132 }
133 }
134 return null;
135 }
136
137 /**
138 * Add a filegroup to this group of files.
139 *
140 * @param <code>METSFileGroup</code> the filegroup.
141 */
142 public void addGroup(METSFileGroup group)
143 {
144 this.childGroups.add(group);
145 }
146
147 /**
148 * Add a file to this group of files.
149 *
150 * @param <code>METSFile</code> the file in a METS File object.
151 */
152 public void addFile(METSFile file)
153 {
154 this.children.add(file);
155 file.setGroup(this);
156 if (!file.getID().isDefined()){
157 file.setID(new METSFileID(this.id + "." + Integer.toString(this.children.size())));
158 }
159 }
160
161 /**
162 * Get the nth child of the group
163 *
164 * @param <code>int</code> the index into the group
165 * @return <code>METSFile</code> the corresponding child. This may be <code>null</code>
166 * particularly if the index given falls outside of the valid range of child
167 * indexes.
168 */
169 public METSFile getFile(int index)
170 {
171 if (index < 0 || index >= this.children.size()){
172 return null;
173 }
174
175 return (METSFile) this.children.get(index);
176 }
177
178 /**
179 * Get all the files in the group as a <code>List</code>
180 *
181 * @return <code>List</code> the file childen of the group.
182 */
183 public List getFiles()
184 {
185 return this.children;
186 }
187
188 /**
189 * Get all the subgroups as a <code>List</code>
190 */
191 public List getSubgroups()
192 {
193 return this.childGroups;
194 }
195
196 /**
197 * Get the number of files in the group
198 *
199 * @return <code>int</code> the count
200 */
201 public int noOfFiles()
202 {
203 return this.children.size();
204 }
205
206 /**
207 * Get the number of subgroups.
208 */
209 public int noOfSubgroups()
210 {
211 return this.childGroups.size();
212 }
213
214 /**
215 * @return <code>String</code> the name of this group
216 */
217 public String getId()
218 {
219 return this.id;
220 }
221
222 public static METSFileGroup parse_groupXML(Element element, METSFileSet set, String parseFilePath, METSFileGroup group)
223 {
224 //deal with mets:fileGrp
225 NodeList children = element.getChildNodes();
226
227 for (int c = 0; c < children.getLength(); c++) {
228 if (children.item(c).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE){
229 continue;
230 }
231 Element child = (Element) children.item(c);
232 String childName = child.getNodeName();
233
234 if (childName.equals("mets:fileGrp")) {
235 String groupId = child.getAttribute("ID");
236 METSFileGroup childGroup = new METSFileGroup(groupId);
237
238 if (group != null){
239 group.addGroup(childGroup);
240 } else {
241 set.addGroup(childGroup);
242 }
243 METSFile file = METSFile.parse_file(child, childGroup, parseFilePath);
244 }
245 }
246 return group;
247 }
248
249 /**
250 * Write the object in an XML METS format.
251 *
252 * @param <code>PrintWriter</code> the printwriter being used to write the object
253 */
254 public void write(PrintWriter writer)
255 {
256 String tag = XMLTools.getOpenTag("mets","fileGrp");
257 tag = XMLTools.addAttribute(tag, "ID", this.id);
258 writer.print(" "); //indentation
259 writer.println(tag);
260
261 Iterator childIter = children.iterator();
262 while (childIter.hasNext()){
263 METSFile file = (METSFile) childIter.next();
264 file.write(writer);
265 }
266 writer.print(" "); //indentation
267 writer.println(XMLTools.getCloseTag("mets","fileGrp"));
268 }
269
270 public boolean writeSQL(DocumentInterface document, String parentRef, boolean parentIsSection,
271 GS3SQLConnection connection)
272 {
273 int sqlId = -1;
274 // check if this node is in the database already
275 GS3SQLSelect select = new GS3SQLSelect("filegroups");
276 select.addField("*");
277 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("FileGroupID", "=", this.id);
278 GS3SQLWhereItem whereDoc = new GS3SQLWhereItem("DocID", "=", document.getID().toString());
279 GS3SQLWhere where = new GS3SQLWhere(whereItem);
280 where.add(whereDoc);
281 select.setWhere(where);
282
283 ResultSet results = null;
284 Statement statement = null;
285
286 try {
287 statement = connection.createStatement();
288 results = statement.executeQuery(select.toString());
289 if (!results.first()) {
290 GS3SQLInsert insert = new GS3SQLInsert("filegroups");
291
292 insert.addValue("DocID", document.getID().toString());
293 insert.addValue("FileGroupID", this.id);
294 insert.addValue("ParentRef", parentRef, GS3SQLField.INTEGER_TYPE);
295 insert.addValue("ParentType", parentIsSection ? SECTION_PARENT : GROUP_PARENT);
296
297 statement.execute(insert.toString());
298 }
299 else {
300 // TODO: update the data for this file group...
301 }
302 }
303 catch (SQLException ex){
304 System.err.println("METSFileGroup.writeSQL(): "+ex);
305 return false;
306 }
307
308 // get the filegroup reference now
309 try {
310 results = statement.executeQuery(select.toString());
311 if (results.first()) {
312 sqlId = results.getInt("FileGroupRef");
313 } else {
314 statement.close();
315 return false;
316 }
317 statement.close();
318 } catch (SQLException sqlex) {
319 System.err.println("METSFileGroup.writeSQL(): "+sqlex);
320 return false;
321 }
322 // iterate over the child groups
323 Iterator childIter = childGroups.iterator();
324 while (childIter.hasNext()){
325 METSFileGroup fileGroup = (METSFileGroup) childIter.next();
326
327 if (!fileGroup.writeSQL(document, Integer.toString(sqlId), false, connection)){
328 System.err.println("METSFileGroup.writeSQL(): Couldn't write FileGroup");
329 return false;
330 }
331 }
332
333 // iterate over the child files
334 childIter = children.iterator();
335 while (childIter.hasNext()){
336 METSFile file = (METSFile) childIter.next();
337 if (!file.writeSQL(sqlId, connection)){
338 System.err.println("METSFileGroup.writeSQL(): Couldn't write File");
339 return false;
340 }
341 }
342
343 return true;
344 }
345
346 public static METSFileGroup readSQL(DocumentInterface document, GS3SQLConnection connection,
347 ResultSet resultSet)
348 {
349 try {
350 String ID = resultSet.getString("FileGroupID");
351 String parentType = resultSet.getString("ParentType");
352 String parentRef = resultSet.getString("ParentRef");
353
354 // create the metadata block object
355 METSFileGroup group = new METSFileGroup(ID);
356
357 // get its metadata reference to retrieve divisions
358 int groupRef = resultSet.getInt("FileGroupRef");
359
360 // query the database for matching groups which are children of this one
361 GS3SQLSelect select = new GS3SQLSelect("filegroups");
362 select.addField("*");
363 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ParentRef", "=", Integer.toString(groupRef),
364 GS3SQLField.INTEGER_TYPE);
365 GS3SQLWhere where = new GS3SQLWhere(whereItem);
366 whereItem = new GS3SQLWhereItem("ParentType", "=", METSFileGroup.GROUP_PARENT);
367 where.add(whereItem);
368 select.setWhere(where);
369
370 Statement statement = connection.createStatement();
371
372 // parse through the child groups
373 ResultSet childSet = statement.executeQuery(select.toString());
374 if (childSet.first()) {
375 do {
376 METSFileGroup fileGroup = METSFileGroup.readSQL(document, connection, childSet);
377 if (fileGroup != null) {
378 group.addGroup(fileGroup);
379 }
380 }
381 while (childSet.next());
382 }
383 // now scan for file members
384 select = new GS3SQLSelect("files");
385 select.addField("*");
386 whereItem = new GS3SQLWhereItem("FileGroupRef", "=", Integer.toString(groupRef), GS3SQLField.INTEGER_TYPE);
387 where = new GS3SQLWhere(whereItem);
388 select.setWhere(where);
389 ResultSet childFileSet = statement.executeQuery(select.toString());
390 if (childFileSet.first()) {
391 do {
392 METSFile file = METSFile.readSQL(connection, childFileSet);
393 if (file != null) {
394 group.addFile(file);
395 }
396 }
397 while (childFileSet.next());
398 }
399 statement.close();
400 return group;
401 }
402 catch (SQLException sqlEx){
403 System.err.println("METSFileGroup.readSQL(): "+sqlEx);
404 System.exit(1);
405 }
406 return null;
407 }
408}
Note: See TracBrowser for help on using the repository browser.