View Javadoc

1   /*
2    * Copyright (c) 2002 Peter Antman, Teknik i Media  <peter.antman@tim.se>
3    *
4    * $Id: XindiceAdapter.java,v 1.1.1.1 2004/05/19 14:10:47 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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  // For the XMLDB specific CollectionManager service
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     // private static Xindice Xdb = null; // instance of Xindice Database
44     
45     private Collection col = null; // instance of collection
46     /*** The path of the collection, in the given server url */
47     private String colPath = null; // path to collection, url+colName
48     private String colName = null; //name of collection in url
49     private boolean isOpen = false; // is db open?
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     // FIXME: need to go through how to really use url and col
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        //xindiceDriver = glob.getProperty().get("Persistence.xindiceDriver", "org.apache.xindice.client.xmldb.DatabaseImpl");
62        //xindiceFilterClass = glob.getProperty().get("Persistence.xindiceFilterClass", "org.apache.xindice.core.filer.BTreeFiler");
63        xindiceDriver =  "org.apache.xindice.client.xmldb.DatabaseImpl";
64        xindiceFilterClass = "org.apache.xindice.core.filer.BTreeFiler";
65  
66        // Fix path
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    } // end of public createCollection()
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    } // end of deleteCollection()
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    } // end of openCollection
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         //log.info("Here I am 1");
183          Database database = (Database) c.newInstance();
184         //log.info("Here I am 2");
185          DatabaseManager.registerDatabase(database);
186         //log.info("Here I am 3");
187          col = DatabaseManager.getCollection(colPath);
188 
189          if ( col == null) {
190             throw new XindiceException("No colection found for " + colPath);
191          } // end of if ()
192          
193         //log.info("Here I am 4");
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    } // end of openCollection()
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    } // end of closeCollection()
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             } // end of if ()
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    } // end of listCollection()
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    } // end of setCollection()
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    } // end of getCollection()
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    } // end of addDocument()
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    } // end of addDocument()
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          // Verify that we were able to find the document
454          if ( resource == null ) {
455             log.warn("Document not found!");
456             return ret;
457          }
458 
459          String documentstr = (String)resource.getContent();
460 
461          //log.info("retrieved document " + documentstr );
462 
463          ret = documentstr;
464 
465       } catch (XMLDBException e1) {
466          throw new XindiceException( String.valueOf(e1.errorCode), e1 );
467       }
468 
469       return ret;
470    } // end of retrieveDocument()
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       } // end of try-catch
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       } // end of try-catch
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    } // end of deleteDocument()
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    } // end of listDocuments()
568    
569    
570 }// XindiceAdapter
571 
572 
573 
574 
575