View Javadoc

1   /*
2    * JBoss DNA (http://www.jboss.org/dna)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * JBoss DNA is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.connector.jcr;
25  
26  import java.util.concurrent.TimeUnit;
27  import javax.jcr.Credentials;
28  import javax.jcr.Repository;
29  import javax.transaction.xa.XAResource;
30  import org.modeshape.common.statistic.Stopwatch;
31  import org.modeshape.common.util.Logger;
32  import org.modeshape.graph.ExecutionContext;
33  import org.modeshape.graph.cache.CachePolicy;
34  import org.modeshape.graph.connector.RepositoryConnection;
35  import org.modeshape.graph.connector.RepositoryContext;
36  import org.modeshape.graph.connector.RepositorySourceException;
37  import org.modeshape.graph.observe.Observer;
38  import org.modeshape.graph.request.Request;
39  
40  /**
41   * 
42   */
43  public class JcrRepositoryConnection implements RepositoryConnection {
44  
45      private final JcrRepositorySource source;
46      private final Repository repository;
47      private final Credentials credentials;
48  
49      public JcrRepositoryConnection( JcrRepositorySource source,
50                                      Repository repository,
51                                      Credentials credentials ) {
52          assert source != null;
53          assert repository != null;
54          this.source = source;
55          this.repository = repository;
56          this.credentials = credentials;
57      }
58  
59      /**
60       * {@inheritDoc}
61       */
62      public String getSourceName() {
63          return source.getName();
64      }
65  
66      /**
67       * {@inheritDoc}
68       */
69      public CachePolicy getDefaultCachePolicy() {
70          return source.getDefaultCachePolicy();
71      }
72  
73      /**
74       * {@inheritDoc}
75       */
76      public XAResource getXAResource() {
77          return null;
78      }
79  
80      /**
81       * {@inheritDoc}
82       */
83      public boolean ping( long time,
84                           TimeUnit unit ) {
85          return true;
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      public void close() {
92          // do nothing
93      }
94  
95      /**
96       * {@inheritDoc}
97       * 
98       * @see org.modeshape.graph.connector.RepositoryConnection#execute(org.modeshape.graph.ExecutionContext,
99       *      org.modeshape.graph.request.Request)
100      */
101     public void execute( final ExecutionContext context,
102                          Request request ) throws RepositorySourceException {
103         Logger logger = context.getLogger(getClass());
104         Stopwatch sw = null;
105         if (logger.isTraceEnabled()) {
106             sw = new Stopwatch();
107             sw.start();
108         }
109 
110         // Do any commands update/write?
111         RepositoryContext repositoryContext = source.getRepositoryContext();
112         Observer observer = repositoryContext != null ? repositoryContext.getObserver() : null;
113         JcrRequestProcessor processor = new JcrRequestProcessor(source.getName(), context, repository, observer, credentials,
114                                                                 source.getDefaultCachePolicy());
115 
116         boolean commit = true;
117         try {
118             // Obtain the lock and execute the commands ...
119             processor.process(request);
120             if (request.hasError() && !request.isReadOnly()) {
121                 // The changes failed, so we need to rollback so we have 'all-or-nothing' behavior
122                 commit = false;
123             }
124         } catch (Throwable error) {
125             commit = false;
126         } finally {
127             try {
128                 if (commit) {
129                     processor.commit();
130                 } else {
131                     // Need to rollback the changes made to the repository ...
132                     processor.rollback();
133                 }
134             } catch (Throwable commitOrRollbackError) {
135                 if (commit && !request.hasError() && !request.isFrozen()) {
136                     // Record the error on the request ...
137                     request.setError(commitOrRollbackError);
138                 }
139                 commit = false; // couldn't do it
140             } finally {
141                 try {
142                     // Release any resources ...
143                     processor.close();
144                 } finally {
145                     if (commit) {
146                         // Now that we've closed our transaction, we can notify the observer of the committed changes ...
147                         processor.notifyObserverOfChanges();
148                     }
149                 }
150             }
151         }
152         if (logger.isTraceEnabled()) {
153             assert sw != null;
154             sw.stop();
155             logger.trace("JcrRepositoryConnection.execute(...) took " + sw.getTotalDuration());
156         }
157     }
158 
159     /**
160      * {@inheritDoc}
161      * 
162      * @see java.lang.Object#toString()
163      */
164     @Override
165     public String toString() {
166         return "Connection to the \"" + getSourceName() + "\" " + repository.getClass().getSimpleName();
167     }
168 
169 }