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

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

Fixed stupid package error for URLTools

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