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.Set; 027 import java.util.concurrent.TimeUnit; 028 import javax.transaction.xa.XAResource; 029 import org.jboss.dna.common.util.CheckArg; 030 import org.jboss.dna.graph.ExecutionContext; 031 import org.jboss.dna.graph.cache.CachePolicy; 032 import org.jboss.dna.graph.connector.RepositoryConnection; 033 import org.jboss.dna.graph.connector.RepositorySourceException; 034 import org.jboss.dna.graph.request.Request; 035 import org.jboss.dna.graph.request.processor.RequestProcessor; 036 import org.tmatesoft.svn.core.SVNErrorCode; 037 import org.tmatesoft.svn.core.SVNErrorMessage; 038 import org.tmatesoft.svn.core.SVNException; 039 import org.tmatesoft.svn.core.SVNNodeKind; 040 import org.tmatesoft.svn.core.io.SVNRepository; 041 042 /** 043 * The defaultRepository connection to a SVN Repository instance. 044 * 045 * @author Serge Pagop 046 */ 047 public class SVNRepositoryConnection implements RepositoryConnection { 048 049 private final String sourceName; 050 private final CachePolicy cachePolicy; 051 private final SVNRepository defaultWorkspace; 052 private final boolean updatesAllowed; 053 private final Set<String> availableWorkspaceNames; 054 private final boolean creatingWorkspacesAllowed; 055 private final RepositoryAccessData accessData; 056 057 /** 058 * default workspace must can be a root repository or any folders from the root directory. 059 * available workspace names must consist of URLs from repository folders. 060 * 061 * @param sourceName 062 * @param defaultWorkspace 063 * @param availableWorkspaceNames 064 * @param creatingWorkspacesAllowed 065 * @param cachePolicy 066 * @param updatesAllowed 067 * @param accessData 068 */ 069 public SVNRepositoryConnection( String sourceName, 070 SVNRepository defaultWorkspace, 071 Set<String> availableWorkspaceNames, 072 boolean creatingWorkspacesAllowed, 073 CachePolicy cachePolicy, 074 boolean updatesAllowed, RepositoryAccessData accessData ) { 075 076 CheckArg.isNotNull(defaultWorkspace, "defaultWorkspace"); 077 CheckArg.isNotEmpty(sourceName, "sourceName"); 078 assert availableWorkspaceNames != null; 079 assert accessData != null; 080 081 // Check if the default workspace is a folder. 082 SVNNodeKind nodeKind = null; 083 try { 084 nodeKind = defaultWorkspace.checkPath("", -1); 085 if (nodeKind == SVNNodeKind.NONE) { 086 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, 087 "No entry at URL ''{0}''", 088 defaultWorkspace.getLocation().getPath()); 089 throw new SVNException(error); 090 } else if (nodeKind == SVNNodeKind.UNKNOWN) { 091 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, 092 "Entry at URL ''{0}'' is a file while directory was expected", 093 defaultWorkspace.getLocation().getPath()); 094 throw new SVNException(error); 095 } else if (nodeKind == SVNNodeKind.FILE) { 096 SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, 097 "Entry at URL ''{0}'' is a file while directory was expected", 098 defaultWorkspace.getLocation().getPath()); 099 throw new SVNException(error); 100 } 101 } catch (SVNException e) { 102 // deal with the exception 103 throw new RuntimeException(e); 104 } 105 106 this.sourceName = sourceName; 107 this.cachePolicy = cachePolicy; 108 this.defaultWorkspace = defaultWorkspace; 109 this.updatesAllowed = updatesAllowed; 110 this.availableWorkspaceNames = availableWorkspaceNames; 111 this.creatingWorkspacesAllowed = creatingWorkspacesAllowed; 112 this.accessData = accessData; 113 } 114 115 SVNRepository getDefaultWorkspace() { 116 return defaultWorkspace; 117 } 118 119 /** 120 * {@inheritDoc} 121 */ 122 public String getSourceName() { 123 return sourceName; 124 } 125 126 /** 127 * {@inheritDoc} 128 */ 129 public CachePolicy getDefaultCachePolicy() { 130 return cachePolicy; 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 public XAResource getXAResource() { 137 return null; 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 public boolean ping( long time, 144 TimeUnit unit ) { 145 try { 146 this.defaultWorkspace.getRepositoryRoot(true); 147 } catch (SVNException e) { 148 return false; 149 } 150 return true; 151 } 152 153 /** 154 * {@inheritDoc} 155 * 156 * @see org.jboss.dna.graph.connector.RepositoryConnection#close() 157 */ 158 public void close() { 159 // do not care about. 160 } 161 162 /** 163 * {@inheritDoc} 164 * 165 * @see org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext, 166 * org.jboss.dna.graph.request.Request) 167 */ 168 public void execute( final ExecutionContext context, 169 final Request request ) throws RepositorySourceException { 170 171 172 RequestProcessor processor = new SVNRepositoryRequestProcessor(sourceName, defaultWorkspace, 173 availableWorkspaceNames, creatingWorkspacesAllowed, 174 context, updatesAllowed, accessData); 175 try { 176 processor.process(request); 177 } finally { 178 processor.close(); 179 } 180 } 181 182 /** 183 * @return the accessData 184 */ 185 public RepositoryAccessData getAccessData() { 186 return accessData; 187 } 188 }