001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.connector.svn;
025
026 import java.util.concurrent.TimeUnit;
027 import javax.transaction.xa.XAResource;
028 import org.jboss.dna.common.util.CheckArg;
029 import org.jboss.dna.graph.ExecutionContext;
030 import org.jboss.dna.graph.cache.CachePolicy;
031 import org.jboss.dna.graph.connector.RepositoryConnection;
032 import org.jboss.dna.graph.connector.RepositorySourceException;
033 import org.jboss.dna.graph.connector.RepositorySourceListener;
034 import org.jboss.dna.graph.property.PathFactory;
035 import org.jboss.dna.graph.property.PropertyFactory;
036 import org.jboss.dna.graph.request.Request;
037 import org.jboss.dna.graph.request.processor.RequestProcessor;
038 import org.tmatesoft.svn.core.SVNErrorCode;
039 import org.tmatesoft.svn.core.SVNErrorMessage;
040 import org.tmatesoft.svn.core.SVNException;
041 import org.tmatesoft.svn.core.SVNNodeKind;
042 import org.tmatesoft.svn.core.io.SVNRepository;
043
044 /**
045 * The repository connection to a SVN Repository instance.
046 *
047 * @author Serge Pagop
048 */
049 public class SVNRepositoryConnection implements RepositoryConnection {
050
051 protected static final RepositorySourceListener NO_OP_LISTENER = new RepositorySourceListener() {
052
053 /**
054 * {@inheritDoc}
055 */
056 public void notify( String sourceName,
057 Object... events ) {
058 // do nothing
059 }
060 };
061
062 private final String sourceName;
063 private final CachePolicy cachePolicy;
064 private final SVNRepository repository;
065 private final boolean updatesAllowed;
066 private RepositorySourceListener listener = NO_OP_LISTENER;
067
068 public SVNRepositoryConnection( String sourceName,
069 CachePolicy cachePolicy,
070 boolean updatesAllowed,
071 SVNRepository repository ) {
072 CheckArg.isNotNull(repository, "repository");
073 CheckArg.isNotNull(sourceName, "sourceName");
074
075 SVNNodeKind nodeKind = null;
076 try {
077 nodeKind = repository.checkPath("", -1);
078 if (nodeKind == SVNNodeKind.NONE) {
079 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
080 "No entry at URL ''{0}''",
081 repository.getLocation().getPath());
082 throw new SVNException(error);
083 } else if (nodeKind == SVNNodeKind.UNKNOWN) {
084 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
085 "Entry at URL ''{0}'' is a file while directory was expected",
086 repository.getLocation().getPath());
087 throw new SVNException(error);
088 } else if (nodeKind == SVNNodeKind.FILE) {
089 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN,
090 "Entry at URL ''{0}'' is a file while directory was expected",
091 repository.getLocation().getPath());
092 throw new SVNException(error);
093 }
094 } catch (SVNException e) {
095 // deal with the exception
096 throw new RuntimeException(e);
097 }
098
099 this.sourceName = sourceName;
100 this.cachePolicy = cachePolicy;
101 this.repository = repository;
102 this.updatesAllowed = updatesAllowed;
103 }
104
105 SVNRepository getRepository() {
106 return repository;
107 }
108
109 /**
110 * {@inheritDoc}
111 */
112 public String getSourceName() {
113 return sourceName;
114 }
115
116 /**
117 * {@inheritDoc}
118 */
119 public CachePolicy getDefaultCachePolicy() {
120 return cachePolicy;
121 }
122
123 /**
124 * {@inheritDoc}
125 */
126 public XAResource getXAResource() {
127 return null;
128 }
129
130 /**
131 * {@inheritDoc}
132 */
133 public boolean ping( long time,
134 TimeUnit unit ) {
135 try {
136 this.repository.getRepositoryRoot(true);
137 } catch (SVNException e) {
138 return false;
139 }
140 return true;
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 public void setListener( RepositorySourceListener listener ) {
147 this.listener = listener != null ? listener : NO_OP_LISTENER;
148 }
149
150 /**
151 * {@inheritDoc}
152 *
153 * @see org.jboss.dna.graph.connector.RepositoryConnection#close()
154 */
155 public void close() {
156 // do not care about.
157 }
158
159 /**
160 * {@inheritDoc}
161 *
162 * @see org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext,
163 * org.jboss.dna.graph.request.Request)
164 */
165 @SuppressWarnings( "unused" )
166 public void execute( final ExecutionContext context,
167 final Request request ) throws RepositorySourceException {
168
169 final PathFactory pathFactory = context.getValueFactories().getPathFactory();
170 final PropertyFactory propertyFactory = context.getPropertyFactory();
171
172 RequestProcessor processor = new SVNRepositoryRequestProcessor(getSourceName(), context, repository, updatesAllowed);
173 try {
174 processor.process(request);
175 } finally {
176 processor.close();
177 }
178 }
179
180 /**
181 * @return listener
182 */
183 protected RepositorySourceListener getListener() {
184 return this.listener;
185 }
186 }