View Javadoc

1   package org.modeshape.connector.svn;
2   
3   import java.util.LinkedList;
4   import org.modeshape.common.i18n.I18n;
5   import org.modeshape.graph.ExecutionContext;
6   import org.modeshape.graph.connector.base.PathNode;
7   import org.modeshape.graph.connector.base.PathTransaction;
8   import org.modeshape.graph.connector.base.Processor;
9   import org.modeshape.graph.connector.base.Repository;
10  import org.modeshape.graph.connector.base.Transaction;
11  import org.modeshape.graph.observe.Observer;
12  import org.modeshape.graph.property.Path;
13  import org.modeshape.graph.property.Property;
14  import org.modeshape.graph.property.Path.Segment;
15  import org.modeshape.graph.request.InvalidRequestException;
16  import org.modeshape.graph.request.InvalidWorkspaceException;
17  import org.modeshape.graph.request.MoveBranchRequest;
18  import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
19  import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
20  import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
21  import org.tmatesoft.svn.core.io.SVNRepository;
22  
23  public class SvnRepository extends Repository<PathNode, SvnWorkspace> {
24  
25      protected final SvnRepositorySource source;
26  
27      static {
28          // for DAV (over http and https)
29          DAVRepositoryFactory.setup();
30          // For File
31          FSRepositoryFactory.setup();
32          // for SVN (over svn and svn+ssh)
33          SVNRepositoryFactoryImpl.setup();
34      }
35  
36      public SvnRepository( SvnRepositorySource source ) {
37          super(source);
38  
39          this.source = source;
40          initialize();
41      }
42  
43      final SvnRepositorySource source() {
44          return this.source;
45      }
46  
47      @Override
48      public SvnTransaction startTransaction( ExecutionContext context,
49                                              boolean readonly ) {
50          return new SvnTransaction();
51      }
52  
53      /**
54       * Implementation of the {@link PathTransaction} interface for the Subversion connector
55       */
56      class SvnTransaction extends PathTransaction<PathNode, SvnWorkspace> {
57  
58          public SvnTransaction() {
59              super(SvnRepository.this, source.getRootNodeUuidObject());
60          }
61  
62          @Override
63          protected PathNode createNode( Segment name,
64                                         Path parentPath,
65                                         Iterable<Property> properties ) {
66              return new PathNode(null, parentPath, name, properties, new LinkedList<Segment>());
67          }
68  
69          @Override
70          public boolean destroyWorkspace( SvnWorkspace workspace ) throws InvalidWorkspaceException {
71              return true;
72          }
73  
74          @Override
75          public SvnWorkspace getWorkspace( String name,
76                                            SvnWorkspace originalToClone ) throws InvalidWorkspaceException {
77              SvnRepository repository = SvnRepository.this;
78  
79              if (originalToClone != null) {
80                  return new SvnWorkspace(name, originalToClone, repository.getWorkspaceDirectory(name));
81              }
82              return new SvnWorkspace(repository, getWorkspaceDirectory(name), name, source.getRootNodeUuidObject());
83          }
84  
85          @Override
86          protected void validateNode( SvnWorkspace workspace,
87                                       PathNode node ) {
88              workspace.validate(node);
89          }
90      }
91  
92      protected SVNRepository getWorkspaceDirectory( String workspaceName ) {
93          if (workspaceName == null) workspaceName = source().getDefaultWorkspaceName();
94  
95          if (source().getRepositoryRootUrl().endsWith("/")) {
96              workspaceName = source().getRepositoryRootUrl() + workspaceName;
97          } else {
98              workspaceName = source().getRepositoryRootUrl() + "/" + workspaceName;
99          }
100 
101         SVNRepository repository = null;
102         SVNRepository repos = SvnRepositoryUtil.createRepository(workspaceName, source().getUsername(), source().getPassword());
103         if (SvnRepositoryUtil.isDirectory(repos, "")) {
104             repository = repos;
105         } else {
106             return null;
107         }
108         return repository;
109     }
110 
111     /**
112      * Custom {@link Processor} for the file system connector. This processor throws accurate exceptions on attempts to reorder
113      * nodes, since the file system connector does not support node ordering. Otherwise, it provides default behavior.
114      */
115     class SvnProcessor extends Processor<PathNode, SvnWorkspace> {
116 
117         public SvnProcessor( Transaction<PathNode, SvnWorkspace> txn,
118                              Repository<PathNode, SvnWorkspace> repository,
119                              Observer observer,
120                              boolean updatesAllowed ) {
121             super(txn, repository, observer, updatesAllowed);
122         }
123 
124         @Override
125         public void process( MoveBranchRequest request ) {
126             if (request.before() != null) {
127                 I18n msg = SvnRepositoryConnectorI18n.nodeOrderingNotSupported;
128                 throw new InvalidRequestException(msg.text(source.getName()));
129             }
130             super.process(request);
131         }
132 
133         /**
134          * {@inheritDoc}
135          * 
136          * @see org.modeshape.graph.request.processor.RequestProcessor#absoluteMaximumDepthForBranchReads()
137          */
138         @Override
139         protected int absoluteMaximumDepthForBranchReads() {
140             // never read more than one level from SVN, as the file content can get too big and the costs too expensive ...
141             return 1;
142         }
143     }
144 
145 }