/*
 * Copyright (C) 2011, Google Inc.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.transport;

import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Repository;

Describes a way to connect to another Git repository.

Implementations of this class are typically immutable singletons held by static class members, for example:

package com.example.my_transport;
class MyTransport extends Transport {
	public static final TransportProtocol PROTO = new TransportProtocol() {
		public String getName() {
			return "My Protocol";
		}
	};
}

Applications may register additional protocols for use by JGit by calling Transport.register(TransportProtocol). Because that API holds onto the protocol object by a WeakReference, applications must ensure their own ClassLoader retains the TransportProtocol for the life of the application. Using a static singleton pattern as above will ensure the protocol is valid so long as the ClassLoader that defines it remains valid.

Applications may automatically register additional protocols by filling in the names of their TransportProtocol defining classes using the services file META-INF/services/org.eclipse.jgit.transport.Transport. For each class name listed in the services file, any static fields of type TransportProtocol will be automatically registered. For the above example the string com.example.my_transport.MyTransport should be listed in the file, as that is the name of the class that defines the static PROTO singleton.

/** * Describes a way to connect to another Git repository. * <p> * Implementations of this class are typically immutable singletons held by * static class members, for example: * * <pre> * package com.example.my_transport; * * class MyTransport extends Transport { * public static final TransportProtocol PROTO = new TransportProtocol() { * public String getName() { * return &quot;My Protocol&quot;; * } * }; * } * </pre> * * <p> * Applications may register additional protocols for use by JGit by calling * {@link org.eclipse.jgit.transport.Transport#register(TransportProtocol)}. * Because that API holds onto the protocol object by a WeakReference, * applications must ensure their own ClassLoader retains the TransportProtocol * for the life of the application. Using a static singleton pattern as above * will ensure the protocol is valid so long as the ClassLoader that defines it * remains valid. * <p> * Applications may automatically register additional protocols by filling in * the names of their TransportProtocol defining classes using the services file * {@code META-INF/services/org.eclipse.jgit.transport.Transport}. For each * class name listed in the services file, any static fields of type * {@code TransportProtocol} will be automatically registered. For the above * example the string {@code com.example.my_transport.MyTransport} should be * listed in the file, as that is the name of the class that defines the static * PROTO singleton. */
public abstract class TransportProtocol {
Fields within a URIish that a transport uses.
/** Fields within a {@link URIish} that a transport uses. */
public static enum URIishField {
the user field
/** the user field */
USER,
the pass (aka password) field
/** the pass (aka password) field */
PASS,
the host field
/** the host field */
HOST,
the port field
/** the port field */
PORT,
the path field
/** the path field */
PATH, }
Get text name of the protocol suitable for display to a user.
Returns:text name of the protocol suitable for display to a user.
/** * Get text name of the protocol suitable for display to a user. * * @return text name of the protocol suitable for display to a user. */
public abstract String getName();
Get immutable set of schemes supported by this protocol.
Returns:immutable set of schemes supported by this protocol.
/** * Get immutable set of schemes supported by this protocol. * * @return immutable set of schemes supported by this protocol. */
public Set<String> getSchemes() { return Collections.emptySet(); }
Get immutable set of URIishFields that must be filled in.
Returns:immutable set of URIishFields that must be filled in.
/** * Get immutable set of URIishFields that must be filled in. * * @return immutable set of URIishFields that must be filled in. */
public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.PATH)); }
Get immutable set of URIishFields that may be filled in.
Returns:immutable set of URIishFields that may be filled in.
/** * Get immutable set of URIishFields that may be filled in. * * @return immutable set of URIishFields that may be filled in. */
public Set<URIishField> getOptionalFields() { return Collections.emptySet(); }
Get the default port if the protocol supports a port, else -1.
Returns:the default port if the protocol supports a port, else -1.
/** * Get the default port if the protocol supports a port, else -1. * * @return the default port if the protocol supports a port, else -1. */
public int getDefaultPort() { return -1; }
Determine if this protocol can handle a particular URI.

Implementations should try to avoid looking at the local filesystem, but may look at implementation specific configuration options in the remote block of local.getConfig() using remoteName if the name is non-null.

The default implementation of this method matches the scheme against getSchemes(), required fields against getRequiredFields(), and optional fields against getOptionalFields(), returning true only if all of the fields match the specification.

Params:
  • uri – address of the Git repository; never null.
Returns:true if this protocol can handle this URI; false otherwise.
/** * Determine if this protocol can handle a particular URI. * <p> * Implementations should try to avoid looking at the local filesystem, but * may look at implementation specific configuration options in the remote * block of {@code local.getConfig()} using {@code remoteName} if the name * is non-null. * <p> * The default implementation of this method matches the scheme against * {@link #getSchemes()}, required fields against * {@link #getRequiredFields()}, and optional fields against * {@link #getOptionalFields()}, returning true only if all of the fields * match the specification. * * @param uri * address of the Git repository; never null. * @return true if this protocol can handle this URI; false otherwise. */
public boolean canHandle(URIish uri) { return canHandle(uri, null, null); }
Determine if this protocol can handle a particular URI.

Implementations should try to avoid looking at the local filesystem, but may look at implementation specific configuration options in the remote block of local.getConfig() using remoteName if the name is non-null.

The default implementation of this method matches the scheme against getSchemes(), required fields against getRequiredFields(), and optional fields against getOptionalFields(), returning true only if all of the fields match the specification.

Params:
  • uri – address of the Git repository; never null.
  • local – the local repository that will communicate with the other Git repository. May be null if the caller is only asking about a specific URI and does not have a local Repository.
  • remoteName – name of the remote, if the remote as configured in local; otherwise null.
Returns:true if this protocol can handle this URI; false otherwise.
/** * Determine if this protocol can handle a particular URI. * <p> * Implementations should try to avoid looking at the local filesystem, but * may look at implementation specific configuration options in the remote * block of {@code local.getConfig()} using {@code remoteName} if the name * is non-null. * <p> * The default implementation of this method matches the scheme against * {@link #getSchemes()}, required fields against * {@link #getRequiredFields()}, and optional fields against * {@link #getOptionalFields()}, returning true only if all of the fields * match the specification. * * @param uri * address of the Git repository; never null. * @param local * the local repository that will communicate with the other Git * repository. May be null if the caller is only asking about a * specific URI and does not have a local Repository. * @param remoteName * name of the remote, if the remote as configured in * {@code local}; otherwise null. * @return true if this protocol can handle this URI; false otherwise. */
public boolean canHandle(URIish uri, Repository local, String remoteName) { if (!getSchemes().isEmpty() && !getSchemes().contains(uri.getScheme())) return false; for (URIishField field : getRequiredFields()) { switch (field) { case USER: if (uri.getUser() == null || uri.getUser().length() == 0) return false; break; case PASS: if (uri.getPass() == null || uri.getPass().length() == 0) return false; break; case HOST: if (uri.getHost() == null || uri.getHost().length() == 0) return false; break; case PORT: if (uri.getPort() <= 0) return false; break; case PATH: if (uri.getPath() == null || uri.getPath().length() == 0) return false; break; default: return false; } } Set<URIishField> canHave = EnumSet.copyOf(getRequiredFields()); canHave.addAll(getOptionalFields()); if (uri.getUser() != null && !canHave.contains(URIishField.USER)) return false; if (uri.getPass() != null && !canHave.contains(URIishField.PASS)) return false; if (uri.getHost() != null && !canHave.contains(URIishField.HOST)) return false; if (uri.getPort() > 0 && !canHave.contains(URIishField.PORT)) return false; if (uri.getPath() != null && !canHave.contains(URIishField.PATH)) return false; return true; }
Open a Transport instance to the other repository.

Implementations should avoid making remote connections until an operation on the returned Transport is invoked, however they may fail fast here if they know a connection is impossible, such as when using the local filesystem and the target path does not exist.

Implementations may access implementation-specific configuration options within local.getConfig() using the remote block named by the remoteName, if the name is non-null.

Params:
  • uri – address of the Git repository.
  • local – the local repository that will communicate with the other Git repository.
  • remoteName – name of the remote, if the remote as configured in local; otherwise null.
Throws:
Returns:the transport.
/** * Open a Transport instance to the other repository. * <p> * Implementations should avoid making remote connections until an operation * on the returned Transport is invoked, however they may fail fast here if * they know a connection is impossible, such as when using the local * filesystem and the target path does not exist. * <p> * Implementations may access implementation-specific configuration options * within {@code local.getConfig()} using the remote block named by the * {@code remoteName}, if the name is non-null. * * @param uri * address of the Git repository. * @param local * the local repository that will communicate with the other Git * repository. * @param remoteName * name of the remote, if the remote as configured in * {@code local}; otherwise null. * @return the transport. * @throws org.eclipse.jgit.errors.NotSupportedException * this protocol does not support the URI. * @throws org.eclipse.jgit.errors.TransportException * the transport cannot open this URI. */
public abstract Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException, TransportException;
Open a new transport instance to the remote repository. Use default configuration instead of reading from configuration files.
Params:
Throws:
Returns:new Transport
/** * Open a new transport instance to the remote repository. Use default * configuration instead of reading from configuration files. * * @param uri * a {@link org.eclipse.jgit.transport.URIish} object. * @return new Transport * @throws org.eclipse.jgit.errors.NotSupportedException * @throws org.eclipse.jgit.errors.TransportException */
public Transport open(URIish uri) throws NotSupportedException, TransportException { throw new NotSupportedException(JGitText .get().transportNeedsRepository); } }