KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > repository > serverimpl > LocalCollectionStrategy


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.repository.serverimpl;
17
18 import org.outerj.daisy.repository.commonimpl.CollectionStrategy;
19 import org.outerj.daisy.repository.commonimpl.AuthenticatedUser;
20 import org.outerj.daisy.repository.commonimpl.DocumentCollectionImpl;
21 import org.outerj.daisy.repository.RepositoryException;
22 import org.outerj.daisy.repository.RepositoryEventType;
23 import org.outerj.daisy.repository.CollectionNotFoundException;
24 import org.outerj.daisy.jdbcutil.JdbcHelper;
25 import org.apache.xmlbeans.XmlObject;
26 import org.outerx.daisy.x10.CollectionCreatedDocument;
27 import org.outerx.daisy.x10.CollectionDocument;
28 import org.outerx.daisy.x10.CollectionUpdatedDocument;
29 import org.outerx.daisy.x10.CollectionDeletedDocument;
30
31 import java.sql.*;
32 import java.util.Date JavaDoc;
33 import java.util.Collection JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.GregorianCalendar JavaDoc;
36
37 public class LocalCollectionStrategy extends AbstractLocalStrategy implements CollectionStrategy {
38     private static final String JavaDoc STMT_SELECT_ALL_FROM_COLLECTIONS = "select id, \"name\", last_modified, last_modifier, updatecount from collections";
39
40     public LocalCollectionStrategy(LocalRepositoryManager.Context context, AuthenticatedUser systemUser, JdbcHelper jdbcHelper) {
41         super(context, systemUser, jdbcHelper);
42     }
43
44     public void store(DocumentCollectionImpl collection) throws RepositoryException {
45         logger.debug("begin storage of collection");
46         DocumentCollectionImpl.IntimateAccess collectionInt = collection.getIntimateAccess(this);
47
48         if (!collectionInt.getCurrentUser().isInAdministratorRole())
49             throw new RepositoryException("Only Administrators can create or update collections.");
50         long id = collection.getId();
51         boolean isNew = (id == -1);
52
53         Connection conn = null;
54         PreparedStatement stmt = null;
55         try {
56             conn = context.getDataSource().getConnection();
57             jdbcHelper.startTransaction(conn);
58
59             logger.debug("connection fetched");
60             String JavaDoc collectionName = collection.getName();
61             java.util.Date JavaDoc lastModified = new Date JavaDoc();
62             logger.debug("currently in object: id "+id+" colname: "
63                     +collectionName+" lastMod: "+lastModified);
64             /* The user that requested the Collection is now persisting it,
65              * therefore he will be the last modifier
66              */

67             long lastModifier = collectionInt.getCurrentUser().getId();
68             XmlObject eventDescription;
69
70             if (id == -1) {
71                 //a new collection must be stored in the data store
72
stmt = conn.prepareStatement("insert into collections(id, \"name\", last_modified, last_modifier, updatecount) values (?,?,?,?,?)");
73                 id = context.getNextCollectionId();
74                 stmt.setLong(1, id);
75                 stmt.setString(2, collectionName);
76                 stmt.setTimestamp(3, new Timestamp(lastModified.getTime()));
77                 stmt.setLong(4, lastModifier);
78                 stmt.setLong(5, 1L);
79                 stmt.execute();
80                 stmt.close();
81
82                 eventDescription = createCollectionCreatedEvent(collection, id, lastModified);
83             } else {
84                 //we have to update an existing collection
85

86                 // check if nobody else changed it in the meantime
87
stmt = conn.prepareStatement("select updatecount from collections where id = ? " + jdbcHelper.getSharedLockClause());
88                 stmt.setLong(1, id);
89                 ResultSet rs = stmt.executeQuery();
90                 if (!rs.next()) {
91                     throw new RepositoryException("Unexpected error: the Collection with id " + id + " does not exist in the database.");
92                 } else {
93                     long dbUpdateCount = rs.getLong(1);
94                     if (dbUpdateCount != collection.getUpdateCount())
95                         throw new RepositoryException("The Collection was concurrently changed by someone else.");
96                 }
97                 stmt.close();
98
99                 DocumentCollectionImpl oldCollection = loadCollectionInt(collection.getId(), collectionInt.getCurrentUser(), conn);
100
101                 stmt = conn.prepareStatement("update collections set \"name\"=?, last_modified=?, last_modifier=?, updatecount=? where id=?");
102                 stmt.setString(1, collectionName);
103                 stmt.setTimestamp(2, new Timestamp(lastModified.getTime()));
104                 stmt.setLong(3, lastModifier);
105                 stmt.setLong(4, collection.getUpdateCount() + 1);
106                 stmt.setLong(5, id);
107                 stmt.execute();
108                 stmt.close();
109
110                 eventDescription = createCollectionUpdatedEvent(oldCollection, collection, lastModified, collection.getUpdateCount() + 1);
111             }
112
113             eventHelper.createEvent(eventDescription, isNew ? "CollectionCreated" : "CollectionUpdated", conn);
114
115             //everything went ok, so we can actively update the collection OBJECT as well.
116
collectionInt.saved(id, collectionName, lastModified, lastModifier, collection.getUpdateCount() + 1);
117             conn.commit();
118         } catch (Throwable JavaDoc e) {
119             jdbcHelper.rollback(conn);
120             throw new RepositoryException("Error storing collection.", e);
121         } finally {
122             jdbcHelper.closeStatement(stmt);
123             jdbcHelper.closeConnection(conn);
124             logger.debug("collection storage complete");
125         }
126
127         if (isNew)
128             context.getCommonRepository().fireRepositoryEvent(RepositoryEventType.COLLECTION_CREATED, id, collection.getUpdateCount());
129         else
130             context.getCommonRepository().fireRepositoryEvent(RepositoryEventType.COLLECTION_UPDATED, id, collection.getUpdateCount());
131     }
132
133     public DocumentCollectionImpl loadCollection(long collectionId, AuthenticatedUser user) throws RepositoryException {
134         Connection conn = null;
135         try {
136             conn = context.getDataSource().getConnection();
137             jdbcHelper.startTransaction(conn);
138             return loadCollectionInt(collectionId, user, conn);
139         } catch (Throwable JavaDoc e) {
140             throw new RepositoryException("Error loading collection.", e);
141         } finally {
142             jdbcHelper.closeConnection(conn);
143         }
144     }
145
146     private DocumentCollectionImpl loadCollectionInt(long collectionId, AuthenticatedUser user, Connection conn) throws RepositoryException {
147         PreparedStatement stmt = null;
148         try {
149             logger.debug("begin fetching collection with collectionId "+collectionId);
150             stmt = conn.prepareStatement("select id, \"name\", last_modified, last_modifier, updatecount from collections where id = ? ");
151             stmt.setLong(1, collectionId);
152             ResultSet rs = stmt.executeQuery();
153             if (!rs.next())
154                 throw new CollectionNotFoundException(collectionId);
155
156             DocumentCollectionImpl collection = null;
157
158             String JavaDoc name = rs.getString(2);
159             Date JavaDoc lastModified = rs.getTimestamp(3);
160             long lastModifier = rs.getLong(4);
161             long updateCount = rs.getLong(5);
162
163             collection = new DocumentCollectionImpl(this, name, user);
164             DocumentCollectionImpl.IntimateAccess collectionInt = collection.getIntimateAccess(this);
165             collectionInt.saved(collectionId, name, lastModified, lastModifier, updateCount);
166             return collection;
167         } catch (Throwable JavaDoc e) {
168             throw new RepositoryException("Error loading collection.", e);
169         } finally {
170             jdbcHelper.closeStatement(stmt);
171             logger.debug("collection load completed");
172         }
173     }
174
175     public DocumentCollectionImpl loadCollectionByName(String JavaDoc name, AuthenticatedUser user) throws RepositoryException {
176         Connection conn = null;
177         PreparedStatement stmt = null;
178         long id;
179         try {
180             conn = context.getDataSource().getConnection();
181             jdbcHelper.startTransaction(conn);
182
183             stmt = conn.prepareStatement("select id from collections where \"name\" = ?");
184             stmt.setString(1, name);
185             ResultSet rs = stmt.executeQuery();
186             if (!rs.next())
187                 throw new CollectionNotFoundException(name);
188
189             id = rs.getLong(1);
190             stmt.close();
191
192             return loadCollectionInt(id, user, conn);
193         } catch (Throwable JavaDoc e) {
194             throw new RepositoryException("Error loading collection.", e);
195         } finally {
196             jdbcHelper.closeStatement(stmt);
197             jdbcHelper.closeConnection(conn);
198         }
199     }
200
201     public Collection JavaDoc loadCollections(AuthenticatedUser user) throws RepositoryException {
202         PreparedStatement stmt = null;
203         Connection conn = null;
204
205         try {
206             conn = context.getDataSource().getConnection();
207             jdbcHelper.startTransaction(conn);
208
209             stmt = conn.prepareStatement(STMT_SELECT_ALL_FROM_COLLECTIONS);
210             ResultSet rs = stmt.executeQuery();
211
212             ArrayList JavaDoc list = new ArrayList JavaDoc();
213             while (rs.next()) {
214                 DocumentCollectionImpl coll = getDocumentCollectionImpl(user, rs);
215                 list.add(coll);
216             }
217
218             return list;
219         } catch (Throwable JavaDoc e) {
220             throw new RepositoryException("Error loading collections.", e);
221         } finally {
222             jdbcHelper.closeStatement(stmt);
223             jdbcHelper.closeConnection(conn);
224         }
225     }
226
227     /**
228      * Note that this method does NOT call next() on the ResultSet.
229      *
230      * @param user the user requesting the DocumentCollection
231      * @param rs the resultset that has been created for the collections table
232      * @return a DocumentCollectionImpl with the values obtained from the ResultSet
233      * @throws java.sql.SQLException
234      */

235     private DocumentCollectionImpl getDocumentCollectionImpl(AuthenticatedUser user, ResultSet rs) throws SQLException {
236         DocumentCollectionImpl collection = null;
237
238         long id = rs.getLong(1);
239         String JavaDoc name = rs.getString(2);
240         Date JavaDoc lastModified = rs.getTimestamp(3);
241         long lastModifier = rs.getLong(4);
242         long updateCount = rs.getLong(5);
243
244         collection = new DocumentCollectionImpl(this, name, user);
245         DocumentCollectionImpl.IntimateAccess collectionInt = collection.getIntimateAccess(this);
246         collectionInt.saved(id, name, lastModified, lastModifier, updateCount);
247         return collection;
248     }
249
250     public void deleteCollection(long collectionId, AuthenticatedUser user) throws RepositoryException {
251         logger.debug("begin deletion of collection");
252
253         if (!user.isInAdministratorRole())
254             throw new RepositoryException("Only Administrators can delete collections.");
255
256         Connection conn = null;
257         PreparedStatement stmt = null;
258         try {
259             conn = context.getDataSource().getConnection();
260             // we'll need a transaction here...
261
jdbcHelper.startTransaction(conn);
262
263             // retrieve collection, needed for collection deleted event
264
DocumentCollectionImpl collection = loadCollectionInt(collectionId, user, conn);
265
266             logger.debug("start by removing all the child records");
267
268             stmt = conn.prepareStatement("delete from document_collections where collection_id=?");
269             stmt.setLong(1, collectionId);
270
271             // remark that it IS possible that no records are affected, in case the collection
272
// has been defined but a document never was added to the collection
273
stmt.executeUpdate();
274             stmt.close();
275
276             // if the previous action went ok, we can delete the collection itself
277

278             stmt = conn.prepareStatement("delete from collections where id=?");
279             stmt.setLong(1, collectionId);
280             int amountOfRecordsModified = stmt.executeUpdate();
281             stmt.close();
282
283             if (amountOfRecordsModified == 0)
284                 throw new RepositoryException("This collection was not found in the repository!");
285
286             XmlObject eventDescription = createCollectionDeletedEvent(collection);
287             eventHelper.createEvent(eventDescription, "CollectionDeleted", conn);
288
289             conn.commit();
290
291             context.getCommonRepository().fireRepositoryEvent(RepositoryEventType.COLLECTION_DELETED, collectionId, -1);
292
293         } catch (Throwable JavaDoc e) {
294             jdbcHelper.rollback(conn);
295             throw new RepositoryException("Error deleting collection.", e);
296         } finally {
297             jdbcHelper.closeStatement(stmt);
298             jdbcHelper.closeConnection(conn);
299             logger.debug("collection deletion complete");
300         }
301     }
302
303     private CollectionCreatedDocument createCollectionCreatedEvent(DocumentCollectionImpl collection, long collectionId, Date JavaDoc lastModified) {
304         CollectionDocument.Collection collectionXml = collection.getXml().getCollection();
305         collectionXml.setId(collectionId);
306         collectionXml.setLastModified(getCalendar(lastModified));
307         collectionXml.setLastModifier(collection.getIntimateAccess(this).getCurrentUser().getId());
308         collectionXml.setUpdatecount(1);
309
310         CollectionCreatedDocument collectionCreatedDocument = CollectionCreatedDocument.Factory.newInstance();
311         collectionCreatedDocument.addNewCollectionCreated().addNewNewCollection().setCollection(collectionXml);
312
313         return collectionCreatedDocument;
314     }
315
316     private CollectionUpdatedDocument createCollectionUpdatedEvent(DocumentCollectionImpl oldCollection, DocumentCollectionImpl newCollection, Date JavaDoc lastModified, long newUpdateCount) {
317         CollectionUpdatedDocument collectionUpdatedDocument = CollectionUpdatedDocument.Factory.newInstance();
318         CollectionUpdatedDocument.CollectionUpdated collectionUpdated = collectionUpdatedDocument.addNewCollectionUpdated();
319
320         collectionUpdated.addNewOldCollection().setCollection(oldCollection.getXml().getCollection());
321
322         CollectionDocument.Collection newCollectionXml = newCollection.getXml().getCollection();
323         newCollectionXml.setLastModifier(newCollection.getIntimateAccess(this).getCurrentUser().getId());
324         newCollectionXml.setLastModified(getCalendar(lastModified));
325         newCollectionXml.setUpdatecount(newUpdateCount);
326
327         collectionUpdated.addNewNewCollection().setCollection(newCollectionXml);
328
329         return collectionUpdatedDocument;
330     }
331
332     private CollectionDeletedDocument createCollectionDeletedEvent(DocumentCollectionImpl collection) {
333         CollectionDeletedDocument collectionDeletedDocument = CollectionDeletedDocument.Factory.newInstance();
334         CollectionDeletedDocument.CollectionDeleted collectionDeleted = collectionDeletedDocument.addNewCollectionDeleted();
335         collectionDeleted.addNewDeletedCollection().setCollection(collection.getXml().getCollection());
336         collectionDeleted.setDeletedTime(new GregorianCalendar JavaDoc());
337         collectionDeleted.setDeleterId(collection.getIntimateAccess(this).getCurrentUser().getId());
338         return collectionDeletedDocument;
339     }
340 }
341
Popular Tags