View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
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    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
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   * ModeShape 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.graph.connector.map;
25  
26  import java.util.concurrent.TimeUnit;
27  import javax.transaction.xa.XAResource;
28  import org.modeshape.common.statistic.Stopwatch;
29  import org.modeshape.common.util.Logger;
30  import org.modeshape.graph.ExecutionContext;
31  import org.modeshape.graph.cache.CachePolicy;
32  import org.modeshape.graph.connector.RepositoryConnection;
33  import org.modeshape.graph.connector.RepositoryContext;
34  import org.modeshape.graph.connector.RepositorySourceException;
35  import org.modeshape.graph.observe.Observer;
36  import org.modeshape.graph.request.Request;
37  import org.modeshape.graph.request.processor.RequestProcessor;
38  
39  /**
40   * A connection to a {@link MapRepository}.
41   */
42  public class MapRepositoryConnection implements RepositoryConnection {
43      private final MapRepositorySource source;
44      private final MapRepository repository;
45  
46      public MapRepositoryConnection( MapRepositorySource source,
47                                      MapRepository repository ) {
48          assert source != null;
49          assert repository != null;
50          this.source = source;
51          this.repository = repository;
52      }
53  
54      /**
55       * {@inheritDoc}
56       */
57      public String getSourceName() {
58          return source.getName();
59      }
60  
61      /**
62       * {@inheritDoc}
63       */
64      public CachePolicy getDefaultCachePolicy() {
65          return source.getDefaultCachePolicy();
66      }
67  
68      /**
69       * {@inheritDoc}
70       */
71      public XAResource getXAResource() {
72          return null;
73      }
74  
75      /**
76       * {@inheritDoc}
77       */
78      public boolean ping( long time,
79                           TimeUnit unit ) {
80          return true;
81      }
82  
83      /**
84       * {@inheritDoc}
85       */
86      public void close() {
87          // do nothing
88      }
89  
90      /**
91       * {@inheritDoc}
92       * 
93       * @see org.modeshape.graph.connector.RepositoryConnection#execute(org.modeshape.graph.ExecutionContext,
94       *      org.modeshape.graph.request.Request)
95       */
96      public void execute( ExecutionContext context,
97                           Request request ) throws RepositorySourceException {
98          Logger logger = context.getLogger(getClass());
99          Stopwatch sw = null;
100         if (logger.isTraceEnabled()) {
101             sw = new Stopwatch();
102             sw.start();
103         }
104         // Do any commands update/write?
105         RepositoryContext repositoryContext = this.source.getRepositoryContext();
106         Observer observer = repositoryContext != null ? repositoryContext.getObserver() : null;
107         RequestProcessor processor = new MapRequestProcessor(context, this.repository, observer, source.areUpdatesAllowed());
108 
109         boolean commit = true;
110         MapRepositoryTransaction txn = repository.startTransaction(request.isReadOnly());
111         try {
112             // Obtain the lock and execute the commands ...
113             processor.process(request);
114             if (request.hasError() && !request.isReadOnly()) {
115                 // The changes failed, so we need to rollback so we have 'all-or-nothing' behavior
116                 commit = false;
117             }
118         } catch (Throwable error) {
119             commit = false;
120         } finally {
121             try {
122                 processor.close();
123             } finally {
124                 // Now commit or rollback ...
125                 try {
126                     if (commit) {
127                         txn.commit();
128                     } else {
129                         // Need to rollback the changes made to the repository ...
130                         txn.rollback();
131                     }
132                 } catch (Throwable commitOrRollbackError) {
133                     if (commit && !request.hasError() && !request.isFrozen()) {
134                         // Record the error on the request ...
135                         request.setError(commitOrRollbackError);
136                     }
137                     commit = false; // couldn't do it
138                 }
139                 if (commit) {
140                     // Now that we've closed our transaction, we can notify the observer of the committed changes ...
141                     processor.notifyObserverOfChanges();
142                 }
143             }
144         }
145         if (logger.isTraceEnabled()) {
146             assert sw != null;
147             sw.stop();
148             logger.trace("MapRepositoryConnection.execute(...) took " + sw.getTotalDuration());
149         }
150     }
151 
152     /**
153      * {@inheritDoc}
154      * 
155      * @see java.lang.Object#toString()
156      */
157     @Override
158     public String toString() {
159         return "Connection to the \"" + getSourceName() + "\" " + repository.getClass().getSimpleName();
160     }
161 }