Coverage Report - org.kuali.maven.wagon.AbstractWagon
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractWagon
0%
0/151
0%
0/14
2.5
 
 1  
 /*
 2  
  * Copyright 2004-2007 the original author or authors.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 5  
  * the License. You may obtain a copy of the License at
 6  
  *
 7  
  * http://www.apache.org/licenses/LICENSE-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 10  
  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 11  
  * specific language governing permissions and limitations under the License.
 12  
  */
 13  
 package org.kuali.maven.wagon;
 14  
 
 15  
 import java.io.File;
 16  
 import java.io.UnsupportedEncodingException;
 17  
 import java.net.URLEncoder;
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 
 21  
 import org.apache.maven.wagon.ConnectionException;
 22  
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 23  
 import org.apache.maven.wagon.TransferFailedException;
 24  
 import org.apache.maven.wagon.Wagon;
 25  
 import org.apache.maven.wagon.authentication.AuthenticationException;
 26  
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 27  
 import org.apache.maven.wagon.authorization.AuthorizationException;
 28  
 import org.apache.maven.wagon.events.SessionListener;
 29  
 import org.apache.maven.wagon.events.TransferEvent;
 30  
 import org.apache.maven.wagon.events.TransferListener;
 31  
 import org.apache.maven.wagon.observers.Debug;
 32  
 import org.apache.maven.wagon.proxy.ProxyInfo;
 33  
 import org.apache.maven.wagon.proxy.ProxyInfoProvider;
 34  
 import org.apache.maven.wagon.repository.Repository;
 35  
 import org.apache.maven.wagon.resource.Resource;
 36  
 
 37  
 /**
 38  
  * An abstract implementation of the Wagon interface. This implementation manages listener and other common behaviors.
 39  
  *
 40  
  * @author Ben Hale
 41  
  * @author Jeff Caddel - Updates for version 2.0 of the Wagon interface
 42  
  * @since 1.1
 43  
  */
 44  
 public abstract class AbstractWagon implements Wagon {
 45  
 
 46  
         private int timeout;
 47  
 
 48  
         private boolean interactive;
 49  
 
 50  
         private Repository repository;
 51  
 
 52  
         private final boolean supportsDirectoryCopy;
 53  
 
 54  0
         private final SessionListenerSupport sessionListeners = new SessionListenerSupport(this);
 55  
 
 56  0
         private final TransferListenerSupport transferListeners = new TransferListenerSupport(this);
 57  
 
 58  0
         protected AbstractWagon(final boolean supportsDirectoryCopy) {
 59  0
                 this.supportsDirectoryCopy = supportsDirectoryCopy;
 60  0
         }
 61  
 
 62  
         public final void addSessionListener(final SessionListener listener) {
 63  0
                 if (listener.getClass().equals(Debug.class)) {
 64  
                         // This is a junky listener that spews things to System.out in an ugly way
 65  0
                         return;
 66  
                 }
 67  0
                 sessionListeners.addListener(listener);
 68  0
         }
 69  
 
 70  
         protected final SessionListenerSupport getSessionListeners() {
 71  0
                 return sessionListeners;
 72  
         }
 73  
 
 74  
         public final boolean hasSessionListener(final SessionListener listener) {
 75  0
                 return sessionListeners.hasListener(listener);
 76  
         }
 77  
 
 78  
         public final void removeSessionListener(final SessionListener listener) {
 79  0
                 sessionListeners.removeListener(listener);
 80  0
         }
 81  
 
 82  
         public final void addTransferListener(final TransferListener listener) {
 83  0
                 transferListeners.addListener(listener);
 84  0
         }
 85  
 
 86  
         protected final TransferListenerSupport getTransferListeners() {
 87  0
                 return transferListeners;
 88  
         }
 89  
 
 90  
         public final boolean hasTransferListener(final TransferListener listener) {
 91  0
                 return transferListeners.hasListener(listener);
 92  
         }
 93  
 
 94  
         public final void removeTransferListener(final TransferListener listener) {
 95  0
                 transferListeners.removeListener(listener);
 96  0
         }
 97  
 
 98  
         public final Repository getRepository() {
 99  0
                 return repository;
 100  
         }
 101  
 
 102  
         public final boolean isInteractive() {
 103  0
                 return interactive;
 104  
         }
 105  
 
 106  
         public final void setInteractive(final boolean interactive) {
 107  0
                 this.interactive = interactive;
 108  0
         }
 109  
 
 110  
         public final void connect(final Repository source) throws ConnectionException, AuthenticationException {
 111  0
                 doConnect(source, null, null);
 112  0
         }
 113  
 
 114  
         public final void connect(final Repository source, final ProxyInfo proxyInfo) throws ConnectionException,
 115  
                         AuthenticationException {
 116  0
                 connect(source, null, proxyInfo);
 117  0
         }
 118  
 
 119  
         public final void connect(final Repository source, final AuthenticationInfo authenticationInfo)
 120  
                         throws ConnectionException, AuthenticationException {
 121  0
                 doConnect(source, authenticationInfo, null);
 122  0
         }
 123  
 
 124  
         protected void doConnect(final Repository source, final AuthenticationInfo authenticationInfo,
 125  
                         final ProxyInfo proxyInfo) throws ConnectionException, AuthenticationException {
 126  0
                 repository = source;
 127  0
                 sessionListeners.fireSessionOpening();
 128  
                 try {
 129  0
                         connectToRepository(source, authenticationInfo, proxyInfo);
 130  0
                 } catch (ConnectionException e) {
 131  0
                         sessionListeners.fireSessionConnectionRefused();
 132  0
                         throw e;
 133  0
                 } catch (AuthenticationException e) {
 134  0
                         sessionListeners.fireSessionConnectionRefused();
 135  0
                         throw e;
 136  0
                 } catch (Exception e) {
 137  0
                         sessionListeners.fireSessionConnectionRefused();
 138  0
                         throw new ConnectionException("Could not connect to repository", e);
 139  0
                 }
 140  0
                 sessionListeners.fireSessionLoggedIn();
 141  0
                 sessionListeners.fireSessionOpened();
 142  0
         }
 143  
 
 144  
         public final void connect(final Repository source, final AuthenticationInfo authenticationInfo,
 145  
                         final ProxyInfo proxyInfo) throws ConnectionException, AuthenticationException {
 146  0
                 doConnect(source, authenticationInfo, proxyInfo);
 147  0
         }
 148  
 
 149  
         public final void disconnect() throws ConnectionException {
 150  0
                 sessionListeners.fireSessionDisconnecting();
 151  
                 try {
 152  0
                         disconnectFromRepository();
 153  0
                 } catch (ConnectionException e) {
 154  0
                         sessionListeners.fireSessionConnectionRefused();
 155  0
                         throw e;
 156  0
                 } catch (Exception e) {
 157  0
                         sessionListeners.fireSessionConnectionRefused();
 158  0
                         throw new ConnectionException("Could not disconnect from repository", e);
 159  0
                 }
 160  0
                 sessionListeners.fireSessionLoggedOff();
 161  0
                 sessionListeners.fireSessionDisconnected();
 162  0
         }
 163  
 
 164  
         public final void get(final String resourceName, final File destination) throws TransferFailedException,
 165  
                         ResourceDoesNotExistException, AuthorizationException {
 166  0
                 Resource resource = new Resource(resourceName);
 167  0
                 transferListeners.fireTransferInitiated(resource, TransferEvent.REQUEST_GET);
 168  0
                 transferListeners.fireTransferStarted(resource, TransferEvent.REQUEST_GET);
 169  
 
 170  
                 try {
 171  0
                         getResource(resourceName, destination, new TransferProgress(resource, TransferEvent.REQUEST_GET,
 172  
                                         transferListeners));
 173  0
                         transferListeners.fireTransferCompleted(resource, TransferEvent.REQUEST_GET);
 174  0
                 } catch (TransferFailedException e) {
 175  0
                         throw e;
 176  0
                 } catch (ResourceDoesNotExistException e) {
 177  0
                         throw e;
 178  0
                 } catch (AuthorizationException e) {
 179  0
                         throw e;
 180  0
                 } catch (Exception e) {
 181  0
                         transferListeners.fireTransferError(resource, TransferEvent.REQUEST_GET, e);
 182  0
                         throw new TransferFailedException("Transfer of resource " + destination + "failed", e);
 183  0
                 }
 184  0
         }
 185  
 
 186  
         public final List<String> getFileList(final String destinationDirectory) throws TransferFailedException,
 187  
                         ResourceDoesNotExistException, AuthorizationException {
 188  
                 try {
 189  0
                         return listDirectory(destinationDirectory);
 190  0
                 } catch (TransferFailedException e) {
 191  0
                         throw e;
 192  0
                 } catch (ResourceDoesNotExistException e) {
 193  0
                         throw e;
 194  0
                 } catch (AuthorizationException e) {
 195  0
                         throw e;
 196  0
                 } catch (Exception e) {
 197  0
                         sessionListeners.fireSessionError(e);
 198  0
                         throw new TransferFailedException("Listing of directory " + destinationDirectory + "failed", e);
 199  
                 }
 200  
         }
 201  
 
 202  
         public final boolean getIfNewer(final String resourceName, final File destination, final long timestamp)
 203  
                         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {
 204  0
                 Resource resource = new Resource(resourceName);
 205  
                 try {
 206  0
                         if (isRemoteResourceNewer(resourceName, timestamp)) {
 207  0
                                 get(resourceName, destination);
 208  0
                                 return true;
 209  
                         } else {
 210  0
                                 return false;
 211  
                         }
 212  0
                 } catch (TransferFailedException e) {
 213  0
                         throw e;
 214  0
                 } catch (ResourceDoesNotExistException e) {
 215  0
                         throw e;
 216  0
                 } catch (AuthorizationException e) {
 217  0
                         throw e;
 218  0
                 } catch (Exception e) {
 219  0
                         transferListeners.fireTransferError(resource, TransferEvent.REQUEST_GET, e);
 220  0
                         throw new TransferFailedException("Transfer of resource " + destination + "failed", e);
 221  
                 }
 222  
         }
 223  
 
 224  
         public final void openConnection() throws ConnectionException, AuthenticationException {
 225  
                 // Nothing to do here (never called by the wagon manager)
 226  0
         }
 227  
 
 228  
         protected PutContext getPutContext(File source, String destination) {
 229  0
                 Resource resource = new Resource(destination);
 230  0
                 PutContext context = new PutContext();
 231  0
                 context.setResource(resource);
 232  0
                 context.setProgress(new TransferProgress(resource, TransferEvent.REQUEST_PUT, transferListeners));
 233  0
                 context.setListeners(transferListeners);
 234  0
                 context.setDestination(destination);
 235  0
                 context.setSource(source);
 236  0
                 return context;
 237  
         }
 238  
 
 239  
         public final void put(final File source, final String destination) throws TransferFailedException,
 240  
                         ResourceDoesNotExistException, AuthorizationException {
 241  0
                 PutContext context = getPutContext(source, destination);
 242  
 
 243  
                 try {
 244  0
                         context.fireStart();
 245  0
                         putResource(source, destination, context.getProgress());
 246  0
                         context.fireComplete();
 247  0
                 } catch (Exception e) {
 248  0
                         handleException(e, context);
 249  0
                 }
 250  0
         }
 251  
 
 252  
         protected void handleException(Exception e, PutContext context) throws TransferFailedException,
 253  
                         ResourceDoesNotExistException, AuthorizationException {
 254  0
                 if (e instanceof TransferFailedException) {
 255  0
                         throw (TransferFailedException) e;
 256  
                 }
 257  0
                 if (e instanceof ResourceDoesNotExistException) {
 258  0
                         throw (ResourceDoesNotExistException) e;
 259  
                 }
 260  0
                 if (e instanceof AuthorizationException) {
 261  0
                         throw (AuthorizationException) e;
 262  
                 }
 263  0
                 transferListeners.fireTransferError(context.getResource(), TransferEvent.REQUEST_PUT, e);
 264  0
                 throw new TransferFailedException("Transfer of resource " + context.getDestination() + "failed", e);
 265  
         }
 266  
 
 267  
         protected List<PutContext> getPutContexts(File sourceDirectory, String destinationDirectory) {
 268  0
                 List<PutContext> contexts = new ArrayList<PutContext>();
 269  
                 // Cycle through all the files in this directory
 270  0
                 for (File f : sourceDirectory.listFiles()) {
 271  
 
 272  
                         /**
 273  
                          * The filename is used 2 ways:<br>
 274  
                          *
 275  
                          * 1 - as a "key" into the bucket<br>
 276  
                          * 2 - In the http url itself<br>
 277  
                          *
 278  
                          * We encode it here so the key matches the url AND to guarantee that the url is valid even in cases where
 279  
                          * filenames contain characters (eg spaces) that are not allowed in urls
 280  
                          */
 281  0
                         String filename = encodeUTF8(f.getName());
 282  
 
 283  
                         // We hit a directory
 284  0
                         if (f.isDirectory()) {
 285  
                                 // Recurse into the sub-directory and create put requests for any files we find
 286  0
                                 contexts.addAll(getPutContexts(f, destinationDirectory + "/" + filename));
 287  
                         } else {
 288  0
                                 PutContext context = getPutContext(f, destinationDirectory + "/" + filename);
 289  0
                                 contexts.add(context);
 290  
                         }
 291  
                 }
 292  0
                 return contexts;
 293  
         }
 294  
 
 295  
         protected String encodeUTF8(String s) {
 296  
                 try {
 297  0
                         return URLEncoder.encode(s, "UTF-8");
 298  0
                 } catch (UnsupportedEncodingException e) {
 299  0
                         throw new RuntimeException(e);
 300  
                 }
 301  
         }
 302  
 
 303  
         public final boolean resourceExists(final String resourceName) throws TransferFailedException,
 304  
                         AuthorizationException {
 305  
                 try {
 306  0
                         return doesRemoteResourceExist(resourceName);
 307  0
                 } catch (TransferFailedException e) {
 308  0
                         throw e;
 309  0
                 } catch (AuthorizationException e) {
 310  0
                         throw e;
 311  0
                 } catch (Exception e) {
 312  0
                         sessionListeners.fireSessionError(e);
 313  0
                         throw new TransferFailedException("Listing of resource " + resourceName + "failed", e);
 314  
                 }
 315  
         }
 316  
 
 317  
         public final boolean supportsDirectoryCopy() {
 318  0
                 return supportsDirectoryCopy;
 319  
         }
 320  
 
 321  
         /**
 322  
          * Subclass must implement with specific connection behavior
 323  
          *
 324  
          * @param source
 325  
          *            The repository connection information
 326  
          * @param authenticationInfo
 327  
          *            Authentication information, if any
 328  
          * @param proxyInfo
 329  
          *            Proxy information, if any
 330  
          * @throws Exception
 331  
          *             Implementations can throw any exception and it will be handled by the base class
 332  
          */
 333  
         protected abstract void connectToRepository(Repository source, AuthenticationInfo authenticationInfo,
 334  
                         ProxyInfo proxyInfo) throws Exception;
 335  
 
 336  
         /**
 337  
          * Subclass must implement with specific detection behavior
 338  
          *
 339  
          * @param resourceName
 340  
          *            The remote resource to detect
 341  
          * @return true if the remote resource exists
 342  
          * @throws Exception
 343  
          *             Implementations can throw any exception and it will be handled by the base class
 344  
          */
 345  
         protected abstract boolean doesRemoteResourceExist(String resourceName) throws Exception;
 346  
 
 347  
         /**
 348  
          * Subclasses must implement with specific disconnection behavior
 349  
          *
 350  
          * @throws Exception
 351  
          *             Implementations can throw any exception and it will be handled by the base class
 352  
          */
 353  
         protected abstract void disconnectFromRepository() throws Exception;
 354  
 
 355  
         /**
 356  
          * Subclass must implement with specific get behavior
 357  
          *
 358  
          * @param resourceName
 359  
          *            The name of the remote resource to read
 360  
          * @param destination
 361  
          *            The local file to write to
 362  
          * @param progress
 363  
          *            A progress notifier for the upload. It must be used or hashes will not be calculated correctly
 364  
          * @throws Exception
 365  
          *             Implementations can throw any exception and it will be handled by the base class
 366  
          */
 367  
         protected abstract void getResource(String resourceName, File destination, TransferProgress progress)
 368  
                         throws Exception;
 369  
 
 370  
         /**
 371  
          * Subclass must implement with newer detection behavior
 372  
          *
 373  
          * @param resourceName
 374  
          *            The name of the resource being compared
 375  
          * @param timestamp
 376  
          *            The timestamp to compare against
 377  
          * @return true if the current version of the resource is newer than the timestamp
 378  
          * @throws Exception
 379  
          *             Implementations can throw any exception and it will be handled by the base class
 380  
          */
 381  
         protected abstract boolean isRemoteResourceNewer(String resourceName, long timestamp) throws Exception;
 382  
 
 383  
         /**
 384  
          * Subclass must implement with specific directory listing behavior
 385  
          *
 386  
          * @param directory
 387  
          *            The directory to list files in
 388  
          * @return A collection of file names
 389  
          * @throws Exception
 390  
          *             Implementations can throw any exception and it will be handled by the base class
 391  
          */
 392  
         protected abstract List<String> listDirectory(String directory) throws Exception;
 393  
 
 394  
         /**
 395  
          * Subclasses must implement with specific put behavior
 396  
          *
 397  
          * @param source
 398  
          *            The local source file to read from
 399  
          * @param destination
 400  
          *            The name of the remote resource to write to
 401  
          * @param progress
 402  
          *            A progress notifier for the upload. It must be used or hashes will not be calculated correctly
 403  
          * @throws Exception
 404  
          *             Implementations can throw any exception and it will be handled by the base class
 405  
          */
 406  
         protected abstract void putResource(File source, String destination, TransferProgress progress) throws Exception;
 407  
 
 408  
         public void connect(final Repository source, final AuthenticationInfo authenticationInfo,
 409  
                         final ProxyInfoProvider proxyInfoProvider) throws ConnectionException, AuthenticationException {
 410  0
                 doConnect(source, authenticationInfo, null);
 411  0
         }
 412  
 
 413  
         public void connect(final Repository source, final ProxyInfoProvider proxyInfoProvider) throws ConnectionException,
 414  
                         AuthenticationException {
 415  0
                 doConnect(source, null, null);
 416  0
         }
 417  
 
 418  
         public int getTimeout() {
 419  0
                 return this.timeout;
 420  
         }
 421  
 
 422  
         public void setTimeout(final int timeoutValue) {
 423  0
                 this.timeout = timeoutValue;
 424  0
         }
 425  
 
 426  
 }