source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/CollectionManager.java@ 7468

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

Used URLTools to get File converted to URL

  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1package org.greenstone.gsdl3.gs3build;
2
3import java.util.Date;
4import java.util.Calendar;
5import java.util.List;
6import java.util.ArrayList;
7import java.util.Map;
8import java.util.HashMap;
9import java.util.Iterator;
10import java.util.GregorianCalendar;
11
12import java.io.File;
13import java.io.IOException;
14import java.io.FileOutputStream;
15import java.io.BufferedWriter;
16import java.io.OutputStreamWriter;
17
18import java.net.URL;
19
20import javax.xml.parsers.*;
21
22import org.w3c.dom.Document;
23import org.w3c.dom.Element;
24import org.w3c.dom.NamedNodeMap;
25import org.w3c.dom.Node;
26import org.w3c.dom.NodeList;
27import org.w3c.dom.Text;
28
29import org.xml.sax.SAXException;
30import org.xml.sax.SAXParseException;
31
32import org.greenstone.gsdl3.gs3build.collection.*;
33import org.greenstone.gsdl3.gs3build.classifier.*;
34import org.greenstone.gsdl3.gs3build.indexers.*;
35
36import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
37import org.greenstone.gsdl3.gs3build.util.GS3SQLConnectionFactory;
38import org.greenstone.gsdl3.gs3build.util.DOMUtils;
39
40import org.greenstone.gsdl3.util.GSFile;
41import org.greenstone.gsdl3.util.GSXML;
42import org.greenstone.gsdl3.util.XMLConverter;
43import org.greenstone.gsdl3.util.URLTools;
44
45/**
46 * Store and hold collection-level configuration information for a collection.
47 * This should be used by BuildManager to work out which classes, etc. to load
48 * at build time, and as a repository for the collection-level metadata, and
49 * a means of loading and saving the same to a file or database, as is seen
50 * fit in the final development of gs3.
51 */
52
53public class CollectionManager
54{
55 GregorianCalendar lastBuildDate; // pretty obvious
56 String adminEmail; // the email address of the administrator of the
57 // collection
58 int buildDocNo; // used to generate document identifiers
59 CollectionMetadata metadata; // collection-level metadata
60 GS3SQLConnection database; // the database to store everything in
61 String collectionHome;
62 String siteHome;
63 String collectionName;
64 String qualifiedCollectionName; // used as the database name
65
66 BuildManager buildManager;
67
68 class CollectionClassifier
69 { URL file;
70 String type;
71 List fields;
72 String sort;
73 String className;
74
75 public CollectionClassifier(URL parentURL, String type, String className, Node node)
76 { this.type = type;
77 this.className = className;
78 this.fields = new ArrayList();
79
80 NodeList children = node.getChildNodes();
81 for (int c = 0; c < children.getLength(); c ++) {
82 Node child = children.item(c);
83
84 if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
85 String name = child.getNodeName();
86
87 if (name.equals("file")) {
88 NamedNodeMap atts = children.item(c).getAttributes();
89 Node attribute = atts.getNamedItem("URL");
90 String urlString = attribute.getNodeValue();
91 if (urlString == null)
92 continue;
93
94 try {
95 URL url = new URL(parentURL, urlString);
96 this.file = url;
97 }
98 catch (java.net.MalformedURLException malEx) {
99 System.out.println(malEx);
100 }
101 }
102 else if (name.equals("field")) {
103 String fieldName = DOMUtils.getNodeChildText(children.item(c));
104 this.fields.add(fieldName.toString());
105 }
106 else if (name.equals("sort")) {
107 String sortName = DOMUtils.getNodeChildText(children.item(c));
108 this.sort = sortName;
109 }
110 }
111 }
112 }
113
114 public ClassifierInterface getClassifier()
115 { ClassifierInterface classifier = null;
116
117 if (this.type == null) {
118 return null;
119 }
120 System.out.println(this.type.toLowerCase());
121
122 if (this.type.toLowerCase().equals("hierarchy")) {
123 classifier = new HierarchyClassifier(this.className, this.file, this.fields, this.sort);
124 }
125 else if (this.type.toLowerCase().equals("azlist")) {
126 classifier = new AZListClassifier(this.className, this.fields);
127 }
128
129 return classifier;
130 }
131 }
132
133 /**
134 * Create the collection manager for a given collection
135 *
136 * @param site the name of the site
137 * @param collection <code>String</code> the name of the collection
138 */
139 public CollectionManager(String site, String collection) {
140
141 String gsdl3Root = System.getProperty("GSDL3HOME");
142 if (gsdl3Root == null) {
143 System.out.println("Error: Unable to locate GSDL3HOME");
144 System.exit(1);
145 //return;
146 }
147
148 this.siteHome = GSFile.siteHome(gsdl3Root, site);
149 File site_dir = new File(this.siteHome);
150 if (!site_dir.exists()) {
151 System.out.println("Error: Non-existant site ("+site+") specified");
152 System.exit(1);
153 }
154 site_dir = null;
155 this.collectionHome = GSFile.collectionBaseDir(this.siteHome, collection);
156
157 File collect_dir = new File(this.collectionHome);
158 if (!collect_dir.exists()) {
159 System.out.println("Error: Non-existant collection ("+collection+") specified in site "+site);
160 System.exit(1);
161 }
162 collect_dir = null;
163
164 this.collectionName = collection;
165 this.qualifiedCollectionName = site+"_"+collection;
166
167 this.database = GS3SQLConnectionFactory.createConnection(this.qualifiedCollectionName);
168 /* if (this.database != null) {
169 this.database.clearCollection(collection);
170 this.database = null;
171 }
172 */
173 if (this.database == null) {
174 this.database = GS3SQLConnectionFactory.createConnection("test");
175 this.database.initCollection(this.qualifiedCollectionName);
176 }
177
178 this.metadata = new CollectionMetadata();
179
180 File buildDirectory = new File(GSFile.collectionBuildDir(this.collectionHome));
181 if (!buildDirectory.exists()) {
182 buildDirectory.mkdir();
183 }
184
185 File archiveDirectory = new File(GSFile.collectionArchiveDir(this.collectionHome));
186 if (!archiveDirectory.exists()) {
187 archiveDirectory.mkdir();
188 }
189
190 this.buildDocNo = 1;
191 }
192
193 public void setBuildManager(BuildManager build_man)
194 { this.buildManager = build_man;
195 }
196
197 private void configureBrowsers(Node node, File etcFile)
198 { CollectionClassifier classifier = null;
199 URL etcURL = null;
200
201 try {
202 etcURL = URLTools.getFileURL(etcFile);
203 }
204 catch (java.net.MalformedURLException malEx) {
205 System.out.println(malEx);
206 }
207
208 NodeList children = node.getChildNodes();
209 for (int c = 0; c < children.getLength(); c ++)
210 { // assume that non-element children are irrelevant
211 if (children.item(c).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE)
212 { continue;
213 }
214
215 String name = children.item(c).getNodeName();
216 System.out.println(name);
217
218 if (name.equals(GSXML.CLASSIFIER_ELEM))
219 { NamedNodeMap atts = children.item(c).getAttributes();
220
221 // get the type attribute
222 Node attribute = atts.getNamedItem(GSXML.TYPE_ATT);
223 if (attribute == null) {
224 continue;
225 }
226 String type = attribute.getNodeValue();
227
228 // get the type attribute
229 attribute = atts.getNamedItem(GSXML.NAME_ATT);
230 if (attribute == null) {
231 continue;
232 }
233 String className = attribute.getNodeValue();
234
235 classifier = new CollectionClassifier(etcURL, type, className, children.item(c));
236
237 System.out.println("Found classifier " + type);
238
239 // attach the classifier
240 ClassifierInterface classify = classifier.getClassifier();
241 this.buildManager.getClassifierManager().addClassifier(classify);
242 }
243 }
244 }
245
246 public void configureCollection()
247 { File collectionConfig = new File(GSFile.collectionConfigFile(this.collectionHome));
248
249 // get the File and read it in
250 try
251 {
252 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
253 DocumentBuilder builder = factory.newDocumentBuilder();
254 Document document = builder.parse(collectionConfig);
255
256 // TODO: report an error
257 if (document == null)
258 {
259 }
260
261 // now parse the manager file...
262 Element rootElement = document.getDocumentElement();
263
264 if (rootElement.getTagName() != GSXML.COLLECTION_CONFIG_ELEM)
265 { // TODO: throw exception
266 }
267
268 System.out.println("Configuring collection");
269
270 NodeList children = rootElement.getChildNodes();
271 for (int c = 0; c < children.getLength(); c ++)
272 { // assume that non-element children are irrelevant
273 if (children.item(c).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE)
274 { continue;
275 }
276
277 String name = children.item(c).getNodeName();
278
279 // the name is a plugin element
280
281 if (name.equals("doctype")) {
282 System.out.println("document type");
283 NamedNodeMap typeAttributes = children.item(c).getAttributes();
284 Node typeAttribute = typeAttributes.getNamedItem("type");
285 String documentType = null;
286
287 NodeList childNodes = children.item(c).getChildNodes();
288 for (int n = 0; n < childNodes.getLength(); n ++)
289 { if (childNodes.item(n).getNodeType() == org.w3c.dom.Node.TEXT_NODE)
290 { String label = childNodes.item(n).getNodeValue();
291 label.trim();
292 if (label.length() > 0) {
293 documentType = label;
294 System.out.println("Document type " + documentType);
295 }
296 }
297 }
298 }
299 else if (name.equals(GSXML.SEARCH_ELEM)) {
300 // pick up attributes from the <search> tag now...
301 NamedNodeMap searchAttributes = children.item(c).getAttributes();
302 Node searchAttribute = searchAttributes.getNamedItem(GSXML.TYPE_ATT);
303 String searchType = null;
304 if (searchAttribute != null) {
305 searchType = searchAttribute.getNodeValue();
306 } else {
307 System.out.println("no "+GSXML.TYPE_ATT+" attribute found for the "+GSXML.SEARCH_ELEM+" element, assuming mg");
308 searchType = MGIndexer.MG_INDEX_TYPE;
309 }
310
311 searchAttribute = searchAttributes.getNamedItem(GSXML.NAME_ATT);
312 String searchName = null;
313 if (searchAttribute != null) {
314 searchName = searchAttribute.getNodeValue();
315 }
316 if (searchName == null) {
317 searchName = "idx"; // need to modify this if we have two search elements with no names
318 }
319 // create the pertinent indexer...
320 IndexerInterface indexer = IndexerFactory.makeIndexer(searchType, searchName);
321
322 if (indexer == null) {
323 continue;
324 }
325
326 // configure the indexer
327 indexer.configure(children.item(c));
328
329 // install it into the build manager
330 this.buildManager.addIndexer(indexer);
331 }
332 else if (name.equals(GSXML.BROWSE_ELEM))
333 { this.configureBrowsers(children.item(c), collectionConfig);
334 }
335 // TODO: other elements - make a factory-method approach here...
336 else
337 {
338 }
339 }
340 }
341 catch (FactoryConfigurationError e) {
342 System.out.println(e);
343 }
344 catch (ParserConfigurationException ex) {
345 System.out.println(ex);
346 }
347 catch (SAXException ex) {
348 System.out.println(ex);
349 }
350 catch (IOException ex)
351 {
352 System.out.println(ex);
353 }
354
355 System.out.println("<<<Obtaining database>>>>");
356 }
357
358 public String getEtcDirectory()
359
360 { return GSFile.collectionEtcDir(this.collectionHome);
361 }
362
363 public String getImportDirectory()
364 { return GSFile.collectionImportDir(this.collectionHome);
365 }
366
367 public String getBuildDirectory()
368 { return GSFile.collectionBuildDir(this.collectionHome);
369 }
370
371 public String getArchiveDirectory()
372 { return GSFile.collectionArchiveDir(this.collectionHome);
373 }
374
375 public GS3SQLConnection getDatabase()
376 {
377 return this.database;
378 }
379
380 public void startBuild()
381 { GregorianCalendar today = new GregorianCalendar();
382
383 if (this.lastBuildDate != null)
384 { // if the build date is different to the last build date, then reset the build
385 // document number
386 if (today.get(Calendar.YEAR) != this.lastBuildDate.get(Calendar.YEAR) ||
387 today.get(Calendar.MONTH) != this.lastBuildDate.get(Calendar.MONTH) ||
388 today.get(Calendar.DAY_OF_MONTH) != this.lastBuildDate.get(Calendar.DAY_OF_MONTH))
389 { this.buildDocNo = 1;
390 }
391 }
392 this.lastBuildDate = today;
393 }
394
395 public void endBuild()
396 {
397 // here we write out the build config file
398 // create the xml for the buildConfig
399 XMLConverter converter = new XMLConverter();
400 Document doc = converter.newDOM();
401 Element build_config = doc.createElement(GSXML.COLLECTION_BUILD_ELEM);
402 Element meta_list = doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
403 build_config.appendChild(meta_list);
404 Element service_list = doc.createElement(GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
405 build_config.appendChild(service_list);
406
407 // the document structure and metadata retrieval will use GS3REtrieve service, so add it in here
408 Element base_retrieve_service = doc.createElement(GSXML.SERVICE_CLASS_ELEM);
409 base_retrieve_service.setAttribute(GSXML.NAME_ATT, "GS3Retrieve");
410 service_list.appendChild(base_retrieve_service);
411 // ask the indexers to add stuff into the service rack list
412 this.buildManager.getIndexerManager().addServiceDescriptions(service_list);
413 this.buildManager.getClassifierManager().addServiceDescriptions(service_list);
414 // get the String
415 String build_config_string = converter.getString(build_config);
416 // write it to the file
417 try {
418 File build_config_file = new File(GSFile.collectionBuildConfigFileBuilding(this.collectionHome));
419 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(build_config_file), "UTF-8"));
420 writer.write(build_config_string, 0, build_config_string.length());
421 writer.close();
422 } catch (Exception e) {
423 System.err.println("CollectionManager.endBuild() Error while trying to output the buildConfig.xml file.");
424 System.err.println(e.getMessage());
425 }
426 Date startDate = this.lastBuildDate.getTime();
427 Date date = new Date();
428
429 long startTime = startDate.getTime();
430 long endTime = date.getTime();
431
432 long difference = ((endTime - startTime) + 500) / 1000;
433
434 System.out.println("Build completed");
435 System.out.println("---------------");
436 System.out.println("Total Documents: " + this.getCollectionMetadata("gsdl3", "documentCount"));
437 System.out.println("Total Time : " + (difference / 60) + " min. " + (difference % 60) + " secs.");
438 }
439
440 public String getNextDocumentID()
441 { StringBuffer ID = new StringBuffer();
442
443 int value;
444 ID.append(lastBuildDate.get(Calendar.YEAR));
445
446 // the use of month is a little odd, hence the following
447 // code. Calendar.MONTH yields 0 = January, 1 = February,
448 // etc. hence there is a '+1' added to the month to make
449 // it into January = 1, etc., and the padding is altered
450 // correspondingly.
451 value = lastBuildDate.get(Calendar.MONTH);
452 if (value < 9)
453 { ID.append("0");
454 }
455 ID.append(value + 1);
456 value = lastBuildDate.get(Calendar.DAY_OF_MONTH);
457 if (value < 10)
458 ID.append("0");
459 ID.append(value);
460
461
462 value = this.buildDocNo;
463 this.buildDocNo ++;
464
465 ID.append(":");
466 ID.append(Integer.toString(value));
467 return ID.toString();
468 }
469
470 public int getDocumentNumber()
471 { this.buildDocNo ++;
472 return this.buildDocNo - 1;
473 }
474
475 /**
476 * Get the collection metadata item in the given namespace
477 *
478 * @param <code>String</code> the namespace
479 * @param <code>String</code> the label of the metadata
480 */
481 public String getCollectionMetadata(String namespace, String label)
482 { return this.metadata.getCollectionMetadata(namespace, label).get(0).toString();
483 }
484
485 /**
486 * Set the collection metadata item in the given namespace
487 *
488 * @param <code>String</code> the namespace
489 * @param <code>String</code> the label
490 * @param <code>String</code> the value
491 */
492 public void setCollectionMetadata(String namespace, String label, String value)
493 { this.metadata.setCollectionMetadata(namespace, label, value);
494 }
495}
496
Note: See TracBrowser for help on using the repository browser.