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.base;
25  
26  import java.util.LinkedList;
27  import java.util.List;
28  import java.util.Set;
29  import java.util.UUID;
30  import net.jcip.annotations.NotThreadSafe;
31  import org.modeshape.graph.ExecutionContext;
32  import org.modeshape.graph.GraphI18n;
33  import org.modeshape.graph.Location;
34  import org.modeshape.graph.connector.LockFailedException;
35  import org.modeshape.graph.property.Name;
36  import org.modeshape.graph.property.NameFactory;
37  import org.modeshape.graph.property.Path;
38  import org.modeshape.graph.property.PathFactory;
39  import org.modeshape.graph.property.PathNotFoundException;
40  import org.modeshape.graph.property.PropertyFactory;
41  import org.modeshape.graph.property.ValueFactories;
42  import org.modeshape.graph.request.LockBranchRequest.LockScope;
43  
44  /**
45   * @param <NodeType> the type of node
46   * @param <WorkspaceType> the type of workspace
47   */
48  @NotThreadSafe
49  public abstract class BaseTransaction<NodeType extends Node, WorkspaceType extends Workspace>
50      implements Transaction<NodeType, WorkspaceType> {
51  
52      protected final UUID rootNodeUuid;
53      protected final ExecutionContext context;
54      protected final PathFactory pathFactory;
55      protected final NameFactory nameFactory;
56      protected final PropertyFactory propertyFactory;
57      protected final ValueFactories valueFactories;
58      protected final Location rootLocation;
59  
60      /** The repository against which this transaction is operating */
61      private final Repository<NodeType, WorkspaceType> repository;
62  
63      protected BaseTransaction( ExecutionContext context,
64                                 Repository<NodeType, WorkspaceType> repository,
65                                 UUID rootNodeUuid ) {
66          this.rootNodeUuid = rootNodeUuid;
67          this.context = context;
68          this.propertyFactory = context.getPropertyFactory();
69          this.valueFactories = context.getValueFactories();
70          this.pathFactory = valueFactories.getPathFactory();
71          this.nameFactory = valueFactories.getNameFactory();
72          this.repository = repository;
73          this.rootLocation = Location.create(rootNodeUuid);
74      }
75  
76      protected String readable( Object obj ) {
77          return valueFactories.getStringFactory().create(obj);
78      }
79  
80      /**
81       * {@inheritDoc}
82       * 
83       * @see org.modeshape.graph.connector.base.Transaction#getContext()
84       */
85      public ExecutionContext getContext() {
86          return context;
87      }
88  
89      /**
90       * Obtain the repository object against which this transaction is running.
91       * 
92       * @return the repository object; never null
93       */
94      protected Repository<NodeType, WorkspaceType> getRepository() {
95          return repository;
96      }
97  
98      /**
99       * {@inheritDoc}
100      * 
101      * @see org.modeshape.graph.connector.base.Transaction#getWorkspaceNames()
102      */
103     public Set<String> getWorkspaceNames() {
104         return repository.getWorkspaceNames();
105     }
106 
107     /**
108      * {@inheritDoc}
109      * 
110      * @see org.modeshape.graph.connector.base.Transaction#getRootNode(org.modeshape.graph.connector.base.Workspace)
111      */
112     public NodeType getRootNode( WorkspaceType workspace ) {
113         return getNode(workspace, rootLocation);
114     }
115 
116     protected NodeType getNode( WorkspaceType workspace,
117                                 Path path,
118                                 Location location ) {
119         NodeType node = getRootNode(workspace);
120         for (Path.Segment segment : path) {
121             NodeType child = getChild(workspace, node, segment);
122             if (child == null) {
123                 List<Path.Segment> segments = new LinkedList<Path.Segment>();
124                 for (Path.Segment seg : path) {
125                     if (seg != segment) segments.add(seg);
126                     else break;
127                 }
128                 Path lowestExisting = pathFactory.createAbsolutePath(segments);
129                 throw new PathNotFoundException(location, lowestExisting, GraphI18n.nodeDoesNotExist.text(path));
130             }
131             node = child;
132         }
133         return node;
134     }
135 
136     /**
137      * {@inheritDoc}
138      * 
139      * @see org.modeshape.graph.connector.base.Transaction#pathFor(org.modeshape.graph.connector.base.Workspace,
140      *      org.modeshape.graph.connector.base.Node)
141      */
142     public Path pathFor( WorkspaceType workspace,
143                          NodeType node ) {
144         assert node != null;
145         assert pathFactory != null;
146 
147         LinkedList<Path.Segment> segments = new LinkedList<Path.Segment>();
148         do {
149             segments.addFirst(node.getName());
150             node = getParent(workspace, node);
151         } while (node != null);
152         segments.removeFirst(); // remove the root name, which is meaningless
153 
154         return pathFactory.createAbsolutePath(segments);
155     }
156 
157     /**
158      * {@inheritDoc}
159      * <p>
160      * This method is implemented by iterating through the children, looking for the first child that has a matching name.
161      * Obviously this may be implemented more efficiently in certain systems. For example, an implementation might create a path
162      * by appending the child name to the supplied parent, and find the node with this path.
163      * </p>
164      * 
165      * @see org.modeshape.graph.connector.base.Transaction#getFirstChild(org.modeshape.graph.connector.base.Workspace,
166      *      org.modeshape.graph.connector.base.Node, org.modeshape.graph.property.Name)
167      */
168     public NodeType getFirstChild( WorkspaceType workspace,
169                                    NodeType parent,
170                                    Name childName ) {
171         for (NodeType child : getChildren(workspace, parent)) {
172             if (child.getName().getName().equals(childName)) return child;
173         }
174         return null;
175     }
176 
177     /**
178      * {@inheritDoc}
179      * 
180      * @see org.modeshape.graph.connector.base.Transaction#lockNode(org.modeshape.graph.connector.base.Workspace,
181      *      org.modeshape.graph.connector.base.Node, org.modeshape.graph.request.LockBranchRequest.LockScope, long)
182      */
183     public void lockNode( WorkspaceType workspace,
184                           NodeType node,
185                           LockScope lockScope,
186                           long lockTimeoutInMillis ) throws LockFailedException {
187         // do nothing by default
188     }
189 
190     /**
191      * {@inheritDoc}
192      * 
193      * @see org.modeshape.graph.connector.base.Transaction#unlockNode(org.modeshape.graph.connector.base.Workspace,
194      *      org.modeshape.graph.connector.base.Node)
195      */
196     public void unlockNode( WorkspaceType workspace,
197                             NodeType node ) {
198         // do nothing by default
199     }
200 
201     /**
202      * {@inheritDoc}
203      * 
204      * @see org.modeshape.graph.connector.base.Transaction#commit()
205      */
206     public void commit() {
207     }
208 
209     /**
210      * {@inheritDoc}
211      * 
212      * @see org.modeshape.graph.connector.base.Transaction#rollback()
213      */
214     public void rollback() {
215     }
216 }