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 }