KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > services > cms > repository > slide > CmsDescriptorsStore


1 /*
2  *
3  * The Apache Software License, Version 1.1
4  *
5  * Copyright (c) 1999 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution, if
21  * any, must include the following acknowlegement:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowlegement may appear in the software itself,
25  * if and wherever such third-party acknowlegements normally appear.
26  *
27  * 4. The names "The Jakarta Project", "Jetspeed", and "Apache Software
28  * Foundation" must not be used to endorse or promote products derived
29  * from this software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache"
33  * nor may "Apache" appear in their names without prior written
34  * permission of the Apache Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  *
55  * [Additional notices, if required by prior licensing conditions]
56  *
57  */

58
59 package org.apache.jetspeed.services.cms.repository.slide;
60
61 import java.lang.reflect.Constructor JavaDoc;
62 import java.util.Hashtable JavaDoc;
63 import java.util.Enumeration JavaDoc;
64 import java.util.Vector JavaDoc;
65 import java.util.Date JavaDoc;
66 import java.io.FileWriter JavaDoc;
67 import java.io.IOException JavaDoc;
68 import java.sql.*;
69
70 import javax.transaction.xa.XAException JavaDoc;
71 import javax.transaction.xa.Xid JavaDoc;
72
73 import org.apache.slide.common.*;
74 import org.apache.slide.store.*;
75 import org.apache.slide.structure.*;
76 import org.apache.slide.security.*;
77 import org.apache.slide.lock.*;
78 import org.apache.slide.content.*;
79 import org.apache.slide.util.logger.Logger;
80
81 import org.apache.jetspeed.services.resources.JetspeedResources;
82 /**
83  * JDBC 1.0 and 2.0 compliant store implementation.
84  * This class comes from Slide code. Can be replace by another descriptor
85  * store.
86  *
87  *
88  *
89  * TO DO : Use J2EE Datastore instead of this class
90  *
91  * @author <a HREF="mailto:remm@apache.org">Remy Maucherat</a>
92  * @author Dirk Verbeeck
93  * @author <a HREF="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
94  */

95
96 public class CmsDescriptorsStore
97     extends AbstractSimpleService
98     implements
99         LockStore,
100         NodeStore,
101         RevisionDescriptorsStore,
102         RevisionDescriptorStore,
103         SecurityStore {
104
105     // -------------------------------------------------------------- Constants
106

107     // Column numbers
108

109     // Structure descriptors
110

111     protected static final int OBJECTS_URI = 1;
112     protected static final int OBJECTS_CLASS = 2;
113
114     protected static final int CHILDREN_URI = 1;
115     protected static final int CHILDREN_CHILDURI = 2;
116
117     protected static final int LINKS_LINK = 1;
118     protected static final int LINKS_LINKTO = 2;
119
120     // Security descriptors
121

122     protected static final int PERMISSIONS_OBJECT = 1;
123     protected static final int PERMISSIONS_REVISION_NUMBER = 2;
124     protected static final int PERMISSIONS_SUBJECT = 3;
125     protected static final int PERMISSIONS_ACTION = 4;
126     protected static final int PERMISSIONS_INHERITABLE = 5;
127     protected static final int PERMISSIONS_NEGATIVE = 6;
128
129     // Lock descriptors
130

131     protected static final int LOCKS_ID = 1;
132     protected static final int LOCKS_OBJECT = 2;
133     protected static final int LOCKS_SUBJECT = 3;
134     protected static final int LOCKS_TYPE = 4;
135     protected static final int LOCKS_EXPIRATIONDATE = 5;
136     protected static final int LOCKS_INHERITABLE = 6;
137     protected static final int LOCKS_EXCLUSIVE = 7;
138
139     // Content descriptors
140

141     protected static final int REVISIONS_URI = 1;
142     protected static final int REVISIONS_ISVERSIONED = 2;
143     protected static final int REVISIONS_INITIALREVISION = 3;
144
145     protected static final int WORKINGREVISION_URI = 1;
146     protected static final int WORKINGREVISION_BASEREVISION = 2;
147     protected static final int WORKINGREVISION_NUMBER = 3;
148
149     protected static final int LATESTREVISIONS_URI = 1;
150     protected static final int LATESTREVISIONS_BRANCHNAME = 2;
151     protected static final int LATESTREVISIONS_NUMBER = 3;
152
153     protected static final int BRANCHES_URI = 1;
154     protected static final int BRANCHES_NUMBER = 2;
155     protected static final int BRANCHES_CHILDNUMBER = 3;
156
157     protected static final int REVISION_URI = 1;
158     protected static final int REVISION_NUMBER = 2;
159     protected static final int REVISION_BRANCHNAME = 3;
160
161     protected static final int LABEL_URI = 1;
162     protected static final int LABEL_NUMBER = 2;
163     protected static final int LABEL_LABEL = 3;
164
165     protected static final int PROPERTY_URI = 1;
166     protected static final int PROPERTY_NUMBER = 2;
167     protected static final int PROPERTY_NAME = 3;
168     protected static final int PROPERTY_VALUE = 4;
169     protected static final int PROPERTY_NAMESPACE = 5;
170     protected static final int PROPERTY_TYPE = 6;
171     protected static final int PROPERTY_PROTECTED = 7;
172
173     // ----------------------------------------------------- Instance Variables
174

175     /**
176      * Database connection.
177      */

178     protected Connection connection;
179
180     /**
181      * Driver class name.
182      */

183     protected String JavaDoc driver;
184
185     /**
186      * Connection URL.
187      */

188     protected String JavaDoc url;
189
190     /**
191      * User name.
192      */

193     protected String JavaDoc user;
194
195     /**
196      * Password.
197      */

198     protected String JavaDoc password;
199
200     /**
201      * JDBC Version to use.
202      */

203     protected int jdbcVersion;
204
205     /**
206      * This store doesn't handle nested transactions, this variable keeps track
207      * if the store is already enlisted to a transaction.
208      */

209     protected boolean alreadyEnlisted = false;
210
211     // -------------------------------------------------------- Service Methods
212

213     /**
214      * Returns the sql statements to create the database objects.
215      */

216     protected String JavaDoc[] getDatabaseCreateStatements() {
217         String JavaDoc[] statements =
218             {
219                 "create table objects(uri varchar(65536) primary key,"
220                     + " classname varchar(4096))",
221                 "create table children(uri varchar(65536), "
222                     + " childuri varchar(65536))",
223                 "create table links(link varchar(65536), "
224                     + " linkto varchar(65536))",
225                 "create table permissions(object varchar(65536),"
226                     + " revisionnumber varchar(20), "
227                     + " subject varchar(65536), action varchar(65536), "
228                     + " inheritable int, negative int)",
229                 "create table locks(id varchar(65536), object varchar(4096),"
230                     + " subject varchar(4096), type varchar(4096), "
231                     + " expirationdate varchar(15), inheritable int, "
232                     + " xexclusive int)",
233                 "create table revisions(uri varchar(65536) primary key, "
234                     + " isversioned int, initialrevision varchar(10))",
235                 "create table workingrevision(uri varchar(65536), "
236                     + " baserevision varchar(20), xnumber varchar(20))",
237                 "create table latestrevisions(uri varchar(65536), "
238                     + " branchname varchar(4096), xnumber varchar(20))",
239                 "create table branches(uri varchar(65536), xnumber varchar(20),"
240                     + " childnumber varchar(20))",
241                 "create table revision(uri varchar(65536), xnumber varchar(20),"
242                     + " branchname varchar(4096))",
243                 "create table label(uri varchar(65536), xnumber varchar(20),"
244                     + " label varchar(4096))",
245                 "create table property(uri varchar(65536), xnumber varchar(20),"
246                     + " name varchar(4096), value varchar(65536), "
247                     + " namespace varchar(4096), type varchar(100), protected int)" };
248
249         return statements;
250     }
251
252     /**
253      * Initializes the data source with a set of parameters.
254      *
255      * @param parameters Hashtable containing the parameters' name
256      * and associated value
257      * @exception ServiceParameterErrorException Incorrect service parameter
258      * @exception ServiceParameterMissingException Service parameter missing
259      */

260     public void setParameters(Hashtable JavaDoc parameters)
261         throws ServiceParameterErrorException, ServiceParameterMissingException {
262
263         // Driver classname
264
driver =
265             JetspeedResources.getString(
266                 "services.CmsService.slide.descriptor.driver");
267
268         // Connection url - might contain variable like ${webappRoot}
269
url =
270             JetspeedResources.getString(
271                 "services.CmsService.slide.descriptor.url");
272
273         // FIXME: before slide 1.0.12 the database url was passed
274
// without "jdbc:" this compatibility code sould be removed in the
275
// future code changed 18 jul 2001
276
if (!url.startsWith("jdbc:")) {
277             url = "jdbc:" + url;
278         }
279         // end compatibility code
280

281         // User name
282
user =
283             JetspeedResources.getString(
284                 "services.CmsService.slide.descriptor.user");
285         if (user == null) {
286             user = new String JavaDoc();
287         }
288
289         // Password
290
password =
291             JetspeedResources.getString(
292                 "services.CmsService.slide.descriptor.password");
293         if (password == null) {
294             password = new String JavaDoc();
295         }
296
297         // JDBC version to use
298
jdbcVersion = 1;
299         String JavaDoc version =
300             JetspeedResources.getString(
301                 "services.CmsService.slide.descriptor.jdbcversion");
302         if (version != null) {
303             jdbcVersion = (new Integer JavaDoc(version)).intValue();
304         }
305     }
306
307     /**
308      * Connects to JDBC and creates the basic table structure.
309      *
310      * @exception ServiceConnectionFailedException Connection to the
311      * database failed
312      */

313     public synchronized void connect()
314         throws ServiceConnectionFailedException {
315         getLogger().log(
316             "Connecting to \"" + url + "\" as user \"" + user + "\"",
317             LOG_CHANNEL,
318             Logger.INFO);
319         try {
320             connection = DriverManager.getConnection(url, user, password);
321         } catch (SQLException e) {
322             getLogger().log(
323                 "Connecting to \"" + url + "\" as user \"" + user + "\" failed",
324                 LOG_CHANNEL,
325                 Logger.ERROR);
326             getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
327             throw new ServiceConnectionFailedException(this, e);
328         }
329
330         // all updates must be done inside a transaction, no auto commits
331
try {
332             connection.setAutoCommit(true);
333         } catch (SQLException e) {
334         }
335         /*
336          Statement statement = null;
337          try {
338              statement = connection.createStatement();
339              String[] statements = getDatabaseCreateStatements();
340              for (int i=0; i<statements.length ; i++ ) {
341                  statement.execute(statements[i]);
342              }
343         
344              // Cloudscape needs a commit on DDL statements (create,...)
345              connection.commit();
346         
347          } catch (SQLException e) {
348              try { connection.rollback(); } catch (SQLException ex) { }
349          } finally {
350              closeStatement(statement);
351          }
352          */

353         // we are just connected and are not enlisted
354
alreadyEnlisted = false;
355     }
356
357     /**
358      * Disconnects from data source.
359      *
360      * @exception ServiceDisconnectionFailedException Disconnection
361      * from database failed
362      */

363     public void disconnect() throws ServiceDisconnectionFailedException {
364         getLogger().log(
365             "Disconnecting from \"" + url + "\" as user \"" + user + "\"",
366             LOG_CHANNEL,
367             Logger.INFO);
368         try {
369             if (connection != null) {
370                 connection.close();
371             }
372             connection = null;
373         } catch (SQLException e) {
374             getLogger().log(
375                 "Disconnecting from \""
376                     + url
377                     + "\" as user \""
378                     + user
379                     + "\" failed",
380                 LOG_CHANNEL,
381                 Logger.ERROR);
382             getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
383             throw new ServiceDisconnectionFailedException(this, e);
384         }
385     }
386
387     /**
388      * Initializes data source.
389      * <p/>
390      * Occurs in four steps :
391      * <li>Driver class is loaded</li>
392      * <li>Driver is intantiated</li>
393      * <li>Driver registration in the driver manager</li>
394      * <li>Creation of the basic tables, if they didn't exist before</li>
395      *
396      * @exception ServiceInitializationFailedException Throws an exception
397      * if the data source has already been initialized before
398      */

399     public synchronized void initialize(NamespaceAccessToken token)
400         throws ServiceInitializationFailedException {
401         try {
402             // Loading and registering driver
403
token.getLogger().log(
404                 "Loading and registering driver: " + driver,
405                 LOG_CHANNEL,
406                 Logger.INFO);
407             Class JavaDoc driverClass = Class.forName(driver);
408             Driver databaseDriver = (Driver) driverClass.newInstance();
409             DriverManager.registerDriver(databaseDriver);
410         } catch (ClassNotFoundException JavaDoc e) {
411             token.getLogger().log(
412                 "Loading and registering driver " + driver + " failed",
413                 LOG_CHANNEL,
414                 Logger.ERROR);
415             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
416             throw new ServiceInitializationFailedException(
417                 this,
418                 e.getMessage());
419         } catch (InstantiationException JavaDoc e) {
420             token.getLogger().log(
421                 "Loading and registering driver " + driver + " failed",
422                 LOG_CHANNEL,
423                 Logger.ERROR);
424             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
425             throw new ServiceInitializationFailedException(
426                 this,
427                 e.getMessage());
428         } catch (IllegalAccessException JavaDoc e) {
429             token.getLogger().log(
430                 "Loading and registering driver " + driver + " failed",
431                 LOG_CHANNEL,
432                 Logger.ERROR);
433             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
434             throw new ServiceInitializationFailedException(
435                 this,
436                 e.getMessage());
437         } catch (SQLException e) {
438             token.getLogger().log(
439                 "Loading and registering driver " + driver + " failed",
440                 LOG_CHANNEL,
441                 Logger.ERROR);
442             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
443             throw new ServiceInitializationFailedException(
444                 this,
445                 e.getMessage());
446         } catch (ClassCastException JavaDoc e) {
447             token.getLogger().log(
448                 "Loading and registering driver " + driver + " failed",
449                 LOG_CHANNEL,
450                 Logger.ERROR);
451             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
452             throw new ServiceInitializationFailedException(
453                 this,
454                 e.getMessage());
455         } catch (Exception JavaDoc e) {
456             token.getLogger().log(
457                 "Loading and registering driver " + driver + " failed",
458                 LOG_CHANNEL,
459                 Logger.ERROR);
460             token.getLogger().log(e.toString(), LOG_CHANNEL, Logger.ERROR);
461             throw new ServiceInitializationFailedException(
462                 this,
463                 e.getMessage());
464         }
465     }
466
467     /**
468      * Deletes data source. Should remove stored data if possible.
469      *
470      * @exception ServiceResetFailedException Reset failed
471      */

472     public synchronized void reset() throws ServiceResetFailedException {
473         Statement statement = null;
474         /*
475          try {
476              connectIfNeeded();
477         
478              statement = connection.createStatement();
479              String s = null;
480         
481              s = "drop table objects";
482              statement.execute(s);
483         
484              s = "drop table children";
485              statement.execute(s);
486         
487              s = "drop table links";
488              statement.execute(s);
489         
490              s = "drop table permissions";
491              statement.execute(s);
492         
493              s = "drop table locks";
494              statement.execute(s);
495         
496              s = "drop table revisions";
497              statement.execute(s);
498         
499              s = "drop table workingrevision";
500              statement.execute(s);
501         
502              s = "drop table latestrevisions";
503              statement.execute(s);
504         
505              s = "drop table branches";
506              statement.execute(s);
507         
508              s = "drop table revision";
509              statement.execute(s);
510         
511              s = "drop table label";
512              statement.execute(s);
513         
514              s = "drop table property";
515              statement.execute(s);
516         
517              statement.close();
518              disconnect();
519          } catch (SQLException e) {
520              throw new ServiceResetFailedException(this, e.getMessage());
521          } catch (ServiceAccessException e) {
522              throw new ServiceResetFailedException(this, e.getMessage());
523          } catch (ServiceConnectionFailedException e) {
524              throw new ServiceResetFailedException(this, e.getMessage());
525          } catch (ServiceDisconnectionFailedException e) {
526              throw new ServiceResetFailedException(this, e.getMessage());
527          } finally {
528              closeStatement(statement);
529          }
530          */

531     }
532
533     /**
534      * This function tells whether or not the data source is connected.
535      *
536      * @return boolean true if we are connected
537      * @exception ServiceAccessException Error accessing DataSource
538      */

539     public boolean isConnected() throws ServiceAccessException {
540         try {
541             return ((connection != null) && (!connection.isClosed()));
542         } catch (SQLException e) {
543             throw new ServiceAccessException(this, e);
544         }
545     }
546
547     // ----------------------------------------------------- XAResource Methods
548

549     /**
550      * Commit the global transaction specified by xid.
551      */

552     public void commit(Xid JavaDoc xid, boolean onePhase) throws XAException JavaDoc {
553         super.commit(xid, onePhase);
554
555         try {
556             // getLogger().log("commit",LOG_CHANNEL,Logger.DEBUG);
557
connection.commit();
558         } catch (SQLException e) {
559             throw new XAException JavaDoc(XAException.XA_RBCOMMFAIL);
560         }
561         alreadyEnlisted = false;
562     }
563
564     /**
565      * Inform the resource manager to roll back work done on behalf of a
566      * transaction branch.
567      */

568     public void rollback(Xid JavaDoc xid) throws XAException JavaDoc {
569         super.rollback(xid);
570
571         try {
572             // getLogger().log("rollback",LOG_CHANNEL,Logger.DEBUG);
573
connection.rollback();
574         } catch (SQLException e) {
575             throw new XAException JavaDoc(XAException.XA_HEURCOM);
576         }
577         alreadyEnlisted = false;
578     }
579
580     /**
581      * Start work on behalf of a transaction branch specified in xid.
582      */

583     public void start(Xid JavaDoc xid, int flags) throws XAException JavaDoc {
584         super.start(xid, flags);
585         if (!alreadyEnlisted) {
586             try {
587                 // getLogger().log("start",LOG_CHANNEL,Logger.DEBUG);
588
// discard changes made outside a tranaction
589
connection.rollback();
590             } catch (SQLException e) {
591                 throw new XAException JavaDoc(XAException.XAER_RMERR);
592             }
593             alreadyEnlisted = true;
594         }
595     }
596
597     // ----------------------------------------------- DescriptorsStore Methods
598

599     /**
600      * Retrive an object.
601      *
602      * @param uri Uri of the object we want to retrieve
603      * @exception ServiceAccessException Error accessing the Service
604      * @exception ObjectNotFoundException The object to retrieve was not found
605      */

606     public ObjectNode retrieveObject(Uri uri)
607         throws ServiceAccessException, ObjectNotFoundException {
608
609         ObjectNode result = null;
610         PreparedStatement statement = null;
611
612         try {
613
614             statement =
615                 connection.prepareStatement(
616                     "select * from objects where uri= ?");
617             statement.setString(1, uri.toString());
618
619             ResultSet res = statement.executeQuery();
620
621             // Parsing result set
622

623             String JavaDoc className;
624
625             if (res.next()) {
626                 // Retrieving and loading the object
627
className = res.getString(OBJECTS_CLASS);
628             } else {
629                 // Object was not found ...
630
throw new ObjectNotFoundException(uri);
631             }
632
633             closeStatement(statement);
634
635             // Then, retrieve the children
636
statement =
637                 connection.prepareStatement(
638                     "select * from children where uri= ?");
639             statement.setString(1, uri.toString());
640             res = statement.executeQuery();
641
642             Vector JavaDoc childrenVector = new Vector JavaDoc();
643
644             // Parse result set
645
while (res.next()) {
646                 // Load each permission
647
childrenVector.addElement(res.getString(CHILDREN_CHILDURI));
648             }
649             closeStatement(statement);
650
651             statement =
652                 connection.prepareStatement(
653                     "select * from links where linkto= ?");
654             statement.setString(1, uri.toString());
655             res = statement.executeQuery();
656
657             Vector JavaDoc linksVector = new Vector JavaDoc();
658
659             // Parse result set
660
while (res.next()) {
661                 // Load each permission
662
linksVector.addElement(res.getString(LINKS_LINKTO));
663             }
664
665             closeStatement(statement);
666
667             if (className.equals("org.apache.slide.structure.LinkNode")) {
668
669                 String JavaDoc linkTo = new String JavaDoc();
670                 statement =
671                     connection.prepareStatement(
672                         "select * from links where link= ?");
673                 statement.setString(1, uri.toString());
674                 res = statement.executeQuery();
675
676                 if (res.next()) {
677                     linkTo = res.getString(LINKS_LINKTO);
678                 }
679
680                 closeStatement(statement);
681
682                 result =
683                     new LinkNode(
684                         uri.toString(),
685                         childrenVector,
686                         linksVector,
687                         linkTo);
688
689             } else {
690
691                 try {
692                     Class JavaDoc objclass = Class.forName(className);
693
694                     Class JavaDoc[] argClasses =
695                         {
696                             Class.forName("java.lang.String"),
697                             Class.forName("java.util.Vector"),
698                             Class.forName("java.util.Vector")};
699                     Object JavaDoc[] arguments =
700                         { uri.toString(), childrenVector, linksVector };
701
702                     Constructor JavaDoc constructor =
703                         objclass.getConstructor(argClasses);
704                     result = (ObjectNode) constructor.newInstance(arguments);
705                 } catch (Exception JavaDoc e) {
706                     // ClassNotFoundException, NoSuchMethodException, etc.
707
throw new ServiceAccessException(this, e);
708                 }
709             }
710         } catch (SQLException e) {
711             getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
712             throw new ServiceAccessException(this, e);
713         } finally {
714             closeStatement(statement);
715         }
716         return result;
717     }
718
719     /**
720      * Update an object.
721      *
722      * @param object Object to update
723      * @exception ServiceAccessException Error accessing the Service
724      * @exception ObjectNotFoundException The object to update was not found
725      */

726     public void storeObject(Uri uri, ObjectNode object)
727         throws ServiceAccessException, ObjectNotFoundException {
728
729         PreparedStatement statement = null;
730
731         try {
732             statement =
733                 connection.prepareStatement(
734                     "select * from objects where uri= ?");
735             statement.setString(1, uri.toString());
736
737             ResultSet res = statement.executeQuery();
738
739             // Parsing result set
740

741             if (!res.next()) {
742                 throw new ObjectNotFoundException(uri);
743             }
744
745             closeStatement(statement);
746
747             // Updating children
748
statement =
749                 connection.prepareStatement(
750                     "delete from children where uri= ?");
751             statement.setString(1, object.getUri());
752             statement.execute();
753             closeStatement(statement);
754
755             statement = null;
756             Enumeration JavaDoc children = object.enumerateChildren();
757             while (children.hasMoreElements()) {
758                 if (statement == null) {
759                     statement =
760                         connection.prepareStatement(
761                             "insert into children values(?, ?)");
762                 }
763                 statement.setString(1, object.getUri());
764                 statement.setString(2, (String JavaDoc) children.nextElement());
765                 statement.execute();
766             }
767             closeStatement(statement);
768
769             // Updating inbound links
770
/*
771             s = "delete from links where linkto='" + object.getUri() + "'";
772             statement.execute(s);
773             Enumeration links = object.enumerateLinks();
774             while (children.hasMoreElements()) {
775                 s = "insert into links values('"
776                     + (String) links.nextElement() + "', '"
777                     + object.getUri() + "')";
778                 statement.execute(s);
779             }
780             */

781
782             // Updating links
783
statement =
784                 connection.prepareStatement("delete from links where link= ?");
785             statement.setString(1, object.getUri());
786             statement.execute();
787             closeStatement(statement);
788
789             if (object instanceof LinkNode) {
790                 statement =
791                     connection.prepareStatement(
792                         "insert into links values(?,?)");
793                 statement.setString(1, object.getUri());
794                 statement.setString(2, ((LinkNode) object).getLinkedUri());
795                 statement.execute();
796                 closeStatement(statement);
797             }
798         } catch (SQLException e) {
799             getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
800             throw new ServiceAccessException(this, e);
801         } finally {
802             closeStatement(statement);
803         }
804     }
805
806     /**
807      * Create a new object.
808      *
809      * @param object ObjectNode
810      * @param uri Uri of the object we want to create
811      * @exception ServiceAccessException Error accessing the Service
812      * @exception ObjectAlreadyExistsException An object already exists
813      * at this Uri
814      */

815     public void createObject(Uri uri, ObjectNode object)
816         throws ServiceAccessException, ObjectAlreadyExistsException {
817
818         PreparedStatement statement = null;
819
820         try {
821
822             String JavaDoc className = object.getClass().getName();
823
824             statement =
825                 connection.prepareStatement(
826                     "select * from objects where uri= ?");
827             statement.setString(1, uri.toString());
828
829             ResultSet res = statement.executeQuery();
830
831             // Parsing result set
832

833             if (res.next()) {
834                 throw new ObjectAlreadyExistsException(uri.toString());
835             }
836
837             closeStatement(statement);
838
839             statement =
840                 connection.prepareStatement("insert into objects values(?,?)");
841             statement.setString(1, uri.toString());
842             statement.setString(2, className);
843
844             statement.execute();
845             closeStatement(statement);
846
847             statement = null;
848             // Inserting children
849
Enumeration JavaDoc children = object.enumerateChildren();
850             while (children.hasMoreElements()) {
851                 if (statement == null) {
852                     statement =
853                         connection.prepareStatement(
854                             "insert into children values(?,?)");
855                 }
856                 statement.setString(1, uri.toString());
857                 statement.setString(2, (String JavaDoc) children.nextElement());
858                 statement.execute();
859             }
860             closeStatement(statement);
861
862             // Updating inbound links
863
/*
864             Enumeration links = object.enumerateLinks();
865             while (children.hasMoreElements()) {
866                 s = "insert into links values('"
867                     + (String) links.nextElement() + "', '"
868                     + object.getUri() + "')";
869                 statement.execute(s);
870             }
871             */

872
873             // If the object is a link, also store the link information
874
if (object instanceof LinkNode) {
875                 statement =
876                     connection.prepareStatement(
877                         "insert into links values(?,?)");
878                 statement.setString(1, uri.toString());
879                 statement.setString(2, ((LinkNode) object).getLinkedUri());
880                 statement.execute();
881                 closeStatement(statement);
882             }
883         } catch (SQLException e) {
884             getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
885             throw new ServiceAccessException(this, e);
886         } finally {
887             closeStatement(statement);
888         }
889
890     }
891
892     /**
893      * Remove an object.
894      *
895      * @param object Object to remove
896      * @exception ServiceAccessException Error accessing the Service
897      * @exception ObjectNotFoundException The object to remove was not found
898      */

899     public void removeObject(Uri uri, ObjectNode object)
900         throws ServiceAccessException, ObjectNotFoundException {
901
902         PreparedStatement statement = null;
903
904         try {
905             // Removing object
906
statement =
907                 connection.prepareStatement("delete from objects where uri= ?");
908             statement.setString(1, object.getUri());
909             statement.execute();
910             closeStatement(statement);
911
912             // Removing children
913
statement =
914                 connection.prepareStatement("delete from children where uri=?");
915             statement.setString(1, object.getUri());
916             statement.execute();
917             closeStatement(statement);
918
919             // Removing inbound links
920
/*
921             s = "delete from links where linkto='" + object.getUri() + "'";
922             statement.execute(s);
923             */

924
925             // Removing links
926
statement =
927                 connection.prepareStatement("delete from links where link= ?");
928             statement.setString(1, object.getUri());
929             statement.execute();
930             closeStatement(statement);
931         } catch (SQLException e) {
932             getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
933             throw new ServiceAccessException(this, e);
934         }
935     }
936
937     /**
938      * Grant a new permission.
939      *
940      * @param permission Permission we want to create
941      * @exception ServiceAccessException Error accessing the Service
942      */

943     public void grantPermission(Uri uri, NodePermission permission)
944         throws ServiceAccessException {
945
946         PreparedStatement statement = null;
947
948         try {
949             int inheritable = 0;
950             if (permission.isInheritable()) {
951                 inheritable = 1;
952             }
953
954             int negative = 0;
955             if (permission.isNegative()) {
956                 negative = 1;
957             }
958
959             NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
960             String JavaDoc revisionNumberStr =
961                 (revisionNumber == null) ? null : revisionNumber.toString();
962
963             statement =
964                 connection.prepareStatement(
965                     "insert into permissions values(?,?,?,?,?,?)");
966             statement.setString(1, permission.getObjectUri());
967             statement.setString(2, revisionNumberStr);
968             statement.setString(3, permission.getSubjectUri());
969             statement.setString(4, permission.getActionUri());
970             statement.setInt(5, inheritable);
971             statement.setInt(6, negative);
972             statement.execute();
973         } catch (SQLException e) {
974             getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
975             throw new ServiceAccessException(this, e);
976         } finally {
977             closeStatement(statement);
978         }
979     }
980
981     /**
982      * Revoke a permission.
983      *
984      * @param permission Permission we want to create
985      * @exception ServiceAccessException Error accessing the Service
986      */

987     public void revokePermission(Uri uri, NodePermission permission)
988         throws ServiceAccessException {
989
990         PreparedStatement statement = null;
991
992         try {
993             NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
994
995             if (revisionNumber != null) {
996                 statement =
997                     connection.prepareStatement(
998                         "delete from permissions where object= ? and subject = ? and \"ACTION\" = ? and revisionnumber = ? ");
999                 statement.setString(4, revisionNumber.toString());
1000            } else {
1001                statement =
1002                    connection.prepareStatement(
1003                        "delete from permissions where object = ? and subject = ? and \"ACTION\" = ? and revisionnumber is NULL");
1004            }
1005
1006            statement.setString(1, permission.getObjectUri());
1007            statement.setString(2, permission.getSubjectUri());
1008            statement.setString(3, permission.getActionUri());
1009
1010            statement.execute();
1011        } catch (SQLException e) {
1012            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1013            throw new ServiceAccessException(this, e);
1014        } finally {
1015            closeStatement(statement);
1016        }
1017    }
1018
1019    /**
1020     * Revoke all the permissions on an object.
1021     *
1022     * @param permission Permission we want to create
1023     * @exception ServiceAccessException Error accessing the Service
1024     */

1025    public void revokePermissions(Uri uri) throws ServiceAccessException {
1026
1027        PreparedStatement statement = null;
1028
1029        try {
1030            statement =
1031                connection.prepareStatement(
1032                    "delete from permissions where object= ?");
1033            statement.setString(1, uri.toString());
1034            statement.execute();
1035        } catch (SQLException e) {
1036            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1037            throw new ServiceAccessException(this, e);
1038        } finally {
1039            closeStatement(statement);
1040        }
1041    }
1042
1043    /**
1044     * Enumerate permissions on an object.
1045     *
1046     * @param permission Permission we want to create
1047     * @exception ServiceAccessException Error accessing the Service
1048     */

1049    public Enumeration JavaDoc enumeratePermissions(Uri uri)
1050        throws ServiceAccessException {
1051
1052        Vector JavaDoc permissionVector = new Vector JavaDoc();
1053        PreparedStatement statement = null;
1054
1055        try {
1056            statement =
1057                connection.prepareStatement(
1058                    "select * from permissions where object= ?");
1059            statement.setString(1, uri.toString());
1060            ResultSet res = statement.executeQuery();
1061
1062            while (res.next()) {
1063                String JavaDoc object = res.getString(PERMISSIONS_OBJECT);
1064                String JavaDoc revision = res.getString(PERMISSIONS_REVISION_NUMBER);
1065                String JavaDoc subject = res.getString(PERMISSIONS_SUBJECT);
1066                String JavaDoc action = res.getString(PERMISSIONS_ACTION);
1067
1068                boolean inheritable = false;
1069                if (res.getInt(PERMISSIONS_INHERITABLE) == 1) {
1070                    inheritable = true;
1071                }
1072                boolean negative = false;
1073                if (res.getInt(PERMISSIONS_NEGATIVE) == 1) {
1074                    negative = true;
1075                }
1076                NodePermission permission =
1077                    new NodePermission(
1078                        object,
1079                        revision,
1080                        subject,
1081                        action,
1082                        inheritable,
1083                        negative);
1084                permissionVector.addElement(permission);
1085            }
1086        } catch (SQLException e) {
1087            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1088            throw new ServiceAccessException(this, e);
1089        } finally {
1090            closeStatement(statement);
1091        }
1092
1093        return permissionVector.elements();
1094    }
1095
1096    /**
1097     * Create a new lock.
1098     *
1099     * @param lock Lock token
1100     * @exception ServiceAccessException Service access error
1101     */

1102    public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException {
1103
1104        PreparedStatement statement = null;
1105
1106        try {
1107            int inheritable = 0;
1108            if (lock.isInheritable()) {
1109                inheritable = 1;
1110            }
1111
1112            int exclusive = 0;
1113            if (lock.isExclusive()) {
1114                exclusive = 1;
1115            }
1116
1117            statement =
1118                connection.prepareStatement(
1119                    "insert into locks values(?,?,?,?,?,?,?)");
1120            statement.setString(1, lock.getLockId());
1121            statement.setString(2, lock.getObjectUri());
1122            statement.setString(3, lock.getSubjectUri());
1123            statement.setString(4, lock.getTypeUri());
1124            statement.setString(
1125                5,
1126                String.valueOf(lock.getExpirationDate().getTime()));
1127            statement.setInt(6, inheritable);
1128            statement.setInt(7, exclusive);
1129            statement.execute();
1130        } catch (SQLException e) {
1131            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1132            throw new ServiceAccessException(this, e);
1133        } finally {
1134            closeStatement(statement);
1135        }
1136
1137    }
1138
1139    /**
1140     * Renew a lock.
1141     *
1142     * @param lock Token to renew
1143     * @exception ServiceAccessException Service access error
1144     * @exception LockTokenNotFoundException Lock token was not found
1145     */

1146    public void renewLock(Uri uri, NodeLock lock)
1147        throws ServiceAccessException, LockTokenNotFoundException {
1148
1149        PreparedStatement statement = null;
1150
1151        try {
1152
1153            int inheritable = 0;
1154            if (lock.isInheritable()) {
1155                inheritable = 1;
1156            }
1157
1158            int exclusive = 0;
1159            if (lock.isExclusive()) {
1160                exclusive = 1;
1161            }
1162
1163            statement =
1164                connection.prepareStatement("delete from locks where id=?");
1165            statement.setString(1, lock.getLockId());
1166            statement.execute();
1167            closeStatement(statement);
1168
1169            statement =
1170                connection.prepareStatement(
1171                    "insert into locks values(?,?,?,?,?,?,?)");
1172            statement.setString(1, lock.getLockId());
1173            statement.setString(2, lock.getObjectUri());
1174            statement.setString(3, lock.getSubjectUri());
1175            statement.setString(4, lock.getTypeUri());
1176            statement.setString(
1177                5,
1178                String.valueOf(lock.getExpirationDate().getTime()));
1179            statement.setInt(6, inheritable);
1180            statement.setInt(7, exclusive);
1181            statement.execute();
1182
1183        } catch (SQLException e) {
1184            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1185            throw new ServiceAccessException(this, e);
1186        } finally {
1187            closeStatement(statement);
1188        }
1189    }
1190
1191    /**
1192     * Unlock.
1193     *
1194     * @param lock Token to remove
1195     * @exception ServiceAccessException Service access error
1196     * @exception LockTokenNotFoundException Lock token was not found
1197     */

1198    public void removeLock(Uri uri, NodeLock lock)
1199        throws ServiceAccessException, LockTokenNotFoundException {
1200
1201        Statement statement = null;
1202
1203        try {
1204
1205            statement = connection.createStatement();
1206
1207            int inheritable = 0;
1208            if (lock.isInheritable()) {
1209                inheritable = 1;
1210            }
1211
1212            String JavaDoc s = null;
1213
1214            s = "delete from locks where id='" + lock.getLockId() + "'";
1215            statement.execute(s);
1216
1217        } catch (SQLException e) {
1218            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1219            throw new ServiceAccessException(this, e);
1220        } finally {
1221            closeStatement(statement);
1222        }
1223    }
1224
1225    /**
1226     * Kill a lock.
1227     *
1228     * @param lock Token to remove
1229     * @exception ServiceAccessException Service access error
1230     * @exception LockTokenNotFoundException Lock token was not found
1231     */

1232    public void killLock(Uri uri, NodeLock lock)
1233        throws ServiceAccessException, LockTokenNotFoundException {
1234        removeLock(uri, lock);
1235    }
1236
1237    /**
1238     * Enumerate locks on an object.
1239     *
1240     * @param subject Subject
1241     * @return Enumeration List of locks which have been put on the subject
1242     * @exception ServiceAccessException Service access error
1243     */

1244    public Enumeration JavaDoc enumerateLocks(Uri uri) throws ServiceAccessException {
1245
1246        Vector JavaDoc lockVector = new Vector JavaDoc();
1247        PreparedStatement statement = null;
1248
1249        try {
1250            statement =
1251                connection.prepareStatement(
1252                    "select * from locks where object= ?");
1253            statement.setString(1, uri.toString());
1254            statement.execute();
1255            ResultSet res = statement.getResultSet();
1256
1257            while (res.next()) {
1258                Date JavaDoc expirationDate = null;
1259                try {
1260                    Long JavaDoc timeValue =
1261                        new Long JavaDoc(res.getString(LOCKS_EXPIRATIONDATE));
1262                    expirationDate = new Date JavaDoc(timeValue.longValue());
1263                } catch (NumberFormatException JavaDoc e) {
1264                    expirationDate = new Date JavaDoc();
1265                }
1266                NodeLock lock =
1267                    new NodeLock(
1268                        res.getString(LOCKS_ID),
1269                        res.getString(LOCKS_OBJECT),
1270                        res.getString(LOCKS_SUBJECT),
1271                        res.getString(LOCKS_TYPE),
1272                        expirationDate,
1273                        (res.getInt(LOCKS_INHERITABLE) == 1),
1274                        (res.getInt(LOCKS_EXCLUSIVE) == 1));
1275                lockVector.addElement(lock);
1276            }
1277        } catch (SQLException e) {
1278            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1279            throw new ServiceAccessException(this, e);
1280        } finally {
1281            closeStatement(statement);
1282        }
1283
1284        return lockVector.elements();
1285    }
1286
1287    /**
1288     * Retrieve the revisions informations of an object.
1289     *
1290     * @param uri Uri
1291     * @exception ServiceAccessException Service access error
1292     * @exception RevisionDescriptorNotFoundException Revision descriptor
1293     * was not found
1294     */

1295    public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
1296        throws ServiceAccessException, RevisionDescriptorNotFoundException {
1297
1298        NodeRevisionDescriptors revisionDescriptors = null;
1299        PreparedStatement statement = null;
1300        PreparedStatement statement2 = null;
1301
1302        try {
1303            ResultSet res = null;
1304
1305            NodeRevisionNumber initialRevision = new NodeRevisionNumber();
1306            Hashtable JavaDoc workingRevisions = new Hashtable JavaDoc();
1307            Hashtable JavaDoc latestRevisionNumbers = new Hashtable JavaDoc();
1308            Hashtable JavaDoc branches = new Hashtable JavaDoc();
1309            boolean isVersioned = false;
1310
1311            statement =
1312                connection.prepareStatement(
1313                    "select * from revisions where uri= ?");
1314            statement.setString(1, uri.toString());
1315            res = statement.executeQuery();
1316
1317            if (res.next()) {
1318                int isVersionedInt = res.getInt(REVISIONS_ISVERSIONED);
1319                if (isVersionedInt == 1) {
1320                    isVersioned = true;
1321                }
1322            } else {
1323                throw new RevisionDescriptorNotFoundException(uri.toString());
1324            }
1325
1326            closeStatement(statement);
1327
1328            statement =
1329                connection.prepareStatement(
1330                    "select * from workingrevision where uri= ?");
1331            statement.setString(1, uri.toString());
1332            res = statement.executeQuery();
1333
1334            while (res.next()) {
1335                // TODO : Parse each working revision definition
1336
}
1337
1338            closeStatement(statement);
1339
1340            statement =
1341                connection.prepareStatement(
1342                    "select * from latestrevisions where uri=?");
1343            statement.setString(1, uri.toString());
1344            res = statement.executeQuery();
1345
1346            while (res.next()) {
1347                latestRevisionNumbers.put(
1348                    res.getString(LATESTREVISIONS_BRANCHNAME),
1349                    new NodeRevisionNumber(
1350                        res.getString(LATESTREVISIONS_NUMBER)));
1351            }
1352            closeStatement(statement);
1353
1354            statement =
1355                connection.prepareStatement(
1356                    "select * from revision where uri= ?");
1357            statement.setString(1, uri.toString());
1358            res = statement.executeQuery();
1359
1360            while (res.next()) {
1361                String JavaDoc currentRevisionNumber = res.getString(REVISION_NUMBER);
1362
1363                // We parse the revision list of the object
1364
if (statement2 == null) {
1365                    statement2 =
1366                        connection.prepareStatement(
1367                            "select * from branches where uri = ? and xnumber = ?");
1368                }
1369                statement2.setString(1, uri.toString());
1370                statement2.setString(2, currentRevisionNumber);
1371                ResultSet res2 = statement2.executeQuery();
1372                Vector JavaDoc childList = new Vector JavaDoc();
1373
1374                while (res2.next()) {
1375                    childList.addElement(
1376                        new NodeRevisionNumber(
1377                            res2.getString(BRANCHES_CHILDNUMBER)));
1378                }
1379
1380                branches.put(
1381                    new NodeRevisionNumber(currentRevisionNumber),
1382                    childList);
1383
1384                res2.close();
1385            }
1386            closeStatement(statement2);
1387
1388            revisionDescriptors =
1389                new NodeRevisionDescriptors(
1390                    uri.toString(),
1391                    initialRevision,
1392                    workingRevisions,
1393                    latestRevisionNumbers,
1394                    branches,
1395                    isVersioned);
1396
1397        } catch (SQLException e) {
1398            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1399            throw new ServiceAccessException(this, e);
1400        } finally {
1401            closeStatement(statement);
1402            closeStatement(statement2);
1403        }
1404        return revisionDescriptors;
1405    }
1406
1407    /**
1408     * Create a new revision information object.
1409     *
1410     * @param uri Uri
1411     * @param revisionDescriptors Node revision descriptors
1412     * @exception ServiceAccessException Service access error
1413     */

1414    public void createRevisionDescriptors(
1415        Uri uri,
1416        NodeRevisionDescriptors revisionDescriptors)
1417        throws ServiceAccessException {
1418
1419        // TODO : Here, we have the option of "cleaning up" before
1420
// creating the new records in the database.
1421

1422        PreparedStatement statement = null;
1423
1424        try {
1425            ResultSet res = null;
1426
1427            // Creating record in revisions tables
1428

1429            int isVersioned = 0;
1430            if (revisionDescriptors.isVersioned()) {
1431                isVersioned = 1;
1432            }
1433
1434            statement =
1435                connection.prepareStatement(
1436                    "insert into revisions values(?,?,?)");
1437            statement.setString(1, uri.toString());
1438            statement.setInt(2, isVersioned);
1439            statement.setString(
1440                3,
1441                revisionDescriptors.getInitialRevision().toString());
1442            statement.execute();
1443            closeStatement(statement);
1444
1445            // Creating records in working revisions table
1446
// ... TODO (working revisions are not used for now)
1447

1448            // Creating records in latest revisions table
1449

1450            // For now, only the latest revision from the main branch is stored
1451
if (revisionDescriptors.getLatestRevision() != null) {
1452                statement =
1453                    connection.prepareStatement(
1454                        "insert into latestrevisions values(?,?,?)");
1455                statement.setString(1, uri.toString());
1456                statement.setString(
1457                    2,
1458                    NodeRevisionDescriptors.MAIN_BRANCH.toString());
1459                statement.setString(
1460                    3,
1461                    revisionDescriptors.getLatestRevision().toString());
1462                statement.execute();
1463                closeStatement(statement);
1464            }
1465
1466            // Creating records in the branches table
1467
// TODO
1468

1469        } catch (SQLException e) {
1470            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1471            throw new ServiceAccessException(this, e);
1472        } finally {
1473            closeStatement(statement);
1474        }
1475
1476    }
1477
1478    /**
1479     * Update revision information.
1480     *
1481     * @param uri Uri
1482     * @param revisionDescriptors Node revision descriptors
1483     * @exception ServiceAccessException Service access error
1484     * @exception RevisionDescriptorNotFoundException Revision descriptor
1485     * was not found
1486     */

1487    public void storeRevisionDescriptors(
1488        Uri uri,
1489        NodeRevisionDescriptors revisionDescriptors)
1490        throws ServiceAccessException, RevisionDescriptorNotFoundException {
1491        removeRevisionDescriptors(uri);
1492        createRevisionDescriptors(uri, revisionDescriptors);
1493    }
1494
1495    /**
1496     * Remove revision information.
1497     *
1498     * @param uri Uri
1499     * @exception ServiceAccessException Service access error
1500     */

1501    public void removeRevisionDescriptors(Uri uri)
1502        throws ServiceAccessException {
1503
1504        PreparedStatement statement = null;
1505
1506        try {
1507            statement =
1508                connection.prepareStatement(
1509                    "delete from revisions where uri= ?");
1510            statement.setString(1, uri.toString());
1511            statement.execute();
1512            closeStatement(statement);
1513
1514            statement =
1515                connection.prepareStatement(
1516                    "delete from workingrevision where uri= ?");
1517            statement.setString(1, uri.toString());
1518            statement.execute();
1519            closeStatement(statement);
1520
1521            statement =
1522                connection.prepareStatement(
1523                    "delete from latestrevisions where uri= ?");
1524            statement.setString(1, uri.toString());
1525            statement.execute();
1526            closeStatement(statement);
1527
1528            statement =
1529                connection.prepareStatement(
1530                    "delete from branches where uri= ?");
1531            statement.setString(1, uri.toString());
1532            statement.execute();
1533            closeStatement(statement);
1534        } catch (SQLException e) {
1535            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1536            throw new ServiceAccessException(this, e);
1537        } finally {
1538            closeStatement(statement);
1539        }
1540    }
1541
1542    /**
1543     * Retrieve an individual object's revision descriptor.
1544     *
1545     * @param Uri uri
1546     * @param revisionNumber Node revision number
1547     */

1548    public NodeRevisionDescriptor retrieveRevisionDescriptor(
1549        Uri uri,
1550        NodeRevisionNumber revisionNumber)
1551        throws ServiceAccessException, RevisionDescriptorNotFoundException {
1552
1553        NodeRevisionDescriptor revisionDescriptor = null;
1554        PreparedStatement statement = null;
1555
1556        if (revisionNumber == null) {
1557            throw new RevisionDescriptorNotFoundException(uri.toString());
1558        }
1559
1560        try {
1561            ResultSet res = null;
1562
1563            String JavaDoc branchName = null;
1564            Vector JavaDoc labels = new Vector JavaDoc();
1565            Hashtable JavaDoc properties = new Hashtable JavaDoc();
1566
1567            // Retrieving branch name (and also check that revision
1568
// does indeed exist)
1569

1570            statement =
1571                connection.prepareStatement(
1572                    "select * from revision where uri= ? and xnumber = ?");
1573            statement.setString(1, uri.toString());
1574            statement.setString(2, revisionNumber.toString());
1575            res = statement.executeQuery();
1576
1577            if (res.next()) {
1578                branchName = res.getString(REVISION_BRANCHNAME);
1579            } else {
1580                throw new RevisionDescriptorNotFoundException(uri.toString());
1581            }
1582
1583            closeStatement(statement);
1584
1585            // Retrieve labels
1586

1587            statement =
1588                connection.prepareStatement(
1589                    "select * from label where uri= ? and xnumber = ?");
1590            statement.setString(1, uri.toString());
1591            statement.setString(2, revisionNumber.toString());
1592            res = statement.executeQuery();
1593
1594            while (res.next()) {
1595                labels.addElement(res.getString(LABEL_LABEL));
1596            }
1597
1598            closeStatement(statement);
1599
1600            // Retrieve properties
1601

1602            statement =
1603                connection.prepareStatement(
1604                    "select * from property where uri= ? and xnumber = ?");
1605            statement.setString(1, uri.toString());
1606            statement.setString(2, revisionNumber.toString());
1607            res = statement.executeQuery();
1608
1609            while (res.next()) {
1610                String JavaDoc propertyName = res.getString(PROPERTY_NAME);
1611                String JavaDoc propertyNamespace = res.getString(PROPERTY_NAMESPACE);
1612                NodeProperty property =
1613                    new NodeProperty(
1614                        propertyName,
1615                        res.getString(PROPERTY_VALUE),
1616                        propertyNamespace,
1617                        res.getString(PROPERTY_TYPE),
1618                        (res.getInt(PROPERTY_PROTECTED) == 1));
1619                properties.put(propertyNamespace + propertyName, property);
1620            }
1621
1622            revisionDescriptor =
1623                new NodeRevisionDescriptor(
1624                    revisionNumber,
1625                    branchName,
1626                    labels,
1627                    properties);
1628        } catch (SQLException e) {
1629            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1630            throw new ServiceAccessException(this, e);
1631        } finally {
1632            closeStatement(statement);
1633        }
1634
1635        return revisionDescriptor;
1636    }
1637
1638    /**
1639     * Create a new revision descriptor.
1640     *
1641     * @param uri Uri
1642     * @param revisionDescriptor Node revision descriptor
1643     * @exception ServiceAccessException Service access error
1644     */

1645    public void createRevisionDescriptor(
1646        Uri uri,
1647        NodeRevisionDescriptor revisionDescriptor)
1648        throws ServiceAccessException {
1649
1650        PreparedStatement statement = null;
1651
1652        try {
1653
1654            ResultSet res = null;
1655
1656            statement =
1657                connection.prepareStatement(
1658                    "insert into revision values(?, ?, ?)");
1659            statement.setString(1, uri.toString());
1660            statement.setString(
1661                2,
1662                revisionDescriptor.getRevisionNumber().toString());
1663            statement.setString(3, revisionDescriptor.getBranchName());
1664            statement.execute();
1665            closeStatement(statement);
1666
1667            // Creating revision labels
1668
statement = null;
1669            Enumeration JavaDoc labels = revisionDescriptor.enumerateLabels();
1670            while (labels.hasMoreElements()) {
1671                if (statement == null) {
1672                    statement =
1673                        connection.prepareStatement(
1674                            "insert into label values(?,?,?)");
1675                }
1676                statement.setString(1, uri.toString());
1677                statement.setString(
1678                    2,
1679                    revisionDescriptor.getRevisionNumber().toString());
1680                statement.setString(3, (String JavaDoc) labels.nextElement());
1681                statement.execute();
1682            }
1683            closeStatement(statement);
1684
1685            // Creating associated properties
1686
statement = null;
1687            Enumeration JavaDoc properties = revisionDescriptor.enumerateProperties();
1688            while (properties.hasMoreElements()) {
1689                NodeProperty property = (NodeProperty) properties.nextElement();
1690                int protectedProperty = 0;
1691                if (property.isProtected()) {
1692                    protectedProperty = 1;
1693                }
1694                if (statement == null) {
1695                    statement =
1696                        connection.prepareStatement(
1697                            "insert into property values(?,?,?,?,?,?,?)");
1698                }
1699                statement.setString(1, uri.toString());
1700                statement.setString(
1701                    2,
1702                    revisionDescriptor.getRevisionNumber().toString());
1703                statement.setString(3, property.getName());
1704                statement.setString(4, property.getValue().toString());
1705                statement.setString(5, property.getNamespace());
1706                statement.setString(6, property.getType());
1707                statement.setInt(7, protectedProperty);
1708                statement.execute();
1709            }
1710            closeStatement(statement);
1711
1712        } catch (SQLException e) {
1713            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1714            throw new ServiceAccessException(this, e);
1715        } finally {
1716            closeStatement(statement);
1717        }
1718    }
1719
1720    /**
1721     * Update a revision descriptor.
1722     *
1723     * @param uri Uri
1724     * @param revisionDescriptors Node revision descriptor
1725     * @exception ServiceAccessException Service access error
1726     * @exception RevisionDescriptorNotFoundException Revision descriptor
1727     * was not found
1728     */

1729    public void storeRevisionDescriptor(
1730        Uri uri,
1731        NodeRevisionDescriptor revisionDescriptor)
1732        throws ServiceAccessException, RevisionDescriptorNotFoundException {
1733        removeRevisionDescriptor(uri, revisionDescriptor.getRevisionNumber());
1734        createRevisionDescriptor(uri, revisionDescriptor);
1735    }
1736
1737    /**
1738     * Remove a revision descriptor.
1739     *
1740     * @param uri Uri
1741     * @param revisionNumber Revision number
1742     * @exception ServiceAccessException Service access error
1743     */

1744    public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
1745        throws ServiceAccessException {
1746
1747        PreparedStatement statement = null;
1748
1749        try {
1750            statement =
1751                connection.prepareStatement(
1752                    "delete from revision where uri= ? and xnumber = ?");
1753            statement.setString(1, uri.toString());
1754            statement.setString(2, number.toString());
1755            statement.execute();
1756            closeStatement(statement);
1757
1758            // Removing revision labels
1759

1760            statement =
1761                connection.prepareStatement(
1762                    "delete from label where uri= ? and xnumber = ?");
1763            statement.setString(1, uri.toString());
1764            statement.setString(2, number.toString());
1765            statement.execute();
1766            closeStatement(statement);
1767
1768            // Removing associated properties
1769

1770            statement =
1771                connection.prepareStatement(
1772                    "delete from property where uri= ? and xnumber = ?");
1773            statement.setString(1, uri.toString());
1774            statement.setString(2, number.toString());
1775            statement.execute();
1776
1777        } catch (SQLException e) {
1778            getLogger().log(e, LOG_CHANNEL, Logger.ERROR);
1779            throw new ServiceAccessException(this, e);
1780        } finally {
1781            closeStatement(statement);
1782        }
1783
1784    }
1785
1786    // ------------------------------------------------------ Protected Methods
1787

1788    /**
1789     * Close specified statement.
1790     */

1791    protected void closeStatement(Statement statement) {
1792        if (statement != null) {
1793            try {
1794                statement.close();
1795            } catch (SQLException e) {
1796            }
1797        }
1798    }
1799}
1800
Popular Tags