1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.backsource.xindice;
21 import org.w3c.dom.Node;
22 import org.apache.log4j.Logger;
23 import org.xmldb.api.base.*;
24 import org.xmldb.api.modules.*;
25 import org.xmldb.api.DatabaseManager;
26
27
28 import org.apache.xindice.client.xmldb.services.*;
29 import org.apache.xindice.xml.dom.*;
30 /***
31 * An adapter agains Xincice.
32 *
33 * <p>Farefully a ripp of from XmlBlaster: org.xmlBlaster.engine.persistence.xmldb.xindice.XindiceProxy.</p>
34 *
35 *
36 * @author <a href="mailto:pra@tim.se">Peter Antman</a>
37 * @version $Revision: 1.1.1.1 $
38 */
39
40 public class XindiceAdapter {
41 private Logger log = null;
42
43
44
45 private Collection col = null;
46 /*** The path of the collection, in the given server url */
47 private String colPath = null;
48 private String colName = null;
49 private boolean isOpen = false;
50 /*** The base url of the Xincice server, eg: xmldb:xindice:///db or xmldb:xindice://server:4080/db*/
51 private String url;
52 private String xindiceDriver = null;
53 private String xindiceFilterClass = null;
54
55
56 public XindiceAdapter (String url,String col) throws XindiceException {
57 log = Logger.getLogger("org.backsource.xindice.XindiceAdapter."+col);
58 log.debug("Constructor for XindiceProxy, using path: " + url+col);
59 this.url = url;
60 this.colName = col;
61
62
63 xindiceDriver = "org.apache.xindice.client.xmldb.DatabaseImpl";
64 xindiceFilterClass = "org.apache.xindice.core.filer.BTreeFiler";
65
66
67 String path = (col!= null ? col : "");
68 if ( col!=null && (!col.startsWith("/")))
69 path = "/"+col;
70
71
72
73
74 openCollection(url+ path);
75 }
76 /***
77 * Allows to create a collection
78 *
79 * <p />
80 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
81 * <p />
82 * This method stops with an log.error, if the database isn't open already.
83 * <p />
84 * @param colName The Name of the collection
85 */
86 public void createCollection(String colName) throws XindiceException
87 {
88 log.debug("createCollection");
89 String colConfig = null;
90
91 if (!isOpen) {
92 log.error("Cannot create collection '" + colName + "', db needs to be opened first!");
93 throw new XindiceException("Collection not opened");
94 }
95
96 try {
97 CollectionManager service = (CollectionManager) col.getService("CollectionManager", "1.0");
98
99 colConfig =
100 "<collection compressed='true' name='" + colName + "'>" +
101 " <filer class='" + xindiceFilterClass + "' gzip='true'/>" +
102 "</collection>";
103
104 service.createCollection(colName, DOMParser.toDocument(colConfig));
105
106 } catch (XMLDBException e1) {
107 throw new XindiceException( String.valueOf(e1.errorCode));
108 } catch (org.apache.xindice.util.XindiceException e2) {
109 throw new XindiceException( "org.apache.xindice.util.XindiceException occured", e2 );
110 }
111
112 log.debug("Collection '" + colName + "' created using '" + colConfig + "'");
113 }
114
115 /***
116 * Allows to delete a collection
117 *
118 * <p />
119 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
120 * <p />
121 * This method stops with an log.error, if the database isn't open already.
122 * <p />
123 * @param colName The Name of the collection
124 */
125 public void deleteCollection(String colName) throws XindiceException
126 {
127 log.debug("deleteCollection");
128
129 if (!isOpen) {
130 log.error("Cannot delete collection, collection needs to be opened first!");
131 throw new XindiceException("Collection not opened");
132 }
133
134 try {
135 CollectionManager service = (CollectionManager) col.getService("CollectionManager", "1.0");
136 service.dropCollection(colName);
137 } catch (XMLDBException e1) {
138 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
139 }
140
141 log.debug("Collection '" + colName + "' removed");
142 }
143
144 /***
145 * Allows to set the path of a collection and to open it.
146 *
147 * <p />
148 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
149 * <p />
150 * This method stops with an log.error, if the database is open already.
151 * <p />
152 * @param path The Path of the collection i.e. xmldb:xindice:///db/xmlBlaster
153 */
154 public void openCollection(String path) throws XindiceException
155 {
156 log.debug("invoking openCollection: " + path);
157 this.setCollection(path);
158 this.openCollection();
159 }
160
161 /***
162 * Allows to open a collection.
163 *
164 * <p />
165 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
166 * <p />
167 * This method stops with an log.error, if the database is open already.
168 */
169 public void openCollection() throws XindiceException
170 {
171 log.debug("openCollection");
172 log.debug("colPath " + colPath);
173 log.debug("xindiceDriver " + xindiceDriver);
174
175 if (isOpen) {
176 log.error("Cannot open collection, collection is open already!");
177 throw new XindiceException("Collection already opened");
178 }
179
180 try {
181 Class c = Class.forName(xindiceDriver);
182
183 Database database = (Database) c.newInstance();
184
185 DatabaseManager.registerDatabase(database);
186
187 col = DatabaseManager.getCollection(colPath);
188
189 if ( col == null) {
190 throw new XindiceException("No colection found for " + colPath);
191 }
192
193
194 } catch (XMLDBException e1) {
195 e1.printStackTrace();
196 throw new XindiceException( String.valueOf(e1.errorCode), e1);
197 } catch (java.lang.ClassNotFoundException e2) {
198 throw new XindiceException( "ClassNotFoundException occured ", e2 );
199 } catch (java.lang.InstantiationException e3) {
200 throw new XindiceException( "java.lang.InstantiationException occured ", e3 );
201 } catch (java.lang.IllegalAccessException e4) {
202 throw new XindiceException( "java.lang.IllegalAccessException occured ", e4 );
203 }
204
205 log.debug("Collection '" + colPath + "' opened");
206 isOpen = true;
207
208 }
209
210 /***
211 * Allows to close a collection
212 *
213 * <p />
214 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
215 * <p />
216 * This method stops with an log.error, if the database isn't open already.
217 */
218 public void closeCollection() throws XindiceException
219 {
220 log.debug("closeCollection");
221
222 if (!isOpen) {
223 log.error("Cannot close collection, collection needs to be opened first!");
224 throw new XindiceException("Collection not opened");
225 } else {
226 try {
227 col.close();
228 } catch (XMLDBException e) {
229 log.error("Could not close connection",e);
230 throw new XindiceException( String.valueOf(e.errorCode), e );
231 }
232 log.debug("Collection closed");
233 isOpen = false;
234 }
235 }
236
237 /***
238 * Allows to list a collection
239 *
240 * <p />
241 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
242 * <p />
243 * This method stops with an log.error, if the database isn't open already.
244 */
245 public String[] listCollection() throws XindiceException
246 {
247 log.debug("listCollections:");
248
249 if (!isOpen) {
250 log.error("Cannot list collection, collection needs to be opened first!");
251 throw new XindiceException("Collection not opened");
252 }
253 String[] colArray = new String[0];
254
255 try {
256 if ( col != null ) {
257 colArray = col.listChildCollections();
258
259 if ( log.isDebugEnabled()) {
260 for ( int i=0 ; i < colArray.length ; i++ ) {
261 log.debug("\t - " + colArray[i] );
262 }
263 log.debug("Total collections: " + colArray.length);
264
265 }
266
267 }
268 else {
269 log.error("Collection not found");
270 }
271 } catch (XMLDBException e1) {
272 throw new XindiceException( String.valueOf(e1.errorCode), e1);
273 }
274 return colArray;
275 }
276
277 /***
278 * Allows to set the name of the collection
279 *
280 * <p />
281 * @param path The Path of the collection i.e. xmldb:xindice:///db/xmlBlaster
282 */
283 public void setCollection(String path)
284 {
285 log.debug("setCollection path = " + path);
286 colPath = path;
287 }
288
289 /***
290 * Allows to get the name of a collection
291 *
292 * <p />
293 * <p />
294 * @return The Name of the collection
295 */
296 public String getCollection()
297 {
298 log.debug("getCollection");
299
300 if (!isOpen) {
301 log.error("Collection closed, no collection name available!");
302 return "";
303 }
304 return colPath;
305 }
306
307 /***
308 * Get the collection name, not including the base url.
309 */
310 public String getCollectionName() {
311 return colName;
312 }
313
314 /***
315 * Allows to add a document to the collection
316 *
317 * <p />
318 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
319 * <p />
320 * This method stops with an log.error, if the database isn't open already.
321 * <p />
322 * @param data The data to be stored
323 * @param id The unique id of the stored data
324 */
325 public void addDocument(String data, String id) throws XindiceException
326 {
327 log.info("Add document '" + colPath + "/" + data + "' as: " + id );
328
329 if (!isOpen) {
330 log.error("Cannot add document, collection needs to be opened first!");
331 throw new XindiceException("Collection not opened");
332 }
333 try {
334 XMLResource resource = (XMLResource) col.createResource(id, "XMLResource");
335
336 resource.setContent(data);
337 col.storeResource(resource);
338
339 log.debug("Added document '" + colPath + "/" + data + "' as: " + resource.getId() );
340 resource = null;
341
342 } catch (XMLDBException e1) {
343 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
344 }
345 }
346
347
348
349
350 public void addDocument(Node data, String id) throws XindiceException
351 {
352 log.info("Add document '" + colPath + "/" + data + "' as: " + id );
353
354 if (!isOpen) {
355 log.error("Cannot add document, collection needs to be opened first!");
356 throw new XindiceException("Collection not opened");
357 }
358 try {
359 XMLResource resource = (XMLResource) col.createResource(id, "XMLResource");
360
361 resource.setContentAsDOM(data);
362 col.storeResource(resource);
363
364 log.debug("Added document '" + colPath + "/" + data + "' as: " + resource.getId() );
365 resource = null;
366
367 } catch (XMLDBException e1) {
368 e1.printStackTrace();
369 log.error("Could not add document: " +e1,e1);
370 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
371 }
372 }
373
374
375 /***
376 * Adds a document to the database.
377 *
378 * If update is true and the document exist, it is updated, if it does
379 * not exist it is added. If update is dalse and the document exist
380 * the method simply returns.
381 *
382 * @param data is the document
383 * @param id is the Xindice key
384 * @param update indicates whether to update the document or not.
385 */
386 public void addDocument(Node data, String id, boolean update) throws XindiceException
387 {
388 if(hasDocument(id))
389 {
390 if(update)
391 {
392 log.debug("Deleting document with key " + id + " for update");
393 deleteDocument(id);
394 }
395 else
396 {
397 return;
398 }
399 }
400 addDocument(data,id);
401 }
402
403 /***
404 * Checks if this collection has a document matching the specified key.
405 *
406 * @param id is the document key
407 */
408 public boolean hasDocument(String id) throws XindiceException
409 {
410 if (!isOpen) {
411 log.error("Cannot retrieve document, collection needs to be opened first!");
412 throw new XindiceException("Collection not opened");
413 }
414 try
415 {
416 if ( col.getResource(id) == null )
417 {
418 log.debug("No doc with key: " + id + " found");
419 return false;
420 }
421 return true;
422 }
423 catch (XMLDBException e1) {
424 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
425 }
426 }
427
428
429
430 /***
431 * Allows to retrieve a document from the collection
432 *
433 * <p />
434 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
435 * <p />
436 * This method stops with an log.error, if the database isn't open already.
437 * <p />
438 * @param id The unique id of the stored data
439 * @return The stored data belonging to the id, null otherwise
440 */
441 public String retrieveDocument(String id) throws XindiceException
442 {
443 log.debug("retrieveDocument key='" + id +"'");
444
445 if (!isOpen) {
446 log.error("Cannot retrieve document, collection needs to be opened first!");
447 throw new XindiceException("Collection not opened");
448 }
449 String ret = null;
450 try {
451 XMLResource resource = (XMLResource) col.getResource(id);
452
453
454 if ( resource == null ) {
455 log.warn("Document not found!");
456 return ret;
457 }
458
459 String documentstr = (String)resource.getContent();
460
461
462
463 ret = documentstr;
464
465 } catch (XMLDBException e1) {
466 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
467 }
468
469 return ret;
470 }
471
472 public ResourceSet query(String xpath) throws XindiceException {
473 log.debug("queryCollection xapth='" + xpath +"'");
474 ResourceSet resultSet = null;
475
476 if (!isOpen) {
477 log.error("Cannot query , collection needs to be opened first!");
478 throw new XindiceException("Collection not opened");
479 }
480 try {
481 XPathQueryService service =
482 (XPathQueryService) col.getService("XPathQueryService", "1.0");
483 resultSet = service.query(xpath);
484 } catch (XMLDBException e1) {
485 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
486 }
487 return resultSet;
488 }
489
490
491 public ResourceSet query(String id, String xpath) throws XindiceException {
492 log.debug("queryCollection xapth='" + xpath +"'");
493 ResourceSet resultSet = null;
494 if (!isOpen) {
495 log.error("Cannot query , collection needs to be opened first!");
496 throw new XindiceException("Collection not opened");
497 }
498 try {
499 XPathQueryService service =
500 (XPathQueryService) col.getService("XPathQueryService", "1.0");
501 resultSet = service.queryResource(id,xpath);
502 } catch (XMLDBException e1) {
503 throw new XindiceException( String.valueOf(e1.errorCode), e1 );
504 }
505 return resultSet;
506 }
507
508 /***
509 * Allows to delete a document in the collection
510 *
511 * <p />
512 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
513 * <p />
514 * This method stops with an log.error, if the database isn't open already.
515 * <p />
516 * @param id The unique id of the document to delete
517 */
518 public void deleteDocument(String id) throws XindiceException
519 {
520 log.debug("deleteDocument with id"+id);
521
522 if (!isOpen) {
523 log.error("Cannot delete document, collection needs to be opened first!");
524 throw new XindiceException("Collection not opened");
525 }
526
527 try {
528 Resource colresource = col.getResource(id);
529
530 col.removeResource(colresource);
531
532 log.debug("DELETED: " + id);
533
534 } catch (XMLDBException e1) {
535 throw new XindiceException( "Could not delete document:" + String.valueOf(e1.errorCode), e1);
536 }
537 }
538
539 /***
540 * Allows to list all document of the collection
541 *
542 * <p />
543 * The database needs to be running see <a href="http://www.dbxml.org">Xindice</a> for details.
544 * <p />
545 * This method stops with an log.error, if the database isn't open already.
546 * <p />
547 * @return String[] Array containing the id's (unique key's) of all stored data
548 */
549 public String[] listDocuments() throws XindiceException
550 {
551 log.debug("listDocuments");
552
553 if (!isOpen) {
554 log.error("Cannot list documents, collection needs to be opened first!");
555 throw new XindiceException("Collection not opened");
556 }
557
558 String[] docArray = null;
559
560 try {
561 docArray = col.listResources();
562 } catch (XMLDBException e1) {
563 throw new XindiceException( String.valueOf(e1.errorCode), e1);
564 }
565
566 return docArray;
567 }
568
569
570 }
571
572
573
574
575